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
5f7ebe56
Commit
5f7ebe56
authored
7 years ago
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Optimise calls to the unicode() builtin.
parent
b4b12c73
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
103 additions
and
7 deletions
+103
-7
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+8
-7
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+28
-0
Cython/Utility/StringTools.c
Cython/Utility/StringTools.c
+24
-0
tests/run/unicodefunction.pyx
tests/run/unicodefunction.pyx
+43
-0
No files found.
Cython/Compiler/Code.py
View file @
5f7ebe56
...
...
@@ -482,21 +482,22 @@ class UtilityCode(UtilityCodeBase):
def inject_string_constants(self, impl, output):
"""Replace 'PYIDENT("
xyz
")' by a constant Python identifier cname.
"""
if 'PYIDENT(' not in impl:
if 'PYIDENT(' not in impl
and 'PYUNICODE(' not in impl
:
return False, impl
replacements = {}
def externalise(matchobj):
name = matchobj.group(1
)
key = matchobj.groups(
)
try:
cname = replacements[
name
]
cname = replacements[
key
]
except KeyError:
cname = replacements[name] = output.get_interned_identifier(
StringEncoding.EncodedString(name)).cname
str_type, name = key
cname = replacements[key] = output.get_py_string_const(
StringEncoding.EncodedString(name), identifier=str_type == 'IDENT').cname
return cname
impl = re.sub(r'PY
IDENT
\
(
"
([^"
]
+
)
"
\
)
'
, externalise, impl)
assert 'PYIDENT(' not in impl
impl = re.sub(r'PY
(IDENT|UNICODE)
\
(
"
([^"
]
+
)
"
\
)
'
, externalise, impl)
assert 'PYIDENT(' not in impl
and 'PYUNICODE(' not in impl
return bool(replacements), impl
def inject_unbound_methods(self, impl, output):
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/Optimize.py
View file @
5f7ebe56
...
...
@@ -2309,6 +2309,34 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
return
ExprNodes
.
CachedBuiltinMethodCallNode
(
node
,
function
.
obj
,
attr_name
,
arg_list
)
PyObject_Unicode_func_type
=
PyrexTypes
.
CFuncType
(
Builtin
.
unicode_type
,
[
PyrexTypes
.
CFuncTypeArg
(
"obj"
,
PyrexTypes
.
py_object_type
,
None
)
])
def
_handle_simple_function_unicode
(
self
,
node
,
function
,
pos_args
):
"""Optimise single argument calls to unicode().
"""
if
len
(
pos_args
)
!=
1
:
if
len
(
pos_args
)
==
0
:
return
ExprNodes
.
UnicodeNode
(
node
.
pos
,
value
=
EncodedString
(),
constant_result
=
u''
)
return
node
arg
=
pos_args
[
0
]
if
arg
.
type
is
Builtin
.
unicode_type
:
if
not
arg
.
may_be_none
():
return
arg
cname
=
"__Pyx_PyUnicode_Unicode"
utility_code
=
UtilityCode
.
load_cached
(
'PyUnicode_Unicode'
,
'StringTools.c'
)
else
:
cname
=
"__Pyx_PyObject_Unicode"
utility_code
=
UtilityCode
.
load_cached
(
'PyObject_Unicode'
,
'StringTools.c'
)
return
ExprNodes
.
PythonCapiCallNode
(
node
.
pos
,
cname
,
self
.
PyObject_Unicode_func_type
,
args
=
pos_args
,
is_temp
=
node
.
is_temp
,
utility_code
=
utility_code
,
py_name
=
"unicode"
)
PyDict_Copy_func_type
=
PyrexTypes
.
CFuncType
(
Builtin
.
dict_type
,
[
PyrexTypes
.
CFuncTypeArg
(
"dict"
,
Builtin
.
dict_type
,
None
)
...
...
This diff is collapsed.
Click to expand it.
Cython/Utility/StringTools.c
View file @
5f7ebe56
...
...
@@ -1136,3 +1136,27 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatAndDecref(PyObject* s, PyObj
Py_DECREF
(
s
);
return
result
;
}
//////////////////// PyUnicode_Unicode.proto ////////////////////
static
CYTHON_INLINE
PyObject
*
__Pyx_PyUnicode_Unicode
(
PyObject
*
obj
);
/*proto*/
//////////////////// PyUnicode_Unicode ////////////////////
static
CYTHON_INLINE
PyObject
*
__Pyx_PyUnicode_Unicode
(
PyObject
*
obj
)
{
if
(
unlikely
(
obj
==
Py_None
))
obj
=
PYUNICODE
(
"None"
);
return
__Pyx_NewRef
(
obj
);
}
//////////////////// PyObject_Unicode.proto ////////////////////
#if PY_MAJOR_VERSION >= 3
#define __Pyx_PyObject_Unicode(obj) \
(likely(PyUnicode_CheckExact(obj)) ? __Pyx_NewRef(obj) : PyObject_Str(obj))
#else
#define __Pyx_PyObject_Unicode(obj) \
(likely(PyUnicode_CheckExact(obj)) ? __Pyx_NewRef(obj) : PyObject_Unicode(obj))
#endif
This diff is collapsed.
Click to expand it.
tests/run/unicodefunction.pyx
View file @
5f7ebe56
# mode: run
# tag: unicode
__doc__
=
u"""
>>> u('test')
u'test'
>>> e
u''
>>> z
u'test'
>>> c('testing')
...
...
@@ -16,25 +21,63 @@ __doc__ = u"""
# u'testing a C subtype'
"""
cimport
cython
import
sys
if
sys
.
version_info
[
0
]
>=
3
:
__doc__
=
__doc__
.
replace
(
u" u'"
,
u" '"
)
u
=
unicode
e
=
unicode
()
z
=
unicode
(
u'test'
)
def
c
(
string
):
return
unicode
(
string
)
class
subu
(
unicode
):
pass
def
sub
(
string
):
return
subu
(
string
)
#cdef class csubu(unicode):
# pass
#def csub(string):
# return csubu(string)
@
cython
.
test_fail_if_path_exists
(
"//SimpleCallNode"
)
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
def
typed
(
unicode
s
):
"""
>>> print(typed(None))
None
>>> type(typed(None)) is u or type(typed(None))
True
>>> print(typed(u'abc'))
abc
>>> type(typed(u'abc')) is u or type(typed(u'abc'))
True
"""
return
unicode
(
s
)
@
cython
.
test_fail_if_path_exists
(
"//SimpleCallNode"
,
"//PythonCapiCallNode"
,
)
def
typed_not_none
(
unicode
s
not
None
):
"""
>>> print(typed(u'abc'))
abc
>>> type(typed(u'abc')) is u or type(typed(u'abc'))
True
"""
return
unicode
(
s
)
This diff is collapsed.
Click to expand it.
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