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
30113788
Commit
30113788
authored
Jul 17, 2014
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'static'
parents
67290dbb
71bbce90
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
114 additions
and
32 deletions
+114
-32
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+6
-3
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+3
-1
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+16
-4
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+10
-3
Cython/Compiler/Parsing.pxd
Cython/Compiler/Parsing.pxd
+1
-0
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+19
-6
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+1
-1
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+2
-1
docs/src/userguide/extension_types.rst
docs/src/userguide/extension_types.rst
+19
-11
docs/src/userguide/wrapping_CPlusPlus.rst
docs/src/userguide/wrapping_CPlusPlus.rst
+3
-2
tests/run/cpp_classes_def.pyx
tests/run/cpp_classes_def.pyx
+15
-0
tests/run/cpp_templates.pyx
tests/run/cpp_templates.pyx
+13
-0
tests/run/cpp_templates_helper.h
tests/run/cpp_templates_helper.h
+6
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
30113788
...
...
@@ -5310,10 +5310,10 @@ class AttributeNode(ExprNode):
# C method of an extension type or builtin type. If successful,
# creates a corresponding NameNode and returns it, otherwise
# returns None.
type
=
self
.
obj
.
analyse_as_
extension_
type
(
env
)
if
type
:
type
=
self
.
obj
.
analyse_as_type
(
env
)
if
type
and
(
type
.
is_extension_type
or
type
.
is_builtin_type
or
type
.
is_cpp_class
)
:
entry
=
type
.
scope
.
lookup_here
(
self
.
attribute
)
if
entry
and
entry
.
is_cmethod
:
if
entry
and
(
entry
.
is_cmethod
or
type
.
is_cpp_class
and
entry
.
type
.
is_cfunction
)
:
if
type
.
is_builtin_type
:
if
not
self
.
is_called
:
# must handle this as Python object
...
...
@@ -5326,6 +5326,9 @@ class AttributeNode(ExprNode):
cname
=
entry
.
func_cname
if
entry
.
type
.
is_static_method
:
ctype
=
entry
.
type
elif
type
.
is_cpp_class
:
error
(
self
.
pos
,
"%s not a static member of %s"
%
(
entry
.
name
,
type
))
ctype
=
PyrexTypes
.
error_type
else
:
# Fix self type.
ctype
=
copy
.
copy
(
entry
.
type
)
...
...
Cython/Compiler/ModuleNode.py
View file @
30113788
...
...
@@ -826,7 +826,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
has_virtual_methods
=
False
has_destructor
=
False
for
attr
in
scope
.
var_entries
:
if
attr
.
type
.
is_cfunction
and
attr
.
name
!=
"<init>"
:
if
attr
.
type
.
is_cfunction
and
attr
.
type
.
is_static_method
:
code
.
put
(
"static "
)
elif
attr
.
type
.
is_cfunction
and
attr
.
name
!=
"<init>"
:
code
.
put
(
"virtual "
)
has_virtual_methods
=
True
if
attr
.
cname
[
0
]
==
'~'
:
...
...
Cython/Compiler/Nodes.py
View file @
30113788
...
...
@@ -1294,6 +1294,8 @@ class CVarDefNode(StatNode):
if
self
.
entry
is
not
None
:
self
.
entry
.
is_overridable
=
self
.
overridable
self
.
entry
.
directive_locals
=
copy
.
copy
(
self
.
directive_locals
)
if
'staticmethod'
in
env
.
directives
:
type
.
is_static_method
=
True
else
:
if
self
.
directive_locals
:
error
(
self
.
pos
,
"Decorators can only be followed by functions"
)
...
...
@@ -1361,6 +1363,9 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
# entry Entry
# base_classes [CBaseTypeNode]
# templates [string] or None
# decorators [DecoratorNode] or None
decorators
=
None
def
declare
(
self
,
env
):
if
self
.
templates
is
None
:
...
...
@@ -1394,15 +1399,22 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
if
scope
is
not
None
:
scope
.
type
=
self
.
entry
.
type
defined_funcs
=
[]
def
func_attributes
(
attributes
):
for
attr
in
attributes
:
if
isinstance
(
attr
,
CFuncDefNode
):
yield
attr
elif
isinstance
(
attr
,
CompilerDirectivesNode
):
for
sub_attr
in
func_attributes
(
attr
.
body
.
stats
):
yield
sub_attr
if
self
.
attributes
is
not
None
:
if
self
.
in_pxd
and
not
env
.
in_cinclude
:
self
.
entry
.
defined_in_pxd
=
1
for
attr
in
self
.
attributes
:
attr
.
analyse_declarations
(
scope
)
if
isinstance
(
attr
,
CFuncDefNode
):
defined_funcs
.
append
(
attr
)
if
self
.
templates
is
not
None
:
attr
.
template_declaration
=
"template <typename %s>"
%
", typename "
.
join
(
self
.
templates
)
for
func
in
func_attributes
(
self
.
attributes
):
defined_funcs
.
append
(
func
)
if
self
.
templates
is
not
None
:
func
.
template_declaration
=
"template <typename %s>"
%
", typename "
.
join
(
self
.
templates
)
self
.
body
=
StatListNode
(
self
.
pos
,
stats
=
defined_funcs
)
self
.
scope
=
scope
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
30113788
...
...
@@ -951,11 +951,11 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
for
name
,
value
in
directives
.
iteritems
():
if
name
==
'locals'
:
node
.
directive_locals
=
value
elif
name
!=
'final'
:
elif
name
not
in
(
'final'
,
'staticmethod'
)
:
self
.
context
.
nonfatal_error
(
PostParseError
(
node
.
pos
,
"Cdef functions can only take cython.locals() "
"or final decorators, got %s."
%
name
))
"Cdef functions can only take cython.locals()
,
"
"
staticmethod,
or final decorators, got %s."
%
name
))
body
=
Nodes
.
StatListNode
(
node
.
pos
,
stats
=
[
node
])
return
self
.
visit_with_directives
(
body
,
directives
)
...
...
@@ -966,6 +966,13 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
body
=
Nodes
.
StatListNode
(
node
.
pos
,
stats
=
[
node
])
return
self
.
visit_with_directives
(
body
,
directives
)
def
visit_CppClassNode
(
self
,
node
):
directives
=
self
.
_extract_directives
(
node
,
'cppclass'
)
if
not
directives
:
return
self
.
visit_Node
(
node
)
body
=
Nodes
.
StatListNode
(
node
.
pos
,
stats
=
[
node
])
return
self
.
visit_with_directives
(
body
,
directives
)
def
visit_PyClassDefNode
(
self
,
node
):
directives
=
self
.
_extract_directives
(
node
,
'class'
)
if
not
directives
:
...
...
Cython/Compiler/Parsing.pxd
View file @
30113788
...
...
@@ -187,3 +187,4 @@ cdef p_doc_string(PyrexScanner s)
cdef
p_ignorable_statement
(
PyrexScanner
s
)
cdef
p_compiler_directive_comments
(
PyrexScanner
s
)
cdef
p_cpp_class_definition
(
PyrexScanner
s
,
pos
,
ctx
)
def
p_cpp_class_attribute
(
PyrexScanner
s
,
ctx
):
Cython/Compiler/Parsing.py
View file @
30113788
...
...
@@ -3231,12 +3231,8 @@ def p_cpp_class_definition(s, pos, ctx):
body_ctx
=
Ctx
(
visibility
=
ctx
.
visibility
,
level
=
'cpp_class'
,
nogil
=
nogil
or
ctx
.
nogil
)
body_ctx
.
templates
=
templates
while
s
.
sy
!=
'DEDENT'
:
if
s
.
systring
==
'cppclass'
:
attributes
.
append
(
p_cpp_class_definition
(
s
,
s
.
position
(),
body_ctx
))
elif
s
.
sy
!=
'pass'
:
attributes
.
append
(
p_c_func_or_var_declaration
(
s
,
s
.
position
(),
body_ctx
))
if
s
.
sy
!=
'pass'
:
attributes
.
append
(
p_cpp_class_attribute
(
s
,
body_ctx
))
else
:
s
.
next
()
s
.
expect_newline
(
"Expected a newline"
)
...
...
@@ -3253,6 +3249,23 @@ def p_cpp_class_definition(s, pos, ctx):
attributes
=
attributes
,
templates
=
templates
)
def
p_cpp_class_attribute
(
s
,
ctx
):
decorators
=
None
if
s
.
sy
==
'@'
:
decorators
=
p_decorators
(
s
)
if
s
.
systring
==
'cppclass'
:
return
p_cpp_class_definition
(
s
,
s
.
position
(),
ctx
)
else
:
node
=
p_c_func_or_var_declaration
(
s
,
s
.
position
(),
ctx
)
if
decorators
is
not
None
:
tup
=
Nodes
.
CFuncDefNode
,
Nodes
.
CVarDefNode
,
Nodes
.
CClassDefNode
if
ctx
.
allow_struct_enum_decorator
:
tup
+=
Nodes
.
CStructOrUnionDefNode
,
Nodes
.
CEnumDefNode
if
not
isinstance
(
node
,
tup
):
s
.
error
(
"Decorators can only be followed by functions or classes"
)
node
.
decorators
=
decorators
return
node
#----------------------------------------------
#
...
...
Cython/Compiler/PyrexTypes.py
View file @
30113788
...
...
@@ -3110,7 +3110,7 @@ class CppClassType(CType):
# Need to do these *after* self.specializations[key] is set
# to avoid infinite recursion on circular references.
specialized
.
base_classes
=
[
b
.
specialize
(
values
)
for
b
in
self
.
base_classes
]
specialized
.
scope
=
self
.
scope
.
specialize
(
values
)
specialized
.
scope
=
self
.
scope
.
specialize
(
values
,
specialized
)
if
self
.
namespace
is
not
None
:
specialized
.
namespace
=
self
.
namespace
.
specialize
(
values
)
return
specialized
...
...
Cython/Compiler/Symtab.py
View file @
30113788
...
...
@@ -2190,8 +2190,9 @@ class CppClassScope(Scope):
utility_code
=
base_entry
.
utility_code
)
entry
.
is_inherited
=
1
def
specialize
(
self
,
values
):
def
specialize
(
self
,
values
,
type_entry
):
scope
=
CppClassScope
(
self
.
name
,
self
.
outer_scope
)
scope
.
type
=
type_entry
for
entry
in
self
.
entries
.
values
():
if
entry
.
is_type
:
scope
.
declare_type
(
entry
.
name
,
...
...
docs/src/userguide/extension_types.rst
View file @
30113788
...
...
@@ -345,7 +345,7 @@ functions, C methods are declared using :keyword:`cdef` or :keyword:`cpdef` inst
:keyword:`def`. C methods are "virtual", and may be overridden in derived
extension types. In addition, :keyword:`cpdef` methods can even be overridden by python
methods when called as C method. This adds a little to their calling overhead
compared to a :keyword:`cdef` methd::
compared to a :keyword:`cdef` meth
o
d::
# pets.pyx
cdef class Parrot:
...
...
@@ -382,21 +382,29 @@ method using the usual Python technique, i.e.::
Parrot.describe(self)
`cdef` methods can be declared static by using the @staticmethod decorator.
This can be especially useful for constructing classes that take non-Python
compatible types.::
Forward-declaring extension types
===================================
cdef class OwnedPointer:
cdef void* ptr
Extension types can be forward-declared, like :keyword:`struct` and
:keyword:`union` types. This will be necessary if you have two extension types
that need to refer to each other, e.g.::
cdef __dealloc__(self):
if ptr != NULL:
free(ptr)
cdef class Shrubbery # forward declaration
@staticmethod
cdef create(void* ptr):
p = OwnedPointer()
p.ptr = ptr
return ptr
cdef class Shrubber:
cdef Shrubbery work_in_progress
cdef class Shrubbery:
cdef Shrubber creator
Forward-declaring extension types
===================================
Extension types can be forward-declared, like :keyword:`struct` and
:keyword:`union` types. This is usually necessary.
If you are forward-declaring an extension type that has a base class, you must
specify the base class in both the forward declaration and its subsequent
...
...
docs/src/userguide/wrapping_CPlusPlus.rst
View file @
30113788
...
...
@@ -529,9 +529,10 @@ If the Rectangle class has a static member:
};
}
you can declare it
as a function living in the class namespace
, i.e.::
you can declare it
using the Python @staticmethod decorator
, i.e.::
cdef extern from "Rectangle.h" namespace "shapes::Rectangle":
cdef extern from "Rectangle.h" namespace "shapes":
@staticmethod
void do_something()
...
...
tests/run/cpp_classes_def.pyx
View file @
30113788
...
...
@@ -42,6 +42,21 @@ def test_Poly(int n, float radius=1):
del
poly
cdef
cppclass
WithStatic
:
@
staticmethod
double
square
(
double
x
):
return
x
*
x
def
test_Static
(
x
):
"""
>>> test_Static(2)
4.0
>>> test_Static(0.5)
0.25
"""
return
WithStatic
.
square
(
x
)
cdef
cppclass
InitDealloc
:
__init__
():
print
"Init"
...
...
tests/run/cpp_templates.pyx
View file @
30113788
...
...
@@ -22,6 +22,10 @@ cdef extern from "cpp_templates_helper.h":
cdef
cppclass
SubClass
[
T2
,
T3
](
SuperClass
[
T2
,
T3
]):
pass
cdef
cppclass
Div
[
T
]:
@
staticmethod
T
half
(
T
value
)
def
test_int
(
int
x
,
int
y
):
"""
>>> test_int(3, 4)
...
...
@@ -104,3 +108,12 @@ def test_cast_template_pointer():
sup
=
sub
sup
=
<
SubClass
[
int
,
float
]
*>
sub
def
test_static
(
x
):
"""
>>> test_static(2)
(1, 1.0)
>>> test_static(3)
(1, 1.5)
"""
return
Div
[
int
].
half
(
x
),
Div
[
double
].
half
(
x
)
tests/run/cpp_templates_helper.h
View file @
30113788
...
...
@@ -30,3 +30,9 @@ public:
template
<
class
T2
,
class
T3
>
class
SubClass
:
public
SuperClass
<
T2
,
T3
>
{
};
template
<
class
T
>
class
Div
{
public:
static
T
half
(
T
value
)
{
return
value
/
2
;
}
};
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