From b7a94dfdb3402c25d35489b89506ccb6c98159be Mon Sep 17 00:00:00 2001 From: Haoyu Bai Date: Sat, 2 Apr 2011 01:02:00 +0800 Subject: [PATCH] add py2_import directive to control import level --- Cython/Compiler/ExprNodes.py | 7 +++++++ Cython/Compiler/Options.py | 1 + Cython/Compiler/Parsing.py | 23 ++++++++--------------- tests/run/relativeimport_T542.pyx | 7 ++++++- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 1a1c11e2..db4e6993 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1749,12 +1749,19 @@ class ImportNode(ExprNode): # 0: absolute import; # >0: the number of parent directories to search # relative to the current module. + # None: decide the level according to language level and + # directives type = py_object_type subexprs = ['module_name', 'name_list'] def analyse_types(self, env): + if self.level is None: + if env.directives['language_level'] < 3 or env.directives['py2_import']: + self.level = -1 + else: + self.level = 0 self.module_name.analyse_types(env) self.module_name = self.module_name.coerce_to_pyobject(env) if self.name_list: diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py index 2e3663ae..e4aea76c 100644 --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py @@ -81,6 +81,7 @@ directive_defaults = { 'autotestdict.all': False, 'language_level': 2, 'fast_getattr': False, # Undocumented until we come up with a better way to handle this everywhere. + 'py2_import': False, # For backward compatibility of Cython's source code 'warn': None, 'warn.undeclared': False, diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 910e62a9..6aab2f84 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -1189,11 +1189,6 @@ def p_raise_statement(s): return Nodes.ReraiseStatNode(pos) def p_import_statement(s): - # will do absolute import in Py3 and try both relative and absolute in Py2. - if s.context.language_level >= 3: - level = 0 - else: - level = -1 # s.sy in ('import', 'cimport') pos = s.position() kind = s.sy @@ -1221,7 +1216,7 @@ def p_import_statement(s): rhs = ExprNodes.ImportNode(pos, module_name = ExprNodes.IdentifierStringNode( pos, value = dotted_name), - level = level, + level = None, name_list = name_list)) stats.append(stat) return Nodes.StatListNode(pos, stats = stats) @@ -1236,18 +1231,16 @@ def p_from_import_statement(s, first_statement = 0): while s.sy == '.': level += 1 s.next() + if s.sy == 'cimport': + s.error("Relative cimport is not supported yet") else: - # will do absolute import in Py3 and try both relative and absolute in Py2. - if s.context.language_level >= 3: - level = 0 - else: - level = -1 - - if level > 0 and s.sy == 'cimport': - s.error("Relative cimport is not supported yet") - if level > 0 and s.sy == 'import': + level = None + if level is not None and s.sy == 'import': # we are dealing with "from .. import foo, bar" dotted_name_pos, dotted_name = s.position(), '' + elif level is not None and s.sy == 'cimport': + # "from .. cimport" + s.error("Relative cimport is not supported yet") else: (dotted_name_pos, _, dotted_name, _) = \ p_dotted_name(s, as_allowed = 0) diff --git a/tests/run/relativeimport_T542.pyx b/tests/run/relativeimport_T542.pyx index 2994cc40..c292cc60 100644 --- a/tests/run/relativeimport_T542.pyx +++ b/tests/run/relativeimport_T542.pyx @@ -1,5 +1,10 @@ # cython: language_level=3 -__name__='distutils.baregg' # fool Python we are in distutils +import sys +# fool Python we are in distutils +if sys.version_info >= (3,): + __package__='distutils' +else: + __package__=b'distutils' from distutils import cmd, core, version from .core import * -- 2.26.2