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
Kirill Smelkov
cython
Commits
ee80d4b8
Commit
ee80d4b8
authored
Jun 04, 2014
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Static cdef methods.
parent
e406de9e
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
42 additions
and
13 deletions
+42
-13
CHANGES.rst
CHANGES.rst
+4
-0
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+3
-2
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+10
-2
Cython/Compiler/Options.py
Cython/Compiler/Options.py
+2
-0
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+12
-3
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+5
-1
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+6
-5
No files found.
CHANGES.rst
View file @
ee80d4b8
...
...
@@ -9,6 +9,10 @@ Latest
Features added
--------------
* Allow @staticmethod decorator to declare static cdef methods.
This is especially useful for declaring "constructors" for
cdef classes that can take non-Python arguments.
* Generators have new properties ``__name__`` and ``__qualname__``
that provide the plain/qualified name of the generator function
(following CPython 3.5). See http://bugs.python.org/issue21205
...
...
Cython/Compiler/ExprNodes.py
View file @
ee80d4b8
...
...
@@ -4449,7 +4449,7 @@ class SimpleCallNode(CallNode):
self
.
type
=
error_type
return
if
self
.
self
:
if
self
.
self
and
not
self
.
function
.
type
.
is_static_method
:
args
=
[
self
.
self
]
+
self
.
args
else
:
args
=
self
.
args
...
...
@@ -4475,6 +4475,7 @@ class SimpleCallNode(CallNode):
else
:
alternatives
=
overloaded_entry
.
all_alternatives
()
print
self
.
function
.
type
,
args
entry
=
PyrexTypes
.
best_match
(
args
,
alternatives
,
self
.
pos
,
env
)
if
not
entry
:
...
...
@@ -4504,7 +4505,7 @@ class SimpleCallNode(CallNode):
self
.
is_temp
=
1
# check 'self' argument
if
entry
and
entry
.
is_cmethod
and
func_type
.
args
:
if
entry
and
entry
.
is_cmethod
and
func_type
.
args
and
not
func_type
.
is_static_method
:
formal_arg
=
func_type
.
args
[
0
]
arg
=
args
[
0
]
if
formal_arg
.
not_none
:
...
...
Cython/Compiler/Nodes.py
View file @
ee80d4b8
...
...
@@ -616,7 +616,9 @@ class CFuncDeclaratorNode(CDeclaratorNode):
func_type_args
=
[]
for
i
,
arg_node
in
enumerate
(
self
.
args
):
name_declarator
,
type
=
arg_node
.
analyse
(
env
,
nonempty
=
nonempty
,
is_self_arg
=
(
i
==
0
and
env
.
is_c_class_scope
))
env
,
nonempty
=
nonempty
,
is_self_arg
=
(
i
==
0
and
env
.
is_c_class_scope
and
'staticmethod'
not
in
env
.
directives
))
print
arg_node
print
name_declarator
,
type
,
(
i
==
0
and
env
.
is_c_class_scope
and
'staticmethod'
not
in
env
.
directives
)
name
=
name_declarator
.
name
if
name
in
directive_locals
:
type_node
=
directive_locals
[
name
]
...
...
@@ -795,6 +797,7 @@ class CArgDeclNode(Node):
is_dynamic
=
0
def
analyse
(
self
,
env
,
nonempty
=
0
,
is_self_arg
=
False
):
print
"is_self_arg"
,
is_self_arg
,
"type"
,
self
.
type
,
"self.base_type"
,
self
.
base_type
,
"self.base_type.is_self_arg"
,
self
.
base_type
.
is_self_arg
if
is_self_arg
:
self
.
base_type
.
is_self_arg
=
self
.
is_self_arg
=
True
if
self
.
type
is
None
:
...
...
@@ -815,6 +818,7 @@ class CArgDeclNode(Node):
could_be_name
=
False
self
.
base_type
.
is_arg
=
True
base_type
=
self
.
base_type
.
analyse
(
env
,
could_be_name
=
could_be_name
)
print
"base_type"
,
base_type
if
hasattr
(
self
.
base_type
,
'arg_name'
)
and
self
.
base_type
.
arg_name
:
self
.
declarator
.
name
=
self
.
base_type
.
arg_name
...
...
@@ -2140,6 +2144,7 @@ class CFuncDefNode(FuncDefNode):
# inline_in_pxd whether this is an inline function in a pxd file
# template_declaration String or None Used for c++ class methods
# is_const_method whether this is a const method
# is_static_method whether this is a static method
child_attrs
=
[
"base_type"
,
"declarator"
,
"body"
,
"py_func"
]
...
...
@@ -2165,6 +2170,7 @@ class CFuncDefNode(FuncDefNode):
base_type
=
PyrexTypes
.
error_type
else
:
base_type
=
self
.
base_type
.
analyse
(
env
)
self
.
is_static_method
=
'staticmethod'
in
env
.
directives
# The 2 here is because we need both function and argument names.
if
isinstance
(
self
.
declarator
,
CFuncDeclaratorNode
):
name_declarator
,
type
=
self
.
declarator
.
analyse
(
base_type
,
env
,
...
...
@@ -2179,6 +2185,7 @@ class CFuncDefNode(FuncDefNode):
# written here, because the type in the symbol table entry
# may be different if we're overriding a C method inherited
# from the base type of an extension type.
print
"type"
,
type
self
.
type
=
type
type
.
is_overridable
=
self
.
overridable
declarator
=
self
.
declarator
...
...
@@ -2226,6 +2233,7 @@ class CFuncDefNode(FuncDefNode):
cname
=
name_declarator
.
cname
type
.
is_const_method
=
self
.
is_const_method
type
.
is_static_method
=
self
.
is_static_method
self
.
entry
=
env
.
declare_cfunction
(
name
,
type
,
self
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
,
...
...
@@ -2238,7 +2246,7 @@ class CFuncDefNode(FuncDefNode):
if
self
.
return_type
.
is_cpp_class
:
self
.
return_type
.
check_nullary_constructor
(
self
.
pos
,
"used as a return value"
)
if
self
.
overridable
and
not
env
.
is_module_scope
:
if
self
.
overridable
and
not
env
.
is_module_scope
and
not
self
.
is_static_method
:
if
len
(
self
.
args
)
<
1
or
not
self
.
args
[
0
].
type
.
is_pyobject
:
# An error will be produced in the cdef function
self
.
overridable
=
False
...
...
Cython/Compiler/Options.py
View file @
ee80d4b8
...
...
@@ -209,6 +209,7 @@ directive_types = {
'cfunc'
:
None
,
# decorators do not take directive value
'ccall'
:
None
,
'inline'
:
None
,
'staticmethod'
:
None
,
'cclass'
:
None
,
'returns'
:
type
,
'set_initial_path'
:
str
,
...
...
@@ -225,6 +226,7 @@ directive_scopes = { # defaults to available everywhere
# 'module', 'function', 'class', 'with statement'
'final'
:
(
'cclass'
,
'function'
),
'inline'
:
(
'function'
,),
'staticmethod'
:
(
'function'
,),
# FIXME: analysis currently lacks more specific function scope
'no_gc_clear'
:
(
'cclass'
,),
'internal'
:
(
'cclass'
,),
'autotestdict'
:
(
'module'
,),
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
ee80d4b8
...
...
@@ -674,11 +674,13 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
for
key
,
value
in
compilation_directive_defaults
.
items
():
self
.
compilation_directive_defaults
[
unicode
(
key
)]
=
copy
.
deepcopy
(
value
)
self
.
cython_module_names
=
set
()
self
.
directive_names
=
{}
self
.
directive_names
=
{
'staticmethod'
:
'staticmethod'
}
self
.
parallel_directives
=
{}
def
check_directive_scope
(
self
,
pos
,
directive
,
scope
):
print
'check_directive_scope'
,
pos
,
directive
,
scope
legal_scopes
=
Options
.
directive_scopes
.
get
(
directive
,
None
)
print
legal_scopes
if
legal_scopes
and
scope
not
in
legal_scopes
:
self
.
context
.
nonfatal_error
(
PostParseError
(
pos
,
'The %s compiler directive '
'is not allowed in %s scope'
%
(
directive
,
scope
)))
...
...
@@ -979,18 +981,23 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
# Split the decorators into two lists -- real decorators and directives
directives
=
[]
realdecs
=
[]
both
=
[]
for
dec
in
node
.
decorators
:
new_directives
=
self
.
try_to_parse_directives
(
dec
.
decorator
)
if
new_directives
is
not
None
:
for
directive
in
new_directives
:
if
self
.
check_directive_scope
(
node
.
pos
,
directive
[
0
],
scope_name
):
directives
.
append
(
directive
)
name
,
value
=
directive
if
self
.
directives
.
get
(
name
,
object
())
!=
value
:
directives
.
append
(
directive
)
if
directive
[
0
]
==
'staticmethod'
:
both
.
append
(
dec
)
else
:
realdecs
.
append
(
dec
)
if
realdecs
and
isinstance
(
node
,
(
Nodes
.
CFuncDefNode
,
Nodes
.
CClassDefNode
,
Nodes
.
CVarDefNode
)):
raise
PostParseError
(
realdecs
[
0
].
pos
,
"Cdef functions/classes cannot take arbitrary decorators."
)
else
:
node
.
decorators
=
realdecs
node
.
decorators
=
realdecs
+
both
# merge or override repeated directives
optdict
=
{}
directives
.
reverse
()
# Decorators coming first take precedence
...
...
@@ -2705,6 +2712,8 @@ class TransformBuiltinMethods(EnvTransform):
node
.
cdivision
=
True
elif
function
==
u'set'
:
node
.
function
=
ExprNodes
.
NameNode
(
node
.
pos
,
name
=
EncodedString
(
'set'
))
elif
function
==
u'staticmethod'
:
node
.
function
=
ExprNodes
.
NameNode
(
node
.
pos
,
name
=
EncodedString
(
'staticmethod'
))
elif
self
.
context
.
cython_scope
.
lookup_qualified_name
(
function
):
pass
else
:
...
...
Cython/Compiler/PyrexTypes.py
View file @
ee80d4b8
...
...
@@ -2315,6 +2315,7 @@ class CFuncType(CType):
# is_strict_signature boolean function refuses to accept coerced arguments
# (used for optimisation overrides)
# is_const_method boolean
# is_static_method boolean
is_cfunction
=
1
original_sig
=
None
...
...
@@ -2327,7 +2328,8 @@ class CFuncType(CType):
def
__init__
(
self
,
return_type
,
args
,
has_varargs
=
0
,
exception_value
=
None
,
exception_check
=
0
,
calling_convention
=
""
,
nogil
=
0
,
with_gil
=
0
,
is_overridable
=
0
,
optional_arg_count
=
0
,
is_const_method
=
False
,
templates
=
None
,
is_strict_signature
=
False
):
is_const_method
=
False
,
is_static_method
=
False
,
templates
=
None
,
is_strict_signature
=
False
):
self
.
return_type
=
return_type
self
.
args
=
args
self
.
has_varargs
=
has_varargs
...
...
@@ -2339,6 +2341,7 @@ class CFuncType(CType):
self
.
with_gil
=
with_gil
self
.
is_overridable
=
is_overridable
self
.
is_const_method
=
is_const_method
self
.
is_static_method
=
is_static_method
self
.
templates
=
templates
self
.
is_strict_signature
=
is_strict_signature
...
...
@@ -2563,6 +2566,7 @@ class CFuncType(CType):
is_overridable
=
self
.
is_overridable
,
optional_arg_count
=
self
.
optional_arg_count
,
is_const_method
=
self
.
is_const_method
,
is_static_method
=
self
.
is_static_method
,
templates
=
self
.
templates
)
result
.
from_fused
=
self
.
is_fused
...
...
Cython/Compiler/Symtab.py
View file @
ee80d4b8
...
...
@@ -1945,11 +1945,12 @@ class CClassScope(ClassScope):
if
get_special_method_signature
(
name
)
and
not
self
.
parent_type
.
is_builtin_type
:
error
(
pos
,
"Special methods must be declared with 'def', not 'cdef'"
)
args
=
type
.
args
if
not
args
:
error
(
pos
,
"C method has no self argument"
)
elif
not
self
.
parent_type
.
assignable_from
(
args
[
0
].
type
):
error
(
pos
,
"Self argument (%s) of C method '%s' does not match parent type (%s)"
%
(
args
[
0
].
type
,
name
,
self
.
parent_type
))
if
not
type
.
is_static_method
:
if
not
args
:
error
(
pos
,
"C method has no self argument"
)
elif
not
self
.
parent_type
.
assignable_from
(
args
[
0
].
type
):
error
(
pos
,
"Self argument (%s) of C method '%s' does not match parent type (%s)"
%
(
args
[
0
].
type
,
name
,
self
.
parent_type
))
entry
=
self
.
lookup_here
(
name
)
if
cname
is
None
:
cname
=
c_safe_identifier
(
name
)
...
...
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