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
Gwenaël Samain
cython
Commits
e95d3eb7
Commit
e95d3eb7
authored
May 28, 2008
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement "from module [c]import *", some more work on sequence indexing.
parent
d3e1ddfc
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
213 additions
and
20 deletions
+213
-20
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+12
-7
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+153
-0
Cython/Compiler/Naming.py
Cython/Compiler/Naming.py
+2
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+35
-10
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+5
-2
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+6
-1
No files found.
Cython/Compiler/ExprNodes.py
View file @
e95d3eb7
...
@@ -1290,12 +1290,10 @@ class IndexNode(ExprNode):
...
@@ -1290,12 +1290,10 @@ class IndexNode(ExprNode):
self
.
base
.
result_code
,
self
.
index
.
result_code
)
self
.
base
.
result_code
,
self
.
index
.
result_code
)
def
generate_subexpr_evaluation_code
(
self
,
code
):
def
generate_subexpr_evaluation_code
(
self
,
code
):
# do not evaluate self.py_index in case we don't need it
self
.
base
.
generate_evaluation_code
(
code
)
self
.
base
.
generate_evaluation_code
(
code
)
self
.
index
.
generate_evaluation_code
(
code
)
self
.
index
.
generate_evaluation_code
(
code
)
def
generate_subexpr_disposal_code
(
self
,
code
):
def
generate_subexpr_disposal_code
(
self
,
code
):
# if we used self.py_index, it will be disposed of manually
self
.
base
.
generate_disposal_code
(
code
)
self
.
base
.
generate_disposal_code
(
code
)
self
.
index
.
generate_disposal_code
(
code
)
self
.
index
.
generate_disposal_code
(
code
)
...
@@ -1344,13 +1342,20 @@ class IndexNode(ExprNode):
...
@@ -1344,13 +1342,20 @@ class IndexNode(ExprNode):
def
generate_deletion_code
(
self
,
code
):
def
generate_deletion_code
(
self
,
code
):
self
.
generate_subexpr_evaluation_code
(
code
)
self
.
generate_subexpr_evaluation_code
(
code
)
self
.
py_index
.
generate_evaluation_code
(
code
)
#if self.type.is_pyobject:
code
.
put_error_if_neg
(
self
.
pos
,
if
self
.
index
.
type
.
is_int
:
"PyObject_DelItem(%s, %s)"
%
(
function
=
"PySequence_DelItem"
index_code
=
self
.
index
.
result_code
else
:
function
=
"PyObject_DelItem"
index_code
=
self
.
index
.
py_result
()
code
.
putln
(
"if (%s(%s, %s) < 0) %s"
%
(
function
,
self
.
base
.
py_result
(),
self
.
base
.
py_result
(),
self
.
py_index
.
py_result
()))
index_code
,
code
.
error_goto
(
self
.
pos
)))
self
.
generate_subexpr_disposal_code
(
code
)
self
.
generate_subexpr_disposal_code
(
code
)
self
.
py_index
.
generate_disposal_code
(
code
)
class
SliceIndexNode
(
ExprNode
):
class
SliceIndexNode
(
ExprNode
):
...
...
Cython/Compiler/ModuleNode.py
View file @
e95d3eb7
...
@@ -230,6 +230,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -230,6 +230,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_typeobj_definitions
(
env
,
code
)
self
.
generate_typeobj_definitions
(
env
,
code
)
self
.
generate_method_table
(
env
,
code
)
self
.
generate_method_table
(
env
,
code
)
self
.
generate_filename_init_prototype
(
code
)
self
.
generate_filename_init_prototype
(
code
)
if
env
.
has_import_star
:
self
.
generate_import_star
(
env
,
code
)
self
.
generate_module_init_func
(
modules
[:
-
1
],
env
,
code
)
self
.
generate_module_init_func
(
modules
[:
-
1
],
env
,
code
)
code
.
mark_pos
(
None
)
code
.
mark_pos
(
None
)
self
.
generate_module_cleanup_func
(
env
,
code
)
self
.
generate_module_cleanup_func
(
env
,
code
)
...
@@ -1430,6 +1432,66 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1430,6 +1432,66 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
""
);
code
.
putln
(
""
);
code
.
putln
(
"static void %s(void); /*proto*/"
%
Naming
.
fileinit_cname
)
code
.
putln
(
"static void %s(void); /*proto*/"
%
Naming
.
fileinit_cname
)
def
generate_import_star
(
self
,
env
,
code
):
code
.
putln
()
code
.
putln
(
"char* %s_type_names[] = {"
%
Naming
.
import_star
)
for
name
,
entry
in
env
.
entries
.
items
():
if
entry
.
is_type
:
code
.
putln
(
'"%s",'
%
name
)
code
.
putln
(
"0"
)
code
.
putln
(
"};"
)
code
.
putln
()
code
.
putln
(
"static int %s(PyObject *o, PyObject* py_name, char *name) {"
%
Naming
.
import_star_set
)
code
.
putln
(
"char** type_name = %s_type_names;"
%
Naming
.
import_star
)
code
.
putln
(
"while (*type_name) {"
)
code
.
putln
(
"if (!strcmp(name, *type_name)) {"
)
code
.
putln
(
'PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);'
)
code
.
putln
(
'goto bad;'
)
code
.
putln
(
"}"
)
code
.
putln
(
"type_name++;"
)
code
.
putln
(
"}"
)
old_error_label
=
code
.
new_error_label
()
code
.
putln
(
"if (0);"
)
# so the first one can be "else if"
for
name
,
entry
in
env
.
entries
.
items
():
if
entry
.
is_cglobal
and
entry
.
used
:
code
.
putln
(
'else if (!strcmp(name, "%s")) {'
%
name
)
if
entry
.
type
.
is_pyobject
:
if
entry
.
type
.
is_extension_type
or
entry
.
type
.
is_builtin_type
:
code
.
putln
(
"if (!(%s)) %s;"
%
(
entry
.
type
.
type_test_code
(
"o"
),
code
.
error_goto
(
entry
.
pos
)))
code
.
put_var_decref
(
entry
)
code
.
putln
(
"%s = %s;"
%
(
entry
.
cname
,
PyrexTypes
.
typecast
(
entry
.
type
,
py_object_type
,
"o"
)))
elif
entry
.
type
.
from_py_function
:
rhs
=
"%s(o)"
%
entry
.
type
.
from_py_function
if
entry
.
type
.
is_enum
:
rhs
=
typecast
(
entry
.
type
,
c_long_type
,
rhs
)
code
.
putln
(
"%s = %s; if (%s) %s;"
%
(
entry
.
cname
,
rhs
,
entry
.
type
.
error_condition
(
entry
.
cname
),
code
.
error_goto
(
entry
.
pos
)))
code
.
putln
(
"Py_DECREF(o);"
)
else
:
code
.
putln
(
'PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");'
%
(
name
,
entry
.
type
))
code
.
putln
(
code
.
error_goto
(
entry
.
pos
))
code
.
putln
(
"}"
)
code
.
putln
(
"else {"
)
code
.
putln
(
"if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;"
%
Naming
.
module_cname
)
code
.
putln
(
"}"
)
code
.
putln
(
"return 0;"
)
code
.
put_label
(
code
.
error_label
)
# This helps locate the offending name.
code
.
putln
(
'__Pyx_AddTraceback("%s");'
%
self
.
full_module_name
);
code
.
error_label
=
old_error_label
code
.
putln
(
"bad:"
)
code
.
putln
(
"Py_DECREF(o);"
)
code
.
putln
(
"return -1;"
)
code
.
putln
(
"}"
)
code
.
putln
(
import_star_utility_code
)
def
generate_module_init_func
(
self
,
imported_modules
,
env
,
code
):
def
generate_module_init_func
(
self
,
imported_modules
,
env
,
code
):
code
.
putln
(
""
)
code
.
putln
(
""
)
header
=
"PyMODINIT_FUNC init%s(void)"
%
env
.
module_name
header
=
"PyMODINIT_FUNC init%s(void)"
%
env
.
module_name
...
@@ -2019,3 +2081,94 @@ bad:
...
@@ -2019,3 +2081,94 @@ bad:
return ret;
return ret;
}
}
"""
]
"""
]
import_star_utility_code
=
"""
/* import_all_from is an unexposed function from ceval.c */
static int
__Pyx_import_all_from(PyObject *locals, PyObject *v)
{
PyObject *all = PyObject_GetAttrString(v, "__all__");
PyObject *dict, *name, *value;
int skip_leading_underscores = 0;
int pos, err;
if (all == NULL) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
return -1; /* Unexpected error */
PyErr_Clear();
dict = PyObject_GetAttrString(v, "__dict__");
if (dict == NULL) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
return -1;
PyErr_SetString(PyExc_ImportError,
"from-import-* object has no __dict__ and no __all__");
return -1;
}
all = PyMapping_Keys(dict);
Py_DECREF(dict);
if (all == NULL)
return -1;
skip_leading_underscores = 1;
}
for (pos = 0, err = 0; ; pos++) {
name = PySequence_GetItem(all, pos);
if (name == NULL) {
if (!PyErr_ExceptionMatches(PyExc_IndexError))
err = -1;
else
PyErr_Clear();
break;
}
if (skip_leading_underscores &&
PyString_Check(name) &&
PyString_AS_STRING(name)[0] == '_')
{
Py_DECREF(name);
continue;
}
value = PyObject_GetAttr(v, name);
if (value == NULL)
err = -1;
else if (PyDict_CheckExact(locals))
err = PyDict_SetItem(locals, name, value);
else
err = PyObject_SetItem(locals, name, value);
Py_DECREF(name);
Py_XDECREF(value);
if (err != 0)
break;
}
Py_DECREF(all);
return err;
}
static int %s(PyObject* m) {
int i;
int ret = -1;
PyObject *locals = 0;
PyObject *list = 0;
PyObject *name;
PyObject *item;
locals = PyDict_New(); if (!locals) goto bad;
if (__Pyx_import_all_from(locals, m) < 0) goto bad;
list = PyDict_Items(locals); if (!list) goto bad;
for(i=0; i<PyList_GET_SIZE(list); i++) {
name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
if (%s(item, name, PyString_AsString(name)) < 0) goto bad;
}
ret = 0;
bad:
Py_XDECREF(locals);
Py_XDECREF(list);
return ret;
}
"""
%
(
Naming
.
import_star
,
Naming
.
import_star_set
)
Cython/Compiler/Naming.py
View file @
e95d3eb7
...
@@ -67,6 +67,8 @@ print_function_kwargs = pyrex_prefix + "print_kwargs"
...
@@ -67,6 +67,8 @@ print_function_kwargs = pyrex_prefix + "print_kwargs"
cleanup_cname
=
pyrex_prefix
+
"module_cleanup"
cleanup_cname
=
pyrex_prefix
+
"module_cleanup"
optional_args_cname
=
pyrex_prefix
+
"optional_args"
optional_args_cname
=
pyrex_prefix
+
"optional_args"
no_opt_args
=
pyrex_prefix
+
"no_opt_args"
no_opt_args
=
pyrex_prefix
+
"no_opt_args"
import_star
=
pyrex_prefix
+
"import_star"
import_star_set
=
pyrex_prefix
+
"import_star_set"
line_c_macro
=
"__LINE__"
line_c_macro
=
"__LINE__"
...
...
Cython/Compiler/Nodes.py
View file @
e95d3eb7
...
@@ -3665,6 +3665,10 @@ class FromCImportStatNode(StatNode):
...
@@ -3665,6 +3665,10 @@ class FromCImportStatNode(StatNode):
module_scope
=
env
.
find_module
(
self
.
module_name
,
self
.
pos
)
module_scope
=
env
.
find_module
(
self
.
module_name
,
self
.
pos
)
env
.
add_imported_module
(
module_scope
)
env
.
add_imported_module
(
module_scope
)
for
pos
,
name
,
as_name
in
self
.
imported_names
:
for
pos
,
name
,
as_name
in
self
.
imported_names
:
if
name
==
"*"
:
for
local_name
,
entry
in
module_scope
.
entries
.
items
():
env
.
add_imported_entry
(
local_name
,
entry
,
pos
)
else
:
entry
=
module_scope
.
find
(
name
,
pos
)
entry
=
module_scope
.
find
(
name
,
pos
)
if
entry
:
if
entry
:
local_name
=
as_name
or
name
local_name
=
as_name
or
name
...
@@ -3684,11 +3688,20 @@ class FromImportStatNode(StatNode):
...
@@ -3684,11 +3688,20 @@ class FromImportStatNode(StatNode):
# items [(string, NameNode)]
# items [(string, NameNode)]
# interned_items [(string, NameNode)]
# interned_items [(string, NameNode)]
# item PyTempNode used internally
# item PyTempNode used internally
# import_star boolean used internally
child_attrs
=
[
"module"
]
child_attrs
=
[
"module"
]
import_star
=
0
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
for
_
,
target
in
self
.
items
:
for
name
,
target
in
self
.
items
:
if
name
==
"*"
:
if
not
env
.
is_module_scope
:
error
(
self
.
pos
,
"import * only allowed at module level"
)
return
env
.
has_import_star
=
1
self
.
import_star
=
1
else
:
target
.
analyse_target_declaration
(
env
)
target
.
analyse_target_declaration
(
env
)
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
...
@@ -3698,6 +3711,12 @@ class FromImportStatNode(StatNode):
...
@@ -3698,6 +3711,12 @@ class FromImportStatNode(StatNode):
self
.
item
.
allocate_temp
(
env
)
self
.
item
.
allocate_temp
(
env
)
self
.
interned_items
=
[]
self
.
interned_items
=
[]
for
name
,
target
in
self
.
items
:
for
name
,
target
in
self
.
items
:
if
name
==
'*'
:
for
_
,
entry
in
env
.
entries
.
items
():
if
not
entry
.
is_type
and
entry
.
type
.
is_extension_type
:
env
.
use_utility_code
(
ExprNodes
.
type_test_utility_code
)
break
else
:
self
.
interned_items
.
append
(
self
.
interned_items
.
append
(
(
env
.
intern_identifier
(
name
),
target
))
(
env
.
intern_identifier
(
name
),
target
))
target
.
analyse_target_expression
(
env
,
None
)
target
.
analyse_target_expression
(
env
,
None
)
...
@@ -3707,6 +3726,12 @@ class FromImportStatNode(StatNode):
...
@@ -3707,6 +3726,12 @@ class FromImportStatNode(StatNode):
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
self
.
module
.
generate_evaluation_code
(
code
)
self
.
module
.
generate_evaluation_code
(
code
)
if
self
.
import_star
:
code
.
putln
(
'if (%s(%s) < 0) %s;'
%
(
Naming
.
import_star
,
self
.
module
.
py_result
(),
code
.
error_goto
(
self
.
pos
)))
for
cname
,
target
in
self
.
interned_items
:
for
cname
,
target
in
self
.
interned_items
:
code
.
putln
(
code
.
putln
(
'%s = PyObject_GetAttr(%s, %s); %s'
%
(
'%s = PyObject_GetAttr(%s, %s); %s'
%
(
...
...
Cython/Compiler/Parsing.py
View file @
e95d3eb7
...
@@ -944,7 +944,10 @@ def p_from_import_statement(s, first_statement = 0):
...
@@ -944,7 +944,10 @@ def p_from_import_statement(s, first_statement = 0):
else
:
else
:
s
.
error
(
"Expected 'import' or 'cimport'"
)
s
.
error
(
"Expected 'import' or 'cimport'"
)
if
s
.
sy
==
'*'
:
if
s
.
sy
==
'*'
:
s
.
error
(
"'import *' not supported"
)
# s.error("'import *' not supported")
imported_names
=
[(
s
.
position
(),
"*"
,
None
)]
s
.
next
()
else
:
imported_names
=
[
p_imported_name
(
s
)]
imported_names
=
[
p_imported_name
(
s
)]
while
s
.
sy
==
','
:
while
s
.
sy
==
','
:
s
.
next
()
s
.
next
()
...
...
Cython/Compiler/Symtab.py
View file @
e95d3eb7
...
@@ -693,8 +693,10 @@ class ModuleScope(Scope):
...
@@ -693,8 +693,10 @@ class ModuleScope(Scope):
# interned_nums [int/long] Interned numeric constants
# interned_nums [int/long] Interned numeric constants
# all_pystring_entries [Entry] Python string consts from all scopes
# all_pystring_entries [Entry] Python string consts from all scopes
# types_imported {PyrexType : 1} Set of types for which import code generated
# types_imported {PyrexType : 1} Set of types for which import code generated
# has_import_star boolean Module contains import *
is_module_scope = 1
is_module_scope = 1
has_import_star = 0
def __init__(self, name, parent_module, context):
def __init__(self, name, parent_module, context):
self.parent_module = parent_module
self.parent_module = parent_module
...
@@ -734,7 +736,10 @@ class ModuleScope(Scope):
...
@@ -734,7 +736,10 @@ class ModuleScope(Scope):
def declare_builtin(self, name, pos):
def declare_builtin(self, name, pos):
if not hasattr(__builtin__, name):
if not hasattr(__builtin__, name):
if self.outer_scope is not None:
if self.has_import_star:
entry = self.declare_var(name, py_object_type, pos)
return entry
elif self.outer_scope is not None:
return self.outer_scope.declare_builtin(name, pos)
return self.outer_scope.declare_builtin(name, pos)
else:
else:
error(pos, "
undeclared
name
not
builtin
:
%
s
"%name)
error(pos, "
undeclared
name
not
builtin
:
%
s
"%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