Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
84473513
Commit
84473513
authored
Jan 12, 2020
by
Eddie Elizondo
Committed by
Stefan Behnel
Jan 12, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add LIMITED_API support and remove static state (GH-3223)
Blacklists failing test for now
parent
640aab74
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
693 additions
and
42 deletions
+693
-42
.travis.yml
.travis.yml
+12
-1
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+57
-2
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+31
-0
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+283
-7
Cython/Compiler/Naming.py
Cython/Compiler/Naming.py
+2
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+38
-2
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+1
-1
Cython/Compiler/TypeSlots.py
Cython/Compiler/TypeSlots.py
+19
-2
Cython/Utility/Exceptions.c
Cython/Utility/Exceptions.c
+11
-1
Cython/Utility/ExtensionTypes.c
Cython/Utility/ExtensionTypes.c
+5
-1
Cython/Utility/ImportExport.c
Cython/Utility/ImportExport.c
+18
-0
Cython/Utility/ModuleSetupCode.c
Cython/Utility/ModuleSetupCode.c
+114
-3
Cython/Utility/ObjectHandling.c
Cython/Utility/ObjectHandling.c
+8
-0
Cython/Utility/Optimize.c
Cython/Utility/Optimize.c
+12
-0
Cython/Utility/StringTools.c
Cython/Utility/StringTools.c
+34
-16
Cython/Utility/TypeConversion.c
Cython/Utility/TypeConversion.c
+16
-6
runtests.py
runtests.py
+7
-0
tests/limited_api_bugs.txt
tests/limited_api_bugs.txt
+25
-0
No files found.
.travis.yml
View file @
84473513
...
...
@@ -51,6 +51,10 @@ matrix:
dist
:
xenial
# Required for Python 3.7
sudo
:
required
# travis-ci/travis-ci#9069
env
:
TEST_CODE_STYLE=1
-
python
:
3.7
dist
:
xenial
# Required for Python 3.7
sudo
:
required
# travis-ci/travis-ci#9069
env
:
LIMITED_API=--limited-api EXCLUDE=--no-file
-
python
:
3.4
env
:
BACKEND=c
-
python
:
3.4
...
...
@@ -63,6 +67,9 @@ matrix:
env
:
BACKEND=c
-
python
:
3.6
env
:
BACKEND=cpp
-
python
:
3.6
sudo
:
required
# travis-ci/travis-ci#9069
env
:
LIMITED_API=--limited-api EXCLUDE=--no-file
-
python
:
3.8
dist
:
xenial
# Required for Python 3.7
sudo
:
required
# travis-ci/travis-ci#9069
...
...
@@ -71,6 +78,10 @@ matrix:
dist
:
xenial
# Required for Python 3.7
sudo
:
required
# travis-ci/travis-ci#9069
env
:
BACKEND=cpp
-
python
:
3.8-dev
dist
:
xenial
# Required for Python 3.8
sudo
:
required
# travis-ci/travis-ci#9069
env
:
LIMITED_API=--limited-api EXCLUDE=--no-file
-
os
:
osx
osx_image
:
xcode6.4
env
:
PY=2
...
...
@@ -154,5 +165,5 @@ script:
# Need to clear the ccache? Try something like this:
# - if [ -n "${BACKEND##*cpp*}" -a -z "${TRAVIS_PYTHON_VERSION##*3.4}" ]; then ccache -C || true; fi
-
if [ "$COVERAGE" != "1" ]; then CFLAGS="-O2 -ggdb -Wall -Wextra $(python -c 'import sys; print("-fno-strict-aliasing" if sys.version_info[0] == 2 else "")')" python setup.py build_ext -i; fi
-
CFLAGS="-O0 -ggdb -Wall -Wextra" python runtests.py -vv $STYLE_ARGS -x Debugger --backends=$BACKEND $(if [ "$COVERAGE" == "1" ]; then echo " --coverage"; fi) $(if [ -z "$TEST_CODE_STYLE" ]; then echo " -j7 "; fi)
-
CFLAGS="-O0 -ggdb -Wall -Wextra" python runtests.py -vv $STYLE_ARGS -x Debugger --backends=$BACKEND $
LIMITED_API $EXCLUDE $
(if [ "$COVERAGE" == "1" ]; then echo " --coverage"; fi) $(if [ -z "$TEST_CODE_STYLE" ]; then echo " -j7 "; fi)
-
ccache -s ||
true
Cython/Compiler/Code.py
View file @
84473513
...
...
@@ -1080,6 +1080,10 @@ class GlobalState(object):
'
h_code
',
'
filename_table
',
'
utility_code_proto_before_types
',
'
module_state
',
'
module_state_clear
',
'
module_state_traverse
',
'
module_state_defines
',
'
numeric_typedefs
', # Let these detailed individual parts stay!,
'
complex_type_declarations
', # as the proper solution is to make a full DAG...
'
type_declarations
', # More coarse-grained blocks would simply hide
...
...
@@ -1420,9 +1424,18 @@ 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"
)
for
_
,
cname
,
c
in
consts
:
self
.
parts
[
'module_state'
].
putln
(
"%s;"
%
c
.
type
.
declaration_code
(
cname
))
self
.
parts
[
'module_state_defines'
].
putln
(
"#define %s %s->%s"
%
(
cname
,
Naming
.
modulestateglobal_cname
,
cname
))
self
.
parts
[
'module_state_clear'
].
putln
(
"Py_CLEAR(clear_module_state->%s);"
%
cname
)
self
.
parts
[
'module_state_traverse'
].
putln
(
"Py_VISIT(traverse_module_state->%s);"
%
cname
)
decls_writer
.
putln
(
"static %s;"
%
c
.
type
.
declaration_code
(
cname
))
decls_writer
.
putln
(
"#endif"
)
def
generate_cached_methods_decls
(
self
):
if
not
self
.
cached_cmethods
:
...
...
@@ -1476,13 +1489,15 @@ class GlobalState(object):
decls_writer
.
putln
(
"static Py_UNICODE %s[] = { %s };"
%
(
cname
,
utf16_array
))
decls_writer
.
putln
(
"#endif"
)
init_globals
=
self
.
parts
[
'init_globals'
]
if
py_strings
:
self
.
use_utility_code
(
UtilityCode
.
load_cached
(
"InitStrings"
,
"StringTools.c"
))
py_strings
.
sort
()
w
=
self
.
parts
[
'pystring_table'
]
w
.
putln
(
""
)
w
.
putln
(
"static __Pyx_StringTabEntry %s[] = {"
%
Naming
.
stringtab_cname
)
for
c_cname
,
_
,
py_string
in
py_strings
:
for
idx
,
py_string_args
in
enumerate
(
py_strings
):
c_cname
,
_
,
py_string
=
py_string_args
if
not
py_string
.
is_str
or
not
py_string
.
encoding
or
\
py_string
.
encoding
in
(
'ASCII'
,
'USASCII'
,
'US-ASCII'
,
'UTF8'
,
'UTF-8'
):
...
...
@@ -1490,8 +1505,19 @@ class GlobalState(object):
else
:
encoding
=
'"%s"'
%
py_string
.
encoding
.
lower
()
self
.
parts
[
'module_state'
].
putln
(
"PyObject *%s;"
%
py_string
.
cname
)
self
.
parts
[
'module_state_defines'
].
putln
(
"#define %s %s->%s"
%
(
py_string
.
cname
,
Naming
.
modulestateglobal_cname
,
py_string
.
cname
))
self
.
parts
[
'module_state_clear'
].
putln
(
"Py_CLEAR(clear_module_state->%s);"
%
py_string
.
cname
)
self
.
parts
[
'module_state_traverse'
].
putln
(
"Py_VISIT(traverse_module_state->%s);"
%
py_string
.
cname
)
decls_writer
.
putln
(
"#if !CYTHON_COMPILING_IN_LIMITED_API"
)
decls_writer
.
putln
(
"static PyObject *%s;"
%
py_string
.
cname
)
decls_writer
.
putln
(
"#endif"
)
if
py_string
.
py3str_cstring
:
w
.
putln
(
"#if PY_MAJOR_VERSION >= 3"
)
w
.
putln
(
"{&%s, %s, sizeof(%s), %s, %d, %d, %d},"
%
(
...
...
@@ -1502,6 +1528,17 @@ class GlobalState(object):
py_string
.
intern
))
w
.
putln
(
"#else"
)
w
.
putln
(
"#if CYTHON_COMPILING_IN_LIMITED_API"
)
w
.
putln
(
"{0, %s, sizeof(%s), %s, %d, %d, %d},"
%
(
c_cname
,
c_cname
,
encoding
,
py_string
.
is_unicode
,
py_string
.
is_str
,
py_string
.
intern
))
w
.
putln
(
"#else"
)
w
.
putln
(
"{&%s, %s, sizeof(%s), %s, %d, %d, %d},"
%
(
py_string
.
cname
,
c_cname
,
...
...
@@ -1511,25 +1548,42 @@ class GlobalState(object):
py_string
.
is_str
,
py_string
.
intern
))
w
.
putln
(
"#endif"
)
init_globals
.
putln
(
"#if CYTHON_COMPILING_IN_LIMITED_API"
)
init_globals
.
putln
(
"if (__Pyx_InitString(%s[%d], &%s) < 0) %s;"
%
(
Naming
.
stringtab_cname
,
idx
,
py_string
.
cname
,
init_globals
.
error_goto
(
self
.
module_pos
)))
init_globals
.
putln
(
"#endif"
)
if
py_string
.
py3str_cstring
:
w
.
putln
(
"#endif"
)
w
.
putln
(
"{0, 0, 0, 0, 0, 0, 0}"
)
w
.
putln
(
"};"
)
init_globals
=
self
.
parts
[
'init_globals'
]
init_globals
.
putln
(
"#if !CYTHON_COMPILING_IN_LIMITED_API"
)
init_globals
.
putln
(
"if (__Pyx_InitStrings(%s) < 0) %s;"
%
(
Naming
.
stringtab_cname
,
init_globals
.
error_goto
(
self
.
module_pos
)))
init_globals
.
putln
(
"#endif"
)
def
generate_num_constants
(
self
):
consts
=
[(
c
.
py_type
,
c
.
value
[
0
]
==
'-'
,
len
(
c
.
value
),
c
.
value
,
c
.
value_code
,
c
)
for
c
in
self
.
num_const_index
.
values
()]
consts
.
sort
()
decls_writer
=
self
.
parts
[
'decls'
]
decls_writer
.
putln
(
"#if !CYTHON_COMPILING_IN_LIMITED_API"
)
init_globals
=
self
.
parts
[
'init_globals'
]
for
py_type
,
_
,
_
,
value
,
value_code
,
c
in
consts
:
cname
=
c
.
cname
self
.
parts
[
'module_state'
].
putln
(
"PyObject *%s;"
%
cname
)
self
.
parts
[
'module_state_defines'
].
putln
(
"#define %s %s->%s"
%
(
cname
,
Naming
.
modulestateglobal_cname
,
cname
))
self
.
parts
[
'module_state_clear'
].
putln
(
"Py_CLEAR(clear_module_state->%s);"
%
cname
)
self
.
parts
[
'module_state_traverse'
].
putln
(
"Py_VISIT(traverse_module_state->%s);"
%
cname
)
decls_writer
.
putln
(
"static PyObject *%s;"
%
cname
)
if
py_type
==
'float'
:
function
=
'PyFloat_FromDouble(%s)'
...
...
@@ -1544,6 +1598,7 @@ class GlobalState(object):
init_globals
.
putln
(
'%s = %s; %s'
%
(
cname
,
function
%
value_code
,
init_globals
.
error_goto_if_null
(
cname
,
self
.
module_pos
)))
decls_writer
.
putln
(
"#endif"
)
# The functions below are there in a transition phase only
# and will be deprecated. They are called from Nodes.BlockNode.
...
...
Cython/Compiler/ExprNodes.py
View file @
84473513
...
...
@@ -2301,6 +2301,14 @@ class NameNode(AtomicExprNode):
setter
=
'__Pyx_'
+
n
else
:
assert
False
,
repr
(
entry
)
code
.
putln
(
"#if CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
put_incref
(
rhs
.
py_result
(),
py_object_type
)
code
.
put_error_if_neg
(
self
.
pos
,
'%s(%s, %s, %s)'
%
(
"PyModule_AddObject"
,
Naming
.
module_cname
,
code
.
get_string_const
(
self
.
entry
.
name
),
rhs
.
py_result
()))
code
.
putln
(
"#else"
)
code
.
put_error_if_neg
(
self
.
pos
,
'%s(%s, %s, %s)'
%
(
...
...
@@ -2308,6 +2316,7 @@ class NameNode(AtomicExprNode):
namespace
,
interned_cname
,
rhs
.
py_result
()))
code
.
putln
(
"#endif"
)
if
debug_disposal_code
:
print
(
"NameNode.generate_assignment_code:"
)
print
(
"...generating disposal code for %s"
%
rhs
)
...
...
@@ -9370,6 +9379,27 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
else
:
flags
=
'0'
code
.
putln
(
'#if CYTHON_COMPILING_IN_LIMITED_API'
)
dict_temp
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
manage_ref
=
True
)
code
.
putln
(
'%s = PyDict_New(); %s'
%
(
dict_temp
,
code
.
error_goto_if_null
(
dict_temp
,
self
.
pos
)))
code
.
put_gotref
(
dict_temp
)
code
.
putln
(
'%s = %s(&%s, %s, %s, %s, %s, %s, %s); %s'
%
(
self
.
result
(),
constructor
,
self
.
pymethdef_cname
,
flags
,
self
.
get_py_qualified_name
(
code
),
self
.
closure_result_code
(),
self
.
get_py_mod_name
(
code
),
dict_temp
,
code_object_result
,
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_decref_clear
(
dict_temp
,
type
=
py_object_type
)
code
.
funcstate
.
release_temp
(
dict_temp
)
code
.
putln
(
'#else'
)
code
.
putln
(
'%s = %s(&%s, %s, %s, %s, %s, %s, %s); %s'
%
(
self
.
result
(),
...
...
@@ -9382,6 +9412,7 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
Naming
.
moddict_cname
,
code_object_result
,
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
putln
(
'#endif'
)
code
.
put_gotref
(
self
.
py_result
())
...
...
Cython/Compiler/ModuleNode.py
View file @
84473513
...
...
@@ -418,6 +418,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# initialise the macro to reduce the code size of one-time functionality
code
.
putln
(
UtilityCode
.
load_as_string
(
"SmallCodeConfig"
,
"ModuleSetupCode.c"
)[
0
].
strip
())
self
.
generate_module_state_start
(
env
,
globalstate
[
'module_state'
])
self
.
generate_module_state_defines
(
env
,
globalstate
[
'module_state_defines'
])
self
.
generate_module_state_clear
(
env
,
globalstate
[
'module_state_clear'
])
self
.
generate_module_state_traverse
(
env
,
globalstate
[
'module_state_traverse'
])
# init_globals is inserted before this
self
.
generate_module_init_func
(
modules
[:
-
1
],
env
,
globalstate
[
'init_module'
])
self
.
generate_module_cleanup_func
(
env
,
globalstate
[
'cleanup_module'
])
...
...
@@ -432,6 +437,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
globalstate
.
use_utility_code
(
utilcode
)
globalstate
.
finalize_main_c_code
()
self
.
generate_module_state_end
(
env
,
modules
,
globalstate
)
f
=
open_new_file
(
result
.
c_file
)
try
:
rootwriter
.
copyto
(
f
)
...
...
@@ -638,7 +645,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
defined_here
=
module
is
env
modulecode
.
putln
(
""
)
modulecode
.
putln
(
"/* Module declarations from %s */"
%
module
.
qualified_name
.
as_c_string_literal
())
self
.
generate_c_class_declarations
(
module
,
modulecode
,
defined_here
)
self
.
generate_c_class_declarations
(
module
,
modulecode
,
defined_here
,
globalstate
)
self
.
generate_cvariable_declarations
(
module
,
modulecode
,
defined_here
)
self
.
generate_cfunction_declarations
(
module
,
modulecode
,
defined_here
)
...
...
@@ -742,6 +749,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
(
'static PyObject *%s = NULL;'
%
env
.
module_cname
)
code
.
putln
(
'static PyObject *%s;'
%
env
.
module_dict_cname
)
code
.
putln
(
'static PyObject *%s;'
%
Naming
.
builtins_cname
)
...
...
@@ -755,6 +763,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
'static int %s = 0;'
%
Naming
.
clineno_cname
)
code
.
putln
(
'static const char * %s= %s;'
%
(
Naming
.
cfilenm_cname
,
Naming
.
file_c_macro
))
code
.
putln
(
'static const char *%s;'
%
Naming
.
filename_cname
)
code
.
putln
(
'#endif'
)
env
.
use_utility_code
(
UtilityCode
.
load_cached
(
"FastTypeChecks"
,
"ModuleSetupCode.c"
))
if
has_np_pythran
(
env
):
...
...
@@ -1167,11 +1176,28 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# Only for exposing public typedef name.
code
.
putln
(
"typedef struct %s %s;"
%
(
type
.
objstruct_cname
,
type
.
objtypedef_cname
))
def
generate_c_class_declarations
(
self
,
env
,
code
,
definition
):
def
generate_c_class_declarations
(
self
,
env
,
code
,
definition
,
globalstate
):
module_state
=
globalstate
[
'module_state'
]
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"
)
for
entry
in
env
.
c_class_entries
:
if
definition
or
entry
.
defined_in_pxd
:
code
.
putln
(
"static PyTypeObject *%s = 0;"
%
(
entry
.
type
.
typeptr_cname
))
module_state
.
putln
(
"PyTypeObject *%s;"
%
entry
.
type
.
typeptr_cname
)
module_state_defines
.
putln
(
"#define %s %s->%s"
%
(
entry
.
type
.
typeptr_cname
,
Naming
.
modulestateglobal_cname
,
entry
.
type
.
typeptr_cname
))
module_state_clear
.
putln
(
"Py_CLEAR(clear_module_state->%s);"
%
entry
.
type
.
typeptr_cname
)
module_state_traverse
.
putln
(
"Py_VISIT(traverse_module_state->%s);"
%
entry
.
type
.
typeptr_cname
)
code
.
putln
(
"#endif"
)
def
generate_cvariable_declarations
(
self
,
env
,
code
,
definition
):
if
env
.
is_cython_builtin
:
...
...
@@ -1277,7 +1303,11 @@ 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"
)
self
.
generate_typeobj_spec
(
full_module_name
,
entry
,
code
)
code
.
putln
(
"#else"
)
self
.
generate_typeobj_definition
(
full_module_name
,
entry
,
code
)
code
.
putln
(
"#endif"
)
def
generate_exttype_vtable
(
self
,
scope
,
code
):
# Generate the definition of an extension type's vtable.
...
...
@@ -1329,8 +1359,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
freecount_name
=
scope
.
mangle_internal
(
Naming
.
freecount_name
)
decls
=
code
.
globalstate
[
'decls'
]
if
cinit_func_entry
is
None
:
decls
.
putln
(
"#if !CYTHON_COMPILING_IN_LIMITED_API"
)
decls
.
putln
(
"static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/"
%
slot_func
)
if
cinit_func_entry
is
None
:
decls
.
putln
(
"#endif"
)
code
.
putln
(
""
)
if
freelist_size
:
code
.
putln
(
"static %s[%d];"
%
(
...
...
@@ -1338,6 +1372,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
freelist_size
))
code
.
putln
(
"static int %s = 0;"
%
freecount_name
)
code
.
putln
(
""
)
if
cinit_func_entry
is
None
:
code
.
putln
(
"#if !CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
putln
(
"static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {"
%
(
slot_func
,
unused_marker
,
unused_marker
))
...
...
@@ -1354,6 +1390,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"PyObject *o = %s(t, a, k);"
%
tp_new
)
else
:
code
.
putln
(
"PyObject *o;"
)
code
.
putln
(
"#if CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
putln
(
"allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc);"
)
code
.
putln
(
"o = alloc_func(t, 0);"
)
code
.
putln
(
"#else"
)
if
freelist_size
:
code
.
globalstate
.
use_utility_code
(
UtilityCode
.
load_cached
(
"IncludeStringH"
,
"StringTools.c"
))
...
...
@@ -1379,6 +1419,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"} else {"
)
code
.
putln
(
"o = (PyObject *) PyBaseObject_Type.tp_new(t, %s, 0);"
%
Naming
.
empty_tuple
)
code
.
putln
(
"}"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"if (unlikely(!o)) return 0;"
)
if
freelist_size
and
not
base_type
:
code
.
putln
(
'}'
)
...
...
@@ -1441,6 +1482,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"return NULL;"
)
code
.
putln
(
"}"
)
if
cinit_func_entry
is
None
:
code
.
putln
(
"#endif"
)
def
generate_dealloc_function
(
self
,
scope
,
code
):
tp_slot
=
TypeSlots
.
ConstructorSlot
(
"tp_dealloc"
,
'__dealloc__'
)
...
...
@@ -1451,6 +1494,11 @@ 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
)
...
...
@@ -1584,6 +1632,8 @@ 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__"
)
...
...
@@ -2165,6 +2215,52 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"}"
)
def
generate_typeobj_spec
(
self
,
modname
,
entry
,
code
):
type
=
entry
.
type
scope
=
type
.
scope
if
type
.
typedef_flag
:
objstruct
=
type
.
objstruct_cname
else
:
objstruct
=
"struct %s"
%
type
.
objstruct_cname
classname
=
scope
.
class_name
.
as_c_string_literal
()
code
.
putln
(
"static PyType_Slot %s_slots[] = {"
%
type
.
typeobj_cname
)
has_tp_getattro
=
False
for
slot
in
TypeSlots
.
slot_table
:
if
slot
.
slot_name
==
"tp_flags"
:
continue
if
slot
.
slot_name
==
"tp_new"
and
scope
.
lookup_here
(
"__cinit__"
)
is
None
:
continue
if
slot
.
slot_name
==
"tp_dealloc"
and
scope
.
lookup_here
(
"__dealloc__"
)
is
None
:
continue
if
slot
.
slot_name
==
"tp_getattro"
:
has_tp_getattro
=
True
if
slot
.
slot_name
==
"tp_as_number"
:
slot
.
generate_substructure_spec
(
scope
,
code
)
continue
if
slot
.
slot_name
==
"tp_as_sequence"
:
slot
.
generate_substructure_spec
(
scope
,
code
)
continue
if
slot
.
slot_name
==
"tp_as_mapping"
:
slot
.
generate_substructure_spec
(
scope
,
code
)
continue
if
slot
.
slot_name
==
"tp_as_buffer"
:
# Can't support tp_as_buffer
continue
v
=
TypeSlots
.
get_slot_by_name
(
slot
.
slot_name
).
spec_slot_value
(
scope
)
if
v
is
not
None
:
code
.
putln
(
" {Py_%s, (void *)%s},"
%
(
slot
.
slot_name
,
v
))
if
not
has_tp_getattro
:
code
.
putln
(
" {Py_tp_getattro, __Pyx_PyObject_GenericGetAttr},"
)
code
.
putln
(
" {0, 0},"
)
code
.
putln
(
"};"
)
code
.
putln
(
"static PyType_Spec %s_spec = {"
%
type
.
typeobj_cname
)
code
.
putln
(
"
\
"
%s.%s
\
"
,"
%
(
self
.
full_module_name
,
classname
.
replace
(
"
\
"
"
,
""
)))
code
.
putln
(
" sizeof(%s),"
%
objstruct
)
code
.
putln
(
" 0,"
)
code
.
putln
(
" %s,"
%
TypeSlots
.
get_slot_by_name
(
"tp_flags"
).
spec_slot_value
(
scope
))
code
.
putln
(
" %s_slots,"
%
type
.
typeobj_cname
)
code
.
putln
(
"};"
)
def
generate_typeobj_definition
(
self
,
modname
,
entry
,
code
):
type
=
entry
.
type
scope
=
type
.
scope
...
...
@@ -2336,6 +2432,147 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
UtilityCode
.
load_as_string
(
"ImportStar"
,
"ImportExport.c"
)[
1
])
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"
)
code
.
putln
(
'typedef struct {'
)
code
.
putln
(
'PyObject *%s;'
%
Naming
.
builtins_cname
)
code
.
putln
(
'PyObject *%s;'
%
Naming
.
cython_runtime_cname
)
code
.
putln
(
'PyObject *%s;'
%
Naming
.
empty_tuple
)
code
.
putln
(
'PyObject *%s;'
%
Naming
.
empty_bytes
)
code
.
putln
(
'PyObject *%s;'
%
Naming
.
empty_unicode
)
if
Options
.
pre_import
is
not
None
:
code
.
putln
(
'PyObject *%s;'
%
Naming
.
preimport_cname
)
code
.
putln
(
'int %s;'
%
Naming
.
lineno_cname
)
code
.
putln
(
'int %s;'
%
Naming
.
clineno_cname
)
code
.
putln
(
'const char *%s;'
%
Naming
.
filename_cname
)
def
generate_module_state_end
(
self
,
env
,
modules
,
globalstate
):
module_state
=
globalstate
[
'module_state'
]
module_state_defines
=
globalstate
[
'module_state_defines'
]
module_state_clear
=
globalstate
[
'module_state_clear'
]
module_state_traverse
=
globalstate
[
'module_state_traverse'
]
for
module
in
modules
:
definition
=
module
is
env
for
entry
in
env
.
c_class_entries
:
if
definition
or
entry
.
defined_in_pxd
:
module_state
.
putln
(
"PyObject *%s;"
%
entry
.
type
.
typeobj_cname
)
module_state_defines
.
putln
(
"#define %s %s->%s"
%
(
entry
.
type
.
typeobj_cname
,
Naming
.
modulestateglobal_cname
,
entry
.
type
.
typeobj_cname
))
module_state_clear
.
putln
(
"Py_CLEAR(clear_module_state->%s);"
%
entry
.
type
.
typeobj_cname
)
module_state_traverse
.
putln
(
"Py_VISIT(traverse_module_state->%s);"
%
entry
.
type
.
typeobj_cname
)
module_state
.
putln
(
'} %s;'
%
Naming
.
modulestate_cname
)
module_state
.
putln
(
''
)
module_state
.
putln
(
'#ifdef __cplusplus'
)
module_state
.
putln
(
'namespace {'
)
module_state
.
putln
(
'extern struct PyModuleDef %s;'
%
Naming
.
pymoduledef_cname
)
module_state
.
putln
(
'} /* anonymous namespace */'
)
module_state
.
putln
(
'#else'
)
module_state
.
putln
(
'static struct PyModuleDef %s;'
%
Naming
.
pymoduledef_cname
)
module_state
.
putln
(
'#endif'
)
module_state
.
putln
(
''
)
module_state
.
putln
(
'#define %s(o) ((%s *)__Pyx_PyModule_GetState(o))'
%
(
Naming
.
modulestate_cname
,
Naming
.
modulestate_cname
))
module_state
.
putln
(
''
)
module_state
.
putln
(
'#define %s (%s(PyState_FindModule(&%s)))'
%
(
Naming
.
modulestateglobal_cname
,
Naming
.
modulestate_cname
,
Naming
.
pymoduledef_cname
))
module_state
.
putln
(
''
)
module_state
.
putln
(
'#define %s (PyState_FindModule(&%s))'
%
(
env
.
module_cname
,
Naming
.
pymoduledef_cname
))
module_state
.
putln
(
"#endif"
)
module_state_defines
.
putln
(
"#endif"
)
module_state_clear
.
putln
(
"return 0;"
)
module_state_clear
.
putln
(
"};"
)
module_state_clear
.
putln
(
"#endif"
)
module_state_traverse
.
putln
(
"return 0;"
)
module_state_traverse
.
putln
(
"};"
)
module_state_traverse
.
putln
(
"#endif"
)
def
generate_module_state_defines
(
self
,
env
,
code
):
code
.
putln
(
"#if CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
putln
(
'#define %s %s->%s'
%
(
Naming
.
builtins_cname
,
Naming
.
modulestateglobal_cname
,
Naming
.
builtins_cname
))
code
.
putln
(
'#define %s %s->%s'
%
(
Naming
.
cython_runtime_cname
,
Naming
.
modulestateglobal_cname
,
Naming
.
cython_runtime_cname
))
code
.
putln
(
'#define %s %s->%s'
%
(
Naming
.
empty_tuple
,
Naming
.
modulestateglobal_cname
,
Naming
.
empty_tuple
))
code
.
putln
(
'#define %s %s->%s'
%
(
Naming
.
empty_bytes
,
Naming
.
modulestateglobal_cname
,
Naming
.
empty_bytes
))
code
.
putln
(
'#define %s %s->%s'
%
(
Naming
.
empty_unicode
,
Naming
.
modulestateglobal_cname
,
Naming
.
empty_unicode
))
if
Options
.
pre_import
is
not
None
:
code
.
putln
(
'#define %s %s->%s'
%
(
Naming
.
preimport_cname
,
Naming
.
modulestateglobal_cname
,
Naming
.
preimport_cname
))
code
.
putln
(
'#define %s %s->%s'
%
(
Naming
.
lineno_cname
,
Naming
.
modulestateglobal_cname
,
Naming
.
lineno_cname
))
code
.
putln
(
'#define %s %s->%s'
%
(
Naming
.
clineno_cname
,
Naming
.
modulestateglobal_cname
,
Naming
.
clineno_cname
))
code
.
putln
(
'#define %s %s->%s'
%
(
Naming
.
filename_cname
,
Naming
.
modulestateglobal_cname
,
Naming
.
filename_cname
))
def
generate_module_state_clear
(
self
,
env
,
code
):
code
.
putln
(
"#if CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
putln
(
"static int %s_clear(PyObject *m) {"
%
Naming
.
module_cname
)
code
.
putln
(
"%s *clear_module_state = %s(m);"
%
(
Naming
.
modulestate_cname
,
Naming
.
modulestate_cname
))
code
.
putln
(
"if (!clear_module_state) return 0;"
)
code
.
putln
(
'Py_CLEAR(clear_module_state->%s);'
%
Naming
.
builtins_cname
)
code
.
putln
(
'Py_CLEAR(clear_module_state->%s);'
%
Naming
.
cython_runtime_cname
)
code
.
putln
(
'Py_CLEAR(clear_module_state->%s);'
%
Naming
.
empty_tuple
)
code
.
putln
(
'Py_CLEAR(clear_module_state->%s);'
%
Naming
.
empty_bytes
)
code
.
putln
(
'Py_CLEAR(clear_module_state->%s);'
%
Naming
.
empty_unicode
)
def
generate_module_state_traverse
(
self
,
env
,
code
):
code
.
putln
(
"#if CYTHON_COMPILING_IN_LIMITED_API"
)
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
,
Naming
.
modulestate_cname
))
code
.
putln
(
"if (!traverse_module_state) return 0;"
)
code
.
putln
(
'Py_VISIT(traverse_module_state->%s);'
%
Naming
.
builtins_cname
)
code
.
putln
(
'Py_VISIT(traverse_module_state->%s);'
%
Naming
.
cython_runtime_cname
)
code
.
putln
(
'Py_VISIT(traverse_module_state->%s);'
%
Naming
.
empty_tuple
)
code
.
putln
(
'Py_VISIT(traverse_module_state->%s);'
%
Naming
.
empty_bytes
)
code
.
putln
(
'Py_VISIT(traverse_module_state->%s);'
%
Naming
.
empty_unicode
)
def
generate_module_init_func
(
self
,
imported_modules
,
env
,
code
):
subfunction
=
self
.
mod_init_subfunction
(
self
.
scope
,
code
)
...
...
@@ -2425,6 +2662,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
))
code
.
putln
(
"#endif"
)
code
.
putln
(
"/*--- Module creation code ---*/"
)
self
.
generate_module_creation_code
(
env
,
code
)
if
profile
or
linetrace
:
tempdecl_code
.
put_trace_declarations
()
code
.
put_trace_frame_init
()
...
...
@@ -2462,9 +2702,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"#endif"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"/*--- Module creation code ---*/"
)
self
.
generate_module_creation_code
(
env
,
code
)
code
.
putln
(
"/*--- Initialize various global constants etc. ---*/"
)
code
.
put_error_if_neg
(
self
.
pos
,
"__Pyx_InitGlobals()"
)
...
...
@@ -2549,7 +2786,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for
cname
,
type
in
code
.
funcstate
.
all_managed_temps
():
code
.
put_xdecref
(
cname
,
type
)
code
.
putln
(
'if (%s) {'
%
env
.
module_cname
)
code
.
putln
(
"#if !CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
putln
(
'if (%s) {'
%
env
.
module_dict_cname
)
code
.
putln
(
"#endif"
)
code
.
put_add_traceback
(
EncodedString
(
"init %s"
%
env
.
qualified_name
))
code
.
globalstate
.
use_utility_code
(
Nodes
.
traceback_utility_code
)
# Module reference and module dict are in global variables which might still be needed
...
...
@@ -2557,8 +2796,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# At least clearing the module dict here might be a good idea, but could still break
# user code in atexit or other global registries.
##code.put_decref_clear(env.module_dict_cname, py_object_type, nanny=False)
code
.
putln
(
"#if !CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
putln
(
'}'
)
code
.
put_decref_clear
(
env
.
module_cname
,
py_object_type
,
nanny
=
False
,
clear_before_decref
=
True
)
code
.
putln
(
"#endif"
)
code
.
putln
(
'} else if (!PyErr_Occurred()) {'
)
code
.
putln
(
'PyErr_SetString(PyExc_ImportError, "init %s");'
%
env
.
qualified_name
.
as_c_string_literal
()[
1
:
-
1
])
...
...
@@ -2778,8 +3019,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
Options
.
pre_import
is
not
None
:
code
.
put_decref_clear
(
Naming
.
preimport_cname
,
py_object_type
,
nanny
=
False
,
clear_before_decref
=
True
)
for
cname
in
[
env
.
module_dict_cname
,
Naming
.
cython_runtime_cname
,
Naming
.
builtins_cname
]:
for
cname
in
[
Naming
.
cython_runtime_cname
,
Naming
.
builtins_cname
]:
code
.
put_decref_clear
(
cname
,
py_object_type
,
nanny
=
False
,
clear_before_decref
=
True
)
code
.
putln
(
"#if !CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
put_decref_clear
(
env
.
module_dict_cname
,
py_object_type
,
nanny
=
False
,
clear_before_decref
=
True
)
code
.
putln
(
"#endif"
)
def
generate_main_method
(
self
,
env
,
code
):
module_is_main
=
self
.
is_main_module_flag_cname
()
...
...
@@ -2837,12 +3081,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"#endif"
)
code
.
putln
(
""
)
code
.
putln
(
'#ifdef __cplusplus'
)
code
.
putln
(
'namespace {'
)
code
.
putln
(
"struct PyModuleDef %s = {"
%
Naming
.
pymoduledef_cname
)
code
.
putln
(
'#else'
)
code
.
putln
(
"static struct PyModuleDef %s = {"
%
Naming
.
pymoduledef_cname
)
code
.
putln
(
'#endif'
)
code
.
putln
(
" PyModuleDef_HEAD_INIT,"
)
code
.
putln
(
' %s,'
%
env
.
module_name
.
as_c_string_literal
())
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
(
" sizeof(%s), /* m_size */"
%
Naming
.
modulestate_cname
)
code
.
putln
(
"#else"
)
code
.
putln
(
" -1, /* m_size */"
)
code
.
putln
(
"#endif"
)
...
...
@@ -2852,10 +3103,19 @@ 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
(
" %s_traverse, /* m_traverse */"
%
Naming
.
module_cname
)
code
.
putln
(
" %s_clear, /* m_clear */"
%
Naming
.
module_cname
)
code
.
putln
(
" %s /* m_free */"
%
cleanup_func
)
code
.
putln
(
"#else"
)
code
.
putln
(
" NULL, /* m_traverse */"
)
code
.
putln
(
" NULL, /* m_clear */"
)
code
.
putln
(
" %s /* m_free */"
%
cleanup_func
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"};"
)
code
.
putln
(
'#ifdef __cplusplus'
)
code
.
putln
(
'} /* anonymous namespace */'
)
code
.
putln
(
'#endif'
)
code
.
putln
(
"#endif"
)
def
generate_module_creation_code
(
self
,
env
,
code
):
...
...
@@ -2880,7 +3140,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env
.
method_table_cname
,
doc
,
env
.
module_cname
))
code
.
putln
(
"#else"
)
code
.
putln
(
"#elif CYTHON_COMPILING_IN_LIMITED_API"
)
module_temp
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
manage_ref
=
True
)
code
.
putln
(
"%s = PyModule_Create(&%s); %s"
%
(
module_temp
,
Naming
.
pymoduledef_cname
,
code
.
error_goto_if_null
(
module_temp
,
self
.
pos
)))
code
.
put_gotref
(
module_temp
)
code
.
putln
(
code
.
error_goto_if_neg
(
"PyState_AddModule(%s, &%s)"
%
(
module_temp
,
Naming
.
pymoduledef_cname
),
self
.
pos
))
code
.
put_decref_clear
(
module_temp
,
type
=
py_object_type
)
code
.
funcstate
.
release_temp
(
module_temp
)
code
.
putln
(
'#else'
)
code
.
putln
(
"%s = PyModule_Create(&%s);"
%
(
env
.
module_cname
,
...
...
@@ -2889,11 +3161,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
code
.
error_goto_if_null
(
env
.
module_cname
,
self
.
pos
))
code
.
putln
(
"#endif"
)
# CYTHON_PEP489_MULTI_PHASE_INIT
code
.
putln
(
"#if !CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
putln
(
"%s = PyModule_GetDict(%s); %s"
%
(
env
.
module_dict_cname
,
env
.
module_cname
,
code
.
error_goto_if_null
(
env
.
module_dict_cname
,
self
.
pos
)))
code
.
put_incref
(
env
.
module_dict_cname
,
py_object_type
,
nanny
=
False
)
code
.
putln
(
"#endif"
)
code
.
putln
(
'%s = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); %s'
%
(
...
...
@@ -3148,6 +3422,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
""
)
# start in new line
code
.
putln
(
"#if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000"
)
code
.
putln
(
'sizeof(%s),'
%
objstruct
)
code
.
putln
(
"#elif CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
putln
(
'sizeof(%s),'
%
objstruct
)
code
.
putln
(
"#else"
)
code
.
putln
(
'sizeof(%s),'
%
sizeof_objstruct
)
code
.
putln
(
"#endif"
)
...
...
Cython/Compiler/Naming.py
View file @
84473513
...
...
@@ -96,6 +96,8 @@ clineno_cname = pyrex_prefix + "clineno"
cfilenm_cname
=
pyrex_prefix
+
"cfilenm"
local_tstate_cname
=
pyrex_prefix
+
"tstate"
module_cname
=
pyrex_prefix
+
"m"
modulestate_cname
=
pyrex_prefix
+
"mstate"
modulestateglobal_cname
=
pyrex_prefix
+
"mstate_global"
moddoc_cname
=
pyrex_prefix
+
"mdoc"
methtable_cname
=
pyrex_prefix
+
"methods"
retval_cname
=
pyrex_prefix
+
"r"
...
...
Cython/Compiler/Nodes.py
View file @
84473513
...
...
@@ -3715,10 +3715,17 @@ class DefNodeWrapper(FuncDefNode):
code
.
putln
(
'{'
)
all_args
=
tuple
(
positional_args
)
+
tuple
(
kw_only_args
)
non_posonly_args
=
[
arg
for
arg
in
all_args
if
not
arg
.
pos_only
]
non_pos_args_id
=
','
.
join
(
[
'&%s'
%
code
.
intern_identifier
(
arg
.
name
)
for
arg
in
non_posonly_args
]
+
[
'0'
])
code
.
putln
(
"#if CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
putln
(
"PyObject **%s[] = {%s};"
%
(
Naming
.
pykwdlist_cname
,
non_pos_args_id
))
code
.
putln
(
"#else"
)
code
.
putln
(
"static PyObject **%s[] = {%s};"
%
(
Naming
.
pykwdlist_cname
,
','
.
join
([
'&%s'
%
code
.
intern_identifier
(
arg
.
name
)
for
arg
in
non_posonly_args
]
+
[
'0'
]))
)
non_pos_args_id
)
)
code
.
putln
(
"#endif"
)
# Before being converted and assigned to the target variables,
# borrowed references to all unpacked argument values are
...
...
@@ -5070,6 +5077,13 @@ class CClassDefNode(ClassDefNode):
if
not
scope
:
# could be None if there was an error
return
if
entry
.
visibility
!=
'extern'
:
code
.
putln
(
"#if CYTHON_COMPILING_IN_LIMITED_API"
)
code
.
putln
(
"%s = PyType_FromSpec(&%s_spec); %s"
%
(
typeobj_cname
,
typeobj_cname
,
code
.
error_goto_if_null
(
typeobj_cname
,
entry
.
pos
)))
code
.
putln
(
"#else"
)
for
slot
in
TypeSlots
.
slot_table
:
slot
.
generate_dynamic_init_code
(
scope
,
code
)
if
heap_type_bases
:
...
...
@@ -5108,6 +5122,7 @@ class CClassDefNode(ClassDefNode):
code
.
putln
(
"%s.tp_getattro = %s;"
%
(
typeobj_cname
,
py_cfunc
))
code
.
putln
(
"}"
)
code
.
putln
(
"#endif"
)
# Fix special method docstrings. This is a bit of a hack, but
# unless we let PyType_Ready create the slot wrappers we have
...
...
@@ -5145,11 +5160,19 @@ class CClassDefNode(ClassDefNode):
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
.
putln
(
"#endif"
)
if
heap_type_bases
:
code
.
globalstate
.
use_utility_code
(
UtilityCode
.
load_cached
(
'MergeVTables'
,
'ImportExport.c'
))
...
...
@@ -5160,12 +5183,21 @@ class CClassDefNode(ClassDefNode):
# 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"
)
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
:
...
...
@@ -5187,15 +5219,19 @@ class CClassDefNode(ClassDefNode):
# 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
(
"#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 = &%s;"
%
(
type
.
typeptr_cname
,
type
.
typeobj_cname
))
code
.
putln
(
"#endif"
)
def
annotate
(
self
,
code
):
if
self
.
type_init_args
:
...
...
Cython/Compiler/PyrexTypes.py
View file @
84473513
...
...
@@ -1310,7 +1310,7 @@ class BuiltinObjectType(PyObjectType):
name
=
'"%s"'
%
self
.
name
# avoid wasting too much space but limit number of different format strings
space_for_name
=
(
len
(
self
.
name
)
//
16
+
1
)
*
16
error
=
'(PyErr_Format(PyExc_TypeError, "Expected %%.%ds, got %%.200s", %s,
Py_TYPE(%s)->tp_name
), 0)'
%
(
error
=
'(PyErr_Format(PyExc_TypeError, "Expected %%.%ds, got %%.200s", %s,
__Pyx_PyType_Name(Py_TYPE(%s))
), 0)'
%
(
space_for_name
,
name
,
arg
)
return
check
+
'||'
+
error
...
...
Cython/Compiler/TypeSlots.py
View file @
84473513
...
...
@@ -242,7 +242,15 @@ class SlotDescriptor(object):
guard
=
(
"#if PY_MAJOR_VERSION >= 3"
)
return
guard
def
generate
(
self
,
scope
,
code
):
def
spec_slot_value
(
self
,
scope
):
if
self
.
is_initialised_dynamically
:
return
None
result
=
self
.
slot_code
(
scope
)
if
result
==
"0"
:
return
None
return
result
def
generate
(
self
,
scope
,
code
,
spec
=
False
):
preprocessor_guard
=
self
.
preprocessor_guard_code
()
if
preprocessor_guard
:
code
.
putln
(
preprocessor_guard
)
...
...
@@ -271,6 +279,10 @@ class SlotDescriptor(object):
code
.
putln
(
"#else"
)
end_pypy_guard
=
True
if
spec
:
if
value
!=
"0"
:
code
.
putln
(
"{Py_%s, (void *)%s},"
%
(
self
.
slot_name
,
value
))
else
:
code
.
putln
(
"%s, /*%s*/"
%
(
value
,
self
.
slot_name
))
if
end_pypy_guard
:
...
...
@@ -555,6 +567,11 @@ class SuiteSlot(SlotDescriptor):
if
self
.
ifdef
:
code
.
putln
(
"#endif"
)
def
generate_substructure_spec
(
self
,
scope
,
code
):
if
not
self
.
is_empty
(
scope
):
for
slot
in
self
.
sub_slots
:
slot
.
generate
(
scope
,
code
,
spec
=
True
)
substructures
=
[]
# List of all SuiteSlot instances
class
MethodTableSlot
(
SlotDescriptor
):
...
...
Cython/Utility/Exceptions.c
View file @
84473513
...
...
@@ -284,7 +284,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
PyErr_SetObject
(
type
,
value
);
if
(
tb
)
{
#if CYTHON_COMPILING_IN_PYPY
#if CYTHON_COMPILING_IN_PYPY
|| CYTHON_COMPILING_IN_LIMITED_API
PyObject
*
tmp_type
,
*
tmp_value
,
*
tmp_tb
;
PyErr_Fetch
(
&
tmp_type
,
&
tmp_value
,
&
tmp_tb
);
Py_INCREF
(
tb
);
...
...
@@ -705,6 +705,15 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
#include "frameobject.h"
#include "traceback.h"
#if CYTHON_COMPILING_IN_LIMITED_API
static
void
__Pyx_AddTraceback
(
const
char
*
funcname
,
int
c_line
,
int
py_line
,
const
char
*
filename
)
{
if
(
c_line
)
{
c_line
=
__Pyx_CLineForTraceback
(
__Pyx_PyThreadState_Current
,
c_line
);
}
_PyTraceback_Add
(
funcname
,
filename
,
c_line
?
-
c_line
:
py_line
);
}
#else
static
PyCodeObject
*
__Pyx_CreateCodeObjectForTraceback
(
const
char
*
funcname
,
int
c_line
,
int
py_line
,
const
char
*
filename
)
{
...
...
@@ -791,3 +800,4 @@ bad:
Py_XDECREF
(
py_code
);
Py_XDECREF
(
py_frame
);
}
#endif
Cython/Utility/ExtensionTypes.c
View file @
84473513
...
...
@@ -172,13 +172,16 @@ static void __Pyx_call_next_tp_clear(PyObject* obj, inquiry current_tp_clear) {
/////////////// SetupReduce.proto ///////////////
#if !CYTHON_COMPILING_IN_LIMITED_API
static
int
__Pyx_setup_reduce
(
PyObject
*
type_obj
);
#endif
/////////////// SetupReduce ///////////////
//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
//@requires: ObjectHandling.c::PyObjectGetAttrStr
//@substitute: naming
#if !CYTHON_COMPILING_IN_LIMITED_API
static
int
__Pyx_setup_reduce_is_named
(
PyObject
*
meth
,
PyObject
*
name
)
{
int
ret
;
PyObject
*
name_attr
;
...
...
@@ -250,7 +253,7 @@ static int __Pyx_setup_reduce(PyObject* type_obj) {
BAD:
if
(
!
PyErr_Occurred
())
PyErr_Format
(
PyExc_RuntimeError
,
"Unable to initialize pickling for %s"
,
((
PyTypeObject
*
)
type_obj
)
->
tp_name
);
PyErr_Format
(
PyExc_RuntimeError
,
"Unable to initialize pickling for %s"
,
__Pyx_PyType_Name
(
type_obj
)
);
ret
=
-
1
;
GOOD:
#if !CYTHON_USE_PYTYPE_LOOKUP
...
...
@@ -264,3 +267,4 @@ GOOD:
Py_XDECREF
(
setstate_cython
);
return
ret
;
}
#endif
Cython/Utility/ImportExport.c
View file @
84473513
...
...
@@ -182,8 +182,13 @@ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
if
(
level
==
-
1
)
{
if
(
strchr
(
__Pyx_MODULE_NAME
,
'.'
))
{
/* try package relative import first */
#if CYTHON_COMPILING_IN_LIMITED_API
module
=
PyImport_ImportModuleLevelObject
(
name
,
empty_dict
,
empty_dict
,
from_list
,
1
);
#else
module
=
PyImport_ImportModuleLevelObject
(
name
,
$
moddict_cname
,
empty_dict
,
from_list
,
1
);
#endif
if
(
unlikely
(
!
module
))
{
if
(
unlikely
(
!
PyErr_ExceptionMatches
(
PyExc_ImportError
)))
goto
bad
;
...
...
@@ -202,9 +207,14 @@ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
name
,
$
moddict_cname
,
empty_dict
,
from_list
,
py_level
,
(
PyObject
*
)
NULL
);
Py_DECREF
(
py_level
);
#else
#if CYTHON_COMPILING_IN_LIMITED_API
module
=
PyImport_ImportModuleLevelObject
(
name
,
empty_dict
,
empty_dict
,
from_list
,
level
);
#else
module
=
PyImport_ImportModuleLevelObject
(
name
,
$
moddict_cname
,
empty_dict
,
from_list
,
level
);
#endif
#endif
}
}
bad:
...
...
@@ -686,11 +696,19 @@ static int __Pyx_SetVtable(PyObject *dict, 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
PyObject
*
ob
=
PyCapsule_New
(
vtable
,
0
,
0
);
if
(
!
ob
)
goto
bad
;
#if CYTHON_COMPILING_IN_LIMITED_API
if
(
PyObject_SetAttr
(
type
,
PYIDENT
(
"__pyx_vtable__"
),
ob
)
<
0
)
#else
if
(
PyDict_SetItem
(
dict
,
PYIDENT
(
"__pyx_vtable__"
),
ob
)
<
0
)
#endif
goto
bad
;
Py_DECREF
(
ob
);
return
0
;
...
...
Cython/Utility/ModuleSetupCode.c
View file @
84473513
...
...
@@ -44,6 +44,7 @@
#define CYTHON_COMPILING_IN_PYPY 1
#define CYTHON_COMPILING_IN_PYSTON 0
#define CYTHON_COMPILING_IN_CPYTHON 0
#define CYTHON_COMPILING_IN_LIMITED_API 0
#undef CYTHON_USE_TYPE_SLOTS
#define CYTHON_USE_TYPE_SLOTS 0
...
...
@@ -90,6 +91,7 @@
#define CYTHON_COMPILING_IN_PYPY 0
#define CYTHON_COMPILING_IN_PYSTON 1
#define CYTHON_COMPILING_IN_CPYTHON 0
#define CYTHON_COMPILING_IN_LIMITED_API 0
#ifndef CYTHON_USE_TYPE_SLOTS
#define CYTHON_USE_TYPE_SLOTS 1
...
...
@@ -133,10 +135,53 @@
#undef CYTHON_USE_EXC_INFO_STACK
#define CYTHON_USE_EXC_INFO_STACK 0
#elif defined(CYTHON_LIMITED_API)
#define CYTHON_COMPILING_IN_PYPY 0
#define CYTHON_COMPILING_IN_PYSTON 0
#define CYTHON_COMPILING_IN_CPYTHON 0
#define CYTHON_COMPILING_IN_LIMITED_API 1
#undef CYTHON_USE_TYPE_SLOTS
#define CYTHON_USE_TYPE_SLOTS 0
#undef CYTHON_USE_PYTYPE_LOOKUP
#define CYTHON_USE_PYTYPE_LOOKUP 0
#undef CYTHON_USE_PYLIST_INTERNALS
#define CYTHON_USE_ASYNC_SLOTS 0
#define CYTHON_USE_PYLIST_INTERNALS 0
#undef CYTHON_USE_UNICODE_INTERNALS
#define CYTHON_USE_UNICODE_INTERNALS 0
#undef CYTHON_USE_UNICODE_WRITER
#define CYTHON_USE_UNICODE_WRITER 1
#undef CYTHON_USE_PYLONG_INTERNALS
#define CYTHON_USE_PYLONG_INTERNALS 0
#undef CYTHON_AVOID_BORROWED_REFS
#define CYTHON_AVOID_BORROWED_REFS 0
#undef CYTHON_ASSUME_SAFE_MACROS
#define CYTHON_ASSUME_SAFE_MACROS 0
#undef CYTHON_UNPACK_METHODS
#define CYTHON_UNPACK_METHODS 0
#undef CYTHON_FAST_THREAD_STATE
#define CYTHON_FAST_THREAD_STATE 0
#undef CYTHON_FAST_GIL
#define CYTHON_FAST_GIL 0
#undef CYTHON_METH_FASTCALL
#define CYTHON_METH_FASTCALL 0
#undef CYTHON_FAST_PYCALL
#define CYTHON_FAST_PYCALL 0
#undef CYTHON_PEP489_MULTI_PHASE_INIT
#define CYTHON_PEP489_MULTI_PHASE_INIT 0
#undef CYTHON_USE_TP_FINALIZE
#define CYTHON_USE_TP_FINALIZE 1
#undef CYTHON_USE_DICT_VERSIONS
#define CYTHON_USE_DICT_VERSIONS 0
#undef CYTHON_USE_EXC_INFO_STACK
#define CYTHON_USE_EXC_INFO_STACK 0
#else
#define CYTHON_COMPILING_IN_PYPY 0
#define CYTHON_COMPILING_IN_PYSTON 0
#define CYTHON_COMPILING_IN_CPYTHON 1
#define CYTHON_COMPILING_IN_LIMITED_API 0
#ifndef CYTHON_USE_TYPE_SLOTS
#define CYTHON_USE_TYPE_SLOTS 1
...
...
@@ -495,12 +540,17 @@ class __Pyx_FakeReference {
// special C-API functions only in Pyston
#define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co)
#define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno)
#elif CYTHON_COMPILING_IN_LIMITED_API
#define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0)
#define __Pyx_PyFrame_SetLineNumber(frame, lineno)
#else
#define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0)
#define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno)
#endif
#if !CYTHON_FAST_THREAD_STATE
#if CYTHON_COMPILING_IN_LIMITED_API
#define __Pyx_PyThreadState_Current PyThreadState_Get()
#elif !CYTHON_FAST_THREAD_STATE
#define __Pyx_PyThreadState_Current PyThreadState_GET()
#elif PY_VERSION_HEX >= 0x03060000
//#elif PY_VERSION_HEX >= 0x03050200
...
...
@@ -512,6 +562,18 @@ class __Pyx_FakeReference {
#define __Pyx_PyThreadState_Current _PyThreadState_Current
#endif
#if CYTHON_COMPILING_IN_LIMITED_API
static
inline
void
*
__Pyx_PyModule_GetState
(
PyObject
*
op
)
{
void
*
result
;
result
=
PyModule_GetState
(
op
);
if
(
!
result
)
Py_FatalError
(
"Couldn't find the module state"
);
return
result
;
}
#endif
// TSS (Thread Specific Storage) API
#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT)
#include "pythread.h"
...
...
@@ -582,8 +644,39 @@ static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict,
#define __Pyx_PyDict_GetItemStr PyDict_GetItem
#endif
/* new Py3.3 unicode type (PEP 393) */
#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
/* Type slots */
#if CYTHON_COMPILING_IN_LIMITED_API
#if defined(_PyType_Name)
#define __Pyx_PyType_Name(tp) (_PyType_Name((PyTypeObject *)tp))
#else
#define __Pyx_PyType_Name(tp) (((PyTypeObject *)tp)->tp_name)
#endif
#define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp))
#else
#define __Pyx_PyType_Name(tp) (((PyTypeObject *)tp)->tp_name)
#define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags)
#endif
#if CYTHON_COMPILING_IN_LIMITED_API
#if !defined(PyUnicode_GET_SIZE)
#define PyUnicode_GET_SIZE(u) PyUnicode_GetSize(u)
#endif
#define CYTHON_PEP393_ENABLED 1
#define PyUnicode_1BYTE_KIND 1
#define PyUnicode_2BYTE_KIND 2
#define PyUnicode_4BYTE_KIND 4
#define __Pyx_PyUnicode_READY(op) (0)
#define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GetSize(u)
#define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AsUnicode(u)[i]))
#define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(wchar_t) == 2) ? 65535 : 1114111)
#define __Pyx_PyUnicode_KIND(u) (sizeof(wchar_t))
#define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AsUnicode(u))
/* (void)(k) => avoid unused variable warning due to macro: */
#define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((wchar_t*)d)[i]))
#define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((wchar_t*)d)[i] = ch)
#define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetSize(u))
#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
/* new Py3.3 unicode type (PEP 393) */
#define CYTHON_PEP393_ENABLED 1
#define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
0 : _PyUnicode_Ready((PyObject *)(op)))
...
...
@@ -987,12 +1080,20 @@ static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) {
return
0
;
}
#if CYTHON_COMPILING_IN_LIMITED_API
static
CYTHON_SMALL_CODE
int
__Pyx_copy_spec_to_module
(
PyObject
*
spec
,
PyObject
*
module
,
const
char
*
from_name
,
const
char
*
to_name
,
int
allow_none
)
{
#else
static
CYTHON_SMALL_CODE
int
__Pyx_copy_spec_to_module
(
PyObject
*
spec
,
PyObject
*
moddict
,
const
char
*
from_name
,
const
char
*
to_name
,
int
allow_none
)
{
#endif
PyObject
*
value
=
PyObject_GetAttrString
(
spec
,
from_name
);
int
result
=
0
;
if
(
likely
(
value
))
{
if
(
allow_none
||
value
!=
Py_None
)
{
#if CYTHON_COMPILING_IN_LIMITED_API
result
=
PyModule_AddObject
(
module
,
to_name
,
value
);
#else
result
=
PyDict_SetItemString
(
moddict
,
to_name
,
value
);
#endif
}
Py_DECREF
(
value
);
}
else
if
(
PyErr_ExceptionMatches
(
PyExc_AttributeError
))
{
...
...
@@ -1019,9 +1120,13 @@ static CYTHON_SMALL_CODE PyObject* ${pymodule_create_func_cname}(PyObject *spec,
Py_DECREF
(
modname
);
if
(
unlikely
(
!
module
))
goto
bad
;
#if CYTHON_COMPILING_IN_LIMITED_API
moddict
=
module
;
#else
moddict
=
PyModule_GetDict
(
module
);
if
(
unlikely
(
!
moddict
))
goto
bad
;
// moddict is a borrowed reference
#endif
if
(
unlikely
(
__Pyx_copy_spec_to_module
(
spec
,
moddict
,
"loader"
,
"__loader__"
,
1
)
<
0
))
goto
bad
;
if
(
unlikely
(
__Pyx_copy_spec_to_module
(
spec
,
moddict
,
"origin"
,
"__file__"
,
1
)
<
0
))
goto
bad
;
...
...
@@ -1038,6 +1143,7 @@ bad:
/////////////// CodeObjectCache.proto ///////////////
#if !CYTHON_COMPILING_IN_LIMITED_API
typedef
struct
{
PyCodeObject
*
code_object
;
int
code_line
;
...
...
@@ -1054,11 +1160,13 @@ static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
static
int
__pyx_bisect_code_objects
(
__Pyx_CodeObjectCacheEntry
*
entries
,
int
count
,
int
code_line
);
static
PyCodeObject
*
__pyx_find_code_object
(
int
code_line
);
static
void
__pyx_insert_code_object
(
int
code_line
,
PyCodeObject
*
code_object
);
#endif
/////////////// CodeObjectCache ///////////////
// Note that errors are simply ignored in the code below.
// This is just a cache, if a lookup or insertion fails - so what?
#if !CYTHON_COMPILING_IN_LIMITED_API
static
int
__pyx_bisect_code_objects
(
__Pyx_CodeObjectCacheEntry
*
entries
,
int
count
,
int
code_line
)
{
int
start
=
0
,
mid
=
0
,
end
=
count
-
1
;
if
(
end
>=
0
&&
code_line
>
entries
[
end
].
code_line
)
{
...
...
@@ -1139,9 +1247,11 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
__pyx_code_cache
.
count
++
;
Py_INCREF
(
code_object
);
}
#endif
/////////////// CodeObjectCache.cleanup ///////////////
#if !CYTHON_COMPILING_IN_LIMITED_API
if
(
__pyx_code_cache
.
entries
)
{
__Pyx_CodeObjectCacheEntry
*
entries
=
__pyx_code_cache
.
entries
;
int
i
,
count
=
__pyx_code_cache
.
count
;
...
...
@@ -1153,6 +1263,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
}
PyMem_Free
(
entries
);
}
#endif
/////////////// CheckBinaryVersion.proto ///////////////
...
...
Cython/Utility/ObjectHandling.c
View file @
84473513
...
...
@@ -1289,6 +1289,14 @@ static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name)
}
else
if
(
unlikely
(
PyErr_Occurred
()))
{
return
NULL
;
}
#elif CYTHON_COMPILING_IN_LIMITED_API
if
(
unlikely
(
!
$
module_cname
))
{
return
NULL
;
}
result
=
PyObject_GetItem
(
$
module_cname
,
name
);
if
(
likely
(
result
))
{
return
result
;
}
#else
result
=
PyDict_GetItem
(
$
moddict_cname
,
name
);
__PYX_UPDATE_DICT_CACHE
(
$
moddict_cname
,
result
,
*
dict_cached_value
,
*
dict_version
)
...
...
Cython/Utility/Optimize.c
View file @
84473513
...
...
@@ -776,7 +776,11 @@ static CYTHON_INLINE {{c_ret_type}} __Pyx_PyInt_{{'' if ret_type.is_pyobject els
if
(
PyFloat_CheckExact
({{
pyval
}}))
{
const
long
{{
'a'
if
order
==
'
CObj
'
else
'b'
}}
=
intval
;
#if CYTHON_COMPILING_IN_LIMITED_API
double
{{
ival
}}
=
__pyx_PyFloat_AsDouble
({{
pyval
}});
#else
double
{{
ival
}}
=
PyFloat_AS_DOUBLE
({{
pyval
}});
#endif
{{
return_compare
(
'
(
double
)
a
'
,
'
(
double
)
b
'
,
c_op
)}}
}
...
...
@@ -1064,7 +1068,11 @@ static {{c_ret_type}} {{cfunc_name}}(PyObject *op1, PyObject *op2, CYTHON_UNUSED
{{
if
c_op
in
'
+-*
'
or
op
in
(
'
TrueDivide
'
,
'
Eq
'
,
'
Ne
'
)}}
if
(
PyFloat_CheckExact
({{
pyval
}}))
{
const
long
{{
'a'
if
order
==
'
CObj
'
else
'b'
}}
=
intval
;
#if CYTHON_COMPILING_IN_LIMITED_API
double
{{
ival
}}
=
__pyx_PyFloat_AsDouble
({{
pyval
}});
#else
double
{{
ival
}}
=
PyFloat_AS_DOUBLE
({{
pyval
}});
#endif
{{
if
op
in
(
'
Eq
'
,
'
Ne
'
)}}
if
((
double
)
a
{{
c_op
}}
(
double
)
b
)
{
{{
return_true
}};
...
...
@@ -1143,7 +1151,11 @@ static {{c_ret_type}} {{cfunc_name}}(PyObject *op1, PyObject *op2, double floatv
{{
endif
}}
if
(
likely
(
PyFloat_CheckExact
({{
pyval
}})))
{
#if CYTHON_COMPILING_IN_LIMITED_API
{{
fval
}}
=
__pyx_PyFloat_AsDouble
({{
pyval
}});
#else
{{
fval
}}
=
PyFloat_AS_DOUBLE
({{
pyval
}});
#endif
{{
zerodiv_check
(
fval
)}}
}
else
...
...
Cython/Utility/StringTools.c
View file @
84473513
...
...
@@ -43,13 +43,42 @@ static CYTHON_INLINE Py_ssize_t __Pyx_Py_UNICODE_ssize_strlen(const Py_UNICODE *
//////////////////// InitStrings.proto ////////////////////
#if CYTHON_COMPILING_IN_LIMITED_API
static
int
__Pyx_InitString
(
__Pyx_StringTabEntry
t
,
PyObject
**
str
);
/*proto*/
#else
static
int
__Pyx_InitStrings
(
__Pyx_StringTabEntry
*
t
);
/*proto*/
#endif
//////////////////// InitStrings ////////////////////
#if PY_MAJOR_VERSION >= 3
static
int
__Pyx_InitString
(
__Pyx_StringTabEntry
t
,
PyObject
**
str
)
{
if
(
t
.
is_unicode
|
t
.
is_str
)
{
if
(
t
.
intern
)
{
*
str
=
PyUnicode_InternFromString
(
t
.
s
);
}
else
if
(
t
.
encoding
)
{
*
str
=
PyUnicode_Decode
(
t
.
s
,
t
.
n
-
1
,
t
.
encoding
,
NULL
);
}
else
{
*
str
=
PyUnicode_FromStringAndSize
(
t
.
s
,
t
.
n
-
1
);
}
}
else
{
*
str
=
PyBytes_FromStringAndSize
(
t
.
s
,
t
.
n
-
1
);
}
if
(
!*
str
)
return
-
1
;
// initialise cached hash value
if
(
PyObject_Hash
(
*
str
)
==
-
1
)
return
-
1
;
return
0
;
}
#endif
#if !CYTHON_COMPILING_IN_LIMITED_API
static
int
__Pyx_InitStrings
(
__Pyx_StringTabEntry
*
t
)
{
while
(
t
->
p
)
{
#if PY_MAJOR_VERSION < 3
#if PY_MAJOR_VERSION >= 3
/* Python 3+ has unicode identifiers */
__Pyx_InitString
(
*
t
,
t
->
p
);
#else
if
(
t
->
is_unicode
)
{
*
t
->
p
=
PyUnicode_DecodeUTF8
(
t
->
s
,
t
->
n
-
1
,
NULL
);
}
else
if
(
t
->
intern
)
{
...
...
@@ -57,28 +86,17 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
}
else
{
*
t
->
p
=
PyString_FromStringAndSize
(
t
->
s
,
t
->
n
-
1
);
}
#else
/* Python 3+ has unicode identifiers */
if
(
t
->
is_unicode
|
t
->
is_str
)
{
if
(
t
->
intern
)
{
*
t
->
p
=
PyUnicode_InternFromString
(
t
->
s
);
}
else
if
(
t
->
encoding
)
{
*
t
->
p
=
PyUnicode_Decode
(
t
->
s
,
t
->
n
-
1
,
t
->
encoding
,
NULL
);
}
else
{
*
t
->
p
=
PyUnicode_FromStringAndSize
(
t
->
s
,
t
->
n
-
1
);
}
}
else
{
*
t
->
p
=
PyBytes_FromStringAndSize
(
t
->
s
,
t
->
n
-
1
);
}
#endif
if
(
!*
t
->
p
)
return
-
1
;
// initialise cached hash value
if
(
PyObject_Hash
(
*
t
->
p
)
==
-
1
)
return
-
1
;
#endif
++
t
;
}
return
0
;
}
#endif
//////////////////// BytesContains.proto ////////////////////
...
...
@@ -189,7 +207,7 @@ static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int
//@requires: BytesEquals
static
CYTHON_INLINE
int
__Pyx_PyUnicode_Equals
(
PyObject
*
s1
,
PyObject
*
s2
,
int
equals
)
{
#if CYTHON_COMPILING_IN_PYPY
#if CYTHON_COMPILING_IN_PYPY
|| CYTHON_COMPILING_IN_LIMITED_API
return
PyObject_RichCompareBool
(
s1
,
s2
,
equals
);
#else
#if PY_MAJOR_VERSION < 3
...
...
@@ -300,7 +318,7 @@ static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int eq
//@requires: IncludeStringH
static
CYTHON_INLINE
int
__Pyx_PyBytes_Equals
(
PyObject
*
s1
,
PyObject
*
s2
,
int
equals
)
{
#if CYTHON_COMPILING_IN_PYPY
#if CYTHON_COMPILING_IN_PYPY
|| CYTHON_COMPILING_IN_LIMITED_API
return
PyObject_RichCompareBool
(
s1
,
s2
,
equals
);
#else
if
(
s1
==
s2
)
{
...
...
Cython/Utility/TypeConversion.c
View file @
84473513
...
...
@@ -80,11 +80,21 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s)
// There used to be a Py_UNICODE_strlen() in CPython 3.x, but it is deprecated since Py3.3.
static
CYTHON_INLINE
size_t
__Pyx_Py_UNICODE_strlen
(
const
Py_UNICODE
*
u
)
{
#if CYTHON_COMPILING_IN_LIMITED_API
static
CYTHON_INLINE
size_t
__Pyx_Py_UNICODE_strlen
(
const
wchar_t
*
u
)
{
const
wchar_t
*
u_end
=
u
;
while
(
*
u_end
++
)
;
return
(
size_t
)(
u_end
-
u
-
1
);
}
#else
static
CYTHON_INLINE
size_t
__Pyx_Py_UNICODE_strlen
(
const
Py_UNICODE
*
u
)
{
const
Py_UNICODE
*
u_end
=
u
;
while
(
*
u_end
++
)
;
return
(
size_t
)(
u_end
-
u
-
1
);
}
#endif
#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
...
...
@@ -271,7 +281,7 @@ static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_
}
else
#endif
/* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT */
#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE))
#if (!CYTHON_COMPILING_IN_PYPY
&& !CYTHON_COMPILING_IN_LIMITED_API
) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE))
if
(
PyByteArray_Check
(
o
))
{
*
length
=
PyByteArray_GET_SIZE
(
o
);
return
PyByteArray_AS_STRING
(
o
);
...
...
@@ -311,7 +321,7 @@ static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const
"__int__ returned non-int (type %.200s). "
"The ability to return an instance of a strict subclass of int "
"is deprecated, and may be removed in a future version of Python."
,
Py_TYPE
(
result
)
->
tp_name
))
{
__Pyx_PyType_Name
(
Py_TYPE
(
result
))
))
{
Py_DECREF
(
result
);
return
NULL
;
}
...
...
@@ -320,7 +330,7 @@ static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const
#endif
PyErr_Format
(
PyExc_TypeError
,
"__%.4s__ returned non-%.4s (type %.200s)"
,
type_name
,
type_name
,
Py_TYPE
(
result
)
->
tp_name
);
type_name
,
type_name
,
__Pyx_PyType_Name
(
Py_TYPE
(
result
))
);
Py_DECREF
(
result
);
return
NULL
;
}
...
...
@@ -947,9 +957,9 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) {
}
}
{
#if
CYTHON_COMPILING_IN_PYPY
&& !defined(_PyLong_AsByteArray)
#if
(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API)
&& !defined(_PyLong_AsByteArray)
PyErr_SetString
(
PyExc_RuntimeError
,
"_PyLong_AsByteArray() not available
in PyPy
, cannot convert large numbers"
);
"_PyLong_AsByteArray() not available, cannot convert large numbers"
);
#else
{{
TYPE
}}
val
;
PyObject
*
v
=
__Pyx_PyNumber_IntOrLong
(
x
);
...
...
runtests.py
View file @
84473513
...
...
@@ -2149,6 +2149,8 @@ def main():
help="specify Pythran include directory. This will run the C++ tests using Pythran backend for Numpy")
parser.add_option("--no-capture", dest="capture", default=True, action="store_false",
help="do not capture stdout, stderr in srctree tests. Makes pdb.set_trace interactive")
parser.add_option("--limited-api", dest="limited_api", default=False, action="store_true",
help="Compiles Cython using CPython's LIMITED_API")
options, cmd_args = parser.parse_args(args)
...
...
@@ -2368,6 +2370,10 @@ def runtests(options, cmd_args, coverage=None):
sys.path.insert(0, os.path.split(libpath)[0])
CFLAGS.append("-DCYTHON_REFNANNY=1")
if options.limited_api:
CFLAGS.append("-DCYTHON_LIMITED_API=1")
if xml_output_dir and options.fork:
# doesn't currently work together
sys.stderr.write("Disabling forked testing to support XML test output
\
n
")
...
...
@@ -2426,6 +2432,7 @@ def runtests(options, cmd_args, coverage=None):
bug_files = [
('bugs.txt', True),
('pypy_bugs.txt', IS_PYPY),
('limited_api_bugs.txt', options.limited_api),
('windows_bugs.txt', sys.platform == 'win32'),
('cygwin_bugs.txt', sys.platform == 'cygwin')
]
...
...
tests/limited_api_bugs.txt
0 → 100644
View file @
84473513
# This file contains tests corresponding to unresolved bugs using CPython's
# Limited API which will be skipped in the normal testing run.
calc_pi_2
calc_pi_3
calc_pi_4
clone
convolve2
cpdef_sin
dict_animal
integrate
landscaping
mymodule
not_none
overhead
profile
profile_2
queue3
resize
safe_usage
shrubbery_2
sin_of_square
test_queue
unsafe_usage
wave_function
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment