From: Robert Bradshaw Date: Wed, 11 Jul 2007 05:02:54 +0000 (-0700) Subject: Added pre-import option, which assumes all undeclared names come from the given module. X-Git-Tag: 0.9.6.14~29^2~174 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=76750ffb814857172912905c407cfb80eccd73b1;p=cython.git Added pre-import option, which assumes all undeclared names come from the given module. Emulates behavior of from import * --- diff --git a/Cython/Compiler/CmdLine.py b/Cython/Compiler/CmdLine.py index 51b148f3..c4793203 100644 --- a/Cython/Compiler/CmdLine.py +++ b/Cython/Compiler/CmdLine.py @@ -18,6 +18,9 @@ Options: -o, --output-file Specify name of generated C file -p, --embed-positions If specified, the positions in Pyrex files of each function definition is embedded in its docstring. + -z, --pre-import If specified, assume undeclared names in this + module. Emulates the behavior of putting + "from import *" at the top of the file. """ #The following experimental options are supported only on MacOSX: # -C, --compile Compile generated .c file to .o file @@ -70,6 +73,8 @@ def parse_command_line(args): options.output_file = pop_arg() elif option in ("-p", "--embed-positions"): Options.embed_pos_in_docstring = 1 + elif option in ("-z", "--pre-import"): + Options.pre_import = pop_arg() else: bad_usage() else: diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py index dec44344..5ba0f7a6 100644 --- a/Cython/Compiler/Code.py +++ b/Cython/Compiler/Code.py @@ -311,7 +311,7 @@ class CCodeWriter: lbl) def error_goto_if(self, cond, pos): - if Options.gcc_branch_hints or 0: # TODO this path is almost _never_ taken, yet this macro makes is slower! + if Options.gcc_branch_hints: return "if (unlikely(%s)) %s" % (cond, self.error_goto(pos)) else: return "if (%s) %s" % (cond, self.error_goto(pos)) diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 64942002..4424be35 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -163,6 +163,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln('') code.putln('static PyObject *%s;' % env.module_cname) code.putln('static PyObject *%s;' % Naming.builtins_cname) + if Options.pre_import is not None: + code.putln('static PyObject *%s;' % Naming.preimport_cname) code.putln('static int %s;' % Naming.lineno_cname) code.putln('static char *%s;' % Naming.filename_cname) code.putln('static char **%s;' % Naming.filetable_cname) @@ -1122,6 +1124,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): env.module_cname, Naming.builtins_cname, code.error_goto(self.pos))) + if Options.pre_import is not None: + code.putln( + '%s = PyImport_AddModule("%s");' % ( + Naming.preimport_cname, + Options.pre_import)) + code.putln( + "if (!%s) %s;" % ( + Naming.preimport_cname, + code.error_goto(self.pos))); def generate_intern_code(self, env, code): if env.intern_map: diff --git a/Cython/Compiler/Naming.py b/Cython/Compiler/Naming.py index abd5a30b..faa19166 100644 --- a/Cython/Compiler/Naming.py +++ b/Cython/Compiler/Naming.py @@ -35,6 +35,7 @@ args_cname = pyrex_prefix + "args" kwdlist_cname = pyrex_prefix + "argnames" obj_base_cname = pyrex_prefix + "base" builtins_cname = pyrex_prefix + "b" +preimport_cname = pyrex_prefix + "i" moddict_cname = pyrex_prefix + "d" dummy_cname = pyrex_prefix + "dummy" filename_cname = pyrex_prefix + "filename" diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py index 0456cf77..d89d304e 100644 --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py @@ -7,3 +7,5 @@ cache_builtins = 1 # Perform lookups on builtin names only once embed_pos_in_docstring = 0 gcc_branch_hints = 1 + +pre_import = None diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index ac394348..22122abf 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -448,12 +448,27 @@ class Scope: return 1 return 0 +class PreImportScope(Scope): + def __init__(self): + Scope.__init__(self, Options.pre_import, None, None) + + def declare_builtin(self, name, pos): + entry = self.declare(name, name, py_object_type, pos) + entry.is_variable = True + entry.is_pyglobal = True + entry.namespace_cname = Naming.preimport_cname + return entry + class BuiltinScope(Scope): # The builtin namespace. def __init__(self): - Scope.__init__(self, "__builtin__", None, None) + if Options.pre_import is None: + Scope.__init__(self, "__builtin__", None, None) + else: + Scope.__init__(self, "__builtin__", PreImportScope(), None) + for name, definition in self.builtin_functions.iteritems(): if len(definition) < 4: definition.append(None) # exception_value if len(definition) < 5: definition.append(False) # exception_check @@ -468,7 +483,10 @@ class BuiltinScope(Scope): def declare_builtin(self, name, pos): if not hasattr(__builtin__, name): - error(pos, "undeclared name not builtin: %s"%name) + if self.outer_scope is not None: + return self.outer_scope.declare_builtin(name, pos) + else: + error(pos, "undeclared name not builtin: %s"%name) entry = self.declare(name, name, py_object_type, pos) if Options.cache_builtins: entry.is_builtin = 1