New builtin types implementation 2026 - brython-dev/brython GitHub Wiki

This page describes the implementation of Python builtin types after a complete rewriting in 2026.

The Brython namespace is defined in the Javascript object __BRYTHON__, abbreviated as $B in Brython scripts.

Python builtins are defined in the attribute __BRYTHON__.builtins, abbreviated as _b_ in Brython scripts. For instance, the builtin type bytearray is stored as _b_.bytearray.

1. Initializing builtin types

The builtin types are all initialized in script init_builtin_types.js before their features are defined in the rest of the scripts. This script itself is generated by the Python program scripts/get_info_from_cpython.py.

For instance, set is initialized as the Javascript object

{
    tp_name: "set",
    tp_flags: 4216066,
    tp_base: _b_.object,
    tp_doc: `Build an unordered collection of unique elements.`,
    tp_bases: [_b_.object]
}

The types that are available in Python builtins (such as object, int, etc.) are defined as attributes of _b_ (_b_.object, _b_.int...). The other builtin types such as the type of functions, generators, etc. are attributes of $B ($B.function, $B.generator, etc.)

2. Types features

As in CPython, builtin types have attributes of different kinds:

  • slots: the attributes defined for usual dunder methods; for instance, the slot for the dunder method __new__ is tp_new. The dunder method exposed to Python programs is a wrapper around the slot. A complete list of type slots is available in the documentation
  • methods: similar to regular methods in a user-defined class. For instance, set.add() is implemented as a method
  • classmethods and staticmethods: same for classmethods and staticmethods
  • members: for attributes that are not stored in the instance dictionary, but directly on the instance itself
  • getset descriptors: for the attributes of instances of the type that are computed, set or deleted using a function

3. Type features in Brython scripts

The features for a specific type are defined in a Brython script. For instance, type is defined in py_type.js, set in py_set.js, etc.

For a given type cls, the features are defined in different ways:

  • cls.ob_type is the type of cls (the result of type(cls) in Python)
  • slots are implemented as attributes of cls: for instance slot tp_init is defined as cls.tp_init
  • methods, classmethods and staticmethods are defined as attributes of an object cls.tp_funcs, aliased as cls_funcs in the scripts. For instance, method int.to_bytes() is implemented as int_funcs.to_bytes(). The list of method names is stored in the attributes cls.tp_methods, cls.classmethods and cls.staticmethods
  • members are defined as a list cls.tp_members of 4-element lists, one for each member. For instance, the attributes name and obj of an AttributeError instance are defined by the list
_b_.AttributeError.tp_members = [
    ["name", $B.TYPES.OBJECT, "name", 0],
    ["obj", $B.TYPES.OBJECT, "obj", 0]
]
  • getset descriptors are implemented by 2 functions, one to get the attribute, one to set or delete it. For instance, the attribute __defaults__ of a function is obtained by function __defaults___get(obj) and can be set / deleted by __defaults___set(func, value). The list of getset descriptors is stored in cls.tp_getset

4. Finalizing builtin types

When all built-in types have been defined, the script finalize_builtin_types.js scans all the builtin types. It creates a dictionary for each type, and sets its keys / values.

For instance, if a type cls has an attribute mp_length, it defines cls.dict['__len__'] as a specific object, an instance of the internal class $B.wrapper_descriptor, which references the underlying function cls.mp_length.

NON BACKWARD COMPATIBLE CHANGES

  • when using Javascript BigInt inside a Python program, adding it to an integer or a number no longer raises TypeError

OTHER CHANGES

  • as before, "safe integers" (< 2 ** 53 - 1) are implemented as JS objects of type "number", but non-safe integers are implemented as JS objects of type "bigint" instead of being wrapped inside a JS object {class: $B.long_int, value: <bigint>}
⚠️ **GitHub.com Fallback** ⚠️