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
0a56c99d
Commit
0a56c99d
authored
Mar 31, 2011
by
Lisandro Dalcin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
public/capi: fixes and cleanups, implement exporting cdef variables
parent
b5037005
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
613 additions
and
152 deletions
+613
-152
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+209
-78
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+23
-24
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+11
-7
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+2
-2
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+50
-40
tests/compile/a_capi.pyx
tests/compile/a_capi.pyx
+6
-0
tests/compile/publicapi_api.pyx
tests/compile/publicapi_api.pyx
+65
-0
tests/compile/publicapi_mix.pyx
tests/compile/publicapi_mix.pyx
+77
-0
tests/compile/publicapi_pub.pyx
tests/compile/publicapi_pub.pyx
+65
-0
tests/compile/publicapi_pxd_mix.pxd
tests/compile/publicapi_pxd_mix.pxd
+68
-0
tests/compile/publicapi_pxd_mix.pyx
tests/compile/publicapi_pxd_mix.pyx
+15
-0
tests/run/capiimpl.pyx
tests/run/capiimpl.pyx
+22
-1
No files found.
Cython/Compiler/ModuleNode.py
View file @
0a56c99d
...
...
@@ -96,14 +96,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
f
.
close
()
def
generate_h_code
(
self
,
env
,
options
,
result
):
def
h_entries
(
entries
,
pxd
=
0
):
def
h_entries
(
entries
,
api
=
0
,
pxd
=
0
):
return
[
entry
for
entry
in
entries
if
entry
.
visibility
==
'public'
or
pxd
and
entry
.
defined_in_pxd
]
h_types
=
h_entries
(
env
.
type_entries
)
if
((
entry
.
visibility
==
'public'
)
or
(
api
and
entry
.
api
)
or
(
pxd
and
entry
.
defined_in_pxd
))]
h_types
=
h_entries
(
env
.
type_entries
,
api
=
1
)
h_vars
=
h_entries
(
env
.
var_entries
)
h_funcs
=
h_entries
(
env
.
cfunc_entries
)
h_extension_types
=
h_entries
(
env
.
c_class_entries
)
if
h_types
or
h_vars
or
h_funcs
or
h_extension_types
:
if
(
h_types
or
h_vars
or
h_funcs
or
h_extension_types
)
:
result
.
h_file
=
replace_suffix
(
result
.
c_file
,
".h"
)
h_code
=
Code
.
CCodeWriter
()
Code
.
GlobalState
(
h_code
)
...
...
@@ -115,31 +117,37 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_guard
=
Naming
.
h_guard_prefix
+
self
.
api_name
(
env
)
h_code
.
put_h_guard
(
h_guard
)
self
.
generate_extern_c_macro_definition
(
h_code
)
h_code
.
putln
(
""
)
self
.
generate_type_header_code
(
h_types
,
h_code
)
h_code
.
putln
(
""
)
api_guard
=
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
)
h_code
.
putln
(
"#ifndef %s"
%
api_guard
)
if
h_vars
:
h_code
.
putln
(
""
)
for
entry
in
h_vars
:
self
.
generate_public_declaration
(
entry
,
h_code
,
i_code
)
if
h_funcs
:
h_code
.
putln
(
""
)
for
entry
in
h_funcs
:
self
.
generate_public_declaration
(
entry
,
h_code
,
i_code
)
self
.
generate_extern_c_macro_definition
(
h_code
)
if
h_extension_types
:
h_code
.
putln
(
""
)
for
entry
in
h_extension_types
:
self
.
generate_cclass_header_code
(
entry
.
type
,
h_code
)
if
i_code
:
self
.
generate_cclass_include_code
(
entry
.
type
,
i_code
)
if
h_funcs
:
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif"
)
for
entry
in
h_funcs
:
self
.
generate_public_declaration
(
entry
,
h_code
,
i_code
)
if
h_vars
:
h_code
.
putln
(
""
)
h_code
.
putln
(
"PyMODINIT_FUNC init%s(void);"
%
env
.
module_name
)
for
entry
in
h_vars
:
self
.
generate_public_declaration
(
entry
,
h_code
,
i_code
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif /* !%s */"
%
api_guard
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#if PY_MAJOR_VERSION < 3"
)
h_code
.
putln
(
"PyMODINIT_FUNC init%s(void);"
%
env
.
module_name
)
h_code
.
putln
(
"#else"
)
h_code
.
putln
(
"PyMODINIT_FUNC PyInit_%s(void);"
%
env
.
module_name
)
h_code
.
putln
(
"#endif"
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif /* !%s */"
%
h_guard
)
f
=
open_new_file
(
result
.
h_file
)
try
:
...
...
@@ -160,63 +168,68 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
return
env
.
qualified_name
.
replace
(
"."
,
"__"
)
def
generate_api_code
(
self
,
env
,
result
):
api_funcs
=
[]
public_extension_types
=
[]
has_api_extension_types
=
0
for
entry
in
env
.
cfunc_entries
:
if
entry
.
api
:
api_funcs
.
append
(
entry
)
for
entry
in
env
.
c_class_entries
:
if
entry
.
visibility
==
'public'
:
public_extension_types
.
append
(
entry
)
if
entry
.
api
:
has_api_extension_types
=
1
if
api_funcs
or
has_api_extension_types
:
def
api_entries
(
entries
,
pxd
=
1
):
return
[
entry
for
entry
in
entries
if
entry
.
api
or
(
pxd
and
entry
.
defined_in_pxd
)]
api_vars
=
api_entries
(
env
.
var_entries
)
api_funcs
=
api_entries
(
env
.
cfunc_entries
)
api_extension_types
=
api_entries
(
env
.
c_class_entries
)
if
api_vars
or
api_funcs
or
api_extension_types
:
result
.
api_file
=
replace_suffix
(
result
.
c_file
,
"_api.h"
)
h_code
=
Code
.
CCodeWriter
()
Code
.
GlobalState
(
h_code
)
name
=
self
.
api_name
(
env
)
guard
=
Naming
.
api_guard_prefix
+
name
h_code
.
put_h_guard
(
guard
)
api_guard
=
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
)
h_code
.
put_h_guard
(
api_guard
)
h_code
.
putln
(
'#include "Python.h"'
)
if
result
.
h_file
:
h_code
.
putln
(
'#include "%s"'
%
os
.
path
.
basename
(
result
.
h_file
))
for
entry
in
public_extension_types
:
type
=
entry
.
type
if
api_extension_types
:
h_code
.
putln
(
""
)
h_code
.
putln
(
"static PyTypeObject *%s;"
%
type
.
typeptr_cname
)
for
entry
in
api_extension_types
:
type
=
entry
.
type
h_code
.
putln
(
"static PyTypeObject *%s = 0;"
%
type
.
typeptr_cname
)
h_code
.
putln
(
"#define %s (*%s)"
%
(
type
.
typeobj_cname
,
type
.
typeptr_cname
))
if
api_funcs
:
h_code
.
putln
(
""
)
for
entry
in
api_funcs
:
type
=
CPtrType
(
entry
.
type
)
h_code
.
putln
(
"static %s;"
%
type
.
declaration_code
(
entry
.
cname
))
cname
=
env
.
mangle
(
Naming
.
func_prefix
,
entry
.
name
)
h_code
.
putln
(
"static %s = 0;"
%
type
.
declaration_code
(
cname
))
h_code
.
putln
(
"#define %s %s"
%
(
entry
.
name
,
cname
))
if
api_vars
:
h_code
.
putln
(
""
)
h_code
.
put_h_guard
(
Naming
.
api_func_guard
+
"import_module"
)
for
entry
in
api_vars
:
type
=
CPtrType
(
entry
.
type
)
cname
=
env
.
mangle
(
Naming
.
var_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
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif"
)
if
api_vars
:
h_code
.
put
(
voidptr_import_utility_code
.
impl
)
if
api_funcs
:
h_code
.
putln
(
""
)
h_code
.
put
(
function_import_utility_code
.
impl
)
if
public_extension_types
:
h_code
.
putln
(
""
)
if
api_extension_types
:
h_code
.
put
(
type_import_utility_code
.
impl
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"static int import_%s(void) {"
%
name
)
h_code
.
putln
(
"static int import_%s(void) {"
%
self
.
api_name
(
env
)
)
h_code
.
putln
(
"PyObject *module = 0;"
)
h_code
.
putln
(
'module = __Pyx_ImportModule("%s");'
%
env
.
qualified_name
)
h_code
.
putln
(
"if (!module) goto bad;"
)
for
entry
in
api_funcs
:
cname
=
env
.
mangle
(
Naming
.
func_prefix
,
entry
.
name
)
sig
=
entry
.
type
.
signature_string
()
h_code
.
putln
(
'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;'
%
(
entry
.
name
,
entry
.
cname
,
sig
))
'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
)
sig
=
entry
.
type
.
declaration_code
(
""
)
h_code
.
putln
(
'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
%
(
entry
.
name
,
cname
,
sig
))
h_code
.
putln
(
"Py_DECREF(module); module = 0;"
)
for
entry
in
public
_extension_types
:
for
entry
in
api
_extension_types
:
self
.
generate_type_import_call
(
entry
.
type
,
h_code
,
"if (!%s) goto bad;"
%
entry
.
type
.
typeptr_cname
)
...
...
@@ -226,7 +239,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_code
.
putln
(
"return -1;"
)
h_code
.
putln
(
"}"
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif
"
)
h_code
.
putln
(
"#endif
/* !%s */"
%
api_guard
)
f
=
open_new_file
(
result
.
api_file
)
try
:
...
...
@@ -235,8 +248,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
f
.
close
()
def
generate_cclass_header_code
(
self
,
type
,
h_code
):
h_code
.
putln
(
"%s
DL_IMPORT(PyTypeObject)
%s;"
%
(
h_code
.
putln
(
"%s
%s
%s;"
%
(
Naming
.
extern_c_macro
,
PyrexTypes
.
public_decl
(
"PyTypeObject"
,
"DL_IMPORT"
),
type
.
typeobj_cname
))
def
generate_cclass_include_code
(
self
,
type
,
i_code
):
...
...
@@ -426,8 +440,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_objstruct_definition
(
type
,
code
)
for
entry
in
vtabslot_list
:
self
.
generate_objstruct_definition
(
entry
.
type
,
code
)
self
.
generate_typeobj_predeclaration
(
entry
,
code
)
for
entry
in
vtab_list
:
self
.
generate_typeobj
ect
_predeclaration
(
entry
,
code
)
self
.
generate_typeobj_predeclaration
(
entry
,
code
)
self
.
generate_exttype_vtable_struct
(
entry
,
code
)
self
.
generate_exttype_vtabptr_declaration
(
entry
,
code
)
...
...
@@ -724,10 +739,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def
generate_extern_c_macro_definition
(
self
,
code
):
name
=
Naming
.
extern_c_macro
code
.
putln
(
"#ifdef __cplusplus"
)
code
.
putln
(
'#define %s extern "C"'
%
name
)
code
.
putln
(
"#else"
)
code
.
putln
(
"#define %s extern"
%
name
)
code
.
putln
(
"#ifndef %s"
%
name
)
code
.
putln
(
" #ifdef __cplusplus"
)
code
.
putln
(
' #define %s extern "C"'
%
name
)
code
.
putln
(
" #else"
)
code
.
putln
(
" #define %s extern"
%
name
)
code
.
putln
(
" #endif"
)
code
.
putln
(
"#endif"
)
def
generate_includes
(
self
,
env
,
cimported_modules
,
code
):
...
...
@@ -789,10 +806,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def
generate_typedef
(
self
,
entry
,
code
):
base_type
=
entry
.
type
.
typedef_base_type
if
base_type
.
is_numeric
:
try
:
writer
=
code
.
globalstate
[
'numeric_typedefs'
]
except
KeyError
:
writer
=
code
else
:
writer
=
code
writer
.
putln
(
""
)
writer
.
mark_pos
(
entry
.
pos
)
writer
.
putln
(
"typedef %s;"
%
base_type
.
declaration_code
(
entry
.
cname
))
def
sue_header_footer
(
self
,
type
,
kind
,
name
):
...
...
@@ -816,7 +836,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
globalstate
.
use_utility_code
(
packed_struct_utility_code
)
header
,
footer
=
\
self
.
sue_header_footer
(
type
,
kind
,
type
.
cname
)
code
.
putln
(
""
)
if
packed
:
code
.
putln
(
"#if defined(__SUNPRO_C)"
)
code
.
putln
(
" #pragma pack(1)"
)
...
...
@@ -847,7 +866,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
name
=
entry
.
cname
or
entry
.
name
or
""
header
,
footer
=
\
self
.
sue_header_footer
(
type
,
"enum"
,
name
)
code
.
putln
(
""
)
code
.
putln
(
header
)
enum_values
=
entry
.
enum_values
if
not
enum_values
:
...
...
@@ -873,21 +891,23 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
value_code
)
code
.
putln
(
footer
)
def
generate_typeobj
ect
_predeclaration
(
self
,
entry
,
code
):
def
generate_typeobj_predeclaration
(
self
,
entry
,
code
):
code
.
putln
(
""
)
name
=
entry
.
type
.
typeobj_cname
if
name
:
if
entry
.
visibility
==
'extern'
and
not
entry
.
in_cinclude
:
code
.
putln
(
"%s
DL_IMPORT(PyTypeObject)
%s;"
%
(
code
.
putln
(
"%s
%s
%s;"
%
(
Naming
.
extern_c_macro
,
PyrexTypes
.
public_decl
(
"PyTypeObject"
,
"DL_IMPORT"
),
name
))
elif
entry
.
visibility
==
'public'
:
code
.
putln
(
"%s
DL_EXPORT(PyTypeObject)
%s;"
%
(
code
.
putln
(
"%s
%s
%s;"
%
(
Naming
.
extern_c_macro
,
PyrexTypes
.
public_decl
(
"PyTypeObject"
,
"DL_EXPORT"
),
name
))
# ??? Do we really need the rest of this? ???
#else:
# code.putln("static
forward
PyTypeObject %s;" % name)
# code.putln("static PyTypeObject %s;" % name)
def
generate_exttype_vtable_struct
(
self
,
entry
,
code
):
code
.
mark_pos
(
entry
.
pos
)
...
...
@@ -927,7 +947,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
return
# Forward declared but never defined
header
,
footer
=
\
self
.
sue_header_footer
(
type
,
"struct"
,
type
.
objstruct_cname
)
code
.
putln
(
""
)
code
.
putln
(
header
)
base_type
=
type
.
base_type
if
base_type
:
...
...
@@ -966,24 +985,26 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
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
in
(
'public'
,
'extern'
):
if
entry
.
visibility
==
'public'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
dll_linkage
=
"DL_EXPORT"
elif
entry
.
visibility
==
'extern'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
dll_linkage
=
"DL_IMPORT"
elif
entry
.
visibility
==
'private'
:
storage_class
=
"static "
dll_linkage
=
None
else
:
storage_class
=
"static "
dll_linkage
=
None
type
=
entry
.
type
if
not
definition
and
entry
.
defined_in_pxd
:
type
=
CPtrType
(
type
)
header
=
type
.
declaration_code
(
entry
.
cname
,
dll_linkage
=
dll_linkage
)
if
entry
.
visibility
==
'private'
:
storage_class
=
"static "
elif
entry
.
visibility
==
'public'
:
storage_class
=
""
else
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
if
entry
.
func_modifiers
:
modifiers
=
'%s '
%
' '
.
join
([
modifier
.
upper
()
for
modifier
in
entry
.
func_modifiers
])
modifiers
=
"%s "
%
' '
.
join
(
entry
.
func_modifiers
).
upper
()
else
:
modifiers
=
''
code
.
putln
(
"%s%s%s; /*proto*/"
%
(
...
...
@@ -1806,6 +1827,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"/*--- Global init code ---*/"
)
self
.
generate_global_init_code
(
env
,
code
)
code
.
putln
(
"/*--- Variable export code ---*/"
)
self
.
generate_c_variable_export_code
(
env
,
code
)
code
.
putln
(
"/*--- Function export code ---*/"
)
self
.
generate_c_function_export_code
(
env
,
code
)
...
...
@@ -1993,6 +2017,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
entry
.
type
.
is_pyobject
and
entry
.
used
:
code
.
put_init_var_to_py_none
(
entry
,
nanny
=
False
)
def
generate_c_variable_export_code
(
self
,
env
,
code
):
# Generate code to create PyCFunction wrappers for exported C functions.
for
entry
in
env
.
var_entries
:
if
entry
.
api
or
entry
.
defined_in_pxd
:
env
.
use_utility_code
(
voidptr_export_utility_code
)
signature
=
entry
.
type
.
declaration_code
(
""
)
code
.
putln
(
'if (__Pyx_ExportVoidPtr("%s", (void *)&%s, "%s") < 0) %s'
%
(
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.
for
entry
in
env
.
cfunc_entries
:
...
...
@@ -2336,6 +2372,45 @@ bad:
#------------------------------------------------------------------------------------
voidptr_export_utility_code
=
UtilityCode
(
proto
=
"""
static int __Pyx_ExportVoidPtr(const char *name, void *p, const char *sig); /*proto*/
"""
,
impl
=
r"""
static int __Pyx_ExportVoidPtr(const char *name, void *p, const char *sig) {
PyObject *d = 0;
PyObject *cobj = 0;
d = PyObject_GetAttrString(%(MODULE)s, (char *)"%(API)s");
if (!d) {
PyErr_Clear();
d = PyDict_New();
if (!d)
goto bad;
Py_INCREF(d);
if (PyModule_AddObject(%(MODULE)s, (char *)"%(API)s", d) < 0)
goto bad;
}
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
cobj = PyCapsule_New(p, sig, 0);
#else
cobj = PyCObject_FromVoidPtrAndDesc(p, (void *)sig, 0);
#endif
if (!cobj)
goto bad;
if (PyDict_SetItemString(d, name, cobj) < 0)
goto bad;
Py_DECREF(cobj);
Py_DECREF(d);
return 0;
bad:
Py_XDECREF(cobj);
Py_XDECREF(d);
return -1;
}
"""
%
{
'MODULE'
:
Naming
.
module_cname
,
'API'
:
Naming
.
api_name
}
)
function_export_utility_code
=
UtilityCode
(
proto
=
"""
static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/
...
...
@@ -2380,6 +2455,62 @@ bad:
"""
%
{
'MODULE'
:
Naming
.
module_cname
,
'API'
:
Naming
.
api_name
}
)
voidptr_import_utility_code
=
UtilityCode
(
proto
=
"""
static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, const char *sig); /*proto*/
"""
,
impl
=
"""
#ifndef __PYX_HAVE_RT_ImportVoidPtr
#define __PYX_HAVE_RT_ImportVoidPtr
static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, const char *sig) {
PyObject *d = 0;
PyObject *cobj = 0;
d = PyObject_GetAttrString(module, (char *)"%(API)s");
if (!d)
goto bad;
cobj = PyDict_GetItemString(d, name);
if (!cobj) {
PyErr_Format(PyExc_ImportError,
"%%s does not export expected C variable %%s",
PyModule_GetName(module), name);
goto bad;
}
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
if (!PyCapsule_IsValid(cobj, sig)) {
PyErr_Format(PyExc_TypeError,
"C variable %%s.%%s has wrong signature (expected %%s, got %%s)",
PyModule_GetName(module), name, sig, PyCapsule_GetName(cobj));
goto bad;
}
*p = PyCapsule_GetPointer(cobj, sig);
#else
{const char *desc, *s1, *s2;
desc = (const char *)PyCObject_GetDesc(cobj);
if (!desc)
goto bad;
s1 = desc; s2 = sig;
while (*s1 != '
\
\
0' && *s1 == *s2) { s1++; s2++; }
if (*s1 != *s2) {
PyErr_Format(PyExc_TypeError,
"C variable %%s.%%s has wrong signature (expected %%s, got %%s)",
PyModule_GetName(module), name, sig, desc);
goto bad;
}
*p = PyCObject_AsVoidPtr(cobj);}
#endif
if (!(*p))
goto bad;
Py_DECREF(d);
return 0;
bad:
Py_XDECREF(d);
return -1;
}
#endif
"""
%
dict
(
API
=
Naming
.
api_name
)
)
function_import_utility_code
=
UtilityCode
(
proto
=
"""
static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/
...
...
Cython/Compiler/Nodes.py
View file @
0a56c99d
...
...
@@ -970,7 +970,7 @@ class CVarDefNode(StatNode):
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
,
is_cdef
=
1
)
cname
=
cname
,
visibility
=
visibility
,
api
=
self
.
api
,
is_cdef
=
1
)
entry
.
needs_property
=
need_property
...
...
@@ -980,6 +980,7 @@ class CStructOrUnionDefNode(StatNode):
# kind "struct" or "union"
# typedef_flag boolean
# visibility "public" or "private"
# api boolean
# in_pxd boolean
# attributes [CVarDefNode] or None
# entry Entry
...
...
@@ -995,7 +996,8 @@ class CStructOrUnionDefNode(StatNode):
scope
=
StructOrUnionScope
(
self
.
name
)
self
.
entry
=
env
.
declare_struct_or_union
(
self
.
name
,
self
.
kind
,
scope
,
self
.
typedef_flag
,
self
.
pos
,
self
.
cname
,
visibility
=
self
.
visibility
,
packed
=
self
.
packed
)
self
.
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
,
packed
=
self
.
packed
)
if
self
.
attributes
is
not
None
:
if
self
.
in_pxd
and
not
env
.
in_cinclude
:
self
.
entry
.
defined_in_pxd
=
1
...
...
@@ -1078,6 +1080,7 @@ class CEnumDefNode(StatNode):
# items [CEnumDefItemNode]
# typedef_flag boolean
# visibility "public" or "private"
# api boolean
# in_pxd boolean
# entry Entry
...
...
@@ -1086,7 +1089,7 @@ class CEnumDefNode(StatNode):
def
analyse_declarations
(
self
,
env
):
self
.
entry
=
env
.
declare_enum
(
self
.
name
,
self
.
pos
,
cname
=
self
.
cname
,
typedef_flag
=
self
.
typedef_flag
,
visibility
=
self
.
visibility
)
visibility
=
self
.
visibility
,
api
=
self
.
api
)
if
self
.
items
is
not
None
:
if
self
.
in_pxd
and
not
env
.
in_cinclude
:
self
.
entry
.
defined_in_pxd
=
1
...
...
@@ -1097,7 +1100,7 @@ class CEnumDefNode(StatNode):
pass
def
generate_execution_code
(
self
,
code
):
if
self
.
visibility
==
'public'
:
if
self
.
visibility
==
'public'
or
self
.
api
:
temp
=
code
.
funcstate
.
allocate_temp
(
PyrexTypes
.
py_object_type
,
manage_ref
=
True
)
for
item
in
self
.
entry
.
enum_values
:
code
.
putln
(
"%s = PyInt_FromLong(%s); %s"
%
(
...
...
@@ -1129,7 +1132,7 @@ class CEnumDefItemNode(StatNode):
self
.
value
.
analyse_const_expression
(
env
)
entry
=
env
.
declare_const
(
self
.
name
,
enum_entry
.
type
,
self
.
value
,
self
.
pos
,
cname
=
self
.
cname
,
visibility
=
enum_entry
.
visibility
)
visibility
=
enum_entry
.
visibility
,
api
=
enum_entry
.
api
)
enum_entry
.
enum_values
.
append
(
entry
)
...
...
@@ -1137,6 +1140,7 @@ class CTypeDefNode(StatNode):
# base_type CBaseTypeNode
# declarator CDeclaratorNode
# visibility "public" or "private"
# api boolean
# in_pxd boolean
child_attrs
=
[
"base_type"
,
"declarator"
]
...
...
@@ -1147,7 +1151,7 @@ class CTypeDefNode(StatNode):
name
=
name_declarator
.
name
cname
=
name_declarator
.
cname
entry
=
env
.
declare_typedef
(
name
,
type
,
self
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
)
cname
=
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
)
if
self
.
in_pxd
and
not
env
.
in_cinclude
:
entry
.
defined_in_pxd
=
1
...
...
@@ -1740,7 +1744,6 @@ class CFuncDefNode(FuncDefNode):
def
generate_function_header
(
self
,
code
,
with_pymethdef
,
with_opt_args
=
1
,
with_dispatch
=
1
,
cname
=
None
):
arg_decls
=
[]
type
=
self
.
type
visibility
=
self
.
entry
.
visibility
for
arg
in
type
.
args
[:
len
(
type
.
args
)
-
type
.
optional_arg_count
]:
arg_decls
.
append
(
arg
.
declaration_code
())
if
with_dispatch
and
self
.
overridable
:
...
...
@@ -1754,24 +1757,20 @@ class CFuncDefNode(FuncDefNode):
if
cname
is
None
:
cname
=
self
.
entry
.
func_cname
entity
=
type
.
function_header_code
(
cname
,
', '
.
join
(
arg_decls
))
if
visibility
==
'public
'
:
dll_linkage
=
"DL_EXPORT
"
if
self
.
entry
.
visibility
==
'private
'
:
storage_class
=
"static
"
else
:
dll_linkage
=
None
header
=
self
.
return_type
.
declaration_code
(
entity
,
dll_linkage
=
dll_linkage
)
if
visibility
==
'extern'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
elif
visibility
==
'public'
:
storage_class
=
""
else
:
storage_class
=
"static
"
dll_linkage
=
None
modifiers
=
"
"
if
'inline'
in
self
.
modifiers
:
self
.
modifiers
[
self
.
modifiers
.
index
(
'inline'
)]
=
'cython_inline'
code
.
putln
(
"%s%s %s {"
%
(
storage_class
,
' '
.
join
(
self
.
modifiers
).
upper
(),
# macro forms
header
))
if
self
.
modifiers
:
modifiers
=
"%s "
%
' '
.
join
(
self
.
modifiers
).
upper
()
header
=
self
.
return_type
.
declaration_code
(
entity
,
dll_linkage
=
dll_linkage
)
#print (storage_class, modifiers, header)
code
.
putln
(
"%s%s%s {"
%
(
storage_class
,
modifiers
,
header
))
def
generate_argument_declarations
(
self
,
env
,
code
):
for
arg
in
self
.
args
:
...
...
Cython/Compiler/Parsing.py
View file @
0a56c99d
...
...
@@ -2420,7 +2420,7 @@ def p_c_enum_definition(s, pos, ctx):
return
Nodes
.
CEnumDefNode
(
pos
,
name
=
name
,
cname
=
cname
,
items
=
items
,
typedef_flag
=
ctx
.
typedef_flag
,
visibility
=
ctx
.
visibility
,
in_pxd
=
ctx
.
level
==
'module_pxd'
)
api
=
ctx
.
api
,
in_pxd
=
ctx
.
level
==
'module_pxd'
)
def
p_c_enum_line
(
s
,
ctx
,
items
):
if
s
.
sy
!=
'pass'
:
...
...
@@ -2481,7 +2481,7 @@ def p_c_struct_or_union_definition(s, pos, ctx):
return
Nodes
.
CStructOrUnionDefNode
(
pos
,
name
=
name
,
cname
=
cname
,
kind
=
kind
,
attributes
=
attributes
,
typedef_flag
=
ctx
.
typedef_flag
,
visibility
=
ctx
.
visibility
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
packed
=
packed
)
api
=
ctx
.
api
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
packed
=
packed
)
def
p_visibility
(
s
,
prev_visibility
):
pos
=
s
.
position
()
...
...
@@ -2566,7 +2566,8 @@ def p_ctypedef_statement(s, ctx):
s
.
expect_newline
(
"Syntax error in ctypedef statement"
)
return
Nodes
.
CTypeDefNode
(
pos
,
base_type
=
base_type
,
declarator
=
declarator
,
visibility
=
visibility
,
declarator
=
declarator
,
visibility
=
visibility
,
api
=
api
,
in_pxd
=
ctx
.
level
==
'module_pxd'
)
def
p_decorators
(
s
):
...
...
@@ -2693,8 +2694,8 @@ def p_c_class_definition(s, pos, ctx):
base_class_module
=
"."
.
join
(
base_class_path
[:
-
1
])
base_class_name
=
base_class_path
[
-
1
]
if
s
.
sy
==
'['
:
if
ctx
.
visibility
not
in
(
'public'
,
'extern'
):
error
(
s
.
position
(),
"Name options only allowed for 'public' or 'extern' C class"
)
if
ctx
.
visibility
not
in
(
'public'
,
'extern'
)
and
not
ctx
.
api
:
error
(
s
.
position
(),
"Name options only allowed for 'public'
, 'api',
or 'extern' C class"
)
objstruct_name
,
typeobj_name
=
p_c_class_options
(
s
)
if
s
.
sy
==
':'
:
if
ctx
.
level
==
'module_pxd'
:
...
...
@@ -2718,7 +2719,10 @@ def p_c_class_definition(s, pos, ctx):
error
(
pos
,
"Type object name specification required for 'public' C class"
)
elif
ctx
.
visibility
==
'private'
:
if
ctx
.
api
:
error
(
pos
,
"Only 'public' C class can be declared 'api'"
)
if
not
objstruct_name
:
error
(
pos
,
"Object struct name specification required for 'api' C class"
)
if
not
typeobj_name
:
error
(
pos
,
"Type object name specification required for 'api' C class"
)
else
:
error
(
pos
,
"Invalid class visibility '%s'"
%
ctx
.
visibility
)
return
Nodes
.
CClassDefNode
(
pos
,
...
...
Cython/Compiler/PyrexTypes.py
View file @
0a56c99d
...
...
@@ -1190,8 +1190,8 @@ class CComplexType(CNumericType):
visibility
=
"extern"
)
scope
.
parent_type
=
self
scope
.
directives
=
{}
scope
.
declare_var
(
"real"
,
self
.
real_type
,
None
,
"real"
,
is_cdef
=
True
)
scope
.
declare_var
(
"imag"
,
self
.
real_type
,
None
,
"imag"
,
is_cdef
=
True
)
scope
.
declare_var
(
"real"
,
self
.
real_type
,
None
,
cname
=
"real"
,
is_cdef
=
True
)
scope
.
declare_var
(
"imag"
,
self
.
real_type
,
None
,
cname
=
"imag"
,
is_cdef
=
True
)
entry
=
scope
.
declare_cfunction
(
"conjugate"
,
CFuncType
(
self
,
[
CFuncTypeArg
(
"self"
,
self
,
None
)],
nogil
=
True
),
...
...
Cython/Compiler/Symtab.py
View file @
0a56c99d
...
...
@@ -361,10 +361,10 @@ class Scope(object):
def qualify_name(self, name):
return EncodedString("
%
s
.
%
s
" % (self.qualified_name, name))
def declare_const(self, name, type, value, pos, cname = None, visibility = 'private'):
def declare_const(self, name, type, value, pos, cname = None, visibility = 'private'
, api = 0
):
# Add an entry for a named constant.
if not cname:
if self.in_cinclude or
visibility == 'public'
:
if self.in_cinclude or
(visibility == 'public' or api)
:
cname = name
else:
cname = self.mangle(Naming.enum_prefix, name)
...
...
@@ -374,21 +374,22 @@ class Scope(object):
return entry
def declare_type(self, name, type, pos,
cname = None, visibility = 'private', defining = 1, shadow = 0):
cname = None, visibility = 'private',
api = 0,
defining = 1, shadow = 0):
# Add an entry for a type definition.
if not cname:
cname = name
entry = self.declare(name, cname, type, pos, visibility, shadow)
entry.is_type = 1
entry.api = api
if defining:
self.type_entries.append(entry)
# here we would set as_variable to an object representing this type
return entry
def declare_typedef(self, name, base_type, pos, cname = None,
visibility = 'private'
):
visibility = 'private', api = 0
):
if not cname:
if self.in_cinclude or
visibility == 'public'
:
if self.in_cinclude or
(visibility == 'public' or api)
:
cname = name
else:
cname = self.mangle(Naming.type_prefix, name)
...
...
@@ -398,16 +399,18 @@ class Scope(object):
except ValueError, e:
error(pos, e.args[0])
type = PyrexTypes.error_type
entry = self.declare_type(name, type, pos, cname, visibility)
entry = self.declare_type(name, type, pos, cname,
visibility = visibility, api = api)
type.qualified_name = entry.qualified_name
return entry
def declare_struct_or_union(self, name, kind, scope,
typedef_flag, pos, cname = None, visibility = 'private',
typedef_flag, pos, cname = None,
visibility = 'private', api = 0,
packed = False):
# Add an entry for a struct or union definition.
if not cname:
if self.in_cinclude or
visibility == 'public'
:
if self.in_cinclude or
(visibility == 'public' or api)
:
cname = name
else:
cname = self.mangle(Naming.type_prefix, name)
...
...
@@ -416,7 +419,8 @@ class Scope(object):
type = PyrexTypes.CStructOrUnionType(
name, kind, scope, typedef_flag, cname, packed)
entry = self.declare_type(name, type, pos, cname,
visibility = visibility, defining = scope is not None)
visibility = visibility, api = api,
defining = scope is not None)
self.sue_entries.append(entry)
type.entry = entry
else:
...
...
@@ -484,10 +488,10 @@ class Scope(object):
entry.name, entry.visibility))
def declare_enum(self, name, pos, cname, typedef_flag,
visibility = 'private'):
visibility = 'private'
, api = 0
):
if name:
if not cname:
if self.in_cinclude or
visibility == 'public'
:
if self.in_cinclude or
(visibility == 'public' or api)
:
cname = name
else:
cname = self.mangle(Naming.type_prefix, name)
...
...
@@ -495,13 +499,13 @@ class Scope(object):
else:
type = PyrexTypes.c_anon_enum_type
entry = self.declare_type(name, type, pos, cname = cname,
visibility = visibility)
visibility = visibility
, api = api
)
entry.enum_values = []
self.sue_entries.append(entry)
return entry
def declare_var(self, name, type, pos,
cname = None, visibility = 'private'
, is_cdef = 0):
cname = None, visibility = 'private', api = 0
, is_cdef = 0):
# Add an entry for a variable.
if not cname:
if visibility != 'private':
...
...
@@ -514,6 +518,7 @@ 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
self.control_flow.set_state((), (name, 'initialized'), False)
return entry
...
...
@@ -995,13 +1000,13 @@ class ModuleScope(Scope):
return entry
def declare_var(self, name, type, pos,
cname = None, visibility = 'private'
, is_cdef = 0):
cname = None, visibility = 'private', api = 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, visibility,
is_cdef)
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:
...
...
@@ -1035,8 +1040,8 @@ class ModuleScope(Scope):
# the non-typedef struct internally to avoid needing forward
# declarations for anonymous structs.
if typedef_flag and visibility != 'extern':
if
visibility != 'public'
:
warning(pos, "
ctypedef
only
valid
for
public
and
extern
classes
", 2)
if
not (visibility == 'public' or api)
:
warning(pos, "
ctypedef
only
valid
for
'extern'
,
'public'
,
and
'api'
", 2)
objtypedef_cname = objstruct_cname
typedef_flag = 0
else:
...
...
@@ -1283,12 +1288,12 @@ class LocalScope(Scope):
return
entry
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
is_cdef
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
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
,
visibility
,
is_cdef
)
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
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
...
...
@@ -1354,7 +1359,7 @@ 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'
,
is_cdef
=
True
):
cname
=
None
,
visibility
=
'private'
,
api
=
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
)
...
...
@@ -1397,7 +1402,7 @@ class StructOrUnionScope(Scope):
Scope
.
__init__
(
self
,
name
,
None
,
None
)
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
is_cdef
=
0
,
allow_pyobject
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
0
,
allow_pyobject
=
0
):
# Add an entry for an attribute.
if
not
cname
:
cname
=
name
...
...
@@ -1419,7 +1424,8 @@ class StructOrUnionScope(Scope):
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
defining
=
0
,
api
=
0
,
in_pxd
=
0
,
modifiers
=
()):
# currently no utility code ...
return
self
.
declare_var
(
name
,
type
,
pos
,
cname
,
visibility
)
return
self
.
declare_var
(
name
,
type
,
pos
,
cname
=
cname
,
visibility
=
visibility
)
class
ClassScope
(
Scope
):
# Abstract base class for namespace of
...
...
@@ -1463,12 +1469,12 @@ class PyClassScope(ClassScope):
is_py_class_scope
=
1
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
is_cdef
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
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
,
visibility
,
is_cdef
)
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
is_cdef
=
is_cdef
)
entry
.
is_pyglobal
=
1
entry
.
is_pyclass_attr
=
1
return
entry
...
...
@@ -1513,7 +1519,7 @@ class CClassScope(ClassScope):
self
.
parent_type
.
base_type
.
scope
.
needs_gc
())
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
is_cdef
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
0
):
if
is_cdef
:
# Add an entry for an attribute.
if
self
.
defined
:
...
...
@@ -1553,7 +1559,7 @@ class CClassScope(ClassScope):
type
=
py_object_type
# Add an entry for a class attribute.
entry
=
Scope
.
declare_var
(
self
,
name
,
type
,
pos
,
cname
,
visibility
,
is_cdef
)
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
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
...
...
@@ -1569,7 +1575,8 @@ class CClassScope(ClassScope):
if
name
==
"__new__"
:
error
(
pos
,
"__new__ method of extension type will change semantics "
"in a future version of Pyrex and Cython. Use __cinit__ instead."
)
entry
=
self
.
declare_var
(
name
,
py_object_type
,
pos
,
visibility
=
'extern'
)
entry
=
self
.
declare_var
(
name
,
py_object_type
,
pos
,
visibility
=
'extern'
)
special_sig
=
get_special_method_signature
(
name
)
if
special_sig
:
# Special methods get put in the method table with a particular
...
...
@@ -1694,7 +1701,8 @@ class CppClassScope(Scope):
self
.
inherited_var_entries
=
[]
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'extern'
,
is_cdef
=
0
,
allow_pyobject
=
0
):
cname
=
None
,
visibility
=
'extern'
,
api
=
0
,
is_cdef
=
0
,
allow_pyobject
=
0
):
# Add an entry for an attribute.
if
not
cname
:
cname
=
name
...
...
@@ -1735,15 +1743,16 @@ 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'
,
defining
=
0
,
api
=
0
,
in_pxd
=
0
,
modifiers
=
(),
utility_code
=
None
):
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'extern'
,
api
=
0
,
defining
=
0
,
in_pxd
=
0
,
modifiers
=
(),
utility_code
=
None
):
if
name
==
self
.
name
.
split
(
'::'
)[
-
1
]
and
cname
is
None
:
self
.
check_base_default_constructor
(
pos
)
name
=
'<init>'
type
.
return_type
=
self
.
lookup
(
self
.
name
).
type
prev_entry
=
self
.
lookup_here
(
name
)
entry
=
self
.
declare_var
(
name
,
type
,
pos
,
cname
,
visibility
)
entry
=
self
.
declare_var
(
name
,
type
,
pos
,
cname
=
cname
,
visibility
=
visibility
)
if
prev_entry
:
entry
.
overloaded_alternatives
=
prev_entry
.
all_alternatives
()
entry
.
utility_code
=
utility_code
...
...
@@ -1768,7 +1777,8 @@ class CppClassScope(Scope):
for
base_entry
in
base_scope
.
cfunc_entries
:
entry
=
self
.
declare_cfunction
(
base_entry
.
name
,
base_entry
.
type
,
base_entry
.
pos
,
base_entry
.
cname
,
base_entry
.
visibility
,
base_entry
.
func_modifiers
,
base_entry
.
visibility
,
0
,
modifiers
=
base_entry
.
func_modifiers
,
utility_code
=
base_entry
.
utility_code
)
entry
.
is_inherited
=
1
...
...
tests/compile/a_capi.pyx
View file @
0a56c99d
...
...
@@ -11,6 +11,12 @@ cdef public class C[type C_Type, object C_Obj]:
cdef
public
Zax
*
blarg
cdef
public
C
c_pub
=
C
()
cdef
api
C
c_api
=
C
()
cdef
public
dict
o_pub
=
C
()
cdef
api
list
o_api
=
C
()
cdef
api
float
f
(
Foo
*
x
):
pass
...
...
tests/compile/publicapi_api.pyx
0 → 100644
View file @
0a56c99d
# --
ctypedef
int
Int0
ctypedef
api
int
Int1
ctypedef
enum
EnumA0
:
EA0
ctypedef
api
enum
EnumA1
:
EA1
cdef
enum
EnumB0
:
EB0
=
0
cdef
api
enum
EnumB1
:
EB1
=
1
cdef
Int0
i0
=
0
cdef
EnumA0
ea0
=
EA0
cdef
EnumB0
eb0
=
EB0
cdef
api
Int1
i1
=
0
cdef
api
EnumA1
ea1
=
EA1
cdef
api
EnumB1
eb1
=
EB1
# --
ctypedef
struct
StructA0
:
int
SA0
ctypedef
api
struct
StructA1
:
int
SA1
cdef
struct
StructB0
:
int
SB0
cdef
api
struct
StructB1
:
int
SB1
cdef
StructA0
sa0
=
{
'SA0'
:
0
}
cdef
StructB0
sb0
=
{
'SB0'
:
2
}
cdef
api
StructA1
sa1
=
{
'SA1'
:
1
}
cdef
api
StructB1
sb1
=
{
'SB1'
:
3
}
# --
ctypedef
class
Foo0
:
pass
ctypedef
api
class
Foo1
[
type
PyFoo1_Type
,
object
PyFoo1_Object
]:
pass
cdef
class
Bar0
:
pass
cdef
api
class
Bar1
[
type
PyBar1_Type
,
object
PyBar1_Object
]:
pass
cdef
Foo0
f0
=
None
cdef
Bar0
b0
=
None
cdef
api
Foo1
f1
=
None
cdef
api
Bar1
b1
=
None
# --
cdef
void
bar0
():
pass
cdef
api
void
bar1
():
pass
cdef
void
*
spam0
(
object
o
)
except
NULL
:
return
NULL
cdef
api
void
*
spam1
(
object
o
)
except
NULL
:
return
NULL
bar0
()
bar1
()
spam0
(
None
)
spam1
(
None
)
# --
tests/compile/publicapi_mix.pyx
0 → 100644
View file @
0a56c99d
# --
ctypedef
int
Int0
ctypedef
public
int
Int1
ctypedef
api
int
Int2
ctypedef
public
api
int
Int3
ctypedef
enum
EnumA0
:
EA0
ctypedef
public
enum
EnumA1
:
EA1
ctypedef
api
enum
EnumA2
:
EA2
ctypedef
public
api
enum
EnumA3
:
EA3
cdef
enum
EnumB0
:
EB0
=
0
cdef
public
enum
EnumB1
:
EB1
=
1
cdef
api
enum
EnumB2
:
EB2
=
2
cdef
public
api
enum
EnumB3
:
EB3
=
3
# --
ctypedef
struct
StructA0
:
int
SA0
ctypedef
public
struct
StructA1
:
int
SA1
ctypedef
api
struct
StructA2
:
int
SA2
ctypedef
public
api
struct
StructA3
:
int
SA3
cdef
struct
StructB0
:
int
SB0
cdef
public
struct
StructB1
:
int
SB1
cdef
api
struct
StructB2
:
int
SB2
cdef
public
api
struct
StructB3
:
int
SB3
# --
ctypedef
class
Foo0
:
pass
ctypedef
public
class
Foo1
[
type
PyFoo1_Type
,
object
PyFoo1_Object
]:
pass
ctypedef
api
class
Foo2
[
type
PyFoo2_Type
,
object
PyFoo2_Object
]:
pass
ctypedef
public
api
class
Foo3
[
type
PyFoo3_Type
,
object
PyFoo3_Object
]:
pass
cdef
class
Bar0
:
pass
cdef
public
class
Bar1
[
type
PyBar1_Type
,
object
PyBar1_Object
]:
pass
cdef
api
class
Bar2
[
type
PyBar2_Type
,
object
PyBar2_Object
]:
pass
cdef
public
api
class
Bar3
[
type
PyBar3_Type
,
object
PyBar3_Object
]:
pass
# --
cdef
void
bar0
():
pass
cdef
public
void
bar1
():
pass
cdef
api
void
bar2
():
pass
cdef
public
api
void
bar3
():
pass
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
)
except
NULL
:
return
NULL
cdef
public
api
void
*
spam3
(
object
o
)
except
NULL
:
return
NULL
bar0
()
spam0
(
None
)
# --
cdef
double
d0
=
0
cdef
public
double
d1
=
1
cdef
api
double
d2
=
2
cdef
public
api
double
d3
=
3
cdef
object
o0
=
None
cdef
public
object
o1
=
None
cdef
api
object
o2
=
None
cdef
public
api
object
o3
=
None
# --
tests/compile/publicapi_pub.pyx
0 → 100644
View file @
0a56c99d
# --
ctypedef
int
Int0
ctypedef
public
int
Int1
ctypedef
enum
EnumA0
:
EA0
ctypedef
public
enum
EnumA1
:
EA1
cdef
enum
EnumB0
:
EB0
=
0
cdef
public
enum
EnumB1
:
EB1
=
1
cdef
Int0
i0
=
0
cdef
EnumA0
ea0
=
EA0
cdef
EnumB0
eb0
=
EB0
cdef
public
Int1
i1
=
0
cdef
public
EnumA1
ea1
=
EA1
cdef
public
EnumB1
eb1
=
EB1
# --
ctypedef
struct
StructA0
:
int
SA0
ctypedef
public
struct
StructA1
:
int
SA1
cdef
struct
StructB0
:
int
SB0
cdef
public
struct
StructB1
:
int
SB1
cdef
StructA0
sa0
=
{
'SA0'
:
0
}
cdef
StructB0
sb0
=
{
'SB0'
:
2
}
cdef
public
StructA1
sa1
=
{
'SA1'
:
1
}
cdef
public
StructB1
sb1
=
{
'SB1'
:
3
}
# --
ctypedef
class
Foo0
:
pass
ctypedef
public
class
Foo1
[
type
PyFoo1_Type
,
object
PyFoo1_Object
]:
pass
cdef
class
Bar0
:
pass
cdef
public
class
Bar1
[
type
PyBar1_Type
,
object
PyBar1_Object
]:
pass
cdef
Foo0
f0
=
None
cdef
Bar0
b0
=
None
cdef
public
Foo1
f1
=
None
cdef
public
Bar1
b1
=
None
# --
cdef
void
bar0
():
pass
cdef
public
void
bar1
():
pass
cdef
void
*
spam0
(
object
o
)
except
NULL
:
return
NULL
cdef
public
void
*
spam1
(
object
o
)
except
NULL
:
return
NULL
bar0
()
bar1
()
spam0
(
None
)
spam1
(
None
)
# --
tests/compile/publicapi_pxd_mix.pxd
0 → 100644
View file @
0a56c99d
# --
ctypedef
int
Int0
ctypedef
public
int
Int1
ctypedef
api
int
Int2
ctypedef
public
api
int
Int3
ctypedef
enum
EnumA0
:
EA0
ctypedef
public
enum
EnumA1
:
EA1
ctypedef
api
enum
EnumA2
:
EA2
ctypedef
public
api
enum
EnumA3
:
EA3
cdef
enum
EnumB0
:
EB0
=
0
cdef
public
enum
EnumB1
:
EB1
=
1
cdef
api
enum
EnumB2
:
EB2
=
2
cdef
public
api
enum
EnumB3
:
EB3
=
3
# --
ctypedef
struct
StructA0
:
int
SA0
ctypedef
public
struct
StructA1
:
int
SA1
ctypedef
api
struct
StructA2
:
int
SA2
ctypedef
public
api
struct
StructA3
:
int
SA3
cdef
struct
StructB0
:
int
SB0
cdef
public
struct
StructB1
:
int
SB1
cdef
api
struct
StructB2
:
int
SB2
cdef
public
api
struct
StructB3
:
int
SB3
# --
ctypedef
class
Foo0
:
pass
ctypedef
public
class
Foo1
[
type
PyFoo1_Type
,
object
PyFoo1_Object
]:
pass
ctypedef
api
class
Foo2
[
type
PyFoo2_Type
,
object
PyFoo2_Object
]:
pass
ctypedef
public
api
class
Foo3
[
type
PyFoo3_Type
,
object
PyFoo3_Object
]:
pass
cdef
class
Bar0
:
pass
cdef
public
class
Bar1
[
type
PyBar1_Type
,
object
PyBar1_Object
]:
pass
cdef
api
class
Bar2
[
type
PyBar2_Type
,
object
PyBar2_Object
]:
pass
cdef
public
api
class
Bar3
[
type
PyBar3_Type
,
object
PyBar3_Object
]:
pass
# --
cdef
inline
void
bar0
():
pass
cdef
public
void
bar1
()
cdef
api
void
bar2
()
cdef
public
api
void
bar3
()
cdef
inline
void
*
spam0
(
object
o
)
except
NULL
:
return
NULL
cdef
public
void
*
spam1
(
object
o
)
except
NULL
cdef
api
void
*
spam2
(
object
o
)
nogil
except
NULL
cdef
public
api
void
*
spam3
(
object
o
)
except
NULL
with
gil
# --
#cdef public int i1
#cdef api int i2
#cdef public api int i3
# --
tests/compile/publicapi_pxd_mix.pyx
0 → 100644
View file @
0a56c99d
cdef
class
Foo1
:
pass
cdef
class
Foo2
:
pass
cdef
class
Foo3
:
pass
cdef
class
Bar1
:
pass
cdef
class
Bar2
:
pass
cdef
class
Bar3
:
pass
cdef
public
void
bar1
():
pass
cdef
api
void
bar2
():
pass
cdef
public
api
void
bar3
():
pass
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
tests/run/capiimpl.pyx
View file @
0a56c99d
...
...
@@ -2,8 +2,20 @@ __doc__ = u"""
>>> import sys
>>> sys.getrefcount(Foo.__pyx_vtable__)
2
>>> sys.getrefcount(__pyx_capi__['
spam
'])
>>> sys.getrefcount(__pyx_capi__['
ten
'])
2
>>> sys.getrefcount(__pyx_capi__['pi'])
2
>>> sys.getrefcount(__pyx_capi__['obj'])
2
>>> sys.getrefcount(__pyx_capi__['dct'])
2
>>> sys.getrefcount(__pyx_capi__['one'])
2
>>> sys.getrefcount(__pyx_capi__['two'])
Traceback (most recent call last):
...
KeyError: 'two'
"""
cdef
public
api
class
Foo
[
type
FooType
,
object
FooObject
]:
...
...
@@ -12,3 +24,12 @@ cdef public api class Foo [type FooType, object FooObject]:
cdef
api
void
spam
():
pass
cdef
api
int
ten
=
10
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
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