Cython 3.2.0b2__py3-none-any.whl → 3.2.1__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/Compiler/Code.py +69 -43
- Cython/Compiler/CythonScope.py +4 -0
- Cython/Compiler/ExprNodes.py +9 -3
- Cython/Compiler/MemoryView.py +1 -8
- Cython/Compiler/ModuleNode.py +26 -13
- Cython/Compiler/Nodes.py +5 -3
- Cython/Compiler/PyrexTypes.py +25 -13
- Cython/Compiler/Symtab.py +20 -3
- Cython/Compiler/UtilityCode.py +1 -1
- Cython/Debugger/Cygdb.py +4 -2
- Cython/Shadow.py +1 -1
- Cython/Utility/CommonStructures.c +1 -0
- Cython/Utility/ImportExport.c +18 -6
- Cython/Utility/MemoryView_C.c +19 -4
- Cython/Utility/ModuleSetupCode.c +63 -11
- Cython/Utility/ObjectHandling.c +3 -3
- Cython/Utility/Optimize.c +1 -10
- Cython/Utility/Synchronization.c +28 -18
- Cython/Utility/TypeConversion.c +39 -23
- {cython-3.2.0b2.dist-info → cython-3.2.1.dist-info}/METADATA +37 -19
- {cython-3.2.0b2.dist-info → cython-3.2.1.dist-info}/RECORD +24 -24
- {cython-3.2.0b2.dist-info → cython-3.2.1.dist-info}/WHEEL +0 -0
- {cython-3.2.0b2.dist-info → cython-3.2.1.dist-info}/entry_points.txt +0 -0
- {cython-3.2.0b2.dist-info → cython-3.2.1.dist-info}/top_level.txt +0 -0
Cython/Compiler/Code.py
CHANGED
|
@@ -402,7 +402,7 @@ class AbstractUtilityCode:
|
|
|
402
402
|
|
|
403
403
|
requires = None
|
|
404
404
|
|
|
405
|
-
def put_code(self,
|
|
405
|
+
def put_code(self, globalstate: "GlobalState", used_by=None) -> None:
|
|
406
406
|
pass
|
|
407
407
|
|
|
408
408
|
def get_tree(self, **kwargs):
|
|
@@ -463,7 +463,7 @@ class UtilityCodeBase(AbstractUtilityCode):
|
|
|
463
463
|
# section title
|
|
464
464
|
r'^%(C)s{5,30} \s* (?P<name> (?:\w|\.)+ ) \s* %(C)s{5,30} |'
|
|
465
465
|
# section tags and dependencies
|
|
466
|
-
r'^%(C)s+ @(?P<tag>
|
|
466
|
+
r'^%(C)s+ @(?P<tag> .+)'
|
|
467
467
|
) % {'C': re.escape(line_comment_char)}, re.VERBOSE).match
|
|
468
468
|
|
|
469
469
|
@classmethod
|
|
@@ -496,8 +496,8 @@ class UtilityCodeBase(AbstractUtilityCode):
|
|
|
496
496
|
|
|
497
497
|
if tags:
|
|
498
498
|
all_tags = utility[2]
|
|
499
|
-
for
|
|
500
|
-
all_tags.setdefault(
|
|
499
|
+
for tag_name, tag_values in tags.items():
|
|
500
|
+
all_tags.setdefault(tag_name, set()).update(tag_values)
|
|
501
501
|
|
|
502
502
|
@classmethod
|
|
503
503
|
def load_utilities_from_file(cls, path):
|
|
@@ -528,26 +528,38 @@ class UtilityCodeBase(AbstractUtilityCode):
|
|
|
528
528
|
|
|
529
529
|
for lineno, line in enumerate(all_lines):
|
|
530
530
|
m = match_special(line)
|
|
531
|
-
if m:
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
type = 'impl'
|
|
545
|
-
utility = utilities[name]
|
|
531
|
+
if m is None:
|
|
532
|
+
lines.append(rstrip(strip_comments(line)))
|
|
533
|
+
elif m.group('name'):
|
|
534
|
+
cls._add_utility(utility, name, type, lines, begin_lineno, tags)
|
|
535
|
+
|
|
536
|
+
begin_lineno = lineno + 1
|
|
537
|
+
del lines[:]
|
|
538
|
+
tags.clear()
|
|
539
|
+
|
|
540
|
+
name = m.group('name')
|
|
541
|
+
mtype = match_type(name)
|
|
542
|
+
if mtype:
|
|
543
|
+
name, type = mtype.groups()
|
|
546
544
|
else:
|
|
547
|
-
|
|
548
|
-
|
|
545
|
+
type = 'impl'
|
|
546
|
+
utility = utilities[name]
|
|
549
547
|
else:
|
|
550
|
-
|
|
548
|
+
tag_value = m.group('tag')
|
|
549
|
+
if ':' not in tag_value:
|
|
550
|
+
raise RuntimeError(f"Found invalid tag '{tag_value}' in utility section {name}.{type}")
|
|
551
|
+
|
|
552
|
+
tag_name, _, tag_value = tag_value.partition(':')
|
|
553
|
+
tag_name = tag_name.rstrip()
|
|
554
|
+
tag_value = tag_value.strip()
|
|
555
|
+
|
|
556
|
+
if tag_name not in ('requires', 'substitute', 'proto_block'):
|
|
557
|
+
raise RuntimeError(f"Found unknown tag name '{tag_name}' in utility section {name}.{type}")
|
|
558
|
+
if not re.match(r'\S+$', tag_value):
|
|
559
|
+
raise RuntimeError(f"Found invalid tag value '{tag_value}' in utility section {name}.{type}")
|
|
560
|
+
|
|
561
|
+
tags[tag_name].add(tag_value)
|
|
562
|
+
lines.append('') # keep line number correct
|
|
551
563
|
|
|
552
564
|
if utility is None:
|
|
553
565
|
raise ValueError("Empty utility code file")
|
|
@@ -726,6 +738,8 @@ class UtilityCode(UtilityCodeBase):
|
|
|
726
738
|
self.file = file
|
|
727
739
|
self.export = export
|
|
728
740
|
self.shared_utility_functions = self.parse_export_functions(export) if export else []
|
|
741
|
+
if export:
|
|
742
|
+
self._validate_suitable_for_sharing()
|
|
729
743
|
|
|
730
744
|
# cached for use in hash and eq
|
|
731
745
|
self._parts_tuple = tuple(getattr(self, part, None) for part in self.code_parts)
|
|
@@ -812,8 +826,14 @@ class UtilityCode(UtilityCodeBase):
|
|
|
812
826
|
self.specialize_list.append(s)
|
|
813
827
|
return s
|
|
814
828
|
|
|
829
|
+
def _validate_suitable_for_sharing(self):
|
|
830
|
+
code_string = getattr(self, "impl")
|
|
831
|
+
if not code_string: return
|
|
832
|
+
assert "NAMED_CGLOBAL(moddict_cname)" not in code_string, \
|
|
833
|
+
f"moddict_cname should not be shared: {self}"
|
|
834
|
+
|
|
815
835
|
@cython.final
|
|
816
|
-
def _put_code_section(self, writer: "CCodeWriter", output: "GlobalState", code_type: str):
|
|
836
|
+
def _put_code_section(self, writer: "CCodeWriter", output: "GlobalState", code_type: str, used_by=None):
|
|
817
837
|
code_string = getattr(self, code_type)
|
|
818
838
|
if not code_string:
|
|
819
839
|
return
|
|
@@ -822,8 +842,10 @@ class UtilityCode(UtilityCodeBase):
|
|
|
822
842
|
|
|
823
843
|
code_string, result_is_module_specific = process_utility_ccode(self, output, code_string)
|
|
824
844
|
|
|
825
|
-
|
|
826
|
-
|
|
845
|
+
used_by = f" (used by {used_by})" if used_by else ''
|
|
846
|
+
name = f"{self.name}.{code_type}" if code_type != 'impl' else self.name
|
|
847
|
+
|
|
848
|
+
writer.putln(f"/* {name}{used_by} */")
|
|
827
849
|
|
|
828
850
|
if can_be_reused and not result_is_module_specific:
|
|
829
851
|
# can be reused across modules
|
|
@@ -848,36 +870,36 @@ class UtilityCode(UtilityCodeBase):
|
|
|
848
870
|
code.putln(f'static {shared.ret}(*{shared.name})({shared.params}); /*proto*/')
|
|
849
871
|
code.putln()
|
|
850
872
|
|
|
851
|
-
def put_code(self,
|
|
873
|
+
def put_code(self, globalstate: "GlobalState", used_by=None) -> None:
|
|
852
874
|
has_shared_utility_code = bool(
|
|
853
|
-
self.shared_utility_functions and
|
|
875
|
+
self.shared_utility_functions and globalstate.module_node.scope.context.shared_utility_qualified_name
|
|
854
876
|
)
|
|
855
877
|
|
|
856
878
|
if self.requires and not has_shared_utility_code:
|
|
857
879
|
for dependency in self.requires:
|
|
858
|
-
|
|
880
|
+
globalstate.use_utility_code(dependency, used_by=self.name)
|
|
859
881
|
|
|
860
882
|
if has_shared_utility_code:
|
|
861
|
-
self._put_shared_function_declarations(
|
|
862
|
-
|
|
883
|
+
self._put_shared_function_declarations(globalstate[self.proto_block])
|
|
884
|
+
globalstate.shared_utility_functions.extend(self.shared_utility_functions)
|
|
863
885
|
|
|
864
886
|
if self.proto:
|
|
865
|
-
self._put_code_section(
|
|
887
|
+
self._put_code_section(globalstate[self.proto_block], globalstate, 'proto', used_by=used_by)
|
|
866
888
|
if not has_shared_utility_code:
|
|
867
|
-
self._put_code_section(
|
|
889
|
+
self._put_code_section(globalstate[self.proto_block], globalstate, 'export')
|
|
868
890
|
if self.impl and not has_shared_utility_code:
|
|
869
|
-
self._put_code_section(
|
|
891
|
+
self._put_code_section(globalstate['utility_code_def'], globalstate, 'impl', used_by=used_by)
|
|
870
892
|
if self.cleanup and Options.generate_cleanup_code:
|
|
871
|
-
self._put_code_section(
|
|
893
|
+
self._put_code_section(globalstate['cleanup_globals'], globalstate, 'cleanup')
|
|
872
894
|
if self.module_state_decls:
|
|
873
|
-
self._put_code_section(
|
|
895
|
+
self._put_code_section(globalstate['module_state_contents'], globalstate, 'module_state_decls')
|
|
874
896
|
if self.module_state_traverse:
|
|
875
|
-
self._put_code_section(
|
|
897
|
+
self._put_code_section(globalstate['module_state_traverse_contents'], globalstate, 'module_state_traverse')
|
|
876
898
|
if self.module_state_clear:
|
|
877
|
-
self._put_code_section(
|
|
899
|
+
self._put_code_section(globalstate['module_state_clear_contents'], globalstate, 'module_state_clear')
|
|
878
900
|
|
|
879
901
|
if self.init:
|
|
880
|
-
self._put_init_code_section(
|
|
902
|
+
self._put_init_code_section(globalstate)
|
|
881
903
|
|
|
882
904
|
|
|
883
905
|
def add_macro_processor(*macro_names, regex=None, is_module_specific=False, _last_macro_processor = [None]):
|
|
@@ -1076,9 +1098,9 @@ class LazyUtilityCode(UtilityCodeBase):
|
|
|
1076
1098
|
def __init__(self, callback):
|
|
1077
1099
|
self.callback = callback
|
|
1078
1100
|
|
|
1079
|
-
def put_code(self, globalstate):
|
|
1101
|
+
def put_code(self, globalstate: "GlobalState", used_by=None) -> None:
|
|
1080
1102
|
utility = self.callback(globalstate.rootwriter)
|
|
1081
|
-
globalstate.use_utility_code(utility)
|
|
1103
|
+
globalstate.use_utility_code(utility, used_by=used_by)
|
|
1082
1104
|
|
|
1083
1105
|
|
|
1084
1106
|
class FunctionState:
|
|
@@ -2459,7 +2481,7 @@ class GlobalState:
|
|
|
2459
2481
|
# Utility code state
|
|
2460
2482
|
#
|
|
2461
2483
|
|
|
2462
|
-
def use_utility_code(self, utility_code):
|
|
2484
|
+
def use_utility_code(self, utility_code, used_by=None):
|
|
2463
2485
|
"""
|
|
2464
2486
|
Adds code to the C file. utility_code should
|
|
2465
2487
|
a) implement __eq__/__hash__ for the purpose of knowing whether the same
|
|
@@ -2470,7 +2492,7 @@ class GlobalState:
|
|
|
2470
2492
|
"""
|
|
2471
2493
|
if utility_code and utility_code not in self.utility_codes:
|
|
2472
2494
|
self.utility_codes.add(utility_code)
|
|
2473
|
-
utility_code.put_code(self)
|
|
2495
|
+
utility_code.put_code(self, used_by=used_by)
|
|
2474
2496
|
|
|
2475
2497
|
def use_entry_utility_code(self, entry):
|
|
2476
2498
|
if entry is None:
|
|
@@ -2479,6 +2501,10 @@ class GlobalState:
|
|
|
2479
2501
|
self.use_utility_code(entry.utility_code)
|
|
2480
2502
|
if entry.utility_code_definition:
|
|
2481
2503
|
self.use_utility_code(entry.utility_code_definition)
|
|
2504
|
+
from . import PyrexTypes
|
|
2505
|
+
for tp in PyrexTypes.get_all_subtypes(entry.type):
|
|
2506
|
+
if hasattr(tp, "entry") and tp.entry is not entry:
|
|
2507
|
+
self.use_entry_utility_code(tp.entry)
|
|
2482
2508
|
|
|
2483
2509
|
|
|
2484
2510
|
def funccontext_property(func):
|
|
@@ -2968,7 +2994,7 @@ class CCodeWriter:
|
|
|
2968
2994
|
elif entry.type.is_pyobject:
|
|
2969
2995
|
self.put(" = NULL")
|
|
2970
2996
|
self.putln(";")
|
|
2971
|
-
self.
|
|
2997
|
+
self.globalstate.use_entry_utility_code(entry)
|
|
2972
2998
|
|
|
2973
2999
|
def put_temp_declarations(self, func_context: FunctionState):
|
|
2974
3000
|
for name, type, manage_ref, static in func_context.temps_allocated:
|
Cython/Compiler/CythonScope.py
CHANGED
|
@@ -25,12 +25,16 @@ class CythonScope(ModuleScope):
|
|
|
25
25
|
cname='<error>')
|
|
26
26
|
entry.in_cinclude = True
|
|
27
27
|
|
|
28
|
+
cy_pymutex_type = get_cy_pymutex_type()
|
|
28
29
|
entry = self.declare_type(
|
|
29
30
|
"pymutex", cy_pymutex_type, None,
|
|
30
31
|
cname="__Pyx_Locks_PyMutex")
|
|
32
|
+
entry.utility_code_definition = cy_pymutex_type.get_decl_utility_code()
|
|
33
|
+
cy_pythread_type_lock_type = get_cy_pythread_type_lock_type()
|
|
31
34
|
entry = self.declare_type(
|
|
32
35
|
"pythread_type_lock", cy_pythread_type_lock_type, None,
|
|
33
36
|
cname="__Pyx_Locks_PyThreadTypeLock")
|
|
37
|
+
entry.utility_code_definition = cy_pythread_type_lock_type.get_decl_utility_code()
|
|
34
38
|
|
|
35
39
|
def is_cpp(self):
|
|
36
40
|
# Allow C++ utility code in C++ contexts.
|
Cython/Compiler/ExprNodes.py
CHANGED
|
@@ -76,6 +76,9 @@ class NotConstant:
|
|
|
76
76
|
not_a_constant = NotConstant()
|
|
77
77
|
constant_value_not_set = object()
|
|
78
78
|
|
|
79
|
+
def _type_to_itself(tp):
|
|
80
|
+
return tp, tp
|
|
81
|
+
|
|
79
82
|
# error messages when coercing from key[0] to key[1]
|
|
80
83
|
coercion_error_dict = {
|
|
81
84
|
# string related errors
|
|
@@ -94,9 +97,9 @@ coercion_error_dict = {
|
|
|
94
97
|
(PyrexTypes.c_uchar_ptr_type, unicode_type): "Cannot convert 'char*' to unicode implicitly, decoding required",
|
|
95
98
|
(PyrexTypes.c_const_uchar_ptr_type, unicode_type): (
|
|
96
99
|
"Cannot convert 'char*' to unicode implicitly, decoding required"),
|
|
97
|
-
(PyrexTypes.
|
|
100
|
+
_type_to_itself(PyrexTypes.get_cy_pymutex_type()): (
|
|
98
101
|
"cython.pymutex cannot be copied"),
|
|
99
|
-
(PyrexTypes.
|
|
102
|
+
_type_to_itself(PyrexTypes.get_cy_pythread_type_lock_type()): (
|
|
100
103
|
"cython.pythread_type_lock cannot be copied"),
|
|
101
104
|
}
|
|
102
105
|
|
|
@@ -9167,9 +9170,12 @@ class ListNode(SequenceNode):
|
|
|
9167
9170
|
else:
|
|
9168
9171
|
if len(self.args) < len(dst_type.scope.var_entries):
|
|
9169
9172
|
warning(self.pos, "Too few members for '%s'" % dst_type, 1)
|
|
9170
|
-
for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
|
|
9173
|
+
for i, (arg, coerced_arg, member) in enumerate(zip(self.original_args, self.args, dst_type.scope.var_entries)):
|
|
9171
9174
|
if isinstance(arg, CoerceToPyTypeNode):
|
|
9172
9175
|
arg = arg.arg
|
|
9176
|
+
elif member.type.is_struct_or_union and coerced_arg.is_dict_literal:
|
|
9177
|
+
# For struct assignments, use the coerced dict directly, not a struct type call etc.
|
|
9178
|
+
arg = coerced_arg
|
|
9173
9179
|
self.args[i] = arg.coerce_to(member.type, env)
|
|
9174
9180
|
self.type = dst_type
|
|
9175
9181
|
elif dst_type.is_ctuple:
|
Cython/Compiler/MemoryView.py
CHANGED
|
@@ -518,7 +518,6 @@ def get_copy_new_utility(pos, from_memview, to_memview):
|
|
|
518
518
|
func_cname=copy_c_or_fortran_cname(to_memview),
|
|
519
519
|
dtype_is_object=int(to_memview.dtype.is_pyobject),
|
|
520
520
|
),
|
|
521
|
-
requires=[copy_contents_new_utility],
|
|
522
521
|
)
|
|
523
522
|
|
|
524
523
|
|
|
@@ -847,12 +846,7 @@ overlapping_utility = load_memview_c_utility("OverlappingSlices")
|
|
|
847
846
|
refcount_utility = load_memview_c_utility("MemviewRefcount")
|
|
848
847
|
slice_init_utility = load_memview_c_utility("MemviewSliceInit")
|
|
849
848
|
memviewslice_declare_code = load_memview_c_utility("MemviewSliceStruct", context=template_context)
|
|
850
|
-
|
|
851
|
-
copy_contents_new_utility = load_memview_c_utility(
|
|
852
|
-
"MemviewSliceCopyTemplate",
|
|
853
|
-
context=template_context,
|
|
854
|
-
# Requires general memoryview code - dependency is added below.
|
|
855
|
-
)
|
|
849
|
+
copy_contents_new_utility = load_memview_c_utility("MemviewSliceCopy")
|
|
856
850
|
|
|
857
851
|
|
|
858
852
|
@Utils.cached_function
|
|
@@ -887,7 +881,6 @@ def _get_memoryview_shared_utility_code(shared_utility_qualified_name):
|
|
|
887
881
|
memviewslice_declare_code,
|
|
888
882
|
refcount_utility,
|
|
889
883
|
atomic_utility,
|
|
890
|
-
copy_contents_new_utility,
|
|
891
884
|
],
|
|
892
885
|
)
|
|
893
886
|
|
Cython/Compiler/ModuleNode.py
CHANGED
|
@@ -161,7 +161,7 @@ class SharedUtilityExporter:
|
|
|
161
161
|
shared_utility_qualified_name = EncodedString(self.scope.context.shared_utility_qualified_name)
|
|
162
162
|
import_func = f"__Pyx_ImportFunction_{Naming.cyversion}"
|
|
163
163
|
_generate_import_code(
|
|
164
|
-
code, self.pos, imports, shared_utility_qualified_name, import_func, "void (
|
|
164
|
+
code, self.pos, imports, shared_utility_qualified_name, import_func, "void (**{name})(void)")
|
|
165
165
|
|
|
166
166
|
def _generate_exports(self, shared_utility_functions: Sequence[Code.SharedFunctionDecl]):
|
|
167
167
|
if self.has_shared_exports(shared_utility_functions):
|
|
@@ -285,7 +285,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
|
|
|
285
285
|
|
|
286
286
|
self.body.analyse_declarations(env)
|
|
287
287
|
|
|
288
|
-
|
|
288
|
+
cy_pymutex_type = PyrexTypes.get_cy_pymutex_type()
|
|
289
|
+
if env.find_shared_usages_of_type(cy_pymutex_type):
|
|
289
290
|
# Be very suspicious of cython locks that are shared.
|
|
290
291
|
# They have the potential to cause ABI issues.
|
|
291
292
|
self.scope.use_utility_code(
|
|
@@ -362,30 +363,33 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
|
|
|
362
363
|
h_code_start.put_h_guard(h_guard)
|
|
363
364
|
h_code_start.putln("")
|
|
364
365
|
h_code_start.putln('#include "Python.h"')
|
|
365
|
-
self.generate_type_header_code(h_types,
|
|
366
|
+
self.generate_type_header_code(h_types, h_code_main)
|
|
366
367
|
if options.capi_reexport_cincludes:
|
|
367
|
-
self.generate_includes(env, [],
|
|
368
|
-
|
|
368
|
+
self.generate_includes(env, [], h_code_main)
|
|
369
|
+
h_code_main.putln("")
|
|
369
370
|
api_guard = self.api_name(Naming.api_guard_prefix, env)
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
self.generate_extern_c_macro_definition(
|
|
373
|
-
|
|
374
|
-
self.generate_dl_import_macro(
|
|
371
|
+
h_code_main.putln("#ifndef %s" % api_guard)
|
|
372
|
+
h_code_main.putln("")
|
|
373
|
+
self.generate_extern_c_macro_definition(h_code_main, env.is_cpp())
|
|
374
|
+
h_code_main.putln("")
|
|
375
|
+
self.generate_dl_import_macro(h_code_main)
|
|
375
376
|
if h_extension_types:
|
|
376
377
|
h_code_main.putln("")
|
|
377
378
|
for entry in h_extension_types:
|
|
378
379
|
self.generate_cclass_header_code(entry.type, h_code_main)
|
|
379
380
|
if i_code:
|
|
380
381
|
self.generate_cclass_include_code(entry.type, i_code)
|
|
382
|
+
globalstate.use_entry_utility_code(entry)
|
|
381
383
|
if h_funcs:
|
|
382
384
|
h_code_main.putln("")
|
|
383
385
|
for entry in h_funcs:
|
|
384
386
|
self.generate_public_declaration(entry, h_code_main, i_code)
|
|
387
|
+
globalstate.use_entry_utility_code(entry)
|
|
385
388
|
if h_vars:
|
|
386
389
|
h_code_main.putln("")
|
|
387
390
|
for entry in h_vars:
|
|
388
391
|
self.generate_public_declaration(entry, h_code_main, i_code)
|
|
392
|
+
globalstate.use_entry_utility_code(entry)
|
|
389
393
|
h_code_main.putln("")
|
|
390
394
|
h_code_main.putln("#endif /* !%s */" % api_guard)
|
|
391
395
|
h_code_main.putln("")
|
|
@@ -452,7 +456,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
|
|
|
452
456
|
|
|
453
457
|
h_code = Code.CCodeWriter()
|
|
454
458
|
c_code_config = generate_c_code_config(env, options)
|
|
455
|
-
Code.GlobalState(h_code, self, c_code_config)
|
|
459
|
+
globalstate = Code.GlobalState(h_code, self, c_code_config)
|
|
460
|
+
globalstate.initialize_main_h_code() # in-case utility code is used in the header
|
|
456
461
|
h_code.put_generated_by()
|
|
457
462
|
api_guard = self.api_name(Naming.api_guard_prefix, env)
|
|
458
463
|
h_code.put_h_guard(api_guard)
|
|
@@ -480,6 +485,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
|
|
|
480
485
|
h_code.putln("static PyTypeObject *%s = 0;" % type.typeptr_cname)
|
|
481
486
|
h_code.putln("#define %s (*%s)" % (
|
|
482
487
|
type.typeobj_cname, type.typeptr_cname))
|
|
488
|
+
h_code.globalstate.use_entry_utility_code(entry)
|
|
483
489
|
if api_funcs:
|
|
484
490
|
h_code.putln("")
|
|
485
491
|
for entry in api_funcs:
|
|
@@ -487,6 +493,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
|
|
|
487
493
|
cname = env.mangle(Naming.func_prefix_api, entry.name)
|
|
488
494
|
h_code.putln("static %s = 0;" % type.declaration_code(cname))
|
|
489
495
|
h_code.putln("#define %s %s" % (entry.name, cname))
|
|
496
|
+
h_code.globalstate.use_entry_utility_code(entry)
|
|
490
497
|
if api_vars:
|
|
491
498
|
h_code.putln("")
|
|
492
499
|
for entry in api_vars:
|
|
@@ -494,6 +501,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
|
|
|
494
501
|
cname = env.mangle(Naming.varptr_prefix_api, entry.name)
|
|
495
502
|
h_code.putln("static %s = 0;" % type.declaration_code(cname))
|
|
496
503
|
h_code.putln("#define %s (*%s)" % (entry.name, cname))
|
|
504
|
+
h_code.globalstate.use_entry_utility_code(entry)
|
|
497
505
|
if api_vars:
|
|
498
506
|
put_utility_code("VoidPtrImport", "ImportExport.c")
|
|
499
507
|
if api_funcs:
|
|
@@ -1012,6 +1020,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
|
|
|
1012
1020
|
|
|
1013
1021
|
env.use_utility_code(UtilityCode.load_cached("FastTypeChecks", "ModuleSetupCode.c"))
|
|
1014
1022
|
env.use_utility_code(UtilityCode.load("GetRuntimeVersion", "ModuleSetupCode.c"))
|
|
1023
|
+
env.use_utility_code(UtilityCode.load_cached("AddModuleRef", "ModuleSetupCode.c"))
|
|
1015
1024
|
if has_np_pythran(env):
|
|
1016
1025
|
env.use_utility_code(UtilityCode.load_cached("PythranConversion", "CppSupport.cpp"))
|
|
1017
1026
|
|
|
@@ -1109,6 +1118,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
|
|
|
1109
1118
|
self.generate_cpp_class_definition(entry, code)
|
|
1110
1119
|
elif type.is_extension_type:
|
|
1111
1120
|
self.generate_objstruct_definition(type, code)
|
|
1121
|
+
if getattr(type, "scope", None):
|
|
1122
|
+
for var_entry in type.scope.var_entries:
|
|
1123
|
+
code.globalstate.use_entry_utility_code(var_entry)
|
|
1112
1124
|
|
|
1113
1125
|
def generate_gcc33_hack(self, env, code):
|
|
1114
1126
|
# Workaround for spurious warning generation in gcc 3.3
|
|
@@ -1447,7 +1459,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
|
|
|
1447
1459
|
decl = attr_type.cpp_optional_declaration_code(attr.cname)
|
|
1448
1460
|
else:
|
|
1449
1461
|
decl = attr_type.declaration_code(attr.cname)
|
|
1450
|
-
|
|
1462
|
+
code.globalstate.use_entry_utility_code(attr)
|
|
1451
1463
|
code.putln("%s;" % decl)
|
|
1452
1464
|
code.putln(footer)
|
|
1453
1465
|
if type.objtypedef_cname is not None:
|
|
@@ -1526,7 +1538,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
|
|
|
1526
1538
|
code.putln(";")
|
|
1527
1539
|
if entry.cname != cname:
|
|
1528
1540
|
code.putln("#define %s (*%s)" % (entry.cname, cname))
|
|
1529
|
-
|
|
1541
|
+
code.globalstate.use_entry_utility_code(entry)
|
|
1530
1542
|
|
|
1531
1543
|
def generate_cfunction_declarations(self, env, code, definition):
|
|
1532
1544
|
for entry in env.cfunc_entries:
|
|
@@ -4204,6 +4216,7 @@ def generate_cfunction_declaration(entry, env, code, definition):
|
|
|
4204
4216
|
storage_class,
|
|
4205
4217
|
modifiers,
|
|
4206
4218
|
header))
|
|
4219
|
+
code.globalstate.use_entry_utility_code(entry)
|
|
4207
4220
|
|
|
4208
4221
|
#------------------------------------------------------------------------------------
|
|
4209
4222
|
#
|
Cython/Compiler/Nodes.py
CHANGED
|
@@ -2989,6 +2989,7 @@ class CFuncDefNode(FuncDefNode):
|
|
|
2989
2989
|
if preprocessor_guard:
|
|
2990
2990
|
code.globalstate.parts['module_declarations'].putln("#endif")
|
|
2991
2991
|
code.putln("%s%s%s {" % (storage_class, modifiers, header))
|
|
2992
|
+
code.globalstate.use_entry_utility_code(self.entry)
|
|
2992
2993
|
|
|
2993
2994
|
def generate_argument_declarations(self, env, code):
|
|
2994
2995
|
scope = self.local_scope
|
|
@@ -9030,11 +9031,12 @@ class CriticalSectionStatNode(TryFinallyStatNode):
|
|
|
9030
9031
|
return super().analyse_declarations(env)
|
|
9031
9032
|
|
|
9032
9033
|
def analyse_expressions(self, env):
|
|
9034
|
+
cy_pymutex_type = PyrexTypes.get_cy_pymutex_type()
|
|
9033
9035
|
mutex_count = 0
|
|
9034
9036
|
for i, arg in enumerate(self.args):
|
|
9035
9037
|
arg = arg.analyse_expressions(env)
|
|
9036
|
-
if (arg.type
|
|
9037
|
-
arg.type.is_ptr and arg.type.base_type
|
|
9038
|
+
if (arg.type == cy_pymutex_type or (
|
|
9039
|
+
arg.type.is_ptr and arg.type.base_type == cy_pymutex_type)):
|
|
9038
9040
|
mutex_count += 1
|
|
9039
9041
|
self.is_pymutex_critical_section = True
|
|
9040
9042
|
elif arg.type.is_pyobject:
|
|
@@ -9189,7 +9191,7 @@ class CythonLockStatNode(TryFinallyStatNode):
|
|
|
9189
9191
|
return super().analyse_expressions(env)
|
|
9190
9192
|
|
|
9191
9193
|
def generate_execution_code(self, code):
|
|
9192
|
-
code.globalstate.use_utility_code(self.arg.type.
|
|
9194
|
+
code.globalstate.use_utility_code(self.arg.type.get_usage_utility_code())
|
|
9193
9195
|
|
|
9194
9196
|
code.mark_pos(self.pos)
|
|
9195
9197
|
code.begin_block()
|
Cython/Compiler/PyrexTypes.py
CHANGED
|
@@ -832,8 +832,7 @@ class MemoryViewSliceType(PyrexType):
|
|
|
832
832
|
copy_func_type, pos=pos, defining=1,
|
|
833
833
|
cname=copy_cname)
|
|
834
834
|
|
|
835
|
-
|
|
836
|
-
env.use_utility_code(utility)
|
|
835
|
+
entry.utility_code_definition = MemoryView.get_copy_new_utility(pos, self, to_memview)
|
|
837
836
|
|
|
838
837
|
MemoryView.use_cython_array_utility_code(env)
|
|
839
838
|
|
|
@@ -3822,9 +3821,9 @@ class ToPyStructUtilityCode(AbstractUtilityCode):
|
|
|
3822
3821
|
def __hash__(self):
|
|
3823
3822
|
return hash(self.header)
|
|
3824
3823
|
|
|
3825
|
-
def put_code(self,
|
|
3826
|
-
code =
|
|
3827
|
-
proto =
|
|
3824
|
+
def put_code(self, globalstate, used_by=None):
|
|
3825
|
+
code = globalstate['utility_code_def']
|
|
3826
|
+
proto = globalstate['utility_code_proto']
|
|
3828
3827
|
|
|
3829
3828
|
code.enter_cfunc_scope(self.env.global_scope())
|
|
3830
3829
|
code.putln("%s {" % self.header)
|
|
@@ -4947,9 +4946,10 @@ class CythonLockType(PyrexType):
|
|
|
4947
4946
|
# Singleton, cannot be copied.
|
|
4948
4947
|
return src_type is self._special_assignable_reference_type
|
|
4949
4948
|
|
|
4950
|
-
def
|
|
4951
|
-
|
|
4952
|
-
|
|
4949
|
+
def get_decl_utility_code(self):
|
|
4950
|
+
return UtilityCode.load_cached(f"{self.cname_part}Decl", "Synchronization.c")
|
|
4951
|
+
|
|
4952
|
+
def get_usage_utility_code(self):
|
|
4953
4953
|
return UtilityCode.load_cached(self.cname_part, "Synchronization.c")
|
|
4954
4954
|
|
|
4955
4955
|
def needs_explicit_construction(self, scope):
|
|
@@ -4964,7 +4964,7 @@ class CythonLockType(PyrexType):
|
|
|
4964
4964
|
|
|
4965
4965
|
def generate_explicit_construction(self, code, entry, extra_access_code=""):
|
|
4966
4966
|
code.globalstate.use_utility_code(
|
|
4967
|
-
self.
|
|
4967
|
+
self.get_usage_utility_code()
|
|
4968
4968
|
)
|
|
4969
4969
|
code.putln(f"__Pyx_Locks_{self.cname_part}_Init({extra_access_code}{entry.cname});")
|
|
4970
4970
|
|
|
@@ -4992,7 +4992,7 @@ class CythonLockType(PyrexType):
|
|
|
4992
4992
|
pos=None,
|
|
4993
4993
|
defining=1,
|
|
4994
4994
|
cname=f"__Pyx_Locks_{self.cname_part}_Lock",
|
|
4995
|
-
utility_code=self.
|
|
4995
|
+
utility_code=self.get_usage_utility_code())
|
|
4996
4996
|
scope.declare_cfunction(
|
|
4997
4997
|
"release",
|
|
4998
4998
|
CFuncType(c_void_type, [CFuncTypeArg("self", self_type, None)],
|
|
@@ -5000,7 +5000,7 @@ class CythonLockType(PyrexType):
|
|
|
5000
5000
|
pos=None,
|
|
5001
5001
|
defining=1,
|
|
5002
5002
|
cname=f"__Pyx_Locks_{self.cname_part}_Unlock",
|
|
5003
|
-
utility_code=self.
|
|
5003
|
+
utility_code=self.get_usage_utility_code())
|
|
5004
5004
|
# Don't define a "locked" function because we can't do this with Py_Mutex
|
|
5005
5005
|
# (which is the preferred implementation)
|
|
5006
5006
|
|
|
@@ -5012,6 +5012,14 @@ class CythonLockType(PyrexType):
|
|
|
5012
5012
|
def create_from_py_utility_code(self, env):
|
|
5013
5013
|
return False
|
|
5014
5014
|
|
|
5015
|
+
def __eq__(self, other):
|
|
5016
|
+
if type(other) is not type(self):
|
|
5017
|
+
return NotImplemented
|
|
5018
|
+
return other.cname_part == self.cname_part
|
|
5019
|
+
|
|
5020
|
+
def __hash__(self):
|
|
5021
|
+
return hash(self.cname_part)
|
|
5022
|
+
|
|
5015
5023
|
|
|
5016
5024
|
rank_to_type_name = (
|
|
5017
5025
|
"char", # 0
|
|
@@ -5143,8 +5151,12 @@ cython_memoryview_type = CStructOrUnionType("__pyx_memoryview_obj", "struct",
|
|
|
5143
5151
|
memoryviewslice_type = CStructOrUnionType("memoryviewslice", "struct",
|
|
5144
5152
|
None, 1, "__Pyx_memviewslice")
|
|
5145
5153
|
|
|
5146
|
-
|
|
5147
|
-
|
|
5154
|
+
# Don't declare these as globals - it interferes with our ability to check if it's
|
|
5155
|
+
# used in a particular scope.
|
|
5156
|
+
def get_cy_pymutex_type():
|
|
5157
|
+
return CythonLockType("PyMutex")
|
|
5158
|
+
def get_cy_pythread_type_lock_type():
|
|
5159
|
+
return CythonLockType("PyThreadTypeLock")
|
|
5148
5160
|
|
|
5149
5161
|
fixed_sign_int_types = {
|
|
5150
5162
|
"bint": (1, c_bint_type),
|
Cython/Compiler/Symtab.py
CHANGED
|
@@ -1236,7 +1236,7 @@ class Scope:
|
|
|
1236
1236
|
# e.g. slot, function, method
|
|
1237
1237
|
return f"{Naming.modulestateglobal_cname}->{cname}"
|
|
1238
1238
|
|
|
1239
|
-
def find_shared_usages_of_type(self,
|
|
1239
|
+
def find_shared_usages_of_type(self, type_to_find, _seen_scopes=None):
|
|
1240
1240
|
if _seen_scopes is None:
|
|
1241
1241
|
_seen_scopes = set()
|
|
1242
1242
|
include_all_entries = not self.is_module_scope
|
|
@@ -1244,17 +1244,31 @@ class Scope:
|
|
|
1244
1244
|
if not (include_all_entries or entry.defined_in_pxd or entry.visibility == "public" or entry.api):
|
|
1245
1245
|
continue
|
|
1246
1246
|
entry_subtypes = PyrexTypes.get_all_subtypes(entry.type)
|
|
1247
|
-
if any(
|
|
1247
|
+
if any(type_to_find == sub_tp for sub_tp in entry_subtypes):
|
|
1248
1248
|
return True
|
|
1249
1249
|
type_scope = getattr(entry.type, "scope", None)
|
|
1250
1250
|
if type_scope is None or type_scope in _seen_scopes:
|
|
1251
1251
|
continue
|
|
1252
1252
|
_seen_scopes.add(type_scope)
|
|
1253
|
-
if type_scope.find_shared_usages_of_type(
|
|
1253
|
+
if type_scope.find_shared_usages_of_type(type_to_find, _seen_scopes):
|
|
1254
1254
|
return True
|
|
1255
1255
|
return False
|
|
1256
1256
|
|
|
1257
1257
|
|
|
1258
|
+
class PreImportScope(Scope):
|
|
1259
|
+
|
|
1260
|
+
namespace_cname = Naming.preimport_cname
|
|
1261
|
+
|
|
1262
|
+
def __init__(self):
|
|
1263
|
+
Scope.__init__(self, Options.pre_import, None, None)
|
|
1264
|
+
|
|
1265
|
+
def declare_builtin(self, name, pos):
|
|
1266
|
+
entry = self.declare(name, name, py_object_type, pos, 'private')
|
|
1267
|
+
entry.is_variable = True
|
|
1268
|
+
entry.is_pyglobal = True
|
|
1269
|
+
return entry
|
|
1270
|
+
|
|
1271
|
+
|
|
1258
1272
|
class BuiltinScope(Scope):
|
|
1259
1273
|
# The builtin namespace.
|
|
1260
1274
|
|
|
@@ -1777,6 +1791,9 @@ class ModuleScope(Scope):
|
|
|
1777
1791
|
self.utility_code_list.append(entry.utility_code)
|
|
1778
1792
|
if entry.utility_code_definition:
|
|
1779
1793
|
self.utility_code_list.append(entry.utility_code_definition)
|
|
1794
|
+
for tp in PyrexTypes.get_all_subtypes(entry.type):
|
|
1795
|
+
if hasattr(tp, "entry") and tp.entry is not entry:
|
|
1796
|
+
self.use_entry_utility_code(tp.entry)
|
|
1780
1797
|
|
|
1781
1798
|
def declare_c_class(self, name, pos, defining=0, implementing=0,
|
|
1782
1799
|
module_name=None, base_type=None, objstruct_cname=None,
|
Cython/Compiler/UtilityCode.py
CHANGED
Cython/Debugger/Cygdb.py
CHANGED
|
@@ -50,9 +50,11 @@ def make_command_file(path_to_debug_info, prefix_code='',
|
|
|
50
50
|
try:
|
|
51
51
|
# Activate virtualenv, if we were launched from one
|
|
52
52
|
import os
|
|
53
|
+
import sys
|
|
53
54
|
virtualenv = os.getenv('VIRTUAL_ENV')
|
|
54
55
|
if virtualenv:
|
|
55
|
-
|
|
56
|
+
scripts_dir = 'Scripts' if sys.platform == "win32" else 'bin'
|
|
57
|
+
path_to_activate_this_py = os.path.join(virtualenv, scripts_dir, 'activate_this.py')
|
|
56
58
|
print("gdb command file: Activating virtualenv: %s; path_to_activate_this_py: %s" % (
|
|
57
59
|
virtualenv, path_to_activate_this_py))
|
|
58
60
|
with open(path_to_activate_this_py) as f:
|
|
@@ -60,7 +62,7 @@ def make_command_file(path_to_debug_info, prefix_code='',
|
|
|
60
62
|
from Cython.Debugger import libcython, libpython
|
|
61
63
|
except Exception as ex:
|
|
62
64
|
from traceback import print_exc
|
|
63
|
-
print("There was an error in Python code originating from the file ''' +
|
|
65
|
+
print("There was an error in Python code originating from the file " + ''' + repr(__file__) + ''')
|
|
64
66
|
print("It used the Python interpreter " + str(sys.executable))
|
|
65
67
|
print_exc()
|
|
66
68
|
exit(1)
|