From 5aa7540cd3f7841c2d927f41dd0cbf2098846c8c Mon Sep 17 00:00:00 2001 From: giovannibajo Date: Sun, 14 Jun 2009 22:54:44 +0000 Subject: [PATCH] Ticket #69: correctly support relative imports within __init__ files git-svn-id: http://svn.pyinstaller.org/trunk@678 8dd32b29-ccff-0310-8a9a-9233e24343b1 --- buildtests/relimp2/__init__.py | 0 buildtests/relimp2/bar/__init__.py | 1 + buildtests/relimp2/bar/bar2/__init__.py | 1 + buildtests/relimp2/bar/baz.py | 2 ++ buildtests/test-relative-import2.py | 5 +++++ buildtests/test-relative-import2.spec | 17 +++++++++++++++++ iu.py | 10 +++++++--- mf.py | 7 ++++++- 8 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 buildtests/relimp2/__init__.py create mode 100644 buildtests/relimp2/bar/__init__.py create mode 100644 buildtests/relimp2/bar/bar2/__init__.py create mode 100644 buildtests/relimp2/bar/baz.py create mode 100644 buildtests/test-relative-import2.py create mode 100644 buildtests/test-relative-import2.spec diff --git a/buildtests/relimp2/__init__.py b/buildtests/relimp2/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/buildtests/relimp2/bar/__init__.py b/buildtests/relimp2/bar/__init__.py new file mode 100644 index 0000000..e943251 --- /dev/null +++ b/buildtests/relimp2/bar/__init__.py @@ -0,0 +1 @@ +from .baz import * diff --git a/buildtests/relimp2/bar/bar2/__init__.py b/buildtests/relimp2/bar/bar2/__init__.py new file mode 100644 index 0000000..28744f6 --- /dev/null +++ b/buildtests/relimp2/bar/bar2/__init__.py @@ -0,0 +1 @@ +from ..baz import * diff --git a/buildtests/relimp2/bar/baz.py b/buildtests/relimp2/bar/baz.py new file mode 100644 index 0000000..eadffc4 --- /dev/null +++ b/buildtests/relimp2/bar/baz.py @@ -0,0 +1,2 @@ +def say_hello_please(): + print "Hello World!" \ No newline at end of file diff --git a/buildtests/test-relative-import2.py b/buildtests/test-relative-import2.py new file mode 100644 index 0000000..eebb9ca --- /dev/null +++ b/buildtests/test-relative-import2.py @@ -0,0 +1,5 @@ +import relimp2.bar +import relimp2.bar.bar2 + +relimp2.bar.say_hello_please() +relimp2.bar.bar2.say_hello_please() diff --git a/buildtests/test-relative-import2.spec b/buildtests/test-relative-import2.spec new file mode 100644 index 0000000..7ca90f2 --- /dev/null +++ b/buildtests/test-relative-import2.spec @@ -0,0 +1,17 @@ +# -*- mode: python -*- + +__testname__ = 'test-relative-import2' + +a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), + __testname__ + '.py'], + ) +pyz = PYZ(a.pure) +exe = EXE(pyz, + a.scripts, + a.binaries, + a.zipfiles, + name = os.path.join('dist', __testname__, __testname__ +'.exe'), + debug=False, + strip=False, + upx=False, + console=1 ) diff --git a/iu.py b/iu.py index 9e98dc0..fa92434 100644 --- a/iu.py +++ b/iu.py @@ -391,6 +391,7 @@ class ImportManager: contexts = [None] else: # level != 0 importernm = globals.get('__name__', '') + ispkg = hasattr(_sys_modules_get(importernm), '__path__') debug('importernm %s' % importernm) if level < 0: # behaviour up to Python 2.4 (and default in Python 2.5) @@ -400,11 +401,14 @@ class ImportManager: # relative import, do not try absolute if not importernm: raise RuntimeError("Relative import requires package") - importernm = _string_split(importernm, '.')[:-level] - importernm = _string_join('.', importernm) + # level=1 => current package + # level=2 => previous package => drop 1 level + if level > 1: + importernm = _string_split(importernm, '.')[:-level+1] + importernm = _string_join('.', importernm) contexts = [] if importernm: - if hasattr(_sys_modules_get(importernm), '__path__'): + if ispkg: # If you use the "from __init__ import" syntax, the package # name will have a __init__ in it. We want to strip it. if importernm[-len(".__init__"):] == ".__init__": diff --git a/mf.py b/mf.py index 24ad5a8..db16d3f 100644 --- a/mf.py +++ b/mf.py @@ -490,12 +490,17 @@ class ImportTracker: contexts = [None] elif level > 0: # relative import, do not try absolute - contexts = [string.join(string.split(importernm, '.')[:-level], '.')] + if self.ispackage(importernm): + level -= 1 + if level > 0: + importernm = string.join(string.split(importernm, '.')[:-level], ".") + contexts = [importernm] importernm = None _all = None assert contexts + # so contexts is [pkgnm, None] or just [None] if nmparts[-1] == '*': del nmparts[-1]