Cython 3.3.0a2.dev0__py3-none-any.whl → 3.3.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Cython/Build/Dependencies.py +12 -7
- Cython/Build/SharedModule.py +99 -18
- Cython/Build/Tests/TestInline.py +1 -1
- Cython/CodeWriter.py +14 -4
- Cython/Compiler/Buffer.py +0 -1
- Cython/Compiler/Builtin.py +158 -53
- Cython/Compiler/CmdLine.py +154 -44
- Cython/Compiler/Code.pxd +2 -0
- Cython/Compiler/Code.py +58 -205
- Cython/Compiler/CythonScope.py +14 -0
- Cython/Compiler/ExprNodes.py +614 -322
- Cython/Compiler/FlowControl.pxd +46 -33
- Cython/Compiler/FlowControl.py +5 -3
- Cython/Compiler/FusedNode.py +15 -13
- Cython/Compiler/MatchCaseNodes.py +15 -12
- Cython/Compiler/ModuleNode.py +47 -19
- Cython/Compiler/Naming.py +3 -0
- Cython/Compiler/Nodes.py +400 -37
- Cython/Compiler/Optimize.py +172 -63
- Cython/Compiler/Options.py +2 -0
- Cython/Compiler/ParseTreeTransforms.pxd +1 -0
- Cython/Compiler/ParseTreeTransforms.py +67 -3
- Cython/Compiler/Parsing.pxd +1 -1
- Cython/Compiler/Parsing.py +117 -100
- Cython/Compiler/PyrexTypes.py +529 -56
- Cython/Compiler/Scanning.pxd +3 -3
- Cython/Compiler/StringEncoding.py +92 -35
- Cython/Compiler/Symtab.py +45 -16
- Cython/Compiler/Tests/TestBuiltin.py +126 -47
- Cython/Compiler/Tests/TestCmdLine.py +66 -1
- Cython/Compiler/Tests/TestTypes.py +2 -1
- Cython/Compiler/Tests/TestVisitor.py +60 -2
- Cython/Compiler/TreeFragment.py +6 -5
- Cython/Compiler/TypeInference.py +2 -2
- Cython/Compiler/UFuncs.py +7 -1
- Cython/Compiler/UtilNodes.py +0 -24
- Cython/Compiler/UtilityCode.py +9 -3
- Cython/Compiler/Visitor.pxd +2 -3
- Cython/Compiler/Visitor.py +74 -24
- Cython/Debugger/Cygdb.py +50 -13
- Cython/Distutils/build_ext.py +4 -0
- Cython/Includes/cpython/array.pxd +4 -4
- Cython/LZSS.py +35 -21
- Cython/Shadow.py +8 -1
- Cython/TestUtils.py +10 -6
- Cython/Tests/TestShadow.py +16 -1
- Cython/Utility/AsyncGen.c +93 -12
- Cython/Utility/Builtins.c +178 -43
- Cython/Utility/CConvert.pyx +6 -2
- Cython/Utility/Coroutine.c +3 -0
- Cython/Utility/CpdefEnums.pyx +37 -25
- Cython/Utility/CythonFunction.c +74 -45
- Cython/Utility/Exceptions.c +298 -5
- Cython/Utility/Exceptions_Cy.pyx +109 -0
- Cython/Utility/ExtensionTypes.c +26 -13
- Cython/Utility/FunctionArguments.c +9 -2
- Cython/Utility/ImportExport.c +53 -11
- Cython/Utility/MatchCase.c +5 -3
- Cython/Utility/MemoryView.pyx +17 -17
- Cython/Utility/ModuleSetupCode.c +147 -182
- Cython/Utility/ObjectHandling.c +108 -76
- Cython/Utility/Optimize.c +13 -12
- Cython/Utility/StringTools.c +142 -22
- Cython/Utility/TypeConversion.c +32 -0
- Cython/Utility/arrayarray.h +16 -18
- Cython/Utils.py +3 -0
- cython-3.3.0b1.dist-info/METADATA +286 -0
- {cython-3.3.0a2.dev0.dist-info → cython-3.3.0b1.dist-info}/RECORD +71 -70
- cython-3.3.0a2.dev0.dist-info/METADATA +0 -74
- {cython-3.3.0a2.dev0.dist-info → cython-3.3.0b1.dist-info}/WHEEL +0 -0
- {cython-3.3.0a2.dev0.dist-info → cython-3.3.0b1.dist-info}/entry_points.txt +0 -0
- {cython-3.3.0a2.dev0.dist-info → cython-3.3.0b1.dist-info}/top_level.txt +0 -0
Cython/Build/Dependencies.py
CHANGED
|
@@ -12,7 +12,7 @@ from collections.abc import Iterable
|
|
|
12
12
|
|
|
13
13
|
try:
|
|
14
14
|
import pythran
|
|
15
|
-
except:
|
|
15
|
+
except Exception:
|
|
16
16
|
pythran = None
|
|
17
17
|
|
|
18
18
|
from .. import Utils
|
|
@@ -29,7 +29,8 @@ copy_once_if_newer = cached_function(copy_file_to_dir_if_newer)
|
|
|
29
29
|
safe_makedirs_once = cached_function(safe_makedirs)
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
@cython.cfunc
|
|
33
|
+
def _make_relative(file_paths, base=None) -> list[str]:
|
|
33
34
|
if not base:
|
|
34
35
|
base = os.getcwd()
|
|
35
36
|
if base[-1] != os.path.sep:
|
|
@@ -158,6 +159,7 @@ distutils_settings = {
|
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
|
|
162
|
+
@cython.cfunc
|
|
161
163
|
def _legacy_strtobool(val):
|
|
162
164
|
# Used to be "distutils.util.strtobool", adapted for deprecation warnings.
|
|
163
165
|
if val == "True":
|
|
@@ -1183,12 +1185,15 @@ if os.environ.get('XML_RESULTS'):
|
|
|
1183
1185
|
def record_results(func):
|
|
1184
1186
|
def with_record(*args):
|
|
1185
1187
|
t = time.time()
|
|
1186
|
-
success =
|
|
1188
|
+
success = False
|
|
1187
1189
|
try:
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1190
|
+
func(*args)
|
|
1191
|
+
success = True
|
|
1192
|
+
except Exception:
|
|
1193
|
+
# It's not obvious that we should really swallow the exception here,
|
|
1194
|
+
# rather than fail loudly after writing the XML result file,
|
|
1195
|
+
# but that's how it's currently implemented.
|
|
1196
|
+
pass
|
|
1192
1197
|
finally:
|
|
1193
1198
|
t = time.time() - t
|
|
1194
1199
|
module = fully_qualified_name(args[0])
|
Cython/Build/SharedModule.py
CHANGED
|
@@ -5,9 +5,88 @@ from Cython.Compiler import (
|
|
|
5
5
|
)
|
|
6
6
|
from Cython.Compiler.StringEncoding import EncodedString
|
|
7
7
|
from Cython.Compiler.Scanning import SharedUtilitySourceDescriptor
|
|
8
|
+
from Cython.Compiler.Errors import warning
|
|
8
9
|
|
|
9
10
|
|
|
10
|
-
def
|
|
11
|
+
def list_of_features(included=None, excluded=None, _list_of_features=[]):
|
|
12
|
+
if _list_of_features:
|
|
13
|
+
feature_names = _list_of_features[:]
|
|
14
|
+
else:
|
|
15
|
+
feature_names = sorted({feature_name for feature_name, _, _ in _iter_exports()})
|
|
16
|
+
_list_of_features[:] = feature_names
|
|
17
|
+
|
|
18
|
+
return _select_features(feature_names, included, excluded)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _select_features(all_names, included, excluded):
|
|
22
|
+
names = all_names
|
|
23
|
+
if included:
|
|
24
|
+
included = set(included)
|
|
25
|
+
unknown = included.difference(all_names)
|
|
26
|
+
if unknown:
|
|
27
|
+
warning(None, f"Unknown shared module features selected: {', '.join(sorted(unknown))}")
|
|
28
|
+
|
|
29
|
+
names = [name for name in names if name in included]
|
|
30
|
+
|
|
31
|
+
if excluded:
|
|
32
|
+
excluded = set(excluded)
|
|
33
|
+
unknown = excluded.difference(all_names)
|
|
34
|
+
if unknown:
|
|
35
|
+
warning(None, f"Unknown shared module features excluded: {', '.join(sorted(unknown))}")
|
|
36
|
+
unused = excluded.difference(names)
|
|
37
|
+
if unused:
|
|
38
|
+
warning(None, f"Shared module features excluded that was not included: {', '.join(sorted(unused))}")
|
|
39
|
+
|
|
40
|
+
names = [name for name in names if name not in excluded]
|
|
41
|
+
|
|
42
|
+
return names
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _iter_exports(selected_features=None):
|
|
46
|
+
UtilityCode = Code.UtilityCode
|
|
47
|
+
match_special = UtilityCode.get_special_comment_matcher('/')
|
|
48
|
+
|
|
49
|
+
for c_utility_file in os.listdir(Code.get_utility_dir()):
|
|
50
|
+
if not c_utility_file.endswith('.c'):
|
|
51
|
+
continue
|
|
52
|
+
|
|
53
|
+
file_base_name = os.path.splitext(os.path.basename(c_utility_file))[0]
|
|
54
|
+
current_feature_name = file_base_name.partition('_')[0]
|
|
55
|
+
|
|
56
|
+
current_section = None
|
|
57
|
+
for line in Code.read_utilities_hook(c_utility_file):
|
|
58
|
+
if '//' not in line or not line.startswith('//'):
|
|
59
|
+
continue
|
|
60
|
+
match = match_special(line)
|
|
61
|
+
if match is None:
|
|
62
|
+
continue
|
|
63
|
+
|
|
64
|
+
name = match.group('name')
|
|
65
|
+
if name:
|
|
66
|
+
if current_section:
|
|
67
|
+
if selected_features is None or current_section[0] in selected_features:
|
|
68
|
+
yield current_section
|
|
69
|
+
current_section = None
|
|
70
|
+
|
|
71
|
+
section_title = UtilityCode.match_section_title(name) if '.export' in name else None
|
|
72
|
+
if section_title:
|
|
73
|
+
name, section_type = section_title.groups()
|
|
74
|
+
if section_type == 'export':
|
|
75
|
+
current_section = [current_feature_name, name, c_utility_file]
|
|
76
|
+
|
|
77
|
+
elif (tag := match.group('tag')) and tag.startswith('feature') and current_section:
|
|
78
|
+
explicit_feature_name = tag.split(':', 1)[-1].strip()
|
|
79
|
+
assert current_section[0] == current_feature_name, (
|
|
80
|
+
"Conflicting feature names given to the same utility code section: "
|
|
81
|
+
f"{current_section[0]!r} and {explicit_feature_name!r}")
|
|
82
|
+
current_section[0] = explicit_feature_name
|
|
83
|
+
|
|
84
|
+
if current_section:
|
|
85
|
+
if selected_features is None or current_section[0] in selected_features:
|
|
86
|
+
yield current_section
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def create_shared_library_pipeline(context, scope, options, result, selected_features=None):
|
|
11
90
|
|
|
12
91
|
parse = Pipeline.parse_stage_factory(context)
|
|
13
92
|
|
|
@@ -15,11 +94,13 @@ def create_shared_library_pipeline(context, scope, options, result):
|
|
|
15
94
|
def generate_tree(compsrc):
|
|
16
95
|
tree = parse(compsrc)
|
|
17
96
|
|
|
18
|
-
|
|
19
|
-
|
|
97
|
+
if selected_features is None or 'MemoryView' in selected_features:
|
|
98
|
+
tree.scope.use_utility_code(
|
|
99
|
+
MemoryView.get_view_utility_code(options.shared_utility_qualified_name))
|
|
100
|
+
|
|
101
|
+
tree.scope.use_utility_code(MemoryView._get_memviewslice_declare_code())
|
|
102
|
+
tree.scope.use_utility_code(MemoryView._get_typeinfo_to_format_code())
|
|
20
103
|
|
|
21
|
-
tree.scope.use_utility_code(MemoryView._get_memviewslice_declare_code())
|
|
22
|
-
tree.scope.use_utility_code(MemoryView._get_typeinfo_to_format_code())
|
|
23
104
|
context.include_directories.append(Code.get_utility_dir())
|
|
24
105
|
return tree
|
|
25
106
|
|
|
@@ -27,18 +108,8 @@ def create_shared_library_pipeline(context, scope, options, result):
|
|
|
27
108
|
|
|
28
109
|
def generate_c_utilities(module_node):
|
|
29
110
|
UtilityCode = Code.UtilityCode
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if not c_utility_file.endswith('.c'):
|
|
33
|
-
continue
|
|
34
|
-
for line in Code.read_utilities_hook(c_utility_file):
|
|
35
|
-
if not ((m := match_special(line)) and (name := m.group('name'))):
|
|
36
|
-
continue
|
|
37
|
-
if not (section_title := UtilityCode.match_section_title(name)):
|
|
38
|
-
continue
|
|
39
|
-
name, section_type = section_title.groups()
|
|
40
|
-
if section_type == 'export':
|
|
41
|
-
module_node.scope.use_utility_code(UtilityCode.load_cached(name, c_utility_file))
|
|
111
|
+
for _, name, c_utility_file in _iter_exports(selected_features):
|
|
112
|
+
module_node.scope.use_utility_code(UtilityCode.load_cached(name, c_utility_file))
|
|
42
113
|
return module_node
|
|
43
114
|
|
|
44
115
|
orig_cimport_from_pyx = Options.cimport_from_pyx
|
|
@@ -71,6 +142,13 @@ def generate_shared_module(options):
|
|
|
71
142
|
pyx_file = os.path.splitext(dest_c_file)[0] + '.pyx'
|
|
72
143
|
module_name = os.path.splitext(os.path.basename(dest_c_file))[0]
|
|
73
144
|
|
|
145
|
+
selected_features = None
|
|
146
|
+
if options.shared_utility_features_enabled or options.shared_utility_features_disabled:
|
|
147
|
+
selected_features = list_of_features(
|
|
148
|
+
options.shared_utility_features_enabled,
|
|
149
|
+
options.shared_utility_features_disabled,
|
|
150
|
+
)
|
|
151
|
+
|
|
74
152
|
context = Main.Context.from_options(options)
|
|
75
153
|
scope = Symtab.ModuleScope('MemoryView', parent_module = None, context = context, is_package=False)
|
|
76
154
|
|
|
@@ -78,7 +156,10 @@ def generate_shared_module(options):
|
|
|
78
156
|
comp_src = Main.CompilationSource(source_desc, EncodedString(module_name), os.getcwd())
|
|
79
157
|
result = Main.create_default_resultobj(comp_src, options)
|
|
80
158
|
|
|
81
|
-
pipeline = create_shared_library_pipeline(
|
|
159
|
+
pipeline = create_shared_library_pipeline(
|
|
160
|
+
context, scope, options, result,
|
|
161
|
+
selected_features=selected_features,
|
|
162
|
+
)
|
|
82
163
|
err, enddata = Pipeline.run_pipeline(pipeline, comp_src)
|
|
83
164
|
|
|
84
165
|
return err, enddata
|
Cython/Build/Tests/TestInline.py
CHANGED
Cython/CodeWriter.py
CHANGED
|
@@ -673,7 +673,7 @@ class ExpressionWriter(TreeVisitor):
|
|
|
673
673
|
def visit_CondExprNode(self, node):
|
|
674
674
|
self.visit(node.true_val)
|
|
675
675
|
self.put(" if ")
|
|
676
|
-
self.visit(node.
|
|
676
|
+
self.visit(node.condition)
|
|
677
677
|
self.put(" else ")
|
|
678
678
|
self.visit(node.false_val)
|
|
679
679
|
|
|
@@ -748,9 +748,19 @@ class ExpressionWriter(TreeVisitor):
|
|
|
748
748
|
self.visit(node.expr)
|
|
749
749
|
|
|
750
750
|
def visit_DictComprehensionAppendNode(self, node):
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
751
|
+
item = node.dict_item
|
|
752
|
+
if isinstance(item, DictItemNode):
|
|
753
|
+
self.visit(item.key)
|
|
754
|
+
self.put(": ")
|
|
755
|
+
self.visit(item.value)
|
|
756
|
+
else:
|
|
757
|
+
is_simple = item.is_name or item.is_attribute
|
|
758
|
+
self.put("**")
|
|
759
|
+
if not is_simple:
|
|
760
|
+
self.put("(")
|
|
761
|
+
self.visit(item)
|
|
762
|
+
if not is_simple:
|
|
763
|
+
self.put(")")
|
|
754
764
|
|
|
755
765
|
def visit_ComprehensionNode(self, node):
|
|
756
766
|
tpmap = {'list': "[]", 'dict': "{}", 'set': "{}"}
|
Cython/Compiler/Buffer.py
CHANGED
|
@@ -674,7 +674,6 @@ raise_indexerror_nogil = load_buffer_utility("BufferIndexErrorNogil")
|
|
|
674
674
|
raise_buffer_fallback_code = load_buffer_utility("BufferFallbackError")
|
|
675
675
|
|
|
676
676
|
acquire_utility_code = load_buffer_utility("BufferGetAndValidate", context=context)
|
|
677
|
-
buffer_format_check_code = load_buffer_utility("BufferFormatCheck", context=context)
|
|
678
677
|
|
|
679
678
|
# See utility code BufferFormatFromTypeInfo
|
|
680
679
|
_typeinfo_to_format_code = load_buffer_utility("TypeInfoToFormat")
|
Cython/Compiler/Builtin.py
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
# Builtin Definitions
|
|
3
3
|
#
|
|
4
4
|
|
|
5
|
+
from itertools import chain
|
|
5
6
|
|
|
6
7
|
from .StringEncoding import EncodedString
|
|
7
8
|
from .Symtab import BuiltinScope, StructOrUnionScope, ModuleScope, Entry
|
|
8
|
-
from .Code import UtilityCode, TempitaUtilityCode
|
|
9
|
+
from .Code import UtilityCode, TempitaUtilityCode
|
|
9
10
|
from .TypeSlots import Signature
|
|
10
11
|
from . import PyrexTypes
|
|
11
12
|
|
|
@@ -349,6 +350,13 @@ builtin_function_table = [
|
|
|
349
350
|
|
|
350
351
|
# Builtin types
|
|
351
352
|
|
|
353
|
+
hidden_builtin_types = [
|
|
354
|
+
# These are not in the user visible 'builtins' namespace.
|
|
355
|
+
'dict_keys',
|
|
356
|
+
'dict_values',
|
|
357
|
+
'dict_items',
|
|
358
|
+
]
|
|
359
|
+
|
|
352
360
|
builtin_types_table = [
|
|
353
361
|
|
|
354
362
|
("type", "&PyType_Type", []),
|
|
@@ -357,6 +365,9 @@ builtin_types_table = [
|
|
|
357
365
|
|
|
358
366
|
("int", "&PyLong_Type", []),
|
|
359
367
|
("float", "&PyFloat_Type", []),
|
|
368
|
+
("dict_keys", "&PyDictKeys_Type", []),
|
|
369
|
+
("dict_values", "&PyDictValues_Type", []),
|
|
370
|
+
("dict_items", "&PyDictItems_Type", []),
|
|
360
371
|
|
|
361
372
|
("complex", "&PyComplex_Type", [BuiltinAttribute('cval', field_type_name = 'Py_complex'),
|
|
362
373
|
BuiltinAttribute('real', 'cval.real', field_type = PyrexTypes.c_double_type),
|
|
@@ -390,11 +401,14 @@ builtin_types_table = [
|
|
|
390
401
|
("dict", "&PyDict_Type", [BuiltinMethod("__contains__", "TO", "b", "PyDict_Contains"),
|
|
391
402
|
BuiltinMethod("has_key", "TO", "b", "PyDict_Contains"),
|
|
392
403
|
BuiltinMethod("items", "T", "O", "__Pyx_PyDict_Items",
|
|
393
|
-
utility_code=UtilityCode.load("py_dict_items", "Builtins.c")
|
|
404
|
+
utility_code=UtilityCode.load("py_dict_items", "Builtins.c"),
|
|
405
|
+
builtin_return_type='dict_items'),
|
|
394
406
|
BuiltinMethod("keys", "T", "O", "__Pyx_PyDict_Keys",
|
|
395
|
-
utility_code=UtilityCode.load("py_dict_keys", "Builtins.c")
|
|
407
|
+
utility_code=UtilityCode.load("py_dict_keys", "Builtins.c"),
|
|
408
|
+
builtin_return_type='dict_keys'),
|
|
396
409
|
BuiltinMethod("values", "T", "O", "__Pyx_PyDict_Values",
|
|
397
|
-
utility_code=UtilityCode.load("py_dict_values", "Builtins.c")
|
|
410
|
+
utility_code=UtilityCode.load("py_dict_values", "Builtins.c"),
|
|
411
|
+
builtin_return_type='dict_values'),
|
|
398
412
|
BuiltinMethod("iteritems", "T", "O", "__Pyx_PyDict_IterItems",
|
|
399
413
|
utility_code=UtilityCode.load("py_dict_iteritems", "Builtins.c")),
|
|
400
414
|
BuiltinMethod("iterkeys", "T", "O", "__Pyx_PyDict_IterKeys",
|
|
@@ -443,8 +457,6 @@ builtin_types_table = [
|
|
|
443
457
|
BuiltinMethod("add", "TO", "r", "PySet_Add"),
|
|
444
458
|
BuiltinMethod("pop", "T", "O", "PySet_Pop")]),
|
|
445
459
|
("frozenset", "&PyFrozenSet_Type", []),
|
|
446
|
-
("BaseException", "((PyTypeObject*)PyExc_BaseException)", []),
|
|
447
|
-
("Exception", "((PyTypeObject*)PyExc_Exception)", []),
|
|
448
460
|
("memoryview", "&PyMemoryView_Type", [
|
|
449
461
|
# TODO - format would be nice, but hard to get
|
|
450
462
|
# __len__ can be accessed through a direct lookup of the buffer (but probably in Optimize.c)
|
|
@@ -482,7 +494,7 @@ types_that_construct_their_instance = frozenset({
|
|
|
482
494
|
'tuple', 'list', 'dict', 'frozendict', 'set', 'frozenset',
|
|
483
495
|
'memoryview', 'range', 'slice', 'sentinel',
|
|
484
496
|
# All builtin exception types create their own instance.
|
|
485
|
-
*
|
|
497
|
+
*PyrexTypes.KNOWN_EXCEPTION_NAMES,
|
|
486
498
|
|
|
487
499
|
# These types don't currently have a purpose and might become restrictive:
|
|
488
500
|
#'object',
|
|
@@ -497,7 +509,10 @@ types_that_construct_their_instance = frozenset({
|
|
|
497
509
|
# When updating this mapping, also update "unsafe_compile_time_methods" below
|
|
498
510
|
# if methods are added that are not safe to evaluate at compile time.
|
|
499
511
|
# 'T' - type identical to type in dictionary key
|
|
500
|
-
# 'I' - type
|
|
512
|
+
# 'I' - type of index type:
|
|
513
|
+
# - value type from subscript - e.g. for list[int], I is `int`
|
|
514
|
+
# - for mappings this is the second subscripted type - e.g. for dict[int, str], I is `str`
|
|
515
|
+
# 'K' - key type of dictionary - e.g. for dict[int, str], K is `int`
|
|
501
516
|
inferred_method_return_types = {
|
|
502
517
|
'complex': dict(
|
|
503
518
|
conjugate='complex',
|
|
@@ -631,7 +646,7 @@ inferred_method_return_types = {
|
|
|
631
646
|
tolist='list',
|
|
632
647
|
toreadonly='T',
|
|
633
648
|
),
|
|
634
|
-
'
|
|
649
|
+
'frozenset': dict(
|
|
635
650
|
copy='T',
|
|
636
651
|
difference='T',
|
|
637
652
|
intersection='T',
|
|
@@ -640,17 +655,20 @@ inferred_method_return_types = {
|
|
|
640
655
|
issuperset='bint',
|
|
641
656
|
symmetric_difference='T',
|
|
642
657
|
union='T',
|
|
643
|
-
pop='I',
|
|
644
658
|
),
|
|
645
|
-
'
|
|
646
|
-
# Inherited from '
|
|
659
|
+
'set': dict(
|
|
660
|
+
# Inherited from 'frozenset' above.
|
|
661
|
+
pop='I',
|
|
647
662
|
),
|
|
648
663
|
'dict': dict(
|
|
649
664
|
copy='T',
|
|
650
665
|
fromkeys='T', # classmethod
|
|
651
|
-
popitem='tuple',
|
|
666
|
+
popitem='tuple[K,I]',
|
|
652
667
|
pop='I',
|
|
653
668
|
get='I',
|
|
669
|
+
keys='dict_keys[K]',
|
|
670
|
+
values='dict_values[I]',
|
|
671
|
+
items='dict_items[tuple[K,I]]'
|
|
654
672
|
),
|
|
655
673
|
'frozendict': dict(
|
|
656
674
|
copy='T',
|
|
@@ -659,36 +677,55 @@ inferred_method_return_types = {
|
|
|
659
677
|
}
|
|
660
678
|
|
|
661
679
|
inferred_method_return_types['bytearray'].update(inferred_method_return_types['bytes'])
|
|
662
|
-
inferred_method_return_types['
|
|
680
|
+
inferred_method_return_types['set'].update(inferred_method_return_types['frozenset'])
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
def _parse_atomic_signature(builtin_type, sig: str) -> PyrexTypes.PyrexType:
|
|
684
|
+
# Roughly ordered by frequency of occurrence to reduce lookup cost.
|
|
685
|
+
if sig == 'T':
|
|
686
|
+
return builtin_type
|
|
687
|
+
elif sig == 'bint':
|
|
688
|
+
return PyrexTypes.c_bint_type
|
|
689
|
+
elif sig == 'Py_ssize_t':
|
|
690
|
+
return PyrexTypes.c_py_ssize_t_type
|
|
691
|
+
elif sig == 'object':
|
|
692
|
+
return PyrexTypes.py_object_type
|
|
693
|
+
elif sig == 'I':
|
|
694
|
+
return builtin_type.infer_indexed_type() or PyrexTypes.py_object_type
|
|
695
|
+
elif sig == 'K' and builtin_type.is_pyanydict_type:
|
|
696
|
+
return builtin_type.infer_iterator_type() or PyrexTypes.py_object_type
|
|
697
|
+
entry = builtin_scope.lookup(sig)
|
|
698
|
+
if entry is None:
|
|
699
|
+
# Unnamed builtin.
|
|
700
|
+
return builtin_types[sig]
|
|
701
|
+
return entry.type
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
def _parse_signature(pos, env, builtin_type, return_signature: str) -> PyrexTypes.PyrexType:
|
|
705
|
+
if '[' in return_signature:
|
|
706
|
+
container_name, _, subscript_signature = return_signature[:-1].partition('[')
|
|
707
|
+
container_entry = builtin_scope.lookup(container_name)
|
|
708
|
+
container_type = container_entry.type if container_entry is not None else builtin_types[container_name]
|
|
709
|
+
|
|
710
|
+
if container_name in ('tuple', 'dict', 'frozendict'):
|
|
711
|
+
parsed_subscripted_types = [
|
|
712
|
+
_parse_signature(pos, env, builtin_type, sg)
|
|
713
|
+
for sg in subscript_signature.split(',')
|
|
714
|
+
]
|
|
715
|
+
else:
|
|
716
|
+
parsed_subscripted_types = [_parse_signature(pos, env, builtin_type, subscript_signature)]
|
|
717
|
+
return container_type.specialize_here(pos, env, parsed_subscripted_types)
|
|
718
|
+
return _parse_atomic_signature(builtin_type, return_signature)
|
|
663
719
|
|
|
664
720
|
|
|
665
|
-
def find_return_type_of_builtin_method(pos, env, builtin_type, method_name):
|
|
721
|
+
def find_return_type_of_builtin_method(pos, env, builtin_type, method_name) -> PyrexTypes.PyrexType:
|
|
666
722
|
container_type = builtin_type.get_container_type()
|
|
667
723
|
type_name = container_type.name if container_type else builtin_type.name
|
|
668
724
|
if type_name in inferred_method_return_types:
|
|
669
725
|
methods = inferred_method_return_types[type_name]
|
|
670
726
|
if method_name in methods:
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
if '[' in return_type_name:
|
|
674
|
-
return_type_name, _, subscripted_type_names = return_type_name[:-1].partition('[')
|
|
675
|
-
if return_type_name == 'T':
|
|
676
|
-
return builtin_type
|
|
677
|
-
if return_type_name == 'I':
|
|
678
|
-
return builtin_type.infer_indexed_type() or PyrexTypes.py_object_type
|
|
679
|
-
if 'T' in subscripted_type_names:
|
|
680
|
-
subscripted_type_names = subscripted_type_names.replace('T', builtin_type.name)
|
|
681
|
-
if return_type_name == 'bint':
|
|
682
|
-
return PyrexTypes.c_bint_type
|
|
683
|
-
elif return_type_name == 'Py_ssize_t':
|
|
684
|
-
return PyrexTypes.c_py_ssize_t_type
|
|
685
|
-
container_type = builtin_scope.lookup(return_type_name).type
|
|
686
|
-
if subscripted_type_names:
|
|
687
|
-
subscripted_types = [
|
|
688
|
-
entry.type if entry else PyrexTypes.py_object_type
|
|
689
|
-
for entry in map(builtin_scope.lookup, subscripted_type_names.split(','))
|
|
690
|
-
]
|
|
691
|
-
container_type = container_type.specialize_here(pos, env, subscripted_types)
|
|
727
|
+
return_type_signature: str = methods[method_name]
|
|
728
|
+
container_type = _parse_signature(pos, env, builtin_type, return_type_signature)
|
|
692
729
|
return container_type
|
|
693
730
|
return PyrexTypes.py_object_type
|
|
694
731
|
|
|
@@ -778,6 +815,11 @@ builtin_types = {}
|
|
|
778
815
|
|
|
779
816
|
def init_builtin_types():
|
|
780
817
|
global builtin_types
|
|
818
|
+
|
|
819
|
+
# Some builtin types are not available by name,
|
|
820
|
+
# so we declare them in a throw-away scope.
|
|
821
|
+
hidden_builtins_scope = BuiltinScope()
|
|
822
|
+
|
|
781
823
|
for name, cname, methods in builtin_types_table:
|
|
782
824
|
if name == 'frozenset':
|
|
783
825
|
objstruct_cname = 'PySetObject'
|
|
@@ -789,15 +831,12 @@ def init_builtin_types():
|
|
|
789
831
|
objstruct_cname = 'PyUnicodeObject'
|
|
790
832
|
elif name == 'bool':
|
|
791
833
|
objstruct_cname = 'PyLongObject'
|
|
792
|
-
elif name == 'BaseException':
|
|
793
|
-
objstruct_cname = "PyBaseExceptionObject"
|
|
794
|
-
elif name == 'Exception':
|
|
795
|
-
objstruct_cname = "PyBaseExceptionObject"
|
|
796
834
|
else:
|
|
797
835
|
objstruct_cname = 'Py%sObject' % name.capitalize()
|
|
798
836
|
|
|
799
837
|
utility_code = None
|
|
800
838
|
type_class = PyrexTypes.BuiltinObjectType
|
|
839
|
+
scope = builtin_scope
|
|
801
840
|
if name in ['dict', 'list', 'set', 'frozenset', 'frozendict']:
|
|
802
841
|
type_class = PyrexTypes.BuiltinTypeConstructorObjectType
|
|
803
842
|
if name == 'frozendict':
|
|
@@ -806,8 +845,14 @@ def init_builtin_types():
|
|
|
806
845
|
type_class = PyrexTypes.PythonTupleTypeConstructor
|
|
807
846
|
elif name == 'range':
|
|
808
847
|
utility_code = range_utility_code
|
|
848
|
+
elif name in hidden_builtin_types:
|
|
849
|
+
type_class = PyrexTypes.BuiltinTypeConstructorObjectType
|
|
850
|
+
scope = hidden_builtins_scope
|
|
851
|
+
# Make sure the 'type' base type is declared in the hidden scope.
|
|
852
|
+
if 'type' not in hidden_builtins_scope.entries:
|
|
853
|
+
hidden_builtins_scope.entries['type'] = builtin_scope.lookup('type')
|
|
809
854
|
|
|
810
|
-
the_type =
|
|
855
|
+
the_type = scope.declare_builtin_type(
|
|
811
856
|
name, cname, objstruct_cname=objstruct_cname, type_class=type_class, utility_code=utility_code)
|
|
812
857
|
builtin_types[name] = the_type
|
|
813
858
|
for method in methods:
|
|
@@ -817,21 +862,81 @@ def init_builtin_types():
|
|
|
817
862
|
def init_builtin_exceptions():
|
|
818
863
|
"""Declare known builtin Python exceptions as types.
|
|
819
864
|
"""
|
|
820
|
-
|
|
821
|
-
|
|
865
|
+
special_properties = {
|
|
866
|
+
'StopIteration': ['value'],
|
|
867
|
+
'NameError': ['name'],
|
|
868
|
+
'AttributeError': ['name', 'obj'],
|
|
869
|
+
'SystemExit': ['code'],
|
|
870
|
+
}
|
|
871
|
+
unicode_error_properties = ['encoding', 'object', 'reason']
|
|
872
|
+
for name in ['UnicodeError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeTranslateError']:
|
|
873
|
+
special_properties[name] = unicode_error_properties
|
|
874
|
+
|
|
875
|
+
type_check_utility_code = UtilityCode.load_cached("FastTypeChecks", "ModuleSetupCode.c")
|
|
876
|
+
|
|
877
|
+
for name in PyrexTypes.KNOWN_EXCEPTION_NAMES:
|
|
878
|
+
if name in PyrexTypes.uncachable_builtins:
|
|
822
879
|
# Exclude builtins specific to later Python versions or platforms.
|
|
823
880
|
continue
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
if
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
881
|
+
|
|
882
|
+
objstruct_cname = None
|
|
883
|
+
if name == 'BaseException':
|
|
884
|
+
objstruct_cname = "PyBaseExceptionObject"
|
|
885
|
+
utility_code = UtilityCode(
|
|
886
|
+
proto="#define __Pyx_PyExc_BaseException_Check(obj) PyExceptionInstance_Check(obj)",
|
|
887
|
+
name=f"Py{name}_Check",
|
|
888
|
+
)
|
|
889
|
+
else:
|
|
890
|
+
if name == 'Exception':
|
|
891
|
+
objstruct_cname = "PyBaseExceptionObject"
|
|
892
|
+
utility_code = UtilityCode(
|
|
893
|
+
proto=f"#define __Pyx_PyExc_{name}_Check(obj) __Pyx_TypeCheck(obj, PyExc_{name})",
|
|
894
|
+
name=f"Py{name}_Check",
|
|
895
|
+
requires=[type_check_utility_code],
|
|
896
|
+
)
|
|
897
|
+
|
|
898
|
+
assert builtin_scope.lookup_here(name) is None # should not be declared above
|
|
899
|
+
exc_type = builtin_types[name] = builtin_scope.declare_builtin_type(
|
|
900
|
+
name, f"((PyTypeObject*)PyExc_{name})",
|
|
901
|
+
objstruct_cname=objstruct_cname,
|
|
902
|
+
utility_code=utility_code,
|
|
832
903
|
)
|
|
833
|
-
|
|
834
|
-
|
|
904
|
+
|
|
905
|
+
# Also cover known subtypes, but avoid overly long chains of type pointer comparisons.
|
|
906
|
+
subtypes = [
|
|
907
|
+
tpname for tpname in PyrexTypes.exception_subtypes.get(name, ())
|
|
908
|
+
if tpname not in PyrexTypes.uncachable_builtins
|
|
909
|
+
]
|
|
910
|
+
if len(subtypes) > 4:
|
|
911
|
+
subtypes = ()
|
|
912
|
+
|
|
913
|
+
utility_code_config = {'EXC_NAME': name, 'SUBTYPES': subtypes, 'PROPERTY_NAME': ''}
|
|
914
|
+
|
|
915
|
+
for property_name in chain(('args', 'context', 'cause', 'traceback'), special_properties.get(name, ())):
|
|
916
|
+
utility_code_config['PROPERTY_NAME'] = property_name
|
|
917
|
+
|
|
918
|
+
exc_type.scope.declare_cproperty(
|
|
919
|
+
f'__{property_name}__' if property_name in ('context', 'cause', 'traceback') else property_name,
|
|
920
|
+
PyrexTypes.py_object_type,
|
|
921
|
+
f"__Pyx_Py{name}_get_{property_name}",
|
|
922
|
+
f"__Pyx_Py{name}_set_{property_name}",
|
|
923
|
+
utility_code=TempitaUtilityCode.load(
|
|
924
|
+
f"ExceptionGetProperty", "Builtins.c", context=utility_code_config),
|
|
925
|
+
setter_utility_code=TempitaUtilityCode.load(
|
|
926
|
+
f"ExceptionSetProperty", "Builtins.c", context=utility_code_config),
|
|
927
|
+
)
|
|
928
|
+
|
|
929
|
+
for name in PyrexTypes.KNOWN_EXCEPTION_NAMES:
|
|
930
|
+
parents = PyrexTypes.exception_supertypes.get(name)
|
|
931
|
+
if not parents or name not in builtin_types:
|
|
932
|
+
continue
|
|
933
|
+
exc_type = builtin_types[name]
|
|
934
|
+
exc_type.exception_supertypes = [
|
|
935
|
+
# Collect super types bottom up.
|
|
936
|
+
builtin_types.get(parent) for parent in reversed(parents)
|
|
937
|
+
]
|
|
938
|
+
while None in exc_type.exception_supertypes:
|
|
939
|
+
exc_type.exception_supertypes.remove(None)
|
|
835
940
|
|
|
836
941
|
|
|
837
942
|
def init_builtin_structs():
|