Skip to content

Supported Python

p2w compiles a single Python 3.12 source file. This page lists what it compiles; Known bugs and limitations lists what it refuses and the places where it still differs from CPython.

The contract is CPython's behaviour: a program that compiles should print what python3 prints. A construct that p2w cannot compile with the same meaning is refused at compile time with a NotImplementedError naming it.

Values

Type Notes
int 31-bit values are unboxed i31refs; larger ones are boxed 64-bit integers. Overflow past 64 bits raises OverflowError: there are no big integers. // and % round as Python does, toward negative infinity.
float IEEE 754 doubles, printed with CPython's repr.
bool, None
str Indexed by code point; UTF-8 in memory. Case mapping (upper, lower, …) is ASCII only.
bytes Literals, indexing, len, str.encode. Slicing and iteration are not supported yet.
list, tuple Indexing, negative indices, slices with a step, slice assignment and deletion, +, *, in, comparison.
dict An ordered hash table, iterated in insertion order; | and |=.
set A hash table; |, &, -, ^ and their in-place forms.
Functions, classes, bound methods Values like any other: stored, passed, returned, called.

Methods

str
upper lower capitalize title swapcase casefold strip lstrip rstrip startswith endswith find rfind index rindex count replace split rsplit splitlines partition rpartition join ljust rjust center zfill encode format and the is… predicates; % formatting.
list
append extend insert pop remove index count reverse sort (with key and reverse) copy clear.
dict
keys values items get pop setdefault update copy clear.
set
add remove discard pop union intersection difference symmetric_difference issubset issuperset isdisjoint.
int
bit_length to_bytes.

Statements and expressions

  • Assignment of every form: tuple and starred unpacking of any iterable, chained targets, augmented assignment to names, attributes and items (in place where the type is mutable: list +=, set |=, __iadd__), the walrus operator.
  • if/elif/else, while and for with break, continue and else, pass, del, assert, global, nonlocal.
  • Comprehensions: list, dict and set comprehensions, and generator expressions, which are real generators.
  • Chained comparisons, conditional expressions, and/or returning an operand, is, in.
  • f-strings with conversions (!r, !s) and format specs: fill, alignment, zero padding, width, ,, precision, and the types d b o x f %. An explicit sign, #, and the e and g types are refused. str.format takes positional and keyword fields.
  • match with value, singleton, capture, wildcard, or-, sequence and mapping patterns, and guards. Class patterns are refused.
  • with, with any object that has __enter__ and __exit__, and several managers in one statement.

Functions

  • Positional, default, keyword, keyword-only, *args and **kwargs parameters; keyword arguments to any callable, including one whose signature the call site cannot see (a decorator's f(*args, **kwargs), a callback).
  • Closures, nonlocal, nested functions, lambdas.
  • Decorators on functions and methods.
  • Recursion. Small non-recursive functions are inlined at their call sites.

Classes

  • Single inheritance, super(), methods, class attributes, @staticmethod, @classmethod, @property with setters.
  • Special methods: __init__, __str__, __repr__, __eq__ and the other comparisons, the arithmetic operators and their reflected and in-place forms, __neg__, __len__, __getitem__, __setitem__, __contains__, __iter__, __next__, __call__, __enter__, __exit__, __hash__. The bitwise operators (__and__, __or__, __xor__) are not dispatched, and the truth value of an instance ignores __bool__ and __len__.
  • __slots__: a slotted class compiles to a WebAssembly GC struct with one field per slot, and attribute access to a single struct.get (see Performance).
  • User-defined exceptions, which are classes deriving from Exception.

Multiple inheritance, class decorators and metaclasses are refused.

Generators

Generator functions with yield anywhere in their body, inside any nesting of if, while, for, try and with; yield from; send(); a generator's return value, carried by StopIteration; iter() and next() on generators and on classes with __iter__/__next__. throw() and close() into a try around the yield do not work yet.

Exceptions

try/except/else/finally, except with a tuple of classes or as, bare raise, raise … from … (__cause__), and the builtin exception hierarchy. Implicit chaining does not set __context__ yet. Builtins raise what CPython raises, with CPython's messages, for the common cases: ZeroDivisionError, IndexError, KeyError, ValueError, AttributeError, OverflowError, StopIteration. Some type errors still trap instead of raising TypeError (see Known bugs). An uncaught exception ends the program with an error.

Builtins

abs all any ascii bin bool bytes callable chr delattr dict divmod enumerate filter float getattr hasattr hash hex id int isinstance issubclass iter len list map max min next oct ord pow print range repr reversed round set setattr sorted str sum super tuple type zip.

min, max and sorted take key=; sorted takes reverse=; print takes sep= and end=, but not file=.

Modules

A program is one file. Three imports are understood, and compiled away: they bind no module object.

math
The constants pi, e, tau, inf and nan. sqrt, floor, ceil, trunc, fabs, copysign, degrees, radians, isnan, isinf, isfinite, gcd, factorial, isqrt and pow are computed in WebAssembly; log, log2, log10, log1p, exp, expm1, the trigonometric and hyperbolic functions and their inverses, atan2, hypot and cbrt are host imports. Both import math and from math import … work.
typing
TYPE_CHECKING is False, cast(T, x) is x, and annotations are not evaluated. Reading any other typing name at run time is refused.
js
Access to the browser's DOM and Canvas from a page; see below.

Every other module, from collections to sys, is refused.

In the browser

A module compiled from a program that imports js can drive the page it runs in:

import js

canvas = js.document.getElementById("chart")
ctx = canvas.getContext("2d")
ctx.fillStyle = "steelblue"
ctx.fillRect(0, 0, 100, 100)
js.console.log("Hello from Python!")

JavaScript objects stay on the JavaScript side; Python holds handles to them. About 25 DOM and Canvas methods are compiled to dedicated imports, and the page provides those imports in a loader.js. This part of p2w is the least finished: the generic fallback for other methods does not pass its arguments yet, and the two demos in demos/ do not run. JavaScript interop describes the design.

Type annotations

Annotations do not change what a program means. They let the compiler choose a faster representation: float and the native types i32, i64 and f64 keep numbers unboxed, and list[float] or dict[str, int] tell it what a container holds. See Performance and native types.