Commit 70be8d1b authored by scoder's avatar scoder Committed by GitHub

Split the current "CYTHON_COMPILING_IN_LIMITED_API" macro guard (GH-3611)

* Split the current "CYTHON_COMPILING_IN_LIMITED_API" macro guard into separate feature guards:
1) using a global module state struct ("CYTHON_USE_MODULE_STATE")
2) using PyType_FromSpec() for extension types ("CYTHON_USE_TYPE_SPECS")
3) actual limited-API special casing ("CYTHON_COMPILING_IN_LIMITED_API")

* Start using PyType_FromModuleAndSpec() for creating extension types since that adds the module reference with PEP-573.

* Do not pass the module reference into *shared* extension types since we do not want to keep the module alive just because other modules still refer to the type.

* Mark the Limited-API and module state struct features as experimental.

* Add CI setups for using PyType_FromSpec() for creating extension types.

* Avoid overly complicated code in __Pyx_FetchCommonTypeFromSpec() when we are not compiling against the Limited-API.

* Correctly set up the bases tuple for PyType_FromSpecWithBases() and stop relying on the PyTypeObject struct being available in several places by using the type pointer instead (and setting it early enough).

* Set the "tp_dealloc" slot from the type spec, also for the limited API case.

* Generally re-enable the "heaptype bases hack" when creating extension types.

* Implement "tp_dictoffset" slot when using type specs in Py3.9+.

* Fix and simplify the vtable setup in the limited API config.

* Make CyFunction inheritable to "correctly" allow FusedFunction subclassing it.

* Enable buffer interface support when using type specs by assigning the "tp_as_buffer" slot explicitly after creating the type.

* Set "vectorcalloffset" when using type specs.

* Make "__bool__" slot prefer Py3+ name instead of Py2 name to make the correct name ("Py_nb_bool") appear in the type spec.

* Validate and fix up all extension types when constructing them from type specs (not only the internal ones).

* Only call PyType_Modified() once after changing a type, not once per change.

* Turn the "no buffer protocol in the limited API" error into a warning since the user code might still work without it.

* Enable the same flags for CyFunction in the static type and type spec case since it's shared across modules and thus, we might otherwise end up with differently configured types in the same runtime.

* The names of Cython's internal types (functions, generator, coroutine, etc.) are now prefixed with the shared module name, instead of making them look like homeless builtins.
See https://bugs.python.org/issue20204
See https://github.com/python/cpython/commit/490055a1673b524da2ebe2312f072aba2a826036

* Work around a CPython bug that makes it overwrite exttype member definitions for the "__module__" attribute.
See https://bugs.python.org/issue40703

* Inherit buffer slots manually since type slots don't support them and thus PyType_Ready() does not see them.

* Add METH_METHOD call support (currently unused).

* Fix the vectorcall offset used in CyFunction type struct in Py3.9, if it inherits from PyCMethodObject instead of PyCFunctionObject.

* Work around the duplicate creation of the "OverrideCheckNode" for fused cpdef functions.
See https://github.com/cython/cython/issues/3628

* Decref the type when deallocating instances of heap types in Py3.8+.
See https://bugs.python.org/issue35810

* Look up the fused dispatch function in the override check, not the specialisation (which shouldn't be overridden all by itself).
Closes https://github.com/cython/cython/issues/3628

* Avoid running the override check for CyFunction, just because it's not a PyCFunction itself.
parent 3aed7ef5
......@@ -68,6 +68,33 @@ jobs:
backend: "c,cpp"
env: { LIMITED_API: "--limited-api", EXCLUDE: "--no-file" }
extra_hash: "-limited_api"
# Type specs
- os: ubuntu-18.04
python-version: 3.9
backend: c
env: { EXTRA_CFLAGS: "-DCYTHON_USE_TYPE_SPECS=1" }
extra_hash: "-typespecs"
- os: ubuntu-18.04
python-version: 3.8
backend: c
env: { EXTRA_CFLAGS: "-DCYTHON_USE_TYPE_SPECS=1" }
extra_hash: "-typespecs"
- os: ubuntu-18.04
python-version: 3.7
backend: c
env: { EXTRA_CFLAGS: "-DCYTHON_USE_TYPE_SPECS=1" }
extra_hash: "-typespecs"
- os: ubuntu-18.04
python-version: 3.6
backend: c
env: { EXTRA_CFLAGS: "-DCYTHON_USE_TYPE_SPECS=1" }
extra_hash: "-typespecs"
- os: ubuntu-18.04
python-version: 3.5
backend: c
env: { EXTRA_CFLAGS: "-DCYTHON_USE_TYPE_SPECS=1" }
extra_hash: "-typespecs"
allowed_failure: true
# Stackless
- os: ubuntu-18.04
python-version: 2.7
......
......@@ -1476,7 +1476,7 @@ class GlobalState(object):
for c in self.py_constants]
consts.sort()
decls_writer = self.parts['decls']
decls_writer.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
decls_writer.putln("#if !CYTHON_USE_MODULE_STATE")
for _, cname, c in consts:
self.parts['module_state'].putln("%s;" % c.type.declaration_code(cname))
self.parts['module_state_defines'].putln(
......@@ -1551,16 +1551,16 @@ class GlobalState(object):
w = self.parts['pystring_table']
w.putln("")
w.putln("static __Pyx_StringTabEntry %s[] = {" % Naming.stringtab_cname)
w.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
w_limited_writer = w.insertion_point()
w.putln("#if CYTHON_USE_MODULE_STATE")
w_in_module_state = w.insertion_point()
w.putln("#else")
w_not_limited_writer = w.insertion_point()
w_not_in_module_state = w.insertion_point()
w.putln("#endif")
decls_writer.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
decls_writer.putln("#if !CYTHON_USE_MODULE_STATE")
not_limited_api_decls_writer = decls_writer.insertion_point()
decls_writer.putln("#endif")
init_globals.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
init_globals_limited_api = init_globals.insertion_point()
init_globals.putln("#if CYTHON_USE_MODULE_STATE")
init_globals_in_module_state = init_globals.insertion_point()
init_globals.putln("#endif")
for idx, py_string_args in enumerate(py_strings):
c_cname, _, py_string = py_string_args
......@@ -1583,16 +1583,16 @@ class GlobalState(object):
not_limited_api_decls_writer.putln(
"static PyObject *%s;" % py_string.cname)
if py_string.py3str_cstring:
w_not_limited_writer.putln("#if PY_MAJOR_VERSION >= 3")
w_not_limited_writer.putln("{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
w_not_in_module_state.putln("#if PY_MAJOR_VERSION >= 3")
w_not_in_module_state.putln("{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
py_string.cname,
py_string.py3str_cstring.cname,
py_string.py3str_cstring.cname,
'0', 1, 0,
py_string.intern
))
w_not_limited_writer.putln("#else")
w_not_limited_writer.putln("{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
w_not_in_module_state.putln("#else")
w_not_in_module_state.putln("{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
py_string.cname,
c_cname,
c_cname,
......@@ -1602,8 +1602,8 @@ class GlobalState(object):
py_string.intern
))
if py_string.py3str_cstring:
w_not_limited_writer.putln("#endif")
w_limited_writer.putln("{0, %s, sizeof(%s), %s, %d, %d, %d}," % (
w_not_in_module_state.putln("#endif")
w_in_module_state.putln("{0, %s, sizeof(%s), %s, %d, %d, %d}," % (
c_cname if not py_string.py3str_cstring else py_string.py3str_cstring.cname,
c_cname if not py_string.py3str_cstring else py_string.py3str_cstring.cname,
encoding if not py_string.py3str_cstring else '0',
......@@ -1611,7 +1611,7 @@ class GlobalState(object):
py_string.is_str,
py_string.intern
))
init_globals_limited_api.putln("if (__Pyx_InitString(%s[%d], &%s) < 0) %s;" % (
init_globals_in_module_state.putln("if (__Pyx_InitString(%s[%d], &%s) < 0) %s;" % (
Naming.stringtab_cname,
idx,
py_string.cname,
......@@ -1619,7 +1619,7 @@ class GlobalState(object):
w.putln("{0, 0, 0, 0, 0, 0, 0}")
w.putln("};")
init_globals.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
init_globals.putln("#if !CYTHON_USE_MODULE_STATE")
init_globals.putln(
"if (__Pyx_InitStrings(%s) < 0) %s;" % (
Naming.stringtab_cname,
......@@ -1631,7 +1631,7 @@ class GlobalState(object):
for c in self.num_const_index.values()]
consts.sort()
decls_writer = self.parts['decls']
decls_writer.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
decls_writer.putln("#if !CYTHON_USE_MODULE_STATE")
init_globals = self.parts['init_globals']
for py_type, _, _, value, value_code, c in consts:
cname = c.cname
......
......@@ -819,7 +819,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.put(Nodes.branch_prediction_macros)
code.putln('static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; }')
code.putln('')
code.putln('#if !CYTHON_COMPILING_IN_LIMITED_API')
code.putln('#if !CYTHON_USE_MODULE_STATE')
code.putln('static PyObject *%s = NULL;' % env.module_cname)
code.putln('static PyObject *%s;' % env.module_dict_cname)
code.putln('static PyObject *%s;' % Naming.builtins_cname)
......@@ -1254,7 +1254,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
module_state_defines = globalstate['module_state_defines']
module_state_clear = globalstate['module_state_clear']
module_state_traverse = globalstate['module_state_traverse']
code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
code.putln("#if !CYTHON_USE_MODULE_STATE")
for entry in env.c_class_entries:
if definition or entry.defined_in_pxd:
code.putln("static PyTypeObject *%s = 0;" % (
......@@ -1391,7 +1391,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_property_accessors(scope, code)
self.generate_method_table(scope, code)
self.generate_getset_table(scope, code)
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
code.putln("#if CYTHON_USE_TYPE_SPECS")
self.generate_typeobj_spec(entry, code)
code.putln("#else")
self.generate_typeobj_definition(full_module_name, entry, code)
......@@ -1581,11 +1581,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
slot_func_cname = scope.mangle_internal("tp_dealloc")
code.putln("")
cdealloc_func_entry = scope.lookup_here("__dealloc__")
if cdealloc_func_entry and not cdealloc_func_entry.is_special:
cdealloc_func_entry = None
if cdealloc_func_entry is None:
code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
code.putln(
"static void %s(PyObject *o) {" % slot_func_cname)
......@@ -1715,8 +1710,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"}")
if cdealloc_func_entry is None:
code.putln("#endif")
def generate_usr_dealloc_call(self, scope, code):
entry = scope.lookup_here("__dealloc__")
......@@ -2391,6 +2384,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_typeobj_spec(self, entry, code):
ext_type = entry.type
scope = ext_type.scope
members_slot = TypeSlots.get_slot_by_name("tp_members")
members_slot.generate_substructure_spec(scope, code)
buffer_slot = TypeSlots.get_slot_by_name("tp_as_buffer")
if not buffer_slot.is_empty(scope):
code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
buffer_slot.generate_substructure(scope, code)
code.putln("#endif")
code.putln("static PyType_Slot %s_slots[] = {" % ext_type.typeobj_cname)
for slot in TypeSlots.slot_table:
slot.generate_spec(scope, code)
......@@ -2582,8 +2585,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.exit_cfunc_scope() # done with labels
def generate_module_state_start(self, env, code):
# TODO: Reactor LIMITED_API struct decl closer to the static decl
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
# TODO: Refactor to move module state struct decl closer to the static decl
code.putln("#if CYTHON_USE_MODULE_STATE")
code.putln('typedef struct {')
code.putln('PyObject *%s;' % env.module_dict_cname)
code.putln('PyObject *%s;' % Naming.builtins_cname)
......@@ -2637,7 +2640,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
module_state_traverse.putln("#endif")
def generate_module_state_defines(self, env, code):
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
code.putln("#if CYTHON_USE_MODULE_STATE")
code.putln('#define %s %s->%s' % (
env.module_dict_cname,
Naming.modulestateglobal_cname,
......@@ -2681,7 +2684,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln('#endif')
def generate_module_state_clear(self, env, code):
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
code.putln("#if CYTHON_USE_MODULE_STATE")
code.putln("static int %s_clear(PyObject *m) {" % Naming.module_cname)
code.putln("%s *clear_module_state = %s(m);" % (
Naming.modulestate_cname,
......@@ -2709,7 +2712,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln('#endif')
def generate_module_state_traverse(self, env, code):
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
code.putln("#if CYTHON_USE_MODULE_STATE")
code.putln("static int %s_traverse(PyObject *m, visitproc visit, void *arg) {" % Naming.module_cname)
code.putln("%s *traverse_module_state = %s(m);" % (
Naming.modulestate_cname,
......@@ -2861,7 +2864,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for ext_type in ('CyFunction', 'FusedFunction', 'Coroutine', 'Generator', 'AsyncGen', 'StopAsyncIteration'):
code.putln("#ifdef __Pyx_%s_USED" % ext_type)
code.put_error_if_neg(self.pos, "__pyx_%s_init()" % ext_type)
code.put_error_if_neg(self.pos, "__pyx_%s_init(%s)" % (ext_type, env.module_cname))
code.putln("#endif")
code.putln("/*--- Library function declarations ---*/")
......@@ -3278,7 +3281,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(" %s, /* m_doc */" % doc)
code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
code.putln(" 0, /* m_size */")
code.putln("#elif CYTHON_COMPILING_IN_LIMITED_API")
code.putln("#elif CYTHON_USE_MODULE_STATE") # FIXME: should allow combination with PEP-489
code.putln(" sizeof(%s), /* m_size */" % Naming.modulestate_cname)
code.putln("#else")
code.putln(" -1, /* m_size */")
......@@ -3289,7 +3292,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("#else")
code.putln(" NULL, /* m_reload */")
code.putln("#endif")
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
code.putln("#if CYTHON_USE_MODULE_STATE")
code.putln(" %s_traverse, /* m_traverse */" % Naming.module_cname)
code.putln(" %s_clear, /* m_clear */" % Naming.module_cname)
code.putln(" %s /* m_free */" % cleanup_func)
......
......@@ -131,7 +131,7 @@ fused_func_prefix = pyrex_prefix + 'fuse_'
quick_temp_cname = pyrex_prefix + "temp" # temp variable for quick'n'dirty temping
tp_dict_version_temp = pyrex_prefix + "tp_dict_version"
obj_dict_version_temp = pyrex_prefix + "obj_dict_version"
type_dict_guard_temp = pyrex_prefix + "type_dict_guard"
type_dict_guard_temp = pyrex_prefix + "typedict_guard"
cython_runtime_cname = pyrex_prefix + "cython_runtime"
cyfunction_type_cname = pyrex_prefix + "CyFunctionType"
fusedfunction_type_cname = pyrex_prefix + "FusedFunctionType"
......
......@@ -2565,38 +2565,45 @@ class CFuncDefNode(FuncDefNode):
self.create_local_scope(env)
def declare_cpdef_wrapper(self, env):
if self.overridable:
if self.is_static_method:
# TODO(robertwb): Finish this up, perhaps via more function refactoring.
error(self.pos, "static cpdef methods not yet supported")
name = self.entry.name
py_func_body = self.call_self_node(is_module_scope=env.is_module_scope)
if self.is_static_method:
from .ExprNodes import NameNode
decorators = [DecoratorNode(self.pos, decorator=NameNode(self.pos, name=EncodedString('staticmethod')))]
decorators[0].decorator.analyse_types(env)
if not self.overridable:
return
if self.is_static_method:
# TODO(robertwb): Finish this up, perhaps via more function refactoring.
error(self.pos, "static cpdef methods not yet supported")
name = self.entry.name
py_func_body = self.call_self_node(is_module_scope=env.is_module_scope)
if self.is_static_method:
from .ExprNodes import NameNode
decorators = [DecoratorNode(self.pos, decorator=NameNode(self.pos, name=EncodedString('staticmethod')))]
decorators[0].decorator.analyse_types(env)
else:
decorators = []
self.py_func = DefNode(pos=self.pos,
name=self.entry.name,
args=self.args,
star_arg=None,
starstar_arg=None,
doc=self.doc,
body=py_func_body,
decorators=decorators,
is_wrapper=1)
self.py_func.is_module_scope = env.is_module_scope
self.py_func.analyse_declarations(env)
self.py_func.entry.is_overridable = True
self.py_func_stat = StatListNode(self.pos, stats=[self.py_func])
self.py_func.type = PyrexTypes.py_object_type
self.entry.as_variable = self.py_func.entry
self.entry.used = self.entry.as_variable.used = True
# Reset scope entry the above cfunction
env.entries[name] = self.entry
if (not self.entry.is_final_cmethod and
(not env.is_module_scope or Options.lookup_module_cpdef)):
if self.override:
# This is a hack: we shouldn't create the wrapper twice, but we do for fused functions.
assert self.entry.is_fused_specialized # should not happen for non-fused cpdef functions
self.override.py_func = self.py_func
else:
decorators = []
self.py_func = DefNode(pos=self.pos,
name=self.entry.name,
args=self.args,
star_arg=None,
starstar_arg=None,
doc=self.doc,
body=py_func_body,
decorators=decorators,
is_wrapper=1)
self.py_func.is_module_scope = env.is_module_scope
self.py_func.analyse_declarations(env)
self.py_func.entry.is_overridable = True
self.py_func_stat = StatListNode(self.pos, stats=[self.py_func])
self.py_func.type = PyrexTypes.py_object_type
self.entry.as_variable = self.py_func.entry
self.entry.used = self.entry.as_variable.used = True
# Reset scope entry the above cfunction
env.entries[name] = self.entry
if (not self.entry.is_final_cmethod and
(not env.is_module_scope or Options.lookup_module_cpdef)):
self.override = OverrideCheckNode(self.pos, py_func=self.py_func)
self.body = StatListNode(self.pos, stats=[self.override, self.body])
......@@ -3869,7 +3876,7 @@ class DefNodeWrapper(FuncDefNode):
non_posonly_args = [arg for arg in all_args if not arg.pos_only]
non_pos_args_id = ','.join(
['&%s' % code.intern_identifier(arg.entry.name) for arg in non_posonly_args] + ['0'])
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
code.putln("#if CYTHON_USE_MODULE_STATE")
code.putln("PyObject **%s[] = {%s};" % (
Naming.pykwdlist_cname,
non_pos_args_id))
......@@ -4670,7 +4677,10 @@ class OverrideCheckNode(StatNode):
return self
def generate_execution_code(self, code):
interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
# For fused functions, look up the dispatch function, not the specialisation.
method_entry = self.py_func.fused_py_func.entry if self.py_func.fused_py_func else self.py_func.entry
interned_attr_cname = code.intern_identifier(method_entry.name)
# Check to see if we are an extension type
if self.py_func.is_module_scope:
self_arg = "((PyObject *)%s)" % Naming.module_cname
......@@ -4711,10 +4721,14 @@ class OverrideCheckNode(StatNode):
func_node_temp, self_arg, interned_attr_cname, err))
code.put_gotref(func_node_temp, py_object_type)
is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (PyCFunction)(void*)%s)" % (
func_node_temp, self.py_func.entry.func_cname)
code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
func_node_temp, method_entry.func_cname)
code.putln("#ifdef __Pyx_CyFunction_USED")
code.putln("if (!__Pyx_IsCyOrPyCFunction(%s)" % func_node_temp)
code.putln("#else")
code.putln("if (!PyCFunction_Check(%s)" % func_node_temp)
code.putln("#endif")
code.putln(" || %s) {" % is_overridden)
self.body.generate_execution_code(code)
code.putln("}")
......@@ -5226,12 +5240,18 @@ class CClassDefNode(ClassDefNode):
# default values of method arguments.
code.mark_pos(self.pos)
if not self.entry.type.early_init:
bases = None
if self.type_init_args:
# Extract bases tuple and validate 'best base' by actually calling 'type()'.
bases = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
self.type_init_args.generate_evaluation_code(code)
bases = "PyTuple_GET_ITEM(%s, 1)" % self.type_init_args.result()
code.putln("%s = PyTuple_GET_ITEM(%s, 1);" % (bases, self.type_init_args.result()))
code.put_incref(bases, PyrexTypes.py_object_type)
first_base = "((PyTypeObject*)PyTuple_GET_ITEM(%s, 0))" % bases
# Let Python do the base types compatibility checking.
trial_type = code.funcstate.allocate_temp(PyrexTypes.py_object_type, True)
trial_type = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
code.putln("%s = PyType_Type.tp_new(&PyType_Type, %s, NULL);" % (
trial_type, self.type_init_args.result()))
code.putln(code.error_goto_if_null(trial_type, self.pos))
......@@ -5247,73 +5267,156 @@ class CClassDefNode(ClassDefNode):
code.putln("__Pyx_DECREF_TypeName(type_name);")
code.putln(code.error_goto(self.pos))
code.putln("}")
code.funcstate.release_temp(trial_type)
code.put_incref(bases, PyrexTypes.py_object_type)
code.put_giveref(bases, py_object_type)
code.putln("%s.tp_bases = %s;" % (self.entry.type.typeobj_cname, bases))
code.put_decref_clear(trial_type, PyrexTypes.py_object_type)
code.funcstate.release_temp(trial_type)
self.type_init_args.generate_disposal_code(code)
self.type_init_args.free_temps(code)
self.generate_type_ready_code(self.entry, code)
self.generate_type_ready_code(self.entry, code, bases_tuple_cname=bases, check_heap_type_bases=True)
if bases is not None:
code.put_decref_clear(bases, PyrexTypes.py_object_type)
code.funcstate.release_temp(bases)
if self.body:
self.body.generate_execution_code(code)
# Also called from ModuleNode for early init types.
@staticmethod
def generate_type_ready_code(entry, code):
def generate_type_ready_code(entry, code, bases_tuple_cname=None, check_heap_type_bases=False):
# Generate a call to PyType_Ready for an extension
# type defined in this module.
type = entry.type
typeobj_cname = type.typeobj_cname
typeptr_cname = type.typeptr_cname
scope = type.scope
if not scope: # could be None if there was an error
return
if entry.visibility != 'extern':
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
base_type = scope.parent_type.base_type
if base_type:
if entry.visibility == 'extern':
# Generate code to initialise the typeptr of an external extension
# type defined in this module to point to its type object.
if type.typeobj_cname:
# FIXME: this should not normally be set :-?
assert not type.typeobj_cname
code.putln("%s = &%s;" % (
type.typeptr_cname,
type.typeobj_cname,
))
return
# TODO: remove 'else:' and dedent
else:
assert typeptr_cname
assert type.typeobj_cname
typespec_cname = "%s_spec" % type.typeobj_cname
code.putln("#if CYTHON_USE_TYPE_SPECS")
tuple_temp = None
if not bases_tuple_cname and scope.parent_type.base_type:
tuple_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
code.putln(
"%s = PyTuple_Pack(1, (PyObject *)%s); %s" % (
code.putln("%s = PyTuple_Pack(1, (PyObject *)%s); %s" % (
tuple_temp,
base_type.typeptr_cname,
code.error_goto_if_null(tuple_temp, entry.pos)))
scope.parent_type.base_type.typeptr_cname,
code.error_goto_if_null(tuple_temp, entry.pos),
))
code.put_gotref(tuple_temp, py_object_type)
code.putln(
"%s = PyType_FromSpecWithBases(&%s_spec, %s); %s" % (
typeobj_cname,
typeobj_cname,
tuple_temp,
code.error_goto_if_null(typeobj_cname, entry.pos)))
code.put_xdecref_clear(tuple_temp, type=py_object_type)
code.funcstate.release_temp(tuple_temp)
if bases_tuple_cname or tuple_temp:
if check_heap_type_bases:
code.globalstate.use_utility_code(
UtilityCode.load_cached('ValidateBasesTuple', 'ExtensionTypes.c'))
code.put_error_if_neg(entry.pos, "__Pyx_validate_bases_tuple(%s.name, %s, %s)" % (
typespec_cname,
TypeSlots.get_slot_by_name("tp_dictoffset").slot_code(scope),
bases_tuple_cname or tuple_temp,
))
code.putln("%s = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(%s, &%s, %s);" % (
typeptr_cname,
Naming.module_cname,
typespec_cname,
bases_tuple_cname or tuple_temp,
))
if tuple_temp:
code.put_xdecref_clear(tuple_temp, type=py_object_type)
code.funcstate.release_temp(tuple_temp)
code.putln(code.error_goto_if_null(typeptr_cname, entry.pos))
else:
code.putln(
"%s = PyType_FromSpec(&%s_spec); %s" % (
typeobj_cname,
typeobj_cname,
code.error_goto_if_null(typeobj_cname, entry.pos)))
"%s = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(%s, &%s, NULL); %s" % (
typeptr_cname,
Naming.module_cname,
typespec_cname,
code.error_goto_if_null(typeptr_cname, entry.pos),
))
# The buffer interface is not currently supported by PyType_FromSpec().
buffer_slot = TypeSlots.get_slot_by_name("tp_as_buffer")
if not buffer_slot.is_empty(scope):
code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
code.putln("%s->%s = %s;" % (
typeptr_cname,
buffer_slot.slot_name,
buffer_slot.slot_code(scope),
))
# Still need to inherit buffer methods since PyType_Ready() didn't do it for us.
for buffer_method_name in ("__getbuffer__", "__releasebuffer__"):
buffer_slot = TypeSlots.get_slot_by_method_name(buffer_method_name)
if buffer_slot.slot_code(scope) == "0" and not TypeSlots.get_base_slot_function(scope, buffer_slot):
code.putln("if (!%s->tp_as_buffer->%s &&"
" %s->tp_base->tp_as_buffer &&"
" %s->tp_base->tp_as_buffer->%s) {" % (
typeptr_cname, buffer_slot.slot_name,
typeptr_cname,
typeptr_cname, buffer_slot.slot_name,
))
code.putln("%s->tp_as_buffer->%s = %s->tp_base->tp_as_buffer->%s;" % (
typeptr_cname, buffer_slot.slot_name,
typeptr_cname, buffer_slot.slot_name,
))
code.putln("}")
code.putln("#else")
code.putln("#warning The buffer protocol is not supported in the Limited C-API.")
code.putln("#endif")
code.globalstate.use_utility_code(
UtilityCode.load_cached("FixUpExtensionType", "ExtensionTypes.c"))
code.put_error_if_neg(entry.pos, "__Pyx_fix_up_extension_type_from_spec(&%s, %s)" % (
typespec_cname, typeptr_cname))
code.putln("#else")
if bases_tuple_cname:
code.put_incref(bases_tuple_cname, py_object_type)
code.put_giveref(bases_tuple_cname, py_object_type)
code.putln("%s.tp_bases = %s;" % (type.typeobj_cname, bases_tuple_cname))
code.putln("%s = &%s;" % (
typeptr_cname,
type.typeobj_cname,
))
code.putln("#endif") # if CYTHON_USE_TYPE_SPECS
code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
# FIXME: these still need to get initialised even with the limited-API
for slot in TypeSlots.slot_table:
slot.generate_dynamic_init_code(scope, code)
code.putln("#endif")
code.putln("#if !CYTHON_USE_TYPE_SPECS")
code.globalstate.use_utility_code(
UtilityCode.load_cached('PyType_Ready', 'ExtensionTypes.c'))
code.putln(
"if (__Pyx_PyType_Ready(&%s) < 0) %s" % (
typeobj_cname,
code.error_goto(entry.pos)))
code.put_error_if_neg(entry.pos, "__Pyx_PyType_Ready(%s)" % typeptr_cname)
code.putln("#endif")
# Don't inherit tp_print from builtin types in Python 2, restoring the
# behavior of using tp_repr or tp_str instead.
# ("tp_print" was renamed to "tp_vectorcall_offset" in Py3.8b1)
code.putln("#if PY_MAJOR_VERSION < 3")
code.putln("%s.tp_print = 0;" % typeobj_cname)
code.putln("%s->tp_print = 0;" % typeptr_cname)
code.putln("#endif")
# Use specialised attribute lookup for types with generic lookup but no instance dict.
getattr_slot_func = TypeSlots.get_slot_code_by_name(scope, 'tp_getattro')
dictoffset_slot_func = TypeSlots.get_slot_code_by_name(scope, 'tp_dictoffset')
if getattr_slot_func == '0' and dictoffset_slot_func == '0':
code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API") # FIXME
if type.is_final_type:
py_cfunc = "__Pyx_PyObject_GenericGetAttrNoDict" # grepable
utility_func = "PyObject_GenericGetAttrNoDict"
......@@ -5323,12 +5426,12 @@ class CClassDefNode(ClassDefNode):
code.globalstate.use_utility_code(UtilityCode.load_cached(utility_func, "ObjectHandling.c"))
code.putln("if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) &&"
" likely(!%s.tp_dictoffset && %s.tp_getattro == PyObject_GenericGetAttr)) {" % (
typeobj_cname, typeobj_cname))
code.putln("%s.tp_getattro = %s;" % (
typeobj_cname, py_cfunc))
" likely(!%s->tp_dictoffset && %s->tp_getattro == PyObject_GenericGetAttr)) {" % (
typeptr_cname, typeptr_cname))
code.putln("%s->tp_getattro = %s;" % (
typeptr_cname, py_cfunc))
code.putln("}")
code.putln("#endif")
code.putln("#endif") # if !CYTHON_COMPILING_IN_LIMITED_API
# Fix special method docstrings. This is a bit of a hack, but
# unless we let PyType_Ready create the slot wrappers we have
......@@ -5344,8 +5447,8 @@ class CClassDefNode(ClassDefNode):
code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
code.putln("{")
code.putln(
'PyObject *wrapper = PyObject_GetAttrString((PyObject *)&%s, "%s"); %s' % (
typeobj_cname,
'PyObject *wrapper = PyObject_GetAttrString((PyObject *)%s, "%s"); %s' % (
typeptr_cname,
func.name,
code.error_goto_if_null('wrapper', entry.pos)))
code.putln(
......@@ -5363,51 +5466,34 @@ class CClassDefNode(ClassDefNode):
code.putln('#endif')
if preprocessor_guard:
code.putln('#endif')
if type.vtable_cname:
code.globalstate.use_utility_code(
UtilityCode.load_cached('SetVTable', 'ImportExport.c'))
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
code.putln(
"if (__Pyx_SetVtable(%s, %s) < 0) %s" % (
typeobj_cname,
type.vtabptr_cname,
code.error_goto(entry.pos)))
code.putln("#else")
code.putln(
"if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
typeobj_cname,
type.vtabptr_cname,
code.error_goto(entry.pos)))
code.put_error_if_neg(entry.pos, "__Pyx_SetVtable(%s, %s)" % (
typeptr_cname,
type.vtabptr_cname,
))
# TODO: find a way to make this work with the Limited API!
code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
code.globalstate.use_utility_code(
UtilityCode.load_cached('MergeVTables', 'ImportExport.c'))
code.putln("if (__Pyx_MergeVtables(&%s) < 0) %s" % (
typeobj_cname,
code.error_goto(entry.pos)))
code.put_error_if_neg(entry.pos, "__Pyx_MergeVtables(%s)" % typeptr_cname)
code.putln("#endif")
if not type.scope.is_internal and not type.scope.directives.get('internal'):
# scope.is_internal is set for types defined by
# Cython (such as closures), the 'internal'
# directive is set by users
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
code.putln(
'if (PyObject_SetAttr(%s, %s, %s) < 0) %s' % (
Naming.module_cname,
code.intern_identifier(scope.class_name),
typeobj_cname,
code.error_goto(entry.pos)))
code.putln("#else")
code.putln(
'if (PyObject_SetAttr(%s, %s, (PyObject *)&%s) < 0) %s' % (
Naming.module_cname,
code.intern_identifier(scope.class_name),
typeobj_cname,
code.error_goto(entry.pos)))
code.putln("#endif")
code.put_error_if_neg(entry.pos, "PyObject_SetAttr(%s, %s, (PyObject *) %s)" % (
Naming.module_cname,
code.intern_identifier(scope.class_name),
typeptr_cname,
))
weakref_entry = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None
if weakref_entry:
if weakref_entry.type is py_object_type:
tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
tp_weaklistoffset = "%s->tp_weaklistoffset" % typeptr_cname
if type.typedef_flag:
objstruct = type.objstruct_cname
else:
......@@ -5419,29 +5505,16 @@ class CClassDefNode(ClassDefNode):
weakref_entry.cname))
else:
error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
if scope.lookup_here("__reduce_cython__") if not scope.is_closure_class_scope else None:
# Unfortunately, we cannot reliably detect whether a
# superclass defined __reduce__ at compile time, so we must
# do so at runtime.
code.globalstate.use_utility_code(
UtilityCode.load_cached('SetupReduce', 'ExtensionTypes.c'))
code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
code.putln('if (__Pyx_setup_reduce((PyObject*)&%s) < 0) %s' % (
typeobj_cname,
code.error_goto(entry.pos)))
code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API") # FIXME
code.put_error_if_neg(entry.pos, "__Pyx_setup_reduce((PyObject *) %s)" % typeptr_cname)
code.putln("#endif")
# Generate code to initialise the typeptr of an extension
# type defined in this module to point to its type object.
if type.typeobj_cname:
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
code.putln(
"%s = (PyTypeObject *)%s;" % (
type.typeptr_cname, type.typeobj_cname))
code.putln("#else")
code.putln(
"%s = &%s;" % (
type.typeptr_cname, type.typeobj_cname))
code.putln("#endif")
def annotate(self, code):
if self.type_init_args:
......
......@@ -276,7 +276,7 @@ class SlotDescriptor(object):
# PyPy currently has a broken PyType_Ready() that fails to
# inherit some slots. To work around this, we explicitly
# set inherited slots here, but only in PyPy since CPython
# handles this better than we do.
# handles this better than we do (except for buffer slots in type specs).
inherited_value = value
current_scope = scope
while (inherited_value == "0"
......@@ -286,7 +286,9 @@ class SlotDescriptor(object):
current_scope = current_scope.parent_type.base_type.scope
inherited_value = self.slot_code(current_scope)
if inherited_value != "0":
code.putln("#if CYTHON_COMPILING_IN_PYPY")
# we always need inherited buffer slots for the type spec
is_buffer_slot = int(self.slot_name in ("bf_getbuffer", "bf_releasebuffer"))
code.putln("#if CYTHON_COMPILING_IN_PYPY || %d" % is_buffer_slot)
code.putln("%s, /*%s*/" % (inherited_value, self.slot_name))
code.putln("#else")
end_pypy_guard = True
......@@ -315,11 +317,14 @@ class SlotDescriptor(object):
def generate_set_slot_code(self, value, scope, code):
if value == "0":
return
code.putln("%s.%s = %s;" % (
scope.parent_type.typeobj_cname,
self.slot_name,
value,
))
if scope.parent_type.typeptr_cname:
target = "%s->%s" % (scope.parent_type.typeptr_cname, self.slot_name)
else:
assert scope.parent_type.typeobj_cname
target = "%s.%s" % (scope.parent_type.typeobj_cname, self.slot_name)
code.putln("%s = %s;" % (target, value))
class FixedSlot(SlotDescriptor):
......@@ -458,9 +463,11 @@ class ConstructorSlot(InternalMethodSlot):
return InternalMethodSlot.slot_code(self, scope)
def spec_value(self, scope):
if self.slot_name == "tp_dealloc" and not scope.lookup_here("__dealloc__"):
slot_function = self.slot_code(scope)
if self.slot_name == "tp_dealloc" and slot_function != scope.mangle_internal("tp_dealloc"):
# Not used => inherit from base type.
return "0"
return self.slot_code(scope)
return slot_function
def generate_dynamic_init_code(self, scope, code):
if self.slot_code(scope) != '0':
......@@ -468,10 +475,10 @@ class ConstructorSlot(InternalMethodSlot):
# If we don't have our own slot function and don't know the
# parent function statically, copy it dynamically.
base_type = scope.parent_type.base_type
if base_type.is_extension_type and base_type.typeobj_cname:
src = '%s.%s' % (base_type.typeobj_cname, self.slot_name)
elif base_type.typeptr_cname:
if base_type.typeptr_cname:
src = '%s->%s' % (base_type.typeptr_cname, self.slot_name)
elif base_type.is_extension_type and base_type.typeobj_cname:
src = '%s.%s' % (base_type.typeobj_cname, self.slot_name)
else:
return
......@@ -498,8 +505,6 @@ class SyntheticSlot(InternalMethodSlot):
return self.default_value
def spec_value(self, scope):
if self.slot_name == "tp_getattro" and not scope.defines_any_special(self.user_methods):
return "PyObject_GenericGetAttr"
return self.slot_code(scope)
......@@ -623,8 +628,43 @@ class MemberTableSlot(SlotDescriptor):
# Slot descriptor for the table of Python-accessible attributes.
def slot_code(self, scope):
# Only used in specs.
return "0"
def get_member_specs(self, scope):
return [
get_slot_by_name("tp_dictoffset").members_slot_value(scope),
#get_slot_by_name("tp_weaklistoffset").spec_value(scope),
]
def is_empty(self, scope):
for member_entry in self.get_member_specs(scope):
if member_entry:
return False
return True
def substructure_cname(self, scope):
return "%s%s_%s" % (Naming.pyrex_prefix, self.slot_name, scope.class_name)
def generate_substructure_spec(self, scope, code):
if self.is_empty(scope):
return
from .Code import UtilityCode
code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStructmemberH", "ModuleSetupCode.c"))
ext_type = scope.parent_type
code.putln("static struct PyMemberDef %s[] = {" % self.substructure_cname(scope))
for member_entry in self.get_member_specs(scope):
if member_entry:
code.putln(member_entry)
code.putln("{NULL, 0, 0, 0, NULL}")
code.putln("};")
def spec_value(self, scope):
if self.is_empty(scope):
return "0"
return self.substructure_cname(scope)
class GetSetSlot(SlotDescriptor):
# Slot descriptor for the table of attribute get & set methods.
......@@ -645,8 +685,8 @@ class BaseClassSlot(SlotDescriptor):
def generate_dynamic_init_code(self, scope, code):
base_type = scope.parent_type.base_type
if base_type:
code.putln("%s.%s = %s;" % (
scope.parent_type.typeobj_cname,
code.putln("%s->%s = %s;" % (
scope.parent_type.typeptr_cname,
self.slot_name,
base_type.typeptr_cname))
......@@ -671,6 +711,13 @@ class DictOffsetSlot(SlotDescriptor):
else:
return "0"
def members_slot_value(self, scope):
dict_offset = self.slot_code(scope)
if dict_offset == "0":
return None
return '{"__dictoffset__", T_PYSSIZET, %s, READONLY, NULL},' % dict_offset
# The following dictionary maps __xxx__ method names to slot descriptors.
......@@ -712,7 +759,7 @@ def get_base_slot_function(scope, slot):
# This is useful for enabling the compiler to optimize calls
# that recursively climb the class hierarchy.
base_type = scope.parent_type.base_type
if scope.parent_scope is base_type.scope.parent_scope:
if base_type and scope.parent_scope is base_type.scope.parent_scope:
parent_slot = slot.slot_code(base_type.scope)
if parent_slot != '0':
entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name)
......@@ -741,6 +788,11 @@ def get_slot_by_name(slot_name):
assert False, "Slot not found: %s" % slot_name
def get_slot_by_method_name(method_name):
# For now, only search the type struct, no referenced sub-structs.
return method_name_to_slot[method_name]
def get_slot_code_by_name(scope, slot_name):
slot = get_slot_by_name(slot_name)
return slot.slot_code(scope)
......@@ -845,38 +897,38 @@ property_accessor_signatures = {
#
#------------------------------------------------------------------------------------------
PyNumberMethods_Py3_GUARD = "PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000)"
PyNumberMethods_Py2only_GUARD = "PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000)"
PyNumberMethods = (
BinopSlot(binaryfunc, "nb_add", "__add__"),
BinopSlot(binaryfunc, "nb_subtract", "__sub__"),
BinopSlot(binaryfunc, "nb_multiply", "__mul__"),
BinopSlot(binaryfunc, "nb_divide", "__div__", ifdef = PyNumberMethods_Py3_GUARD),
BinopSlot(binaryfunc, "nb_divide", "__div__", ifdef = PyNumberMethods_Py2only_GUARD),
BinopSlot(binaryfunc, "nb_remainder", "__mod__"),
BinopSlot(binaryfunc, "nb_divmod", "__divmod__"),
BinopSlot(ternaryfunc, "nb_power", "__pow__"),
MethodSlot(unaryfunc, "nb_negative", "__neg__"),
MethodSlot(unaryfunc, "nb_positive", "__pos__"),
MethodSlot(unaryfunc, "nb_absolute", "__abs__"),
MethodSlot(inquiry, "nb_nonzero", "__nonzero__", py3 = ("nb_bool", "__bool__")),
MethodSlot(inquiry, "nb_bool", "__bool__", py2 = ("nb_nonzero", "__nonzero__")),
MethodSlot(unaryfunc, "nb_invert", "__invert__"),
BinopSlot(binaryfunc, "nb_lshift", "__lshift__"),
BinopSlot(binaryfunc, "nb_rshift", "__rshift__"),
BinopSlot(binaryfunc, "nb_and", "__and__"),
BinopSlot(binaryfunc, "nb_xor", "__xor__"),
BinopSlot(binaryfunc, "nb_or", "__or__"),
EmptySlot("nb_coerce", ifdef = PyNumberMethods_Py3_GUARD),
EmptySlot("nb_coerce", ifdef = PyNumberMethods_Py2only_GUARD),
MethodSlot(unaryfunc, "nb_int", "__int__", fallback="__long__"),
MethodSlot(unaryfunc, "nb_long", "__long__", fallback="__int__", py3 = "<RESERVED>"),
MethodSlot(unaryfunc, "nb_float", "__float__"),
MethodSlot(unaryfunc, "nb_oct", "__oct__", ifdef = PyNumberMethods_Py3_GUARD),
MethodSlot(unaryfunc, "nb_hex", "__hex__", ifdef = PyNumberMethods_Py3_GUARD),
MethodSlot(unaryfunc, "nb_oct", "__oct__", ifdef = PyNumberMethods_Py2only_GUARD),
MethodSlot(unaryfunc, "nb_hex", "__hex__", ifdef = PyNumberMethods_Py2only_GUARD),
# Added in release 2.0
MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__"),
MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__"),
MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__"),
MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__", ifdef = PyNumberMethods_Py3_GUARD),
MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__", ifdef = PyNumberMethods_Py2only_GUARD),
MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__"),
MethodSlot(ibinaryfunc, "nb_inplace_power", "__ipow__"), # actually ternaryfunc!!!
MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__"),
......@@ -992,7 +1044,7 @@ slot_table = (
SyntheticSlot("tp_descr_get", ["__get__"], "0"),
SyntheticSlot("tp_descr_set", ["__set__", "__delete__"], "0"),
DictOffsetSlot("tp_dictoffset"),
DictOffsetSlot("tp_dictoffset", ifdef="!CYTHON_USE_TYPE_SPECS"), # otherwise set via "__dictoffset__" member
MethodSlot(initproc, "tp_init", "__init__"),
EmptySlot("tp_alloc"), #FixedSlot("tp_alloc", "PyType_GenericAlloc"),
......
......@@ -47,7 +47,7 @@ static __pyx_CoroutineObject *__Pyx_AsyncGen_New(
return __Pyx__Coroutine_NewInit((__pyx_CoroutineObject*)gen, body, code, closure, name, qualname, module_name);
}
static int __pyx_AsyncGen_init(void);
static int __pyx_AsyncGen_init(PyObject *module);
static void __Pyx_PyAsyncGen_Fini(void);
//////////////////// AsyncGenerator.cleanup ////////////////////
......@@ -325,6 +325,10 @@ static PyMemberDef __Pyx_async_gen_memberlist[] = {
//ADDED: "ag_await"
{(char*) "ag_await", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
(char*) PyDoc_STR("object being awaited on, or None")},
{(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0},
#if CYTHON_USE_TYPE_SPECS
{(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0},
#endif
{0, 0, 0, 0, 0} /* Sentinel */
};
......@@ -353,6 +357,31 @@ static PyMethodDef __Pyx_async_gen_methods[] = {
};
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_AsyncGenType_slots[] = {
{Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc},
{Py_am_aiter, (void *)PyObject_SelfIter},
{Py_am_anext, (void *)__Pyx_async_gen_anext},
{Py_tp_repr, (void *)__Pyx_async_gen_repr},
{Py_tp_traverse, (void *)__Pyx_async_gen_traverse},
{Py_tp_methods, (void *)__Pyx_async_gen_methods},
{Py_tp_members, (void *)__Pyx_async_gen_memberlist},
{Py_tp_getset, (void *)__Pyx_async_gen_getsetlist},
#if CYTHON_USE_TP_FINALIZE
{Py_tp_finalize, (void *)__Pyx_Coroutine_del},
#endif
{0, 0},
};
static PyType_Spec __pyx_AsyncGenType_spec = {
__PYX_TYPE_MODULE_PREFIX "async_generator",
sizeof(__pyx_PyAsyncGenObject),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
__pyx_AsyncGenType_slots
};
#else /* CYTHON_USE_TYPE_SPECS */
#if CYTHON_USE_ASYNC_SLOTS
static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_as_async = {
0, /* am_await */
......@@ -438,6 +467,7 @@ static PyTypeObject __pyx_AsyncGenType_type = {
0, /*tp_pypy_flags*/
#endif
};
#endif /* CYTHON_USE_TYPE_SPECS */
static int
......@@ -449,14 +479,14 @@ __Pyx_PyAsyncGen_ClearFreeLists(void)
__pyx__PyAsyncGenWrappedValue *o;
o = __Pyx_ag_value_freelist[--__Pyx_ag_value_freelist_free];
assert(__pyx__PyAsyncGenWrappedValue_CheckExact(o));
PyObject_GC_Del(o);
__Pyx_PyHeapTypeObject_GC_Del(o);
}
while (__Pyx_ag_asend_freelist_free) {
__pyx_PyAsyncGenASend *o;
o = __Pyx_ag_asend_freelist[--__Pyx_ag_asend_freelist_free];
assert(__Pyx_IS_TYPE(o, __pyx__PyAsyncGenASendType));
PyObject_GC_Del(o);
__Pyx_PyHeapTypeObject_GC_Del(o);
}
return ret;
......@@ -510,7 +540,7 @@ __Pyx_async_gen_asend_dealloc(__pyx_PyAsyncGenASend *o)
assert(__pyx_PyAsyncGenASend_CheckExact(o));
__Pyx_ag_asend_freelist[__Pyx_ag_asend_freelist_free++] = o;
} else {
PyObject_GC_Del(o);
__Pyx_PyHeapTypeObject_GC_Del(o);
}
}
......@@ -607,6 +637,26 @@ static PyMethodDef __Pyx_async_gen_asend_methods[] = {
};
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx__PyAsyncGenASendType_slots[] = {
{Py_tp_dealloc, (void *)__Pyx_async_gen_asend_dealloc},
{Py_am_await, (void *)PyObject_SelfIter},
{Py_tp_traverse, (void *)__Pyx_async_gen_asend_traverse},
{Py_tp_methods, (void *)__Pyx_async_gen_asend_methods},
{Py_tp_iter, (void *)PyObject_SelfIter},
{Py_tp_iternext, (void *)__Pyx_async_gen_asend_iternext},
{0, 0},
};
static PyType_Spec __pyx__PyAsyncGenASendType_spec = {
__PYX_TYPE_MODULE_PREFIX "async_generator_asend",
sizeof(__pyx_PyAsyncGenASend),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
__pyx__PyAsyncGenASendType_slots
};
#else /* CYTHON_USE_TYPE_SPECS */
#if CYTHON_USE_ASYNC_SLOTS
static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_asend_as_async = {
PyObject_SelfIter, /* am_await */
......@@ -615,7 +665,6 @@ static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_asend_as_async = {
};
#endif
static PyTypeObject __pyx__PyAsyncGenASendType_type = {
PyVarObject_HEAD_INIT(0, 0)
"async_generator_asend", /* tp_name */
......@@ -687,6 +736,7 @@ static PyTypeObject __pyx__PyAsyncGenASendType_type = {
0, /*tp_pypy_flags*/
#endif
};
#endif /* CYTHON_USE_TYPE_SPECS */
static PyObject *
......@@ -729,7 +779,7 @@ __Pyx_async_gen_wrapped_val_dealloc(__pyx__PyAsyncGenWrappedValue *o)
assert(__pyx__PyAsyncGenWrappedValue_CheckExact(o));
__Pyx_ag_value_freelist[__Pyx_ag_value_freelist_free++] = o;
} else {
PyObject_GC_Del(o);
__Pyx_PyHeapTypeObject_GC_Del(o);
}
}
......@@ -743,6 +793,22 @@ __Pyx_async_gen_wrapped_val_traverse(__pyx__PyAsyncGenWrappedValue *o,
}
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx__PyAsyncGenWrappedValueType_slots[] = {
{Py_tp_dealloc, (void *)__Pyx_async_gen_wrapped_val_dealloc},
{Py_tp_traverse, (void *)__Pyx_async_gen_wrapped_val_traverse},
{0, 0},
};
static PyType_Spec __pyx__PyAsyncGenWrappedValueType_spec = {
__PYX_TYPE_MODULE_PREFIX "async_generator_wrapped_value",
sizeof(__pyx__PyAsyncGenWrappedValue),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
__pyx__PyAsyncGenWrappedValueType_slots
};
#else /* CYTHON_USE_TYPE_SPECS */
static PyTypeObject __pyx__PyAsyncGenWrappedValueType_type = {
PyVarObject_HEAD_INIT(0, 0)
"async_generator_wrapped_value", /* tp_name */
......@@ -805,6 +871,7 @@ static PyTypeObject __pyx__PyAsyncGenWrappedValueType_type = {
0, /*tp_pypy_flags*/
#endif
};
#endif /* CYTHON_USE_TYPE_SPECS */
static PyObject *
......@@ -842,7 +909,7 @@ __Pyx_async_gen_athrow_dealloc(__pyx_PyAsyncGenAThrow *o)
PyObject_GC_UnTrack((PyObject *)o);
Py_CLEAR(o->agt_gen);
Py_CLEAR(o->agt_args);
PyObject_GC_Del(o);
__Pyx_PyHeapTypeObject_GC_Del(o);
}
......@@ -1043,6 +1110,27 @@ static PyMethodDef __Pyx_async_gen_athrow_methods[] = {
};
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx__PyAsyncGenAThrowType_slots[] = {
{Py_tp_dealloc, (void *)__Pyx_async_gen_athrow_dealloc},
{Py_am_await, (void *)PyObject_SelfIter},
{Py_tp_traverse, (void *)__Pyx_async_gen_athrow_traverse},
{Py_tp_iter, (void *)PyObject_SelfIter},
{Py_tp_iternext, (void *)__Pyx_async_gen_athrow_iternext},
{Py_tp_methods, (void *)__Pyx_async_gen_athrow_methods},
{Py_tp_getattro, (void *)__Pyx_PyObject_GenericGetAttrNoDict},
{0, 0},
};
static PyType_Spec __pyx__PyAsyncGenAThrowType_spec = {
__PYX_TYPE_MODULE_PREFIX "async_generator_athrow",
sizeof(__pyx_PyAsyncGenAThrow),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
__pyx__PyAsyncGenAThrowType_slots
};
#else /* CYTHON_USE_TYPE_SPECS */
#if CYTHON_USE_ASYNC_SLOTS
static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_athrow_as_async = {
PyObject_SelfIter, /* am_await */
......@@ -1051,7 +1139,6 @@ static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_athrow_as_async = {
};
#endif
static PyTypeObject __pyx__PyAsyncGenAThrowType_type = {
PyVarObject_HEAD_INIT(0, 0)
"async_generator_athrow", /* tp_name */
......@@ -1122,6 +1209,7 @@ static PyTypeObject __pyx__PyAsyncGenAThrowType_type = {
0, /*tp_pypy_flags*/
#endif
};
#endif /* CYTHON_USE_TYPE_SPECS */
static PyObject *
......@@ -1144,26 +1232,42 @@ __Pyx_async_gen_athrow_new(__pyx_PyAsyncGenObject *gen, PyObject *args)
/* ---------- global type sharing ------------ */
static int __pyx_AsyncGen_init(void) {
static int __pyx_AsyncGen_init(PyObject *module) {
#if CYTHON_USE_TYPE_SPECS
__pyx_AsyncGenType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_AsyncGenType_spec, NULL);
#else
(void) module;
// on Windows, C-API functions can't be used in slots statically
__pyx_AsyncGenType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
__pyx__PyAsyncGenWrappedValueType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
__pyx__PyAsyncGenAThrowType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
__pyx__PyAsyncGenASendType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
__pyx_AsyncGenType = __Pyx_FetchCommonType(&__pyx_AsyncGenType_type);
#endif
if (unlikely(!__pyx_AsyncGenType))
return -1;
#if CYTHON_USE_TYPE_SPECS
__pyx__PyAsyncGenAThrowType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx__PyAsyncGenAThrowType_spec, NULL);
#else
__pyx__PyAsyncGenAThrowType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
__pyx__PyAsyncGenAThrowType = __Pyx_FetchCommonType(&__pyx__PyAsyncGenAThrowType_type);
#endif
if (unlikely(!__pyx__PyAsyncGenAThrowType))
return -1;
#if CYTHON_USE_TYPE_SPECS
__pyx__PyAsyncGenWrappedValueType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx__PyAsyncGenWrappedValueType_spec, NULL);
#else
__pyx__PyAsyncGenWrappedValueType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
__pyx__PyAsyncGenWrappedValueType = __Pyx_FetchCommonType(&__pyx__PyAsyncGenWrappedValueType_type);
#endif
if (unlikely(!__pyx__PyAsyncGenWrappedValueType))
return -1;
#if CYTHON_USE_TYPE_SPECS
__pyx__PyAsyncGenASendType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx__PyAsyncGenASendType_spec, NULL);
#else
__pyx__PyAsyncGenASendType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
__pyx__PyAsyncGenASendType = __Pyx_FetchCommonType(&__pyx__PyAsyncGenASendType_type);
#endif
if (unlikely(!__pyx__PyAsyncGenASendType))
return -1;
......
/////////////// FetchCommonType.proto ///////////////
#if !CYTHON_USE_TYPE_SPECS
static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
#if CYTHON_COMPILING_IN_LIMITED_API
static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyType_Spec *spec, PyObject *bases);
#else
static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases);
#endif
/////////////// FetchCommonType ///////////////
//@requires:ExtensionTypes.c::FixUpExtensionType
static PyObject *__Pyx_FetchSharedCythonABIModule(void) {
PyObject *abi_module = PyImport_AddModule((char*) __PYX_ABI_MODULE_NAME);
......@@ -32,6 +34,7 @@ static int __Pyx_VerifyCachedType(PyObject *cached_type,
return 0;
}
#if !CYTHON_USE_TYPE_SPECS
static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
PyObject* abi_module;
PyTypeObject *cached_type = NULL;
......@@ -68,22 +71,28 @@ bad:
cached_type = NULL;
goto done;
}
#else
#if CYTHON_COMPILING_IN_LIMITED_API
static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyType_Spec *spec, PyObject *bases) {
PyObject *abi_module, *py_basicsize, *cached_type = NULL;
Py_ssize_t basicsize;
static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) {
PyObject *abi_module, *cached_type = NULL;
abi_module = __Pyx_FetchSharedCythonABIModule();
if (!abi_module) return NULL;
cached_type = PyObject_GetAttrString(abi_module, spec->name);
if (cached_type) {
Py_ssize_t basicsize;
#if CYTHON_COMPILING_IN_LIMITED_API
PyObject *py_basicsize;
py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__");
if (!py_basicsize) goto bad;
if (unlikely(!py_basicsize)) goto bad;
basicsize = PyLong_AsSsize_t(py_basicsize);
Py_DECREF(py_basicsize);
py_basicsize = 0;
if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) goto bad;
if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
#else
basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1;
#endif
if (__Pyx_VerifyCachedType(
cached_type,
spec->name,
......@@ -96,8 +105,11 @@ static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyType_Spec *spec, PyObject *
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
PyErr_Clear();
cached_type = PyType_FromSpecWithBases(spec, bases);
// We pass the ABI module reference to avoid keeping the user module alive by foreign type usages.
(void) module;
cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases);
if (unlikely(!cached_type)) goto bad;
if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad;
if (PyObject_SetAttrString(abi_module, spec->name, cached_type) < 0) goto bad;
done:
......
......@@ -453,7 +453,7 @@ static PyTypeObject *__pyx_CoroutineAwaitType = 0;
#define __Pyx_Coroutine_New(body, code, closure, name, qualname, module_name) \
__Pyx__Coroutine_New(__pyx_CoroutineType, body, code, closure, name, qualname, module_name)
static int __pyx_Coroutine_init(void); /*proto*/
static int __pyx_Coroutine_init(PyObject *module); /*proto*/
static PyObject *__Pyx__Coroutine_await(PyObject *coroutine); /*proto*/
typedef struct {
......@@ -475,7 +475,7 @@ static PyTypeObject *__pyx_GeneratorType = 0;
__Pyx__Coroutine_New(__pyx_GeneratorType, body, code, closure, name, qualname, module_name)
static PyObject *__Pyx_Generator_Next(PyObject *self);
static int __pyx_Generator_init(void); /*proto*/
static int __pyx_Generator_init(PyObject *module); /*proto*/
//////////////////// AsyncGen ////////////////////
......@@ -496,8 +496,8 @@ static int __pyx_Generator_init(void); /*proto*/
//@requires: ObjectHandling.c::PyObjectGetAttrStr
//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
//@requires: CommonStructures.c::FetchCommonType
//@requires: ModuleSetupCode.c::IncludeStructmemberH
#include <structmember.h>
#include <frameobject.h>
#define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)
......@@ -1192,7 +1192,7 @@ static void __Pyx_Coroutine_dealloc(PyObject *self) {
}
#endif
__Pyx_Coroutine_clear(self);
PyObject_GC_Del(gen);
__Pyx_PyHeapTypeObject_GC_Del(gen);
}
static void __Pyx_Coroutine_del(PyObject *self) {
......@@ -1456,7 +1456,7 @@ static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit(
static void __Pyx_CoroutineAwait_dealloc(PyObject *self) {
PyObject_GC_UnTrack(self);
Py_CLEAR(((__pyx_CoroutineAwaitObject*)self)->coroutine);
PyObject_GC_Del(self);
__Pyx_PyHeapTypeObject_GC_Del(self);
}
static int __Pyx_CoroutineAwait_traverse(__pyx_CoroutineAwaitObject *self, visitproc visit, void *arg) {
......@@ -1511,6 +1511,29 @@ static PyMethodDef __pyx_CoroutineAwait_methods[] = {
{0, 0, 0, 0}
};
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_CoroutineAwaitType_slots[] = {
{Py_tp_dealloc, (void *)__Pyx_CoroutineAwait_dealloc},
{Py_tp_traverse, (void *)__Pyx_CoroutineAwait_traverse},
{Py_tp_clear, (void *)__Pyx_CoroutineAwait_clear},
#if !CYTHON_COMPILING_IN_PYPY
{Py_tp_new, (void *)__Pyx_CoroutineAwait_no_new},
#endif
{Py_tp_methods, (void *)__pyx_CoroutineAwait_methods},
{Py_tp_iter, (void *)__Pyx_CoroutineAwait_self},
{Py_tp_iternext, (void *)__Pyx_CoroutineAwait_Next},
{0, 0},
};
static PyType_Spec __pyx_CoroutineAwaitType_spec = {
__PYX_TYPE_MODULE_PREFIX "coroutine_wrapper",
sizeof(__pyx_CoroutineAwaitObject),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
__pyx_CoroutineAwaitType_slots
};
#else /* CYTHON_USE_TYPE_SPECS */
static PyTypeObject __pyx_CoroutineAwaitType_type = {
PyVarObject_HEAD_INIT(0, 0)
__PYX_TYPE_MODULE_PREFIX "coroutine_wrapper", /*tp_name*/
......@@ -1576,6 +1599,7 @@ static PyTypeObject __pyx_CoroutineAwaitType_type = {
0, /*tp_pypy_flags*/
#endif
};
#endif /* CYTHON_USE_TYPE_SPECS */
#if PY_VERSION_HEX < 0x030500B1 || defined(__Pyx_IterableCoroutine_USED) || CYTHON_USE_ASYNC_SLOTS
static CYTHON_INLINE PyObject *__Pyx__Coroutine_await(PyObject *coroutine) {
......@@ -1638,7 +1662,10 @@ static PyMemberDef __pyx_Coroutine_memberlist[] = {
{(char*) "cr_await", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
(char*) PyDoc_STR("object being awaited, or None")},
{(char*) "cr_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL},
{(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), PY_WRITE_RESTRICTED, 0},
{(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0},
#if CYTHON_USE_TYPE_SPECS
{(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0},
#endif
{0, 0, 0, 0, 0}
};
......@@ -1652,6 +1679,30 @@ static PyGetSetDef __pyx_Coroutine_getsets[] = {
{0, 0, 0, 0, 0}
};
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_CoroutineType_slots[] = {
{Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc},
{Py_am_await, (void *)&__Pyx_Coroutine_await},
{Py_tp_traverse, (void *)__Pyx_Coroutine_traverse},
{Py_tp_methods, (void *)__pyx_Coroutine_methods},
{Py_tp_members, (void *)__pyx_Coroutine_memberlist},
{Py_tp_getset, (void *)__pyx_Coroutine_getsets},
{Py_tp_getattro, (void *) __Pyx_PyObject_GenericGetAttrNoDict},
#if CYTHON_USE_TP_FINALIZE
{Py_tp_finalize, (void *)__Pyx_Coroutine_del},
#endif
{0, 0},
};
static PyType_Spec __pyx_CoroutineType_spec = {
__PYX_TYPE_MODULE_PREFIX "coroutine",
sizeof(__pyx_CoroutineObject),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
__pyx_CoroutineType_slots
};
#else /* CYTHON_USE_TYPE_SPECS */
#if CYTHON_USE_ASYNC_SLOTS
static __Pyx_PyAsyncMethodsStruct __pyx_Coroutine_as_async = {
__Pyx_Coroutine_await, /*am_await*/
......@@ -1737,20 +1788,30 @@ static PyTypeObject __pyx_CoroutineType_type = {
0, /*tp_pypy_flags*/
#endif
};
#endif /* CYTHON_USE_TYPE_SPECS */
static int __pyx_Coroutine_init(void) {
static int __pyx_Coroutine_init(PyObject *module) {
// on Windows, C-API functions can't be used in slots statically
#if CYTHON_USE_TYPE_SPECS
__pyx_CoroutineType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CoroutineType_spec, NULL);
#else
(void) module;
__pyx_CoroutineType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
__pyx_CoroutineType = __Pyx_FetchCommonType(&__pyx_CoroutineType_type);
#endif
if (unlikely(!__pyx_CoroutineType))
return -1;
#ifdef __Pyx_IterableCoroutine_USED
if (unlikely(__pyx_IterableCoroutine_init() == -1))
if (unlikely(__pyx_IterableCoroutine_init(module) == -1))
return -1;
#endif
#if CYTHON_USE_TYPE_SPECS
__pyx_CoroutineAwaitType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CoroutineAwaitType_spec, NULL);
#else
__pyx_CoroutineAwaitType = __Pyx_FetchCommonType(&__pyx_CoroutineAwaitType_type);
#endif
if (unlikely(!__pyx_CoroutineAwaitType))
return -1;
return 0;
......@@ -1769,13 +1830,39 @@ static PyTypeObject *__pyx_IterableCoroutineType = 0;
#define __Pyx_IterableCoroutine_New(body, code, closure, name, qualname, module_name) \
__Pyx__Coroutine_New(__pyx_IterableCoroutineType, body, code, closure, name, qualname, module_name)
static int __pyx_IterableCoroutine_init(void);/*proto*/
static int __pyx_IterableCoroutine_init(PyObject *module);/*proto*/
//////////////////// IterableCoroutine ////////////////////
//@requires: Coroutine
//@requires: CommonStructures.c::FetchCommonType
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_IterableCoroutineType_slots[] = {
{Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc},
{Py_am_await, (void *)&__Pyx_Coroutine_await},
{Py_tp_traverse, (void *)__Pyx_Coroutine_traverse},
{Py_tp_iter, (void *)__Pyx_Coroutine_await},
{Py_tp_iternext, (void *)__Pyx_Generator_Next},
{Py_tp_methods, (void *)__pyx_Coroutine_methods},
{Py_tp_members, (void *)__pyx_Coroutine_memberlist},
{Py_tp_getset, (void *)__pyx_Coroutine_getsets},
{Py_tp_getattro, (void *) __Pyx_PyObject_GenericGetAttrNoDict},
#if CYTHON_USE_TP_FINALIZE
{Py_tp_finalize, (void *)__Pyx_Coroutine_del},
#endif
{0, 0},
};
static PyType_Spec __pyx_IterableCoroutineType_spec = {
__PYX_TYPE_MODULE_PREFIX "iterable_coroutine",
sizeof(__pyx_CoroutineObject),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
__pyx_IterableCoroutineType_slots
};
#else /* CYTHON_USE_TYPE_SPECS */
static PyTypeObject __pyx_IterableCoroutineType_type = {
PyVarObject_HEAD_INIT(0, 0)
__PYX_TYPE_MODULE_PREFIX "iterable_coroutine", /*tp_name*/
......@@ -1851,11 +1938,17 @@ static PyTypeObject __pyx_IterableCoroutineType_type = {
0, /*tp_pypy_flags*/
#endif
};
#endif /* CYTHON_USE_TYPE_SPECS */
static int __pyx_IterableCoroutine_init(void) {
static int __pyx_IterableCoroutine_init(PyObject *module) {
#if CYTHON_USE_TYPE_SPECS
__pyx_IterableCoroutineType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_IterableCoroutineType_spec, NULL);
#else
(void) module;
__pyx_IterableCoroutineType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
__pyx_IterableCoroutineType = __Pyx_FetchCommonType(&__pyx_IterableCoroutineType_type);
#endif
if (unlikely(!__pyx_IterableCoroutineType))
return -1;
return 0;
......@@ -1882,6 +1975,10 @@ static PyMemberDef __pyx_Generator_memberlist[] = {
{(char*) "gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
(char*) PyDoc_STR("object being iterated by 'yield from', or None")},
{(char*) "gi_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL},
{(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0},
#if CYTHON_USE_TYPE_SPECS
{(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0},
#endif
{0, 0, 0, 0, 0}
};
......@@ -1895,6 +1992,31 @@ static PyGetSetDef __pyx_Generator_getsets[] = {
{0, 0, 0, 0, 0}
};
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_GeneratorType_slots[] = {
{Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc},
{Py_tp_traverse, (void *)__Pyx_Coroutine_traverse},
{Py_tp_iter, (void *)PyObject_SelfIter},
{Py_tp_iternext, (void *)__Pyx_Generator_Next},
{Py_tp_methods, (void *)__pyx_Generator_methods},
{Py_tp_members, (void *)__pyx_Generator_memberlist},
{Py_tp_getset, (void *)__pyx_Generator_getsets},
{Py_tp_getattro, (void *) __Pyx_PyObject_GenericGetAttrNoDict},
#if CYTHON_USE_TP_FINALIZE
{Py_tp_finalize, (void *)__Pyx_Coroutine_del},
#endif
{0, 0},
};
static PyType_Spec __pyx_GeneratorType_spec = {
__PYX_TYPE_MODULE_PREFIX "generator",
sizeof(__pyx_CoroutineObject),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
__pyx_GeneratorType_slots
};
#else /* CYTHON_USE_TYPE_SPECS */
static PyTypeObject __pyx_GeneratorType_type = {
PyVarObject_HEAD_INIT(0, 0)
__PYX_TYPE_MODULE_PREFIX "generator", /*tp_name*/
......@@ -1904,7 +2026,7 @@ static PyTypeObject __pyx_GeneratorType_type = {
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare / tp_as_async*/
0, /*tp_as_async*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
......@@ -1962,13 +2084,18 @@ static PyTypeObject __pyx_GeneratorType_type = {
0, /*tp_pypy_flags*/
#endif
};
#endif /* CYTHON_USE_TYPE_SPECS */
static int __pyx_Generator_init(void) {
static int __pyx_Generator_init(PyObject *module) {
#if CYTHON_USE_TYPE_SPECS
__pyx_GeneratorType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_GeneratorType_spec, NULL);
#else
(void) module;
// on Windows, C-API functions can't be used in slots statically
__pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
__pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
__pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
#endif
if (unlikely(!__pyx_GeneratorType)) {
return -1;
}
......@@ -2301,11 +2428,15 @@ old_types.add(_cython_generator_type)
#define __Pyx_StopAsyncIteration_USED
static PyObject *__Pyx_PyExc_StopAsyncIteration;
static int __pyx_StopAsyncIteration_init(void); /*proto*/
static int __pyx_StopAsyncIteration_init(PyObject *module); /*proto*/
//////////////////// StopAsyncIteration ////////////////////
#if PY_VERSION_HEX < 0x030500B1
#if CYTHON_USE_TYPE_SPECS
#error Using async coroutines with type specs requires Python 3.5 or later.
#else
static PyTypeObject __Pyx__PyExc_StopAsyncIteration_type = {
PyVarObject_HEAD_INIT(0, 0)
"StopAsyncIteration", /*tp_name*/
......@@ -2362,9 +2493,11 @@ static PyTypeObject __Pyx__PyExc_StopAsyncIteration_type = {
#endif
};
#endif
#endif
static int __pyx_StopAsyncIteration_init(void) {
static int __pyx_StopAsyncIteration_init(PyObject *module) {
#if PY_VERSION_HEX >= 0x030500B1
(void) module;
__Pyx_PyExc_StopAsyncIteration = PyExc_StopAsyncIteration;
#else
PyObject *builtins = PyEval_GetBuiltins();
......@@ -2382,6 +2515,7 @@ static int __pyx_StopAsyncIteration_init(void) {
__Pyx__PyExc_StopAsyncIteration_type.tp_dictoffset = ((PyTypeObject*)PyExc_BaseException)->tp_dictoffset;
__Pyx__PyExc_StopAsyncIteration_type.tp_base = (PyTypeObject*)PyExc_Exception;
(void) module;
__Pyx_PyExc_StopAsyncIteration = (PyObject*) __Pyx_FetchCommonType(&__Pyx__PyExc_StopAsyncIteration_type);
if (unlikely(!__Pyx_PyExc_StopAsyncIteration))
return -1;
......
......@@ -10,8 +10,16 @@
#define __Pyx_CyFunction_GetClosure(f) \
(((__pyx_CyFunctionObject *) (f))->func_closure)
#define __Pyx_CyFunction_GetClassObj(f) \
(((__pyx_CyFunctionObject *) (f))->func_classobj)
#if PY_VERSION_HEX < 0x030900B1
#define __Pyx_CyFunction_GetClassObj(f) \
(((__pyx_CyFunctionObject *) (f))->func_classobj)
#else
#define __Pyx_CyFunction_GetClassObj(f) \
((PyObject*) ((PyCMethodObject *) (f))->mm_class)
#endif
#define __Pyx_CyFunction_SetClassObj(f, classobj) \
__Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj))
#define __Pyx_CyFunction_Defaults(type, f) \
((type *)(((__pyx_CyFunctionObject *) (f))->defaults))
......@@ -20,7 +28,12 @@
typedef struct {
#if PY_VERSION_HEX < 0x030900B1
PyCFunctionObject func;
#else
// PEP-573: PyCFunctionObject + mm_class
PyCMethodObject func;
#endif
#if CYTHON_BACKPORT_VECTORCALL
__pyx_vectorcallfunc func_vectorcall;
#endif
......@@ -34,9 +47,10 @@ typedef struct {
PyObject *func_globals;
PyObject *func_code;
PyObject *func_closure;
#if PY_VERSION_HEX < 0x030900B1
// No-args super() class cell
PyObject *func_classobj;
#endif
// Dynamic default args and annotations
void *defaults;
int defaults_pyobjects;
......@@ -53,7 +67,7 @@ typedef struct {
PyObject *func_is_coroutine;
} __pyx_CyFunctionObject;
#if !CYTHON_COMPILING_IN_LIMITED_API
#if !CYTHON_USE_MODULE_STATE
static PyTypeObject *__pyx_CyFunctionType = 0;
#endif
......@@ -67,6 +81,7 @@ static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *
PyObject *module, PyObject *globals,
PyObject* code);
static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj);
static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m,
size_t size,
int pyobjects);
......@@ -78,16 +93,17 @@ static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m,
PyObject *dict);
static int __pyx_CyFunction_init(void);
static int __pyx_CyFunction_init(PyObject *module);
#if CYTHON_METH_FASTCALL
static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
#if CYTHON_BACKPORT_VECTORCALL
#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall)
#else
#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func.vectorcall)
#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall)
#endif
#endif
......@@ -96,20 +112,32 @@ static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func,
//@requires: CommonStructures.c::FetchCommonType
//@requires: ObjectHandling.c::PyMethodNew
//@requires: ObjectHandling.c::PyVectorcallFastCallDict
//@requires: ModuleSetupCode.c::IncludeStructmemberH
//@requires: ObjectHandling.c::PyObjectGetAttrStr
#include <structmember.h>
static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) {
__Pyx_Py_XDECREF_SET(
#if PY_VERSION_HEX < 0x030900B1
__Pyx_CyFunction_GetClassObj(f),
#else
// assigning to "mm_class", which is a "PyTypeObject*"
((PyCMethodObject *) (f))->mm_class,
(PyTypeObject*)
#endif
((classobj) ? __Pyx_NewRef(classobj) : NULL)
);
}
static PyObject *
__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure)
{
CYTHON_UNUSED_VAR(closure);
if (unlikely(op->func_doc == NULL)) {
if (op->func.m_ml->ml_doc) {
if (((PyCFunctionObject*)op)->m_ml->ml_doc) {
#if PY_MAJOR_VERSION >= 3
op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc);
op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc);
#else
op->func_doc = PyString_FromString(op->func.m_ml->ml_doc);
op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc);
#endif
if (unlikely(op->func_doc == NULL))
return NULL;
......@@ -141,9 +169,9 @@ __Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context)
CYTHON_UNUSED_VAR(context);
if (unlikely(op->func_name == NULL)) {
#if PY_MAJOR_VERSION >= 3
op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name);
op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name);
#else
op->func_name = PyString_InternFromString(op->func.m_ml->ml_name);
op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name);
#endif
if (unlikely(op->func_name == NULL))
return NULL;
......@@ -458,9 +486,16 @@ static PyGetSetDef __pyx_CyFunction_getsets[] = {
};
static PyMemberDef __pyx_CyFunction_members[] = {
{(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), PY_WRITE_RESTRICTED, 0},
#if CYTHON_COMPILING_IN_LIMITED_API
{(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0},
#if CYTHON_USE_TYPE_SPECS
{(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0},
#if CYTHON_METH_FASTCALL
#if CYTHON_BACKPORT_VECTORCALL
{(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0},
#else
{(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0},
#endif
#endif
#if PY_VERSION_HEX < 0x030500A0
{(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0},
#else
......@@ -478,7 +513,7 @@ __Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args)
Py_INCREF(m->func_qualname);
return m->func_qualname;
#else
return PyString_FromString(m->func.m_ml->ml_name);
return PyString_FromString(((PyCFunctionObject*)m)->m_ml->ml_name);
#endif
}
......@@ -491,27 +526,32 @@ static PyMethodDef __pyx_CyFunction_methods[] = {
#if PY_VERSION_HEX < 0x030500A0
#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist)
#else
#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist)
#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist)
#endif
static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname,
PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
PyCFunctionObject *cf = (PyCFunctionObject*) op;
if (unlikely(op == NULL))
return NULL;
op->flags = flags;
__Pyx_CyFunction_weakreflist(op) = NULL;
op->func.m_ml = ml;
op->func.m_self = (PyObject *) op;
cf->m_ml = ml;
cf->m_self = (PyObject *) op;
Py_XINCREF(closure);
op->func_closure = closure;
Py_XINCREF(module);
op->func.m_module = module;
cf->m_module = module;
op->func_dict = NULL;
op->func_name = NULL;
Py_INCREF(qualname);
op->func_qualname = qualname;
op->func_doc = NULL;
#if PY_VERSION_HEX < 0x030900B1
op->func_classobj = NULL;
#else
((PyCMethodObject*)op)->mm_class = NULL;
#endif
op->func_globals = globals;
Py_INCREF(op->func_globals);
Py_XINCREF(code);
......@@ -526,7 +566,7 @@ static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *
op->func_annotations = NULL;
op->func_is_coroutine = NULL;
#if CYTHON_METH_FASTCALL
switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS)) {
switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) {
case METH_NOARGS:
__Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS;
break;
......@@ -534,6 +574,9 @@ static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *
__Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O;
break;
// case METH_FASTCALL is not used
case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
__Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD;
break;
case METH_FASTCALL | METH_KEYWORDS:
__Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS;
break;
......@@ -554,14 +597,22 @@ static int
__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
{
Py_CLEAR(m->func_closure);
Py_CLEAR(m->func.m_module);
Py_CLEAR(((PyCFunctionObject*)m)->m_module);
Py_CLEAR(m->func_dict);
Py_CLEAR(m->func_name);
Py_CLEAR(m->func_qualname);
Py_CLEAR(m->func_doc);
Py_CLEAR(m->func_globals);
Py_CLEAR(m->func_code);
Py_CLEAR(m->func_classobj);
#if PY_VERSION_HEX < 0x030900B1
Py_CLEAR(__Pyx_CyFunction_GetClassObj(m));
#else
{
PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class;
((PyCMethodObject *) (m))->mm_class = NULL;
Py_XDECREF(cls);
}
#endif
Py_CLEAR(m->defaults_tuple);
Py_CLEAR(m->defaults_kwdict);
Py_CLEAR(m->func_annotations);
......@@ -586,7 +637,7 @@ static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m)
if (__Pyx_CyFunction_weakreflist(m) != NULL)
PyObject_ClearWeakRefs((PyObject *) m);
__Pyx_CyFunction_clear(m);
PyObject_GC_Del(m);
__Pyx_PyHeapTypeObject_GC_Del(m);
}
static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
......@@ -598,14 +649,14 @@ static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg)
{
Py_VISIT(m->func_closure);
Py_VISIT(m->func.m_module);
Py_VISIT(((PyCFunctionObject*)m)->m_module);
Py_VISIT(m->func_dict);
Py_VISIT(m->func_name);
Py_VISIT(m->func_qualname);
Py_VISIT(m->func_doc);
Py_VISIT(m->func_globals);
Py_VISIT(m->func_code);
Py_VISIT(m->func_classobj);
Py_VISIT(__Pyx_CyFunction_GetClassObj(m));
Py_VISIT(m->defaults_tuple);
Py_VISIT(m->defaults_kwdict);
Py_VISIT(m->func_is_coroutine);
......@@ -749,14 +800,14 @@ static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionO
if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) {
if (unlikely(nargs < 1)) {
PyErr_Format(PyExc_TypeError, "%.200s() needs an argument",
cyfunc->func.m_ml->ml_name);
((PyCFunctionObject*)cyfunc)->m_ml->ml_name);
return -1;
}
ret = 1;
}
if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes no keyword arguments", cyfunc->func.m_ml->ml_name);
"%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name);
return -1;
}
return ret;
......@@ -765,7 +816,7 @@ static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionO
static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
__pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
PyMethodDef* def = cyfunc->func.m_ml;
PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml;
#if CYTHON_BACKPORT_VECTORCALL
Py_ssize_t nargs = (Py_ssize_t)nargsf;
#else
......@@ -779,7 +830,7 @@ static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *c
nargs -= 1;
break;
case 0:
self = cyfunc->func.m_self;
self = ((PyCFunctionObject*)cyfunc)->m_self;
break;
default:
return NULL;
......@@ -797,7 +848,7 @@ static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *c
static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
__pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
PyMethodDef* def = cyfunc->func.m_ml;
PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml;
#if CYTHON_BACKPORT_VECTORCALL
Py_ssize_t nargs = (Py_ssize_t)nargsf;
#else
......@@ -811,7 +862,7 @@ static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const
nargs -= 1;
break;
case 0:
self = cyfunc->func.m_self;
self = ((PyCFunctionObject*)cyfunc)->m_self;
break;
default:
return NULL;
......@@ -829,7 +880,7 @@ static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const
static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
__pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
PyMethodDef* def = cyfunc->func.m_ml;
PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml;
#if CYTHON_BACKPORT_VECTORCALL
Py_ssize_t nargs = (Py_ssize_t)nargsf;
#else
......@@ -843,7 +894,7 @@ static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func,
nargs -= 1;
break;
case 0:
self = cyfunc->func.m_self;
self = ((PyCFunctionObject*)cyfunc)->m_self;
break;
default:
return NULL;
......@@ -851,9 +902,36 @@ static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func,
return ((_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames);
}
static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
__pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml;
PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc);
#if CYTHON_BACKPORT_VECTORCALL
Py_ssize_t nargs = (Py_ssize_t)nargsf;
#else
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
#endif
PyObject *self;
switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) {
case 1:
self = args[0];
args += 1;
nargs -= 1;
break;
case 0:
self = ((PyCFunctionObject*)cyfunc)->m_self;
break;
default:
return NULL;
}
#if CYTHON_COMPILING_IN_LIMITED_API
return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, nargs, kwnames);
}
#endif
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_CyFunctionType_slots[] = {
{Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc},
{Py_tp_repr, (void *)__Pyx_CyFunction_repr},
......@@ -871,11 +949,17 @@ static PyType_Spec __pyx_CyFunctionType_spec = {
__PYX_TYPE_MODULE_PREFIX "cython_function_or_method",
sizeof(__pyx_CyFunctionObject),
0,
// TODO: Support _Py_TPFLAGS_HAVE_VECTORCALL and _Py_TPFLAGS_HAVE_VECTORCALL
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR
Py_TPFLAGS_METHOD_DESCRIPTOR |
#endif
#ifdef _Py_TPFLAGS_HAVE_VECTORCALL
_Py_TPFLAGS_HAVE_VECTORCALL |
#endif
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/
__pyx_CyFunctionType_slots
};
#else
#else /* CYTHON_USE_TYPE_SPECS */
static PyTypeObject __pyx_CyFunctionType_type = {
PyVarObject_HEAD_INIT(0, 0)
__PYX_TYPE_MODULE_PREFIX "cython_function_or_method", /*tp_name*/
......@@ -887,7 +971,7 @@ static PyTypeObject __pyx_CyFunctionType_type = {
#elif CYTHON_BACKPORT_VECTORCALL
(printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), /*tp_vectorcall_offset backported into tp_print*/
#else
offsetof(__pyx_CyFunctionObject, func.vectorcall), /*tp_vectorcall_offset*/
offsetof(PyCFunctionObject, vectorcall), /*tp_vectorcall_offset*/
#endif
0, /*tp_getattr*/
0, /*tp_setattr*/
......@@ -912,7 +996,7 @@ static PyTypeObject __pyx_CyFunctionType_type = {
#ifdef _Py_TPFLAGS_HAVE_VECTORCALL
_Py_TPFLAGS_HAVE_VECTORCALL |
#endif
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/
0, /*tp_doc*/
(traverseproc) __Pyx_CyFunction_traverse, /*tp_traverse*/
(inquiry) __Pyx_CyFunction_clear, /*tp_clear*/
......@@ -957,13 +1041,14 @@ static PyTypeObject __pyx_CyFunctionType_type = {
0, /*tp_pypy_flags*/
#endif
};
#endif /* CYTHON_COMPILING_IN_LIMITED_API */
#endif /* CYTHON_USE_TYPE_SPECS */
static int __pyx_CyFunction_init(void) {
#if CYTHON_COMPILING_IN_LIMITED_API
__pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(&__pyx_CyFunctionType_spec, NULL);
static int __pyx_CyFunction_init(PyObject *module) {
#if CYTHON_USE_TYPE_SPECS
__pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL);
#else
(void) module;
__pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
#endif
if (unlikely(__pyx_CyFunctionType == NULL)) {
......@@ -1045,8 +1130,7 @@ static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *class
if (unlikely(!m))
return -1;
#endif
Py_INCREF(classobj);
m->func_classobj = classobj;
__Pyx_CyFunction_SetClassObj(m, classobj);
#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS)
Py_DECREF((PyObject*)m);
#endif
......@@ -1069,10 +1153,10 @@ static PyObject *__pyx_FusedFunction_New(PyMethodDef *ml, int flags,
PyObject *code);
static int __pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self);
#if !CYTHON_COMPILING_IN_LIMITED_API
#if !CYTHON_USE_MODULE_STATE
static PyTypeObject *__pyx_FusedFunctionType = NULL;
#endif
static int __pyx_FusedFunction_init(void);
static int __pyx_FusedFunction_init(PyObject *module);
#define __Pyx_FusedFunction_USED
......@@ -1175,8 +1259,7 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Py_XINCREF(pydefaults[i]);
}
Py_XINCREF(func->func.func_classobj);
meth->func.func_classobj = func->func.func_classobj;
__Pyx_CyFunction_SetClassObj(meth, __Pyx_CyFunction_GetClassObj(func));
Py_XINCREF(func->__signatures__);
meth->__signatures__ = func->__signatures__;
......@@ -1260,8 +1343,7 @@ __pyx_err:;
__pyx_FusedFunctionObject *unbound = (__pyx_FusedFunctionObject *) unbound_result_func;
// TODO: move this to InitClassCell
Py_XINCREF(self->func.func_classobj);
__Pyx_Py_XDECREF_SET(unbound->func.func_classobj, self->func.func_classobj);
__Pyx_CyFunction_SetClassObj(unbound, __Pyx_CyFunction_GetClassObj(self));
result_func = __pyx_FusedFunction_descr_get(unbound_result_func,
self->self, self->self);
......@@ -1356,8 +1438,7 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
if (unlikely(!new_func))
goto bad;
Py_XINCREF(binding_func->func.func_classobj);
__Pyx_Py_XDECREF_SET(new_func->func.func_classobj, binding_func->func.func_classobj);
__Pyx_CyFunction_SetClassObj(new_func, __Pyx_CyFunction_GetClassObj(binding_func));
func = (PyObject *) new_func;
}
......@@ -1400,7 +1481,7 @@ static PyGetSetDef __pyx_FusedFunction_getsets[] = {
{0, 0, 0, 0, 0}
};
#if CYTHON_COMPILING_IN_LIMITED_API
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_FusedFunctionType_slots[] = {
{Py_tp_dealloc, (void *)__pyx_FusedFunction_dealloc},
{Py_tp_call, (void *)__pyx_FusedFunction_call},
......@@ -1421,7 +1502,7 @@ static PyType_Spec __pyx_FusedFunctionType_spec = {
__pyx_FusedFunctionType_slots
};
#else /* !CYTHON_COMPILING_IN_LIMITED_API */
#else /* !CYTHON_USE_TYPE_SPECS */
static PyMappingMethods __pyx_FusedFunction_mapping_methods = {
0,
......@@ -1497,15 +1578,16 @@ static PyTypeObject __pyx_FusedFunctionType_type = {
};
#endif
static int __pyx_FusedFunction_init(void) {
#if CYTHON_COMPILING_IN_LIMITED_API
static int __pyx_FusedFunction_init(PyObject *module) {
#if CYTHON_USE_TYPE_SPECS
PyObject *bases = PyTuple_Pack(1, __pyx_CyFunctionType);
if (unlikely(!bases)) {
return -1;
}
__pyx_FusedFunctionType = __Pyx_FetchCommonTypeFromSpec(&__pyx_FusedFunctionType_spec, bases);
__pyx_FusedFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_FusedFunctionType_spec, bases);
Py_DECREF(bases);
#else
(void) module;
// Set base from __Pyx_FetchCommonTypeFromSpec, in case it's different from the local static value.
__pyx_FusedFunctionType_type.tp_base = __pyx_CyFunctionType;
__pyx_FusedFunctionType = __Pyx_FetchCommonType(&__pyx_FusedFunctionType_type);
......
/////////////// PyType_Ready.proto ///////////////
/////////////// FixUpExtensionType.proto ///////////////
// FIXME: is this really suitable for CYTHON_COMPILING_IN_LIMITED_API?
#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API
static int __Pyx_PyType_Ready(PyTypeObject *t);/*proto*/
#if CYTHON_USE_TYPE_SPECS
static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); /*proto*/
#endif
/////////////// FixUpExtensionType ///////////////
//@requires:ModuleSetupCode.c::IncludeStructmemberH
//@requires:StringTools.c::IncludeStringH
#if CYTHON_USE_TYPE_SPECS
static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) {
#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API
(void) spec;
(void) type;
#else
// Set tp_weakreflist, tp_dictoffset, tp_vectorcalloffset
// Copied and adapted from https://bugs.python.org/issue38140
const PyType_Slot *slot = spec->slots;
while (slot && slot->slot && slot->slot != Py_tp_members)
slot++;
if (slot && slot->slot == Py_tp_members) {
int changed = 0;
#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON)
const
#endif
PyMemberDef *memb = (PyMemberDef*) slot->pfunc;
while (memb && memb->name) {
if (memb->name[0] == '_' && memb->name[1] == '_') {
#if PY_VERSION_HEX < 0x030900b1
if (strcmp(memb->name, "__weaklistoffset__") == 0) {
// The PyMemberDef must be a Py_ssize_t and readonly.
assert(memb->type == T_PYSSIZET);
assert(memb->flags == READONLY);
type->tp_weaklistoffset = memb->offset;
// FIXME: is it even worth calling PyType_Modified() here?
changed = 1;
}
else if (strcmp(memb->name, "__dictoffset__") == 0) {
// The PyMemberDef must be a Py_ssize_t and readonly.
assert(memb->type == T_PYSSIZET);
assert(memb->flags == READONLY);
type->tp_dictoffset = memb->offset;
// FIXME: is it even worth calling PyType_Modified() here?
changed = 1;
}
#if CYTHON_METH_FASTCALL
else if (strcmp(memb->name, "__vectorcalloffset__") == 0) {
// The PyMemberDef must be a Py_ssize_t and readonly.
assert(memb->type == T_PYSSIZET);
assert(memb->flags == READONLY);
#if PY_VERSION_HEX >= 0x030800b4
type->tp_vectorcall_offset = memb->offset;
#else
#define __Pyx_PyType_Ready(t) PyType_Ready(t)
type->tp_print = (printfunc) memb->offset;
#endif
// FIXME: is it even worth calling PyType_Modified() here?
changed = 1;
}
#endif
#else
if ((0));
#endif
#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON
else if (strcmp(memb->name, "__module__") == 0) {
// PyType_FromSpec() in CPython <= 3.9b1 overwrites this field with a constant string.
// See https://bugs.python.org/issue40703
PyObject *descr;
// The PyMemberDef must be an object and normally readable, possibly writable.
assert(memb->type == T_OBJECT);
assert(memb->flags == 0 || memb->flags == READONLY);
descr = PyDescr_NewMember(type, memb);
if (unlikely(!descr))
return -1;
if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) {
Py_DECREF(descr);
return -1;
}
Py_DECREF(descr);
changed = 1;
}
#endif
}
memb++;
}
if (changed)
PyType_Modified(type);
}
#endif
return 0;
}
#endif
/////////////// PyType_Ready ///////////////
//@requires: ObjectHandling.c::PyObjectCallMethod0
#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API
// Wrapper around PyType_Ready() with some runtime checks and fixes
// to deal with multiple inheritance.
static int __Pyx_PyType_Ready(PyTypeObject *t) {
/////////////// ValidateBasesTuple.proto ///////////////
#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS
static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases); /*proto*/
#endif
/////////////// ValidateBasesTuple ///////////////
#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS
static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) {
// Loop over all bases (except the first) and check that those
// really are heap types. Otherwise, it would not be safe to
// subclass them.
......@@ -24,49 +112,73 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) {
// tp_dictoffset (i.e. there is no __dict__ attribute in the object
// structure), we need to check that none of the base classes sets
// it either.
int r;
PyObject *bases = t->tp_bases;
if (bases)
Py_ssize_t i, n = PyTuple_GET_SIZE(bases);
for (i = 1; i < n; i++) /* Skip first base */
{
Py_ssize_t i, n = PyTuple_GET_SIZE(bases);
for (i = 1; i < n; i++) /* Skip first base */
{
PyObject *b0 = PyTuple_GET_ITEM(bases, i);
PyTypeObject *b;
PyObject *b0 = PyTuple_GET_ITEM(bases, i);
PyTypeObject *b;
#if PY_MAJOR_VERSION < 3
/* Disallow old-style classes */
if (PyClass_Check(b0))
{
PyErr_Format(PyExc_TypeError, "base class '%.200s' is an old-style class",
PyString_AS_STRING(((PyClassObject*)b0)->cl_name));
return -1;
}
/* Disallow old-style classes */
if (PyClass_Check(b0))
{
PyErr_Format(PyExc_TypeError, "base class '%.200s' is an old-style class",
PyString_AS_STRING(((PyClassObject*)b0)->cl_name));
return -1;
}
#endif
b = (PyTypeObject*)b0;
if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE))
{
__Pyx_TypeName b_name = __Pyx_PyType_GetName(b);
PyErr_Format(PyExc_TypeError,
"base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name);
__Pyx_DECREF_TypeName(b_name);
return -1;
}
if (t->tp_dictoffset == 0 && b->tp_dictoffset)
{
__Pyx_TypeName t_name = __Pyx_PyType_GetName(t);
__Pyx_TypeName b_name = __Pyx_PyType_GetName(b);
PyErr_Format(PyExc_TypeError,
"extension type '" __Pyx_FMT_TYPENAME "' has no __dict__ slot, "
"but base type '" __Pyx_FMT_TYPENAME "' has: "
"either add 'cdef dict __dict__' to the extension type "
"or add '__slots__ = [...]' to the base type",
t_name, b_name);
__Pyx_DECREF_TypeName(t_name);
__Pyx_DECREF_TypeName(b_name);
return -1;
}
b = (PyTypeObject*) b0;
if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE))
{
__Pyx_TypeName b_name = __Pyx_PyType_GetName(b);
PyErr_Format(PyExc_TypeError,
"base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name);
__Pyx_DECREF_TypeName(b_name);
return -1;
}
if (dictoffset == 0 && b->tp_dictoffset)
{
__Pyx_TypeName b_name = __Pyx_PyType_GetName(b);
PyErr_Format(PyExc_TypeError,
"extension type '%.200s' has no __dict__ slot, "
"but base type '" __Pyx_FMT_TYPENAME "' has: "
"either add 'cdef dict __dict__' to the extension type "
"or add '__slots__ = [...]' to the base type",
type_name, b_name);
__Pyx_DECREF_TypeName(b_name);
return -1;
}
}
return 0;
}
#endif
/////////////// PyType_Ready.proto ///////////////
static int __Pyx_PyType_Ready(PyTypeObject *t);/*proto*/
/////////////// PyType_Ready ///////////////
//@requires: ObjectHandling.c::PyObjectCallMethod0
//@requires: ValidateBasesTuple
// Wrapper around PyType_Ready() with some runtime checks and fixes
// to deal with multiple inheritance.
static int __Pyx_PyType_Ready(PyTypeObject *t) {
// FIXME: is this really suitable for CYTHON_COMPILING_IN_LIMITED_API?
#if CYTHON_USE_TYPE_SPECS || !(CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API)
// avoid C warning about unused helper function
(void)__Pyx_PyObject_CallMethod0;
#if CYTHON_USE_TYPE_SPECS
(void)__Pyx_validate_bases_tuple;
#endif
return PyType_Ready(t);
#else
int r;
if (t->tp_bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, t->tp_bases) == -1))
return -1;
#if PY_VERSION_HEX >= 0x03050000
{
......@@ -152,8 +264,9 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) {
#endif
return r;
}
#endif
}
/////////////// PyTrashcan.proto ///////////////
......
......@@ -694,22 +694,18 @@ bad:
/////////////// SetVTable.proto ///////////////
static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
static int __Pyx_SetVtable(PyTypeObject* typeptr , void* vtable); /*proto*/
/////////////// SetVTable ///////////////
#if CYTHON_COMPILING_IN_LIMITED_API
static int __Pyx_SetVtable(PyObject *type, void *vtable) {
#else
static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
#endif
static int __Pyx_SetVtable(PyTypeObject *type, void *vtable) {
PyObject *ob = PyCapsule_New(vtable, 0, 0);
if (!ob)
if (unlikely(!ob))
goto bad;
#if CYTHON_COMPILING_IN_LIMITED_API
if (PyObject_SetAttr(type, PYIDENT("__pyx_vtable__"), ob) < 0)
if (unlikely(PyObject_SetAttr((PyObject *) type, PYIDENT("__pyx_vtable__"), ob) < 0))
#else
if (PyDict_SetItem(dict, PYIDENT("__pyx_vtable__"), ob) < 0)
if (unlikely(PyDict_SetItem(type->tp_dict, PYIDENT("__pyx_vtable__"), ob) < 0))
#endif
goto bad;
Py_DECREF(ob);
......
......@@ -61,6 +61,8 @@
#undef CYTHON_USE_TYPE_SLOTS
#define CYTHON_USE_TYPE_SLOTS 0
#undef CYTHON_USE_TYPE_SPECS
#define CYTHON_USE_TYPE_SPECS 0
#undef CYTHON_USE_PYTYPE_LOOKUP
#define CYTHON_USE_PYTYPE_LOOKUP 0
#if PY_VERSION_HEX < 0x03050000
......@@ -96,6 +98,8 @@
#endif
#undef CYTHON_PEP489_MULTI_PHASE_INIT
#define CYTHON_PEP489_MULTI_PHASE_INIT 0
#undef CYTHON_USE_MODULE_STATE
#define CYTHON_USE_MODULE_STATE 0
#undef CYTHON_USE_TP_FINALIZE
#define CYTHON_USE_TP_FINALIZE 0
#undef CYTHON_USE_DICT_VERSIONS
......@@ -112,6 +116,8 @@
#ifndef CYTHON_USE_TYPE_SLOTS
#define CYTHON_USE_TYPE_SLOTS 1
#endif
#undef CYTHON_USE_TYPE_SPECS
#define CYTHON_USE_TYPE_SPECS 0
#undef CYTHON_USE_PYTYPE_LOOKUP
#define CYTHON_USE_PYTYPE_LOOKUP 0
#undef CYTHON_USE_ASYNC_SLOTS
......@@ -146,6 +152,8 @@
#define CYTHON_PEP487_INIT_SUBCLASS 0
#undef CYTHON_PEP489_MULTI_PHASE_INIT
#define CYTHON_PEP489_MULTI_PHASE_INIT 0
#undef CYTHON_USE_MODULE_STATE
#define CYTHON_USE_MODULE_STATE 0
#undef CYTHON_USE_TP_FINALIZE
#define CYTHON_USE_TP_FINALIZE 0
#undef CYTHON_USE_DICT_VERSIONS
......@@ -154,6 +162,7 @@
#define CYTHON_USE_EXC_INFO_STACK 0
#elif defined(CYTHON_LIMITED_API)
// EXPERIMENTAL !!
#define CYTHON_COMPILING_IN_PYPY 0
#define CYTHON_COMPILING_IN_PYSTON 0
#define CYTHON_COMPILING_IN_CPYTHON 0
......@@ -161,6 +170,8 @@
#undef CYTHON_USE_TYPE_SLOTS
#define CYTHON_USE_TYPE_SLOTS 0
#undef CYTHON_USE_TYPE_SPECS
#define CYTHON_USE_TYPE_SPECS 1
#undef CYTHON_USE_PYTYPE_LOOKUP
#define CYTHON_USE_PYTYPE_LOOKUP 0
#undef CYTHON_USE_ASYNC_SLOTS
......@@ -194,6 +205,8 @@
#endif
#undef CYTHON_PEP489_MULTI_PHASE_INIT
#define CYTHON_PEP489_MULTI_PHASE_INIT 0
#undef CYTHON_USE_MODULE_STATE
#define CYTHON_USE_MODULE_STATE 1
#ifndef CYTHON_USE_TP_FINALIZE
#define CYTHON_USE_TP_FINALIZE 1
#endif
......@@ -211,6 +224,9 @@
#ifndef CYTHON_USE_TYPE_SLOTS
#define CYTHON_USE_TYPE_SLOTS 1
#endif
#ifndef CYTHON_USE_TYPE_SPECS
#define CYTHON_USE_TYPE_SPECS 0
#endif
#ifndef CYTHON_USE_PYTYPE_LOOKUP
#define CYTHON_USE_PYTYPE_LOOKUP 1
#endif
......@@ -262,17 +278,33 @@
#ifndef CYTHON_PEP487_INIT_SUBCLASS
#define CYTHON_PEP487_INIT_SUBCLASS 1
#endif
#ifndef CYTHON_PEP489_MULTI_PHASE_INIT
#define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000)
#if PY_VERSION_HEX < 0x03050000
#undef CYTHON_PEP489_MULTI_PHASE_INIT
#define CYTHON_PEP489_MULTI_PHASE_INIT 0
#elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT)
#define CYTHON_PEP489_MULTI_PHASE_INIT 1
#endif
#ifndef CYTHON_USE_TP_FINALIZE
#define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1)
#ifndef CYTHON_USE_MODULE_STATE
// EXPERIMENTAL !!
#define CYTHON_USE_MODULE_STATE 0
#endif
#ifndef CYTHON_USE_DICT_VERSIONS
#define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1)
#if PY_VERSION_HEX < 0x030400a1
#undef CYTHON_USE_TP_FINALIZE
#define CYTHON_USE_TP_FINALIZE 0
#elif !defined(CYTHON_USE_TP_FINALIZE)
#define CYTHON_USE_TP_FINALIZE 1
#endif
#if PY_VERSION_HEX < 0x030600B1
#undef CYTHON_USE_DICT_VERSIONS
#define CYTHON_USE_DICT_VERSIONS 0
#elif !defined(CYTHON_USE_DICT_VERSIONS)
#define CYTHON_USE_DICT_VERSIONS 1
#endif
#ifndef CYTHON_USE_EXC_INFO_STACK
#define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3)
#if PY_VERSION_HEX < 0x030700A3
#undef CYTHON_USE_EXC_INFO_STACK
#define CYTHON_USE_EXC_INFO_STACK 0
#elif !defined(CYTHON_USE_EXC_INFO_STACK)
#define CYTHON_USE_EXC_INFO_STACK 1
#endif
#endif
......@@ -569,6 +601,18 @@ class __Pyx_FakeReference {
#define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n))
#endif
// PEP-573: PyCFunction holds reference to defining class (PyCMethodObject)
#if PY_VERSION_HEX < 0x030900B1
#define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b))
typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *);
#else
#define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b)
#define __Pyx_PyCMethod PyCMethod
#endif
#ifndef METH_METHOD
#define METH_METHOD 0x200
#endif
#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc)
#define PyObject_Malloc(s) PyMem_Malloc(s)
#define PyObject_Free(p) PyMem_Free(p)
......@@ -608,7 +652,7 @@ class __Pyx_FakeReference {
#endif
#if CYTHON_COMPILING_IN_LIMITED_API
static inline void *__Pyx_PyModule_GetState(PyObject *op)
static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op)
{
void *result;
......@@ -708,20 +752,30 @@ static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict,
#endif
/* Type slots */
#if CYTHON_COMPILING_IN_LIMITED_API
#define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp))
#else
#define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags)
#endif
#if CYTHON_USE_TYPE_SLOTS
#define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags)
#define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0)
#define __Pyx_PyObject_GetIterNextFunc(obj) (Py_TYPE(obj)->tp_iternext)
#else
#define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp))
#define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature)
#define __Pyx_PyObject_GetIterNextFunc(obj) PyIter_Next
#endif
#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000
// In Py3.8+, instances of heap types need to decref their type on deallocation.
// https://bugs.python.org/issue35810
#define __Pyx_PyHeapTypeObject_GC_Del(obj) { \
PyTypeObject *type = Py_TYPE(obj); \
assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)); \
PyObject_GC_Del(obj); \
Py_DECREF(type); \
}
#else
#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj)
#endif
#if CYTHON_COMPILING_IN_LIMITED_API
#define CYTHON_PEP393_ENABLED 1
#define __Pyx_PyUnicode_READY(op) (0)
......@@ -923,6 +977,12 @@ static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict,
} __Pyx_PyAsyncMethodsStruct;
#endif
/////////////// IncludeStructmemberH.proto ///////////////
#include <structmember.h>
/////////////// SmallCodeConfig.proto ///////////////
#ifndef CYTHON_SMALL_CODE
......
......@@ -1579,6 +1579,7 @@ static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name)
#endif
{
PyObject *result;
// FIXME: clean up the macro guard order here: limited API first, then borrowed refs, then cpython
#if !CYTHON_AVOID_BORROWED_REFS
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1
// Identifier names are always interned and have a pre-calculated hash value.
......
......@@ -107,7 +107,7 @@ elif [ -n "${PYTHON_VERSION##pypy*}" ]; then
if $PYTHON_DBG -V >&2; then CFLAGS="-O0 -ggdb" $PYTHON_DBG runtests.py -vv --no-code-style Debugger --backends=$BACKEND; fi;
fi
export CFLAGS="-O0 -ggdb -Wall -Wextra"
export CFLAGS="-O0 -ggdb -Wall -Wextra $EXTRA_CFLAGS"
python runtests.py \
-vv $STYLE_ARGS \
-x Debugger \
......
......@@ -9,6 +9,7 @@ environment:
WITH_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd"
BACKEND: c
PARALLEL: "-j4"
EXTRA_CFLAGS: ""
matrix:
- PYTHON: "C:\\Python27"
......@@ -35,6 +36,11 @@ environment:
PYTHON_VERSION: "3.8"
PYTHON_ARCH: "32"
- PYTHON: "C:\\Python38-x64"
PYTHON_VERSION: "3.8"
PYTHON_ARCH: "64"
EXTRA_CFLAGS: "-DCYTHON_USE_TYPE_SPECS=1"
- PYTHON: "C:\\Python38-x64"
PYTHON_VERSION: "3.8"
PYTHON_ARCH: "64"
......@@ -49,6 +55,16 @@ environment:
PYTHON_VERSION: "3.7"
PYTHON_ARCH: "64"
- PYTHON: "C:\\Python37-x64"
PYTHON_VERSION: "3.7"
PYTHON_ARCH: "64"
EXTRA_CFLAGS: "-DCYTHON_USE_TYPE_SPECS=1"
- PYTHON: "C:\\Python37-x64"
PYTHON_VERSION: "3.7"
PYTHON_ARCH: "64"
BACKEND: cpp
- PYTHON: "C:\\Python36"
PYTHON_VERSION: "3.6"
PYTHON_ARCH: "32"
......@@ -108,7 +124,7 @@ test: off
test_script:
- "%PYTHON%\\Scripts\\pip.exe install -r test-requirements.txt"
- "%PYTHON%\\Scripts\\pip.exe install win_unicode_console"
- "set CFLAGS=/Od /W3"
- "set CFLAGS=/Od /W3 %EXTRA_CFLAGS%"
- "%WITH_ENV% %PYTHON%\\python.exe runtests.py -vv --backend=%BACKEND% --no-code-style -j5"
artifacts:
......
......@@ -23,3 +23,16 @@ cdef A a
foo(2, 3, [], [], P, P, &P)
a.point("something", 3, "anything", [], "an object", P, &P)
# Test that internally generated names do not conflict.
cdef class A_spec:
pass
cdef class A_members:
pass
cdef class A_methods:
pass
cdef class A_slots:
pass
......@@ -6,3 +6,6 @@ dict_animal
not_none
queue3
test_queue
memoryview
memview
buffer
......@@ -65,31 +65,31 @@ import sys
try:
import notheaptype
assert False
assert False, "notheaptype"
except TypeError as msg:
assert str(msg) == "base class 'object' is not a heap type"
try:
import wrongbase
assert False
assert False, "wrongbase"
except TypeError as msg:
assert str(msg) == "best base 'str' must be equal to first base 'wrongbase.Base'"
try:
import badmro
assert False
assert False, "badmro"
except TypeError as msg:
assert str(msg).startswith("Cannot create a consistent method resolution")
try:
import nodict
assert False
assert False, "nodict"
except TypeError as msg:
assert str(msg) == "extension type 'nodict.X' has no __dict__ slot, but base type 'Py' has: either add 'cdef dict __dict__' to the extension type or add '__slots__ = [...]' to the base type"
try:
# This should work on Python 3 but fail on Python 2
import oldstyle
assert sys.version_info[0] >= 3
assert sys.version_info[0] >= 3, "oldstyle"
except TypeError as msg:
assert str(msg) == "base class 'OldStyle' is an old-style class"
# tag: pstats
# cython: profile = True
__doc__ = u"""
u"""
>>> import os, tempfile, cProfile as profile, pstats
>>> statsfile = tempfile.mkstemp()[1]
>>> profile.runctx("test_profile(100)", locals(), globals(), statsfile)
......@@ -47,7 +47,7 @@ __doc__ = u"""
200
>>> short_stats['m_cdef']
100
>>> short_stats['m_cpdef']
>>> short_stats['m_cpdef'] - (200 if CPDEF_METHODS_COUNT_TWICE else 0) # FIXME!
300
>>> try:
......@@ -117,6 +117,15 @@ __doc__ = u"""
cimport cython
# FIXME: With type specs, cpdef methods are currently counted twice.
# https://github.com/cython/cython/issues/2137
cdef extern from *:
int CYTHON_USE_TYPE_SPECS
CPDEF_METHODS_COUNT_TWICE = CYTHON_USE_TYPE_SPECS
def callees(pstats, target_caller):
pstats.calc_callees()
for (_, _, caller), callees in pstats.all_callees.items():
......@@ -125,6 +134,7 @@ def callees(pstats, target_caller):
if 'pyx' in file:
yield callee
def test_profile(long N):
cdef long i, n = 0
cdef A a = A()
......
......@@ -56,30 +56,6 @@ __doc__ = u"""
>>> g11 = object.__getattribute__(GetAttribute(), '__getattribute__')
>>> g11('attr')
GetAttribute getattribute 'attr'
>>> # If you define either setattr or delattr, you get wrapper objects
>>> # for both methods. (This behavior is unchanged by #561.)
>>> sa_setattr = SetAttr().__setattr__
>>> sa_setattr('foo', 'bar')
SetAttr setattr 'foo' 'bar'
>>> sa_delattr = SetAttr().__delattr__
>>> sa_delattr('foo')
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561.SetAttr' object has no attribute 'foo'
>>> da_setattr = DelAttr().__setattr__
>>> da_setattr('foo', 'bar')
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561.DelAttr' object has no attribute 'foo'
>>> da_delattr = DelAttr().__delattr__
>>> da_delattr('foo')
DelAttr delattr 'foo'
>>> sda_setattr = SetDelAttr().__setattr__
>>> sda_setattr('foo', 'bar')
SetDelAttr setattr 'foo' 'bar'
>>> sda_delattr = SetDelAttr().__delattr__
>>> sda_delattr('foo')
SetDelAttr delattr 'foo'
>>> # If you define either set or delete, you get wrapper objects
>>> # for both methods. (This behavior is unchanged by #561.)
>>> s_set = Set().__set__
......@@ -119,6 +95,39 @@ if sys.version_info >= (2,5):
VS __index__ 0
"""
cdef extern from *:
# type specs require a bug fix in Py3.8+ for some of these tests.
const int CYTHON_USE_TYPE_SPECS
if not CYTHON_USE_TYPE_SPECS or sys.version_info >= (3,8):
__doc__ += u"""
>>> # If you define either setattr or delattr, you get wrapper objects
>>> # for both methods. (This behavior is unchanged by #561.)
>>> sa_setattr = SetAttr().__setattr__
>>> sa_setattr('foo', 'bar')
SetAttr setattr 'foo' 'bar'
>>> sa_delattr = SetAttr().__delattr__
>>> sa_delattr('foo')
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561.SetAttr' object has no attribute 'foo'
>>> da_setattr = DelAttr().__setattr__
>>> da_setattr('foo', 'bar')
Traceback (most recent call last):
...
AttributeError: 'special_methods_T561.DelAttr' object has no attribute 'foo'
>>> da_delattr = DelAttr().__delattr__
>>> da_delattr('foo')
DelAttr delattr 'foo'
>>> sda_setattr = SetDelAttr().__setattr__
>>> sda_setattr('foo', 'bar')
SetDelAttr setattr 'foo' 'bar'
>>> sda_delattr = SetDelAttr().__delattr__
>>> sda_delattr('foo')
SetDelAttr delattr 'foo'
"""
cdef class VerySpecial:
"""
>>> vs0 = VerySpecial(0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment