Skip to content

Added documentation for ffi.is_none(ref) #189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/beginning-pyscript.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ module in the document's `<head>` tag:
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>🦜 Polyglot - Piratical PyScript</title>
<link rel="stylesheet" href="https://pyscript.net/releases/2025.7.3/core.css">
<script type="module" src="https://pyscript.net/releases/2025.7.3/core.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2025.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2025.8.1/core.js"></script>
</head>
<body>

Expand Down Expand Up @@ -168,8 +168,8 @@ In the end, our HTML should look like this:
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>🦜 Polyglot - Piratical PyScript</title>
<link rel="stylesheet" href="https://pyscript.net/releases/2025.7.3/core.css">
<script type="module" src="https://pyscript.net/releases/2025.7.3/core.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2025.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2025.8.1/core.js"></script>
</head>
<body>
<h1>Polyglot 🦜 💬 🇬🇧 ➡️ 🏴‍☠️</h1>
Expand Down
50 changes: 50 additions & 0 deletions docs/user-guide/ffi.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Our `pyscript.ffi` offers the following utilities:
counterpart.
* `ffi.create_proxy(def_or_lambda)` proxies a generic Python function into a
JavaScript one, without destroying its reference right away.
* `ffi.is_none(reference)` to check if a specific value is either `None` or `JsNull`.

Should you require access to Pyodide or MicroPython's specific version of the
FFI you'll find them under the `pyodide.ffi` and `micropython.ffi` namespaces.
Expand Down Expand Up @@ -209,3 +210,52 @@ only in Pyodide can we then destroy such proxy:
js.setTimeout(proxy, 1000, "success");
</script>
```

## is_none

*Pyodide* version `0.28` onwards has introduced a new *nullish* value that
precisely represents JavaScript's `null` value.

Previously, both JavaScript `null` and `undefined` would have been converted
into Python's `None` but, alas, some APIs behave differently if a value is
`undefined` or explicitly `null`.

For example, in *JSON*, `null` would survive serialization while `undefined`
would vanish. To preserve that distinction in *Python*, the conversion
between *JS* and *Python* now has a new `pyodide.ffi.jsnull` as explained in
the
[pyodide documentation](https://pyodide.org/en/stable/usage/type-conversions.html#javascript-to-python).

In general, there should be no surprises. But, especially when dealing with the
*DOM* world, most utilities and methods return `null`.

To simplify and smooth-out this distinction, we decided to introduce `is_null`,
as [demoed here](https://pyscript.com/@agiammarchi/pyscript-ffi-is-none/latest?files=main.py):

```html title="pyscript.ffi.is_none"
<!-- success in both Pyodide and MicroPython -->
<script type="py">
from pyscript.ffi import is_none
import js

js_undefined = js.undefined
js_null = js.document.body.getAttribute("nope")

print(js_undefined is None) # True
print(js_null) # jsnull
print(js_null is None) # False

# JsNull is still a "falsy" value
if (js_null):
print("this will not be shown")

# safely compared against both
print(is_none(js_undefined)) # True
print(is_none(js_none)) # True
</script>
```

Please note that in *MicroPython* the method works the same but, as we try to
reach feature-parity among runtimes, it is suggested to use `is_none(ref)`
even if, right now, there is no such distinction between `null` and
`undefined` in MicroPython.
4 changes: 2 additions & 2 deletions docs/user-guide/first-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ CSS:
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!-- PyScript CSS -->
<link rel="stylesheet" href="https://pyscript.net/releases/2025.7.3/core.css">
<link rel="stylesheet" href="https://pyscript.net/releases/2025.8.1/core.css">
<!-- This script tag bootstraps PyScript -->
<script type="module" src="https://pyscript.net/releases/2025.7.3/core.js"></script>
<script type="module" src="https://pyscript.net/releases/2025.8.1/core.js"></script>
</head>
<body>
<!-- your code goes here... -->
Expand Down
10 changes: 5 additions & 5 deletions docs/user-guide/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ For example, this will work because all references are contained within the
registered function:

```js
import { hooks } from "https://pyscript.net/releases/2025.7.3/core.js";
import { hooks } from "https://pyscript.net/releases/2025.8.1/core.js";

hooks.worker.onReady.add(() => {
// NOT suggested, just an example!
Expand All @@ -114,7 +114,7 @@ hooks.worker.onReady.add(() => {
However, due to the outer reference to the variable `i`, this will fail:

```js
import { hooks } from "https://pyscript.net/releases/2025.7.3/core.js";
import { hooks } from "https://pyscript.net/releases/2025.8.1/core.js";

// NO NO NO NO NO! ☠️
let i = 0;
Expand Down Expand Up @@ -147,7 +147,7 @@ the page.

```js title="log.js - a plugin that simply logs to the console."
// import the hooks from PyScript first...
import { hooks } from "https://pyscript.net/releases/2025.7.3/core.js";
import { hooks } from "https://pyscript.net/releases/2025.8.1/core.js";

// The `hooks.main` attribute defines plugins that run on the main thread.
hooks.main.onReady.add((wrap, element) => {
Expand Down Expand Up @@ -197,8 +197,8 @@ hooks.worker.onAfterRun.add(() => {
<!-- JS plugins should be available before PyScript bootstraps -->
<script type="module" src="./log.js"></script>
<!-- PyScript -->
<link rel="stylesheet" href="https://pyscript.net/releases/2025.7.3/core.css">
<script type="module" src="https://pyscript.net/releases/2025.7.3/core.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2025.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2025.8.1/core.js"></script>
</head>
<body>
<script type="mpy">
Expand Down
4 changes: 2 additions & 2 deletions docs/user-guide/pygame-ce.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ will be placed. Make sure to update the pyscript release to the latest version.
<title>PyScript Pygame-CE Quickstart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2025.7.3/core.css">
<script type="module" src="https://pyscript.net/releases/2025.7.3/core.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2025.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2025.8.1/core.js"></script>
</head>
<body>
<canvas id="canvas" style="image-rendering: pixelated"></canvas>
Expand Down
4 changes: 2 additions & 2 deletions docs/user-guide/workers.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,9 @@ Here's how:
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- PyScript CSS -->
<link rel="stylesheet" href="https://pyscript.net/releases/2025.7.3/core.css">
<link rel="stylesheet" href="https://pyscript.net/releases/2025.8.1/core.css">
<!-- This script tag bootstraps PyScript -->
<script type="module" src="https://pyscript.net/releases/2025.7.3/core.js"></script>
<script type="module" src="https://pyscript.net/releases/2025.8.1/core.js"></script>
<title>PyWorker - mpy bootstrapping pyodide example</title>
<script type="mpy" src="main.py"></script>
</head>
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "2025.7.3"
"version": "2025.8.1"
}