Skip to content
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

Generate cache for builtins #6043

Merged
merged 9 commits into from
Mar 8, 2024
167 changes: 163 additions & 4 deletions Cython/Compiler/Symtab.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import copy
import operator

import builtins

from ..Utils import try_finally_contextmanager
from .Errors import warning, error, InternalError
from .StringEncoding import EncodedString
Expand All @@ -31,6 +29,167 @@
'_Bool', '_Complex'', _Imaginary', 'inline', 'restrict',
}

# Builtins as of Python 3.12.0
KNOWN_PYTHON_BUILTINS_VERSION = (3, 12, 0, 'final', 0)
KNOWN_PYTHON_BUILTINS = frozenset([
'ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'BaseExceptionGroup',
'BlockingIOError',
'BrokenPipeError',
'BufferError',
'BytesWarning',
'ChildProcessError',
'ConnectionAbortedError',
'ConnectionError',
'ConnectionRefusedError',
'ConnectionResetError',
'DeprecationWarning',
'EOFError',
'Ellipsis',
'EncodingWarning',
'EnvironmentError',
'Exception',
'ExceptionGroup',
'False',
'FileExistsError',
'FileNotFoundError',
'FloatingPointError',
'FutureWarning',
'GeneratorExit',
'IOError',
'ImportError',
'ImportWarning',
'IndentationError',
'IndexError',
'InterruptedError',
'IsADirectoryError',
'KeyError',
'KeyboardInterrupt',
'LookupError',
'MemoryError',
'ModuleNotFoundError',
'NameError',
'None',
'NotADirectoryError',
'NotImplemented',
'NotImplementedError',
'OSError',
'OverflowError',
'PendingDeprecationWarning',
'PermissionError',
'ProcessLookupError',
'RecursionError',
'ReferenceError',
'ResourceWarning',
'RuntimeError',
'RuntimeWarning',
'StopAsyncIteration',
'StopIteration',
'SyntaxError',
'SyntaxWarning',
'SystemError',
'SystemExit',
'TabError',
'TimeoutError',
'True',
'TypeError',
'UnboundLocalError',
'UnicodeDecodeError',
'UnicodeEncodeError',
'UnicodeError',
'UnicodeTranslateError',
'UnicodeWarning',
'UserWarning',
'ValueError',
'Warning',
scoder marked this conversation as resolved.
Show resolved Hide resolved
'ZeroDivisionError',
'__build_class__',
'__debug__',
'__doc__',
'__import__',
'__loader__',
'__name__',
'__package__',
'__spec__',
scoder marked this conversation as resolved.
Show resolved Hide resolved
'abs',
'aiter',
'all',
'anext',
'any',
'ascii',
'bin',
'bool',
'breakpoint',
'bytearray',
'bytes',
'callable',
'chr',
'classmethod',
'compile',
'complex',
'copyright',
'credits',
'delattr',
'dict',
'dir',
'divmod',
'enumerate',
'eval',
'exec',
'exit',
'filter',
'float',
'format',
'frozenset',
'getattr',
'globals',
'hasattr',
'hash',
'help',
'hex',
'id',
'input',
'int',
'isinstance',
'issubclass',
'iter',
'len',
'license',
'list',
'locals',
'map',
'max',
'memoryview',
'min',
'next',
'object',
'oct',
'open',
'ord',
'pow',
'print',
'property',
'quit',
'range',
'repr',
'reversed',
'round',
'set',
'setattr',
'slice',
'sorted',
'staticmethod',
'str',
'sum',
'super',
'tuple',
'type',
'vars',
'zip',
])

def c_safe_identifier(cname):
# There are some C limitations on struct entry names.
Expand Down Expand Up @@ -1190,7 +1349,7 @@ def lookup(self, name, language_level=None, str_is_str=None):
return Scope.lookup(self, name)

def declare_builtin(self, name, pos):
if not hasattr(builtins, name):
if name not in KNOWN_PYTHON_BUILTINS:
if self.outer_scope is not None:
return self.outer_scope.declare_builtin(name, pos)
else:
Expand Down Expand Up @@ -1358,7 +1517,7 @@ def declare_tuple_type(self, pos, components):
return entry

def declare_builtin(self, name, pos):
if not hasattr(builtins, name) \
if name not in KNOWN_PYTHON_BUILTINS \
and name not in Code.non_portable_builtins_map \
and name not in Code.uncachable_builtins:
if self.has_import_star:
Expand Down
14 changes: 14 additions & 0 deletions Cython/Compiler/Tests/TestBuiltin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
builtin_scope,
)

from ..Symtab import (
KNOWN_PYTHON_BUILTINS_VERSION, KNOWN_PYTHON_BUILTINS,
)

class TestBuiltinReturnTypes(unittest.TestCase):
def test_find_return_type_of_builtin_method(self):
Expand All @@ -30,3 +33,14 @@ def test_find_return_type_of_builtin_method(self):
self.assertTrue(hasattr(py_type, method_name), f"{type_name}.{method_name}")
else:
self.assertEqual(return_type.empty_declaration_code(pyrex=True), return_type_name)

class TestBuiltinCompatibility(unittest.TestCase):
def test_python_builtin_compatibility(self):
import builtins
scoder marked this conversation as resolved.
Show resolved Hide resolved
runtime_builtins = frozenset(name for name in dir(builtins) if name[:1] != '_')
scoder marked this conversation as resolved.
Show resolved Hide resolved
if sys.version_info < KNOWN_PYTHON_BUILTINS_VERSION:
missing_builtins = KNOWN_PYTHON_BUILTINS - runtime_builtins
if missing_builtins:
self.skipTest(f'skipping test, older Python release found. Missing builtins: {", ".join(sorted(missing_builtins))}')
self.skipTest('skipping test, older Python release found.')
self.assertSetEqual(runtime_builtins, KNOWN_PYTHON_BUILTINS)