this repo has no description
1CPython Compatibility
2=====================
3
4This runtime intends to be a drop-in replacement for CPython. Occasionally, it
5is advantageous for performance to deviate in small ways. These deviations
6should not affect the majority of programs and it should be easy to adapt the
7rest.
8
9This document describes the differences. Note that it does not cover features
10that are planned but not implemented yet.
11
12
13Built-in Types
14--------------
15
16- `module.__dict__` is always a dictionary and initialized in `module.__new__`;
17 CPython initializes it with `None` and only sets it to a dictionary in
18 `module.__init__`.
19
20- Type dictionaries must only have `str` keys that do not override `__eq__` or
21 `__hash__`. This Example will raise a `TypeError`:
22```python
23>>> class A:
24... locals()[500] = 1
25...
26TypeError: '_type_init' for 'str' objects doesn't apply to a 'int' object
27```
28
29- Object attributes must only have `str` names that do not override `__eq__` or
30 `__hash__`. Identities of attribute names may not preserved.
31
32- `str.__add__` with a non-str other returns `NotImplemented` in Skybison but
33 raises a `TypeError` in CPython. This is because CPython splits the slots
34 into competing `nb_add` and `sq_concat` slots that don't exist here. PyPy
35 does something similar to Skybison.
36
37Interpreter
38-----------
39
40- Changing `__builtins__` has an immediate effect, as opposed to CPython which
41 caches the value and only updates the cache when calling across module
42 boundaries. We generally do not recommend to reassign `__builtins__` and may
43 further limit the ability to do so in the future.
44
45- A dictionary passed to the `globals` parameter of `builtins.exec`,
46 `builtins.eval`, `PyEval_EvalCode` is not updated while the code is
47 being executed, but will be updated only upon completion of the call.
48 Note that this does not affect passing `<some_module>.__dict__` for
49 globals; `__dict__` of a module returns a specialized proxy object
50 which leads to module attributes being updated immediately as the
51 code is running.
52
53- Similarly, a dictionary passed to the `globals` parameter of the function
54 constructor (`types.FunctionType`), will have its contents copied to a
55 specialized proxy object inside a module. This means that any changes to
56 globals from within the function will not reflect in the dictionary
57 passed-in, but instead in the function's module proxy object. The following
58 test will fail:
59
60 def _f():
61 global foo
62 foo = "baz"
63
64 d = {"foo": "bar"}
65 result = types.FunctionType(_f.__code__, d, name="hi")
66 self.assertEqual(d["foo"], "baz")
67
68C-API
69-----
70
71- `PyCFunction_Type` and `PyCFunction_Check` are not supported;
72 `PyCFunction_New` works and returns something that behaves similar.
73
74- `PyEval_EvalCode`: See `builtins.exec`.
75
76Runtime Inspection
77------------------
78
79- `sys._getframe()` always returns a new object whereas CPython returns an
80 identical object for the same frame:
81```python
82>>> sys._getframe(0) is sys._getframe(0)
83False
84```