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
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Xavier Thompson
cython
Commits
29067ceb
Commit
29067ceb
authored
Jul 05, 2017
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Avoid generating utility code unless it's actually used.
This should resolve #1757.
parent
074c49b1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
81 additions
and
8 deletions
+81
-8
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+7
-2
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+74
-6
No files found.
Cython/Compiler/ParseTreeTransforms.py
View file @
29067ceb
...
@@ -1623,8 +1623,9 @@ if VALUE is not None:
...
@@ -1623,8 +1623,9 @@ if VALUE is not None:
non_py
=
[
non_py
=
[
e
for
e
in
all_members
e
for
e
in
all_members
if
not
e
.
type
.
is_pyobject
and
(
not
e
.
type
.
create_from_py_utility_code
(
env
)
if
not
e
.
type
.
is_pyobject
and
(
not
e
.
type
.
can_coerce_to_pyobject
(
env
)
or
not
e
.
type
.
create_to_py_utility_code
(
env
))]
or
not
e
.
type
.
can_coerce_from_pyobject
(
env
))
]
if
cinit
or
non_py
:
if
cinit
or
non_py
:
if
cinit
:
if
cinit
:
...
@@ -1646,6 +1647,10 @@ if VALUE is not None:
...
@@ -1646,6 +1647,10 @@ if VALUE is not None:
node
.
body
.
stats
.
append
(
pickle_func
)
node
.
body
.
stats
.
append
(
pickle_func
)
else
:
else
:
for
e
in
all_members
:
if
not
e
.
type
.
is_pyobject
:
e
.
type
.
create_to_py_utility_code
(
env
)
e
.
type
.
create_from_py_utility_code
(
env
)
all_members_names
=
sorted
([
e
.
name
for
e
in
all_members
])
all_members_names
=
sorted
([
e
.
name
for
e
in
all_members
])
checksum
=
'0x%s'
%
hashlib
.
md5
(
' '
.
join
(
all_members_names
).
encode
(
'utf-8'
)).
hexdigest
()[:
7
]
checksum
=
'0x%s'
%
hashlib
.
md5
(
' '
.
join
(
all_members_names
).
encode
(
'utf-8'
)).
hexdigest
()[:
7
]
unpickle_func_name
=
'__pyx_unpickle_%s'
%
node
.
class_name
unpickle_func_name
=
'__pyx_unpickle_%s'
%
node
.
class_name
...
...
Cython/Compiler/PyrexTypes.py
View file @
29067ceb
...
@@ -34,6 +34,9 @@ class BaseType(object):
...
@@ -34,6 +34,9 @@ class BaseType(object):
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
False
return
False
def
can_coerce_from_pyobject
(
self
,
env
):
return
False
def
can_coerce_to_pystring
(
self
,
env
,
format_spec
=
None
):
def
can_coerce_to_pystring
(
self
,
env
,
format_spec
=
None
):
return
False
return
False
...
@@ -535,6 +538,9 @@ class CTypedefType(BaseType):
...
@@ -535,6 +538,9 @@ class CTypedefType(BaseType):
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
self
.
typedef_base_type
.
can_coerce_to_pyobject
(
env
)
return
self
.
typedef_base_type
.
can_coerce_to_pyobject
(
env
)
def
can_coerce_from_pyobject
(
self
,
env
):
return
self
.
typedef_base_type
.
can_coerce_from_pyobject
(
env
)
class
MemoryViewSliceType
(
PyrexType
):
class
MemoryViewSliceType
(
PyrexType
):
...
@@ -835,6 +841,9 @@ class MemoryViewSliceType(PyrexType):
...
@@ -835,6 +841,9 @@ class MemoryViewSliceType(PyrexType):
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
True
return
True
def
can_coerce_from_pyobject
(
self
,
env
):
return
True
def
check_for_null_code
(
self
,
cname
):
def
check_for_null_code
(
self
,
cname
):
return
cname
+
'.memview'
return
cname
+
'.memview'
...
@@ -1017,6 +1026,9 @@ class BufferType(BaseType):
...
@@ -1017,6 +1026,9 @@ class BufferType(BaseType):
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
True
return
True
def
can_coerce_from_pyobject
(
self
,
env
):
return
True
def
as_argument_type
(
self
):
def
as_argument_type
(
self
):
return
self
return
self
...
@@ -1088,6 +1100,9 @@ class PyObjectType(PyrexType):
...
@@ -1088,6 +1100,9 @@ class PyObjectType(PyrexType):
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
True
return
True
def
can_coerce_from_pyobject
(
self
,
env
):
return
True
def
default_coerced_ctype
(
self
):
def
default_coerced_ctype
(
self
):
"""The default C type that this Python type coerces to, or None."""
"""The default C type that this Python type coerces to, or None."""
return
None
return
None
...
@@ -1420,6 +1435,9 @@ class CType(PyrexType):
...
@@ -1420,6 +1435,9 @@ class CType(PyrexType):
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
self
.
create_to_py_utility_code
(
env
)
return
self
.
create_to_py_utility_code
(
env
)
def
can_coerce_from_pyobject
(
self
,
env
):
return
self
.
create_from_py_utility_code
(
env
)
def
error_condition
(
self
,
result_code
):
def
error_condition
(
self
,
result_code
):
conds
=
[]
conds
=
[]
if
self
.
is_string
or
self
.
is_pyunicode_ptr
:
if
self
.
is_string
or
self
.
is_pyunicode_ptr
:
...
@@ -1527,6 +1545,9 @@ class CConstType(BaseType):
...
@@ -1527,6 +1545,9 @@ class CConstType(BaseType):
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
self
.
const_base_type
.
can_coerce_to_pyobject
(
env
)
return
self
.
const_base_type
.
can_coerce_to_pyobject
(
env
)
def
can_coerce_from_pyobject
(
self
,
env
):
return
self
.
const_base_type
.
can_coerce_from_pyobject
(
env
)
def
create_to_py_utility_code
(
self
,
env
):
def
create_to_py_utility_code
(
self
,
env
):
if
self
.
const_base_type
.
create_to_py_utility_code
(
env
):
if
self
.
const_base_type
.
create_to_py_utility_code
(
env
):
self
.
to_py_function
=
self
.
const_base_type
.
to_py_function
self
.
to_py_function
=
self
.
const_base_type
.
to_py_function
...
@@ -1715,6 +1736,9 @@ class CIntType(CNumericType):
...
@@ -1715,6 +1736,9 @@ class CIntType(CNumericType):
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
True
return
True
def
can_coerce_from_pyobject
(
self
,
env
):
return
True
@
staticmethod
@
staticmethod
def
_parse_format
(
format_spec
):
def
_parse_format
(
format_spec
):
padding
=
' '
padding
=
' '
...
@@ -2087,6 +2111,8 @@ class CComplexType(CNumericType):
...
@@ -2087,6 +2111,8 @@ class CComplexType(CNumericType):
if
(
not
src_type
.
is_complex
and
src_type
.
is_numeric
and
src_type
.
is_typedef
if
(
not
src_type
.
is_complex
and
src_type
.
is_numeric
and
src_type
.
is_typedef
and
src_type
.
typedef_is_external
):
and
src_type
.
typedef_is_external
):
return
False
return
False
elif
src_type
.
is_pyobject
:
return
True
else
:
else
:
return
super
(
CComplexType
,
self
).
assignable_from
(
src_type
)
return
super
(
CComplexType
,
self
).
assignable_from
(
src_type
)
...
@@ -2139,6 +2165,9 @@ class CComplexType(CNumericType):
...
@@ -2139,6 +2165,9 @@ class CComplexType(CNumericType):
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
True
return
True
def
can_coerce_from_pyobject
(
self
,
env
):
return
True
def
create_to_py_utility_code
(
self
,
env
):
def
create_to_py_utility_code
(
self
,
env
):
env
.
use_utility_code
(
UtilityCode
.
load_cached
(
'ToPy'
,
'Complex.c'
))
env
.
use_utility_code
(
UtilityCode
.
load_cached
(
'ToPy'
,
'Complex.c'
))
return
True
return
True
...
@@ -2312,6 +2341,9 @@ class CArrayType(CPointerBaseType):
...
@@ -2312,6 +2341,9 @@ class CArrayType(CPointerBaseType):
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
self
.
base_type
.
can_coerce_to_pyobject
(
env
)
return
self
.
base_type
.
can_coerce_to_pyobject
(
env
)
def
can_coerce_from_pyobject
(
self
,
env
):
return
self
.
base_type
.
can_coerce_from_pyobject
(
env
)
def
create_to_py_utility_code
(
self
,
env
):
def
create_to_py_utility_code
(
self
,
env
):
if
self
.
to_py_function
is
not
None
:
if
self
.
to_py_function
is
not
None
:
return
self
.
to_py_function
return
self
.
to_py_function
...
@@ -3190,20 +3222,20 @@ class CStructOrUnionType(CType):
...
@@ -3190,20 +3222,20 @@ class CStructOrUnionType(CType):
self
.
_convert_from_py_code
=
None
self
.
_convert_from_py_code
=
None
self
.
packed
=
packed
self
.
packed
=
packed
def
create_to_py_utility_code
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
if
env
.
outer_scope
is
None
:
return
False
if
self
.
_convert_to_py_code
is
False
:
if
self
.
_convert_to_py_code
is
False
:
return
None
# tri-state-ish
return
None
# tri-state-ish
if
env
.
outer_scope
is
None
:
return
False
if
self
.
_convert_to_py_code
is
None
:
if
self
.
_convert_to_py_code
is
None
:
is_union
=
not
self
.
is_struct
is_union
=
not
self
.
is_struct
unsafe_union_types
=
set
()
unsafe_union_types
=
set
()
safe_union_types
=
set
()
safe_union_types
=
set
()
for
member
in
self
.
scope
.
var_entries
:
for
member
in
self
.
scope
.
var_entries
:
member_type
=
member
.
type
member_type
=
member
.
type
if
not
member_type
.
c
reate_to_py_utility_code
(
env
):
if
not
member_type
.
c
an_coerce_to_pyobject
(
env
):
self
.
to_py_function
=
None
self
.
to_py_function
=
None
self
.
_convert_to_py_code
=
False
self
.
_convert_to_py_code
=
False
return
False
return
False
...
@@ -3219,12 +3251,29 @@ class CStructOrUnionType(CType):
...
@@ -3219,12 +3251,29 @@ class CStructOrUnionType(CType):
self
.
_convert_from_py_code
=
False
self
.
_convert_from_py_code
=
False
return
False
return
False
return
True
def
create_to_py_utility_code
(
self
,
env
):
if
not
self
.
can_coerce_to_pyobject
(
env
):
return
False
if
self
.
_convert_to_py_code
is
None
:
for
member
in
self
.
scope
.
var_entries
:
member
.
type
.
create_to_py_utility_code
(
env
)
forward_decl
=
self
.
entry
.
visibility
!=
'extern'
and
not
self
.
typedef_flag
forward_decl
=
self
.
entry
.
visibility
!=
'extern'
and
not
self
.
typedef_flag
self
.
_convert_to_py_code
=
ToPyStructUtilityCode
(
self
,
forward_decl
,
env
)
self
.
_convert_to_py_code
=
ToPyStructUtilityCode
(
self
,
forward_decl
,
env
)
env
.
use_utility_code
(
self
.
_convert_to_py_code
)
env
.
use_utility_code
(
self
.
_convert_to_py_code
)
return
True
return
True
def
can_coerce_from_pyobject
(
self
):
if
env
.
outer_scope
is
None
or
self
.
_convert_from_py_code
is
False
:
return
False
for
member
in
self
.
scope
.
var_entries
:
if
not
member
.
type
.
assignable_from_resolved_type
(
PyrexTypes
.
py_object_type
):
return
False
return
True
def
create_from_py_utility_code
(
self
,
env
):
def
create_from_py_utility_code
(
self
,
env
):
if
env
.
outer_scope
is
None
:
if
env
.
outer_scope
is
None
:
return
False
return
False
...
@@ -3375,6 +3424,9 @@ class CppClassType(CType):
...
@@ -3375,6 +3424,9 @@ class CppClassType(CType):
else
:
else
:
return
''
return
''
def
can_coerce_from_pyobject
(
self
,
env
):
return
self
.
cname
in
builtin_cpp_conversions
or
self
.
cname
in
cpp_string_conversions
def
create_from_py_utility_code
(
self
,
env
):
def
create_from_py_utility_code
(
self
,
env
):
if
self
.
from_py_function
is
not
None
:
if
self
.
from_py_function
is
not
None
:
return
True
return
True
...
@@ -3407,6 +3459,9 @@ class CppClassType(CType):
...
@@ -3407,6 +3459,9 @@ class CppClassType(CType):
self
.
from_py_function
=
cname
self
.
from_py_function
=
cname
return
True
return
True
def
can_coerce_to_pyobject
(
self
,
env
):
return
self
.
cname
in
builtin_cpp_conversions
or
self
.
cname
in
cpp_string_conversions
def
create_to_py_utility_code
(
self
,
env
):
def
create_to_py_utility_code
(
self
,
env
):
if
self
.
to_py_function
is
not
None
:
if
self
.
to_py_function
is
not
None
:
return
True
return
True
...
@@ -3612,7 +3667,8 @@ class CppClassType(CType):
...
@@ -3612,7 +3667,8 @@ class CppClassType(CType):
# TODO: handle operator=(...) here?
# TODO: handle operator=(...) here?
if
other_type
is
error_type
:
if
other_type
is
error_type
:
return
True
return
True
return
other_type
.
is_cpp_class
and
other_type
.
is_subclass
(
self
)
elif
other_type
.
is_cpp_class
:
return
other_type
.
is_subclass
(
self
)
def
attributes_known
(
self
):
def
attributes_known
(
self
):
return
self
.
scope
is
not
None
return
self
.
scope
is
not
None
...
@@ -3731,6 +3787,12 @@ class CEnumType(CType):
...
@@ -3731,6 +3787,12 @@ class CEnumType(CType):
self
.
name
,
self
.
cname
,
self
.
typedef_flag
,
namespace
)
self
.
name
,
self
.
cname
,
self
.
typedef_flag
,
namespace
)
return
self
return
self
def
can_coerce_to_pyobject
(
self
,
env
):
return
True
def
can_coerce_from_pyobject
(
self
,
env
):
return
True
def
create_to_py_utility_code
(
self
,
env
):
def
create_to_py_utility_code
(
self
,
env
):
self
.
to_py_function
=
"__Pyx_PyInt_From_"
+
self
.
specialization_name
()
self
.
to_py_function
=
"__Pyx_PyInt_From_"
+
self
.
specialization_name
()
env
.
use_utility_code
(
TempitaUtilityCode
.
load_cached
(
env
.
use_utility_code
(
TempitaUtilityCode
.
load_cached
(
...
@@ -3797,6 +3859,12 @@ class CTupleType(CType):
...
@@ -3797,6 +3859,12 @@ class CTupleType(CType):
return
False
return
False
return
True
return
True
def
can_coerce_from_pyobject
(
self
,
env
):
for
component
in
self
.
components
:
if
not
component
.
can_coerce_from_pyobject
(
env
):
return
False
return
True
def
create_to_py_utility_code
(
self
,
env
):
def
create_to_py_utility_code
(
self
,
env
):
if
self
.
_convert_to_py_code
is
False
:
if
self
.
_convert_to_py_code
is
False
:
return
None
# tri-state-ish
return
None
# tri-state-ish
...
...
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