Skip to content
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
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ jobs:
- run: uv run --no-sync python runtime/check_classes.py --target browser --corpus tests/fixtures/interpreter/generators.json --stepped --report build/generators-browser-stepped-report.json
- run: uv run --no-sync python runtime/check_classes.py --target browser --corpus tests/fixtures/interpreter/generators.json --profile core-source/1 --report build/generators-core-browser-report.json
- run: uv run --no-sync python runtime/check_classes.py --target browser --corpus tests/fixtures/interpreter/generators.json --profile core-source/1 --stepped --report build/generators-core-browser-stepped-report.json
- run: uv run --no-sync python runtime/check_classes.py --target browser --corpus tests/fixtures/interpreter/object-protocols.json --report build/object-protocols-browser-report.json
- run: uv run --no-sync python runtime/check_classes.py --target browser --corpus tests/fixtures/interpreter/object-protocols.json --stepped --report build/object-protocols-browser-stepped-report.json
- run: uv run --no-sync python runtime/check_classes.py --target browser --report build/classes-browser-report.json
- run: uv run --no-sync python runtime/check_classes.py --target browser --corpus tests/fixtures/interpreter/value-families.json --report build/value-families-browser-report.json
- run: uv run --no-sync python runtime/check_classes.py --target browser --corpus tests/fixtures/interpreter/value-families.json --stepped --report build/value-families-browser-stepped-report.json
Expand Down Expand Up @@ -162,6 +164,7 @@ jobs:
- run: node --test runtime/memory.test.mjs
- run: node --test runtime/syntax.test.mjs
- run: node --test runtime/function-binding.test.mjs
- run: node --test runtime/object-protocols.test.mjs
- run: node --test runtime/generators.test.mjs
- run: node --test runtime/functions.test.mjs
- run: node --test runtime/execution.test.mjs
Expand Down Expand Up @@ -196,6 +199,8 @@ jobs:
- run: python runtime/check_classes.py --target node --corpus tests/fixtures/interpreter/generators.json --stepped --report build/generators-node-stepped-report.json
- run: python runtime/check_classes.py --target node --corpus tests/fixtures/interpreter/generators.json --profile core-source/1 --report build/generators-core-node-report.json
- run: python runtime/check_classes.py --target node --corpus tests/fixtures/interpreter/generators.json --profile core-source/1 --stepped --report build/generators-core-node-stepped-report.json
- run: python runtime/check_classes.py --target node --corpus tests/fixtures/interpreter/object-protocols.json --report build/object-protocols-node-report.json
- run: python runtime/check_classes.py --target node --corpus tests/fixtures/interpreter/object-protocols.json --stepped --report build/object-protocols-node-stepped-report.json
- run: python runtime/check_classes.py --target node --report build/classes-node-report.json
- run: python runtime/check_classes.py --target node --corpus tests/fixtures/interpreter/value-families.json --report build/value-families-node-report.json
- run: python runtime/check_classes.py --target node --corpus tests/fixtures/interpreter/value-families.json --stepped --report build/value-families-node-stepped-report.json
Expand Down
46 changes: 27 additions & 19 deletions docs/interpreter-compatibility.json
Original file line number Diff line number Diff line change
Expand Up @@ -588,9 +588,9 @@
},
{
"id": "dynamic-code-reflection",
"status": "deferred",
"scope": "compile/eval/exec, dynamic imports and broader globals/locals/type/attribute reflection.",
"gaps": "Source admission, namespace/identity and target authority need separate explicit contracts.",
"status": "partial",
"scope": "getattr/setattr/delattr/hasattr on adopted class attributes through ordinary owned descriptor callbacks.",
"gaps": "Dynamic source admission, namespaces, richer types and broader reflection remain deferred.",
"reference_version": "3.14.7",
"targets": [
"node",
Expand Down Expand Up @@ -1065,9 +1065,9 @@
},
{
"id": "delattr",
"status": "deferred",
"scope": "Not installed; resolving this builtin name raises Python NameError.",
"gaps": "No implementation/API support credit from the negative availability probe.",
"status": "partial",
"scope": "Positional attribute reflection on adopted class/instance attributes, preserving descriptor precedence, arbitrary bounded string names and AttributeError-only suppression.",
"gaps": "Custom attribute hooks, reflective namespaces and unadopted receivers/metadata remain separately gated.",
"reference_version": "3.14.7",
"targets": [
"node",
Expand All @@ -1079,7 +1079,9 @@
"probes": [
"builtin-delattr"
],
"evidence": []
"evidence": [
"tests/fixtures/interpreter/object-protocols.json:attribute-defaults"
]
},
{
"id": "dict",
Expand Down Expand Up @@ -1267,9 +1269,9 @@
},
{
"id": "getattr",
"status": "deferred",
"scope": "Not installed; resolving this builtin name raises Python NameError.",
"gaps": "No implementation/API support credit from the negative availability probe.",
"status": "partial",
"scope": "Positional attribute reflection on adopted class/instance attributes, preserving descriptor precedence, arbitrary bounded string names and AttributeError-only suppression.",
"gaps": "Custom attribute hooks, reflective namespaces and unadopted receivers/metadata remain separately gated.",
"reference_version": "3.14.7",
"targets": [
"node",
Expand All @@ -1281,7 +1283,9 @@
"probes": [
"builtin-getattr"
],
"evidence": []
"evidence": [
"tests/fixtures/interpreter/object-protocols.json:attribute-defaults"
]
},
{
"id": "globals",
Expand All @@ -1303,9 +1307,9 @@
},
{
"id": "hasattr",
"status": "deferred",
"scope": "Not installed; resolving this builtin name raises Python NameError.",
"gaps": "No implementation/API support credit from the negative availability probe.",
"status": "partial",
"scope": "Positional attribute reflection on adopted class/instance attributes, preserving descriptor precedence, arbitrary bounded string names and AttributeError-only suppression.",
"gaps": "Custom attribute hooks, reflective namespaces and unadopted receivers/metadata remain separately gated.",
"reference_version": "3.14.7",
"targets": [
"node",
Expand All @@ -1317,7 +1321,9 @@
"probes": [
"builtin-hasattr"
],
"evidence": []
"evidence": [
"tests/fixtures/interpreter/object-protocols.json:attribute-defaults"
]
},
{
"id": "hash",
Expand Down Expand Up @@ -1862,9 +1868,9 @@
},
{
"id": "setattr",
"status": "deferred",
"scope": "Not installed; resolving this builtin name raises Python NameError.",
"gaps": "No implementation/API support credit from the negative availability probe.",
"status": "partial",
"scope": "Positional attribute reflection on adopted class/instance attributes, preserving descriptor precedence, arbitrary bounded string names and AttributeError-only suppression.",
"gaps": "Custom attribute hooks, reflective namespaces and unadopted receivers/metadata remain separately gated.",
"reference_version": "3.14.7",
"targets": [
"node",
Expand All @@ -1876,7 +1882,9 @@
"probes": [
"builtin-setattr"
],
"evidence": []
"evidence": [
"tests/fixtures/interpreter/object-protocols.json:attribute-defaults"
]
},
{
"id": "slice",
Expand Down
8 changes: 4 additions & 4 deletions docs/interpreter-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ issue families; availability alone never certifies an entire type or module.
| classmethod | partial | classmethod(callable), classes-source/1 and accessed-owner binding. | Unrestricted wrapper introspection. |
| compile | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| complex | partial | Owned immutable Cartesian values, literal/text/real/complex construction, real/imag keywords and attributes, finite basic arithmetic, equality/truth/hash and bounded integer powers. Owned conversion and index fallback callbacks run in ordinary VM frames under classes-source/1. | General powers, non-finite arithmetic/recovery families, numeric methods, formatting and builtin subclasses remain later boundaries. |
| delattr | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| delattr | partial | Positional reflection on adopted class attributes and descriptors. | Custom hooks and broader reflection remain separate. |
| dict | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| dir | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| divmod | partial | Positional-only primitive int/float quotient and remainder with owned tuple results and Python sign/zero rules. | General user arithmetic/reflected slots remain INT-OBJECT-01. |
Expand All @@ -113,9 +113,9 @@ issue families; availability alone never certifies an entire type or module.
| float | partial | Real primitive and Unicode text construction with exact signatures, base/underscore rules and bounded input/result work in both source profiles. Owned conversion and index fallback callbacks run in ordinary VM frames under classes-source/1. | Bytes (int/float), builtin subclasses, numeric methods and formatting remain later value/object stages. |
| format | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| frozenset | partial | Zero/one positional iterable construction, set displays, membership/equality/iteration, finite methods and primitive algebra; owned iterator/hash/equality callbacks in classes-source/1. | Broader methods, set-algebra callbacks, recursive user-key frozen hashing and comprehensions remain deferred. |
| getattr | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| getattr | partial | Positional reflection on adopted class attributes and descriptors. | Custom hooks and broader reflection remain separate. |
| globals | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| hasattr | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| hasattr | partial | Positional reflection on adopted class attributes and descriptors. | Custom hooks and broader reflection remain separate. |
| hash | partial | hash(value), positional-only in classes-source/1; numeric/string/primitive tuple hashes, user __hash__ and owned default identities. | Tuple-with-instance, bound-method and slice hash families remain deferred; exact string/object hash numbers are not a cross-process guarantee. |
| help | host-restricted | Not installed; availability probe only, never invoked. | Interactive/process/filesystem behavior needs an explicit target capability contract. |
| hex | supported | Primitive numeric signatures in both source profiles and owned type-level callbacks in classes-source/1; see interpreter-numeric.md for the finite contract. | |
Expand Down Expand Up @@ -145,7 +145,7 @@ issue families; availability alone never certifies an entire type or module.
| reversed | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| round | supported | Primitive numeric signatures in both source profiles and owned type-level callbacks in classes-source/1; see interpreter-numeric.md for the finite contract. | |
| set | partial | Zero/one positional iterable construction, set displays, membership/equality/iteration, finite methods and primitive algebra; owned iterator/hash/equality callbacks in classes-source/1. | Broader methods, set-algebra callbacks, recursive user-key frozen hashing and comprehensions remain deferred. |
| setattr | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| setattr | partial | Positional reflection on adopted class attributes and descriptors. | Custom hooks and broader reflection remain separate. |
| slice | partial | classes-source/1: slice(stop), slice(start,stop), slice(start,stop,step), positional only; immutable raw start/stop/step fields. | Core constructor, slice.indices, repr, equality/hash and other reflection are deferred. |
| sorted | deferred | Not installed; resolving this builtin name raises Python NameError. | No implementation/API support credit from the negative availability probe. |
| staticmethod | partial | staticmethod(value) and existing wrapper binding/direct-call rules; classes-source/1. | Unrestricted wrapper introspection. |
Expand Down
3 changes: 2 additions & 1 deletion docs/interpreter-object-protocols.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

INT-OBJECT-01 adopts finite slices against CPython 3.14.7. The authored
`object-protocols.json` reference must also execute independently in Node and
Chromium, draining and instruction-boundary drivers. Classes remain explicit in
Chromium, draining and instruction-boundary drivers. O1 is implemented; O2 is the next stage. Attribute names can be arbitrary strings
within the 256-code-unit name quota. Classes remain explicit in
classes-source/1; core-source/1 keeps primitive arithmetic and generator support.

| Stage | Finite contract |
Expand Down
3 changes: 2 additions & 1 deletion runtime/class-values.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ export class ClassRuntime {
bounded(condition, message) { if (!condition) this.fail("ExecutionLimitError", message, "BUDGET"); }
key(name) {
this.charge(typeof name === "string" ? name.length + 1 : 1);
if (typeof name !== "string" || name.length > CLASS_LIMITS.name || !isPythonIdentifier(name)) throw new TypeError("Invalid class attribute name.");
if (typeof name !== "string" || name.length > CLASS_LIMITS.name) throw new TypeError("Invalid class attribute name.");
}
root() { return this.make(ClassValue, "object", "object", "builtins", [], [], new Map(), true); }
create(name, qualname, module, bases, namespace, root) {
this.key(name);
if (!isPythonIdentifier(name)) throw new TypeError("Invalid class name.");
this.bounded(typeof qualname === "string" && qualname.length <= 256 && typeof module === "string" && module.length <= 192,
"Class identity budget exceeded.");
if (!(root instanceof ClassValue) || !root.root || !Array.isArray(bases) || !(namespace instanceof Map)) throw new TypeError("Invalid class construction record.");
Expand Down
2 changes: 1 addition & 1 deletion runtime/functions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function activation(program, {maxSteps = 10_000, maxWork = 1_000_000, maxDepth =
if (frame.callable.pool.code.version === 5 && key === "NotImplemented") return moduleContext.builtin(key, () => allocate(NotImplementedValue));
if (builtinNames.has(key) || (moduleContext && ["isinstance", "bool", "iter", "next"].includes(key)) ||
(frame.callable.pool.code.version >= 4 && ["memoryview", "bytes", "bytearray", "set", "frozenset", "all", "any", "list", "tuple", "range", "int", "float", "complex", "abs", "divmod", "pow", "round", "bin", "oct", "hex", "chr", "ord"].includes(key)) ||
(frame.callable.pool.code.version === 5 && ["type", "issubclass", "property", "staticmethod", "classmethod", "callable", "slice", "hash"].includes(key))) {
(frame.callable.pool.code.version === 5 && ["getattr", "setattr", "delattr", "hasattr", "type", "issubclass", "property", "staticmethod", "classmethod", "callable", "slice", "hash"].includes(key))) {
if (moduleContext) return moduleContext.builtin(key, () => allocate(BuiltinValue, key));
if (!state.builtins.has(key)) state.builtins.set(key, allocate(BuiltinValue, key));
return state.builtins.get(key);
Expand Down
Loading
Loading