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
Boxiang Sun
cython
Commits
6853d59e
Commit
6853d59e
authored
May 22, 2011
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
ff08e584
7c6f0728
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
381 additions
and
99 deletions
+381
-99
.gitignore
.gitignore
+1
-0
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+8
-28
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+1
-1
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+105
-22
Cython/Compiler/Naming.py
Cython/Compiler/Naming.py
+1
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+6
-9
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+97
-32
tests/build/module_api.srctree
tests/build/module_api.srctree
+121
-0
tests/compile/publicapi_cimport.pyx
tests/compile/publicapi_cimport.pyx
+16
-0
tests/compile/publicapi_pxd_mix.pxd
tests/compile/publicapi_pxd_mix.pxd
+4
-3
tests/compile/publicapi_pxd_mix.pyx
tests/compile/publicapi_pxd_mix.pyx
+5
-0
tests/errors/cdef_in_pyclass.pyx
tests/errors/cdef_in_pyclass.pyx
+3
-1
tests/errors/cfunc_directive_in_pyclass.pyx
tests/errors/cfunc_directive_in_pyclass.pyx
+2
-1
tests/run/capiimpl.pyx
tests/run/capiimpl.pyx
+11
-2
No files found.
.gitignore
View file @
6853d59e
...
...
@@ -8,6 +8,7 @@ Cython/Runtime/refnanny.c
BUILD/
build/
!tests/build/
dist/
.gitrev
.coverage
...
...
Cython/Compiler/Code.py
View file @
6853d59e
...
...
@@ -1166,39 +1166,19 @@ class CCodeWriter(object):
self
.
funcstate
.
use_label
(
lbl
)
self
.
putln
(
"goto %s;"
%
lbl
)
def
put_var_declarations
(
self
,
entries
,
static
=
0
,
dll_linkage
=
None
,
definition
=
True
):
for
entry
in
entries
:
if
not
entry
.
in_cinclude
:
self
.
put_var_declaration
(
entry
,
static
,
dll_linkage
,
definition
)
def
put_var_declaration
(
self
,
entry
,
static
=
0
,
dll_linkage
=
None
,
definition
=
True
):
def
put_var_declaration
(
self
,
entry
,
storage_class
=
""
,
dll_linkage
=
None
,
definition
=
True
):
#print "Code.put_var_declaration:", entry.name, "definition =", definition ###
if
entry
.
in_closure
:
return
visibility
=
entry
.
visibility
if
visibility
==
'private'
and
not
definition
:
#print "...private and not definition, skipping" ###
if
entry
.
visibility
==
'private'
and
not
(
definition
or
entry
.
defined_in_pxd
):
#print "...private and not definition, skipping", entry.cname ###
return
if
not
entry
.
used
and
visibility
==
"private"
:
#print "
not used and private
, skipping", entry.cname ###
if
entry
.
visibility
==
"private"
and
not
entry
.
used
:
#print "
...private and not used
, skipping", entry.cname ###
return
storage_class
=
""
if
visibility
==
'extern'
:
storage_class
=
Naming
.
extern_c_macro
elif
visibility
==
'public'
:
if
not
definition
:
storage_class
=
Naming
.
extern_c_macro
elif
visibility
==
'private'
:
if
static
:
storage_class
=
"static"
if
storage_class
:
self
.
put
(
"%s "
%
storage_class
)
if
visibility
!=
'public'
:
dll_linkage
=
None
self
.
put
(
entry
.
type
.
declaration_code
(
entry
.
cname
,
dll_linkage
=
dll_linkage
))
self
.
put
(
entry
.
type
.
declaration_code
(
entry
.
cname
,
dll_linkage
=
dll_linkage
))
if
entry
.
init
is
not
None
:
self
.
put_safe
(
" = %s"
%
entry
.
type
.
literal_code
(
entry
.
init
))
self
.
putln
(
";"
)
...
...
Cython/Compiler/ExprNodes.py
View file @
6853d59e
...
...
@@ -7507,7 +7507,7 @@ class NoneCheckNode(CoercionNode):
def
generate_result_code
(
self
,
code
):
code
.
putln
(
"if (unlikely(%s == Py_None)) {"
%
self
.
arg
.
result
())
"if (unlikely(%s == Py_None)) {"
%
self
.
arg
.
py_
result
())
code
.
putln
(
'PyErr_SetString(%s, "%s"); %s '
%
(
self
.
exception_type_cname
,
StringEncoding
.
escape_byte_string
(
...
...
Cython/Compiler/ModuleNode.py
View file @
6853d59e
...
...
@@ -201,7 +201,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_code
.
putln
(
""
)
for
entry
in
api_vars
:
type
=
CPtrType
(
entry
.
type
)
cname
=
env
.
mangle
(
Naming
.
var_prefix
,
entry
.
name
)
cname
=
env
.
mangle
(
Naming
.
var
ptr
_prefix
,
entry
.
name
)
h_code
.
putln
(
"static %s = 0;"
%
type
.
declaration_code
(
cname
))
h_code
.
putln
(
"#define %s (*%s)"
%
(
entry
.
name
,
cname
))
h_code
.
put
(
import_module_utility_code
.
impl
)
...
...
@@ -223,7 +223,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;'
%
(
entry
.
name
,
cname
,
sig
))
for
entry
in
api_vars
:
cname
=
env
.
mangle
(
Naming
.
var_prefix
,
entry
.
name
)
cname
=
env
.
mangle
(
Naming
.
var
ptr
_prefix
,
entry
.
name
)
sig
=
entry
.
type
.
declaration_code
(
""
)
h_code
.
putln
(
'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
...
...
@@ -290,7 +290,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
'#define __Pyx_MODULE_NAME "%s"'
%
self
.
full_module_name
)
code
.
putln
(
"int %s%s = 0;"
%
(
Naming
.
module_is_main
,
self
.
full_module_name
.
replace
(
'.'
,
'__'
)))
code
.
putln
(
""
)
code
.
putln
(
"/* Implementation of
%s
*/"
%
env
.
qualified_name
)
code
.
putln
(
"/* Implementation of
'%s'
*/"
%
env
.
qualified_name
)
code
=
globalstate
[
'all_the_rest'
]
...
...
@@ -449,17 +449,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def
generate_declarations_for_modules
(
self
,
env
,
modules
,
globalstate
):
typecode
=
globalstate
[
'type_declarations'
]
typecode
.
putln
(
""
)
typecode
.
putln
(
"/*
Type declarations
*/"
)
typecode
.
putln
(
"/*
--- Type declarations ---
*/"
)
vtab_list
,
vtabslot_list
=
self
.
sort_type_hierarchy
(
modules
,
env
)
self
.
generate_type_definitions
(
env
,
modules
,
vtab_list
,
vtabslot_list
,
typecode
)
modulecode
=
globalstate
[
'module_declarations'
]
for
module
in
modules
:
defined_here
=
module
is
env
modulecode
.
putln
(
"/* Module declarations from %s */"
%
module
.
qualified_name
)
self
.
generate_global_declarations
(
module
,
modulecode
,
defined_here
)
self
.
generate_cfunction_predeclarations
(
module
,
modulecode
,
defined_here
)
modulecode
.
putln
(
""
)
modulecode
.
putln
(
"/* Module declarations from '%s' */"
%
module
.
qualified_name
)
self
.
generate_c_class_declarations
(
module
,
modulecode
,
defined_here
)
self
.
generate_cvariable_declarations
(
module
,
modulecode
,
defined_here
)
self
.
generate_cfunction_declarations
(
module
,
modulecode
,
defined_here
)
def
generate_module_preamble
(
self
,
env
,
cimported_modules
,
code
):
code
.
putln
(
"/* Generated by Cython %s on %s */"
%
(
...
...
@@ -978,25 +979,68 @@ 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_global_declarations
(
self
,
env
,
code
,
definition
):
code
.
putln
(
""
)
def
generate_c_class_declarations
(
self
,
env
,
code
,
definition
):
for
entry
in
env
.
c_class_entries
:
if
definition
or
entry
.
defined_in_pxd
:
code
.
putln
(
"static PyTypeObject *%s = 0;"
%
entry
.
type
.
typeptr_cname
)
code
.
put_var_declarations
(
env
.
var_entries
,
static
=
1
,
dll_linkage
=
"DL_EXPORT"
,
definition
=
definition
)
def
generate_cfunction_predeclarations
(
self
,
env
,
code
,
definition
):
def
generate_cvariable_declarations
(
self
,
env
,
code
,
definition
):
for
entry
in
env
.
var_entries
:
if
(
entry
.
in_cinclude
or
entry
.
in_closure
or
(
entry
.
visibility
==
'private'
and
not
(
entry
.
defined_in_pxd
or
entry
.
used
))):
continue
storage_class
=
None
dll_linkage
=
None
cname
=
None
init
=
None
if
entry
.
visibility
==
'extern'
:
storage_class
=
Naming
.
extern_c_macro
dll_linkage
=
"DL_IMPORT"
elif
entry
.
visibility
==
'public'
:
if
definition
:
dll_linkage
=
"DL_EXPORT"
else
:
storage_class
=
Naming
.
extern_c_macro
dll_linkage
=
"DL_IMPORT"
elif
entry
.
visibility
==
'private'
:
storage_class
=
"static"
if
entry
.
defined_in_pxd
and
not
definition
:
type
=
CPtrType
(
entry
.
type
)
storage_class
=
"static"
dll_linkage
=
None
cname
=
env
.
mangle
(
Naming
.
varptr_prefix
,
entry
.
name
)
init
=
0
else
:
type
=
entry
.
type
cname
=
entry
.
cname
if
entry
.
init
is
not
None
:
init
=
type
.
literal_code
(
entry
.
init
)
if
storage_class
:
code
.
put
(
"%s "
%
storage_class
)
code
.
put
(
type
.
declaration_code
(
cname
,
dll_linkage
=
dll_linkage
))
if
init
is
not
None
:
code
.
put_safe
(
" = %s"
%
init
)
code
.
putln
(
";"
)
if
entry
.
cname
!=
cname
:
code
.
putln
(
"#define %s (*%s)"
%
(
entry
.
cname
,
cname
))
def
generate_cfunction_declarations
(
self
,
env
,
code
,
definition
):
for
entry
in
env
.
cfunc_entries
:
if
entry
.
inline_func_in_pxd
or
(
not
entry
.
in_cinclude
and
(
definition
or
entry
.
defined_in_pxd
or
entry
.
visibility
==
'extern'
)):
if
entry
.
visibility
==
'public'
:
storage_class
=
""
dll_linkage
=
"DL_EXPORT"
elif
entry
.
visibility
==
'extern'
:
if
entry
.
visibility
==
'extern'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
dll_linkage
=
"DL_IMPORT"
elif
entry
.
visibility
==
'public'
:
storage_class
=
""
dll_linkage
=
"DL_EXPORT"
elif
entry
.
visibility
==
'private'
:
storage_class
=
"static "
dll_linkage
=
None
...
...
@@ -1009,6 +1053,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
storage_class
=
"static "
dll_linkage
=
None
type
=
CPtrType
(
type
)
header
=
type
.
declaration_code
(
entry
.
cname
,
dll_linkage
=
dll_linkage
)
if
entry
.
func_modifiers
:
...
...
@@ -1851,6 +1896,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for
module
in
imported_modules
:
self
.
generate_type_import_code_for_module
(
module
,
env
,
code
)
code
.
putln
(
"/*--- Variable import code ---*/"
)
for
module
in
imported_modules
:
self
.
generate_c_variable_import_code_for_module
(
module
,
env
,
code
)
code
.
putln
(
"/*--- Function import code ---*/"
)
for
module
in
imported_modules
:
self
.
generate_c_function_import_code_for_module
(
module
,
env
,
code
)
...
...
@@ -2030,21 +2079,27 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def
generate_c_variable_export_code
(
self
,
env
,
code
):
# Generate code to create PyCFunction wrappers for exported C functions.
entries
=
[]
for
entry
in
env
.
var_entries
:
if
entry
.
api
or
entry
.
defined_in_pxd
:
entries
.
append
(
entry
)
if
entries
:
env
.
use_utility_code
(
voidptr_export_utility_code
)
for
entry
in
entries
:
signature
=
entry
.
type
.
declaration_code
(
""
)
code
.
putln
(
'if (__Pyx_ExportVoidPtr("%s", (void *)&%s, "%s") < 0) %s'
%
(
entry
.
name
,
entry
.
cname
,
signature
,
entry
.
name
,
entry
.
cname
,
signature
,
code
.
error_goto
(
self
.
pos
)))
def
generate_c_function_export_code
(
self
,
env
,
code
):
# Generate code to create PyCFunction wrappers for exported C functions.
entries
=
[]
for
entry
in
env
.
cfunc_entries
:
if
entry
.
api
or
entry
.
defined_in_pxd
:
entries
.
append
(
entry
)
if
entries
:
env
.
use_utility_code
(
function_export_utility_code
)
for
entry
in
entries
:
signature
=
entry
.
type
.
signature_string
()
code
.
putln
(
'if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s'
%
(
entry
.
name
,
...
...
@@ -2060,6 +2115,34 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
entry
.
defined_in_pxd
:
self
.
generate_type_import_code
(
env
,
entry
.
type
,
entry
.
pos
,
code
)
def
generate_c_variable_import_code_for_module
(
self
,
module
,
env
,
code
):
# Generate import code for all exported C functions in a cimported module.
entries
=
[]
for
entry
in
module
.
var_entries
:
if
entry
.
defined_in_pxd
:
entries
.
append
(
entry
)
if
entries
:
env
.
use_utility_code
(
import_module_utility_code
)
env
.
use_utility_code
(
voidptr_import_utility_code
)
temp
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
manage_ref
=
True
)
code
.
putln
(
'%s = __Pyx_ImportModule("%s"); if (!%s) %s'
%
(
temp
,
module
.
qualified_name
,
temp
,
code
.
error_goto
(
self
.
pos
)))
for
entry
in
entries
:
if
env
is
module
:
cname
=
entry
.
cname
else
:
cname
=
module
.
mangle
(
Naming
.
varptr_prefix
,
entry
.
name
)
signature
=
entry
.
type
.
declaration_code
(
""
)
code
.
putln
(
'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s'
%
(
temp
,
entry
.
name
,
cname
,
signature
,
code
.
error_goto
(
self
.
pos
)))
code
.
putln
(
"Py_DECREF(%s); %s = 0;"
%
(
temp
,
temp
))
def
generate_c_function_import_code_for_module
(
self
,
module
,
env
,
code
):
# Generate import code for all exported C functions in a cimported module.
entries
=
[]
...
...
Cython/Compiler/Naming.py
View file @
6853d59e
...
...
@@ -36,6 +36,7 @@ prop_set_prefix = pyrex_prefix + "setprop_"
type_prefix
=
pyrex_prefix
+
"t_"
typeobj_prefix
=
pyrex_prefix
+
"type_"
var_prefix
=
pyrex_prefix
+
"v_"
varptr_prefix
=
pyrex_prefix
+
"vp_"
wrapperbase_prefix
=
pyrex_prefix
+
"wrapperbase_"
bufstruct_prefix
=
pyrex_prefix
+
"bstruct_"
bufstride_prefix
=
pyrex_prefix
+
"bstride_"
...
...
Cython/Compiler/Nodes.py
View file @
6853d59e
...
...
@@ -969,18 +969,16 @@ class CVarDefNode(StatNode):
return
if
type
.
is_cfunction
:
entry
=
dest_scope
.
declare_cfunction
(
name
,
type
,
declarator
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
,
in_pxd
=
self
.
in_pxd
,
api
=
self
.
api
)
cname
=
cname
,
visibility
=
self
.
visibility
,
in_pxd
=
self
.
in_pxd
,
api
=
self
.
api
)
if
entry
is
not
None
:
entry
.
directive_locals
=
copy
.
copy
(
self
.
directive_locals
)
else
:
if
self
.
directive_locals
:
error
(
self
.
pos
,
"Decorators can only be followed by functions"
)
if
self
.
in_pxd
and
self
.
visibility
!=
'extern'
:
error
(
self
.
pos
,
"Only 'extern' C variable declaration allowed in .pxd file"
)
entry
=
dest_scope
.
declare_var
(
name
,
type
,
declarator
.
pos
,
cname
=
cname
,
visibility
=
visibility
,
api
=
self
.
api
,
is_cdef
=
1
)
cname
=
cname
,
visibility
=
visibility
,
in_pxd
=
self
.
in_pxd
,
api
=
self
.
api
,
is_cdef
=
1
)
class
CStructOrUnionDefNode
(
StatNode
):
...
...
@@ -1700,9 +1698,8 @@ class CFuncDefNode(FuncDefNode):
cname
=
name_declarator
.
cname
self
.
entry
=
env
.
declare_cfunction
(
name
,
type
,
self
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
,
defining
=
self
.
body
is
not
None
,
api
=
self
.
api
,
modifiers
=
self
.
modifiers
)
cname
=
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
,
defining
=
self
.
body
is
not
None
,
modifiers
=
self
.
modifiers
)
self
.
entry
.
inline_func_in_pxd
=
self
.
inline_in_pxd
self
.
return_type
=
type
.
return_type
if
self
.
return_type
.
is_array
and
visibility
!=
'extern'
:
...
...
Cython/Compiler/Symtab.py
View file @
6853d59e
...
...
@@ -507,10 +507,11 @@ class Scope(object):
return entry
def declare_var(self, name, type, pos,
cname = None, visibility = 'private', api = 0, is_cdef = 0):
cname = None, visibility = 'private',
api = 0, in_pxd = 0, is_cdef = 0):
# Add an entry for a variable.
if not cname:
if visibility != 'private':
if visibility != 'private'
or api
:
cname = name
else:
cname = self.mangle(Naming.var_prefix, name)
...
...
@@ -520,7 +521,12 @@ class Scope(object):
error(pos, "
C
++
class
must
have
a
default
constructor
to
be
stack
allocated
")
entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1
entry.api = api
if in_pxd and visibility != 'extern':
entry.defined_in_pxd = 1
entry.used = 1
if api:
entry.api = 1
entry.used = 1
self.control_flow.set_state((), (name, 'initialized'), False)
return entry
...
...
@@ -578,12 +584,11 @@ class Scope(object):
self.pyfunc_entries.append(entry)
def declare_cfunction(self, name, type, pos,
cname = None, visibility = 'private',
defining
= 0,
api = 0, in_pxd
= 0, modifiers = (), utility_code = None):
cname = None, visibility = 'private',
api = 0, in_pxd
= 0,
defining
= 0, modifiers = (), utility_code = None):
# Add an entry for a C function.
if not cname:
if (visibility == 'extern' or
visibility == 'public'and defining):
if visibility != 'private' or api:
cname = name
else:
cname = self.mangle(Naming.func_prefix, name)
...
...
@@ -613,8 +618,6 @@ class Scope(object):
entry.type = type
else:
error(pos, "
Function
signature
does
not
match
previous
declaration
")
entry.cname = cname
entry.func_cname = cname
else:
entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
entry.func_cname = cname
...
...
@@ -1027,13 +1030,12 @@ class ModuleScope(Scope):
return entry
def declare_var(self, name, type, pos,
cname = None, visibility = 'private', api = 0, is_cdef = 0):
cname = None, visibility = 'private',
api = 0, in_pxd = 0, is_cdef = 0):
# Add an entry for a global variable. If it is a Python
# object type, and not declared with cdef, it will live
# in the module dictionary, otherwise it will be a C
# global variable.
entry = Scope.declare_var(self, name, type, pos,
cname=cname, visibility=visibility, api=api, is_cdef=is_cdef)
if not visibility in ('private', 'public', 'extern'):
error(pos, "
Module
-
level
variable
cannot
be
declared
%
s
" % visibility)
if not is_cdef:
...
...
@@ -1042,12 +1044,66 @@ class ModuleScope(Scope):
if not (type.is_pyobject and not type.is_extension_type):
raise InternalError(
"
Non
-
cdef
global
variable
is
not
a
generic
Python
object
")
entry.is_pyglobal = 1
if not cname:
defining = not in_pxd
if (visibility == 'extern' or (visibility == 'public' and defining)):
cname = name
else:
cname = self.mangle(Naming.var_prefix, name)
entry = self.lookup_here(name)
if entry and entry.defined_in_pxd:
#if visibility != 'private' and visibility != entry.visibility:
# warning(pos, "
Variable
'%s'
previously
declared
as
'%s'" % (name, entry.visibility), 1)
if not entry.type.same_as(type):
if visibility == 'extern' and entry.visibility == 'extern':
warning(pos, "
Variable
'%s'
type
does
not
match
previous
declaration
" % name, 1)
entry.type = type
#else:
# error(pos, "
Variable
'%s'
type
does
not
match
previous
declaration
" % name)
if entry.visibility != "
private
":
mangled_cname = self.mangle(Naming.var_prefix, name)
if entry.cname == mangled_cname:
cname = name
entry.cname = name
if not entry.is_implemented:
entry.is_implemented = True
return entry
entry = Scope.declare_var(self, name, type, pos,
cname=cname, visibility=visibility,
api=api, in_pxd=in_pxd, is_cdef=is_cdef)
if is_cdef:
entry.is_cglobal = 1
if entry.type.is_pyobject:
entry.init = 0
self.var_entries.append(entry)
else:
entry.is_pyglobal = 1
return entry
def declare_cfunction(self, name, type, pos,
cname = None, visibility = 'private', api = 0, in_pxd = 0,
defining = 0, modifiers = (), utility_code = None):
# Add an entry for a C function.
if not cname:
if (visibility == 'extern' or (visibility == 'public' and defining)):
cname = name
else:
cname = self.mangle(Naming.func_prefix, name)
entry = self.lookup_here(name)
if entry and entry.defined_in_pxd:
if entry.visibility != "
private
":
mangled_cname = self.mangle(Naming.var_prefix, name)
if entry.cname == mangled_cname:
cname = name
entry.cname = cname
entry.func_cname = cname
entry = Scope.declare_cfunction(
self, name, type, pos,
cname = cname, visibility = visibility, api = api, in_pxd = in_pxd,
defining = defining, modifiers = modifiers, utility_code = utility_code)
return entry
def declare_global(self, name, pos):
...
...
@@ -1315,12 +1371,14 @@ class LocalScope(Scope):
return
entry
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
is_cdef
=
0
):
# Add an entry for a local variable.
if
visibility
in
(
'public'
,
'readonly'
):
error
(
pos
,
"Local variable cannot be declared %s"
%
visibility
)
entry
=
Scope
.
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
is_cdef
=
is_cdef
)
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
in_pxd
=
in_pxd
,
is_cdef
=
is_cdef
)
if
type
.
is_pyobject
and
not
Options
.
init_local_none
:
entry
.
init
=
"0"
entry
.
init_to_none
=
(
type
.
is_pyobject
or
type
.
is_unspecified
)
and
Options
.
init_local_none
...
...
@@ -1397,7 +1455,8 @@ class GeneratorExpressionScope(Scope):
return
'%s%s'
%
(
self
.
genexp_prefix
,
self
.
parent_scope
.
mangle
(
prefix
,
name
))
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
True
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
is_cdef
=
True
):
if
type
is
unspecified_type
:
# if the outer scope defines a type for this variable, inherit it
outer_entry
=
self
.
outer_scope
.
lookup
(
name
)
...
...
@@ -1446,7 +1505,9 @@ class StructOrUnionScope(Scope):
Scope
.
__init__
(
self
,
name
,
None
,
None
)
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
0
,
allow_pyobject
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
is_cdef
=
0
,
allow_pyobject
=
0
):
# Add an entry for an attribute.
if
not
cname
:
cname
=
name
...
...
@@ -1466,8 +1527,8 @@ class StructOrUnionScope(Scope):
return
entry
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
defining
=
0
,
api
=
0
,
in_pxd
=
0
,
modifiers
=
()):
# currently no utility code ...
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
defining
=
0
,
modifiers
=
()):
# currently no utility code ...
return
self
.
declare_var
(
name
,
type
,
pos
,
cname
=
cname
,
visibility
=
visibility
)
...
...
@@ -1513,12 +1574,14 @@ class PyClassScope(ClassScope):
is_py_class_scope
=
1
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
is_cdef
=
0
):
if
type
is
unspecified_type
:
type
=
py_object_type
# Add an entry for a class attribute.
entry
=
Scope
.
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
is_cdef
=
is_cdef
)
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
in_pxd
=
in_pxd
,
is_cdef
=
is_cdef
)
entry
.
is_pyglobal
=
1
# FIXME: WTF?
entry
.
is_pyclass_attr
=
1
return
entry
...
...
@@ -1577,7 +1640,8 @@ class CClassScope(ClassScope):
self
.
parent_type
.
base_type
.
scope
.
needs_gc
())
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
is_cdef
=
0
):
if
is_cdef
:
# Add an entry for an attribute.
if
self
.
defined
:
...
...
@@ -1623,7 +1687,8 @@ class CClassScope(ClassScope):
type
=
py_object_type
# Add an entry for a class attribute.
entry
=
Scope
.
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
is_cdef
=
is_cdef
)
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
in_pxd
=
in_pxd
,
is_cdef
=
is_cdef
)
entry
.
is_member
=
1
entry
.
is_pyglobal
=
1
# xxx: is_pyglobal changes behaviour in so many places that
# I keep it in for now. is_member should be enough
...
...
@@ -1660,9 +1725,8 @@ class CClassScope(ClassScope):
return
ClassScope
.
lookup_here
(
self
,
name
)
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
defining
=
0
,
api
=
0
,
in_pxd
=
0
,
modifiers
=
(),
utility_code
=
None
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
defining
=
0
,
modifiers
=
(),
utility_code
=
None
):
if
get_special_method_signature
(
name
):
error
(
pos
,
"Special methods must be declared with 'def', not 'cdef'"
)
args
=
type
.
args
...
...
@@ -1765,8 +1829,9 @@ class CppClassScope(Scope):
self
.
inherited_var_entries
=
[]
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'extern'
,
api
=
0
,
is_cdef
=
0
,
allow_pyobject
=
0
):
cname
=
None
,
visibility
=
'extern'
,
api
=
0
,
in_pxd
=
0
,
is_cdef
=
0
,
allow_pyobject
=
0
):
# Add an entry for an attribute.
if
not
cname
:
cname
=
name
...
...
@@ -1807,9 +1872,9 @@ class CppClassScope(Scope):
error
(
pos
,
"no matching function for call to %s::%s()"
%
(
self
.
default_constructor
,
self
.
default_constructor
))
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'extern'
,
api
=
0
,
defining
=
0
,
in_pxd
=
0
,
modifiers
=
(),
utility_code
=
None
):
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'extern'
,
api
=
0
,
in_pxd
=
0
,
defining
=
0
,
modifiers
=
(),
utility_code
=
None
):
if
name
==
self
.
name
.
split
(
'::'
)[
-
1
]
and
cname
is
None
:
self
.
check_base_default_constructor
(
pos
)
name
=
'<init>'
...
...
tests/build/module_api.srctree
0 → 100644
View file @
6853d59e
PYTHON setup.py build_ext --inplace
PYTHON test.py
######## setup.py ########
from Cython.Build.Dependencies import cythonize
from distutils.core import setup
exts = cythonize("*.pyx")
for e in exts:
if e.name == "d":
e.sources.append("a.c")
setup(
ext_modules = exts,
)
######## a.pxd ########
ctypedef api float flt
cdef int int0
cdef float flt0
cdef api int int1
cdef api float flt1
cdef public api int int2
cdef public api flt flt2
######## a.pyx ########
cdef int int0 = 1, int1 = 1, int2 = 1
cdef float flt0 = 1, flt1 = 1, flt2 = 1
cdef api int int3 = 1
cdef api flt flt3 = 1
cdef public int int4 = 1
cdef public flt flt4 = 1
def get_int():
return (int0, int1, int2, int3, int4)
def get_flt():
return (flt0, flt1, flt2, flt3, flt4)
######## b.pyx ########
from a cimport *
int0 = int1 = int2 = 7
flt0 = flt1 = flt2 = 7
######## c.pyx ########
# distutils: language = c++
cdef extern from "a_api.h":
int import_a() except -1
ctypedef float flt
int int1, int2, int3
flt flt1, flt2, flt3
import_a()
int1 = int2 = int3 = 5
flt1 = flt2 = flt3 = 5
######## inita.h ########
#if PY_MAJOR_VERSION >= 3
void inita(void)
{
PyObject *sys_modules = NULL;
PyObject *mod = NULL;
sys_modules = PyImport_GetModuleDict();
if (!sys_modules) return;
mod = PyInit_a();
if (!mod) return;
PyDict_SetItemString(sys_modules, (char*)"a", mod);
}
#endif
######## d.pyx ########
cdef extern from "a.h":
pass
cdef extern from "inita.h":
pass
cdef extern from "a.h":
void inita() except *
ctypedef float flt
int int2, int4
flt flt2, flt4
inita()
int2 = int4 = 3
flt2 = flt4 = 3
######## test.py ########
import a
assert a.get_int() == (1,1,1,1,1)
assert a.get_flt() == (1,1,1,1,1)
import b
assert a.get_int() == (7,7,7,1,1)
assert a.get_flt() == (7,7,7,1,1)
import c
assert a.get_int() == (7,5,5,5,1)
assert a.get_flt() == (7,5,5,5,1)
import d
import a
assert a.get_int() == (1,1,3,1,3)
assert a.get_flt() == (1,1,3,1,3)
tests/compile/publicapi_cimport.pyx
View file @
6853d59e
# mode: compile
from
publicapi_pxd_mix
cimport
*
bar0
()
bar1
()
bar2
()
bar3
()
spam0
(
None
)
spam1
(
None
)
spam2
(
None
)
spam3
(
None
)
i0
=
0
i1
=
1
i2
=
2
i3
=
3
tests/compile/publicapi_pxd_mix.pxd
View file @
6853d59e
...
...
@@ -66,8 +66,9 @@ cdef public api void* spam3(object o) except NULL with gil
# --
#cdef public int i1
#cdef api int i2
#cdef public api int i3
cdef
int
i0
=
0
# XXX implement initialization!!!
cdef
public
int
i1
cdef
api
int
i2
cdef
public
api
int
i3
# --
tests/compile/publicapi_pxd_mix.pyx
View file @
6853d59e
...
...
@@ -17,3 +17,8 @@ cdef void* spam0(object o) except NULL: return NULL
cdef
public
void
*
spam1
(
object
o
)
except
NULL
:
return
NULL
cdef
api
void
*
spam2
(
object
o
)
nogil
except
NULL
:
return
NULL
cdef
public
api
void
*
spam3
(
object
o
)
except
NULL
with
gil
:
return
NULL
cdef
int
i0
=
0
# XXX This should not be required!
cdef
public
int
i1
=
1
cdef
api
int
i2
=
2
cdef
public
api
int
i3
=
3
tests/errors/cdef_in_pyclass.pyx
View file @
6853d59e
# mode: error
class
Pyclass
(
object
):
cdef
bad
(
self
):
pass
_ERRORS
=
"""
2
:9: cdef statement not allowed here
4
:9: cdef statement not allowed here
"""
tests/errors/cfunc_directive_in_pyclass.pyx
View file @
6853d59e
# mode: error
import
cython
class
Pyclass
(
object
):
...
...
@@ -6,5 +7,5 @@ class Pyclass(object):
pass
_ERRORS
=
"""
5
:4: cfunc directive is not allowed here
6
:4: cfunc directive is not allowed here
"""
tests/run/capiimpl.pyx
View file @
6853d59e
...
...
@@ -2,6 +2,10 @@ __doc__ = u"""
>>> import sys
>>> sys.getrefcount(Foo.__pyx_vtable__)
2
>>> sys.getrefcount(__pyx_capi__['bar'])
2
>>> sys.getrefcount(__pyx_capi__['spam'])
2
>>> sys.getrefcount(__pyx_capi__['ten'])
2
>>> sys.getrefcount(__pyx_capi__['pi'])
...
...
@@ -10,6 +14,8 @@ __doc__ = u"""
2
>>> sys.getrefcount(__pyx_capi__['dct'])
2
>>> sys.getrefcount(__pyx_capi__['tpl'])
2
>>> sys.getrefcount(__pyx_capi__['one'])
2
>>> sys.getrefcount(__pyx_capi__['two'])
...
...
@@ -22,6 +28,8 @@ cdef public api class Foo [type FooType, object FooObject]:
cdef
void
bar
(
self
):
pass
cdef
public
api
void
bar
():
pass
cdef
api
void
spam
():
pass
...
...
@@ -30,6 +38,7 @@ cdef api double pi = 3.14
cdef
api
object
obj
=
object
()
cdef
api
dict
dct
=
{}
cdef
public
api
int
one
=
1
cdef
public
int
two
=
2
cdef
public
api
tuple
tpl
=
()
cdef
public
api
float
one
=
1
cdef
public
float
two
=
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