[py-svn] r7202 - in py/dist/py: magic path path/test
arigo at codespeak.net
arigo at codespeak.net
Tue Nov 9 17:57:57 CET 2004
Author: arigo
Date: Tue Nov 9 17:57:56 2004
New Revision: 7202
Modified:
py/dist/py/magic/autopath.py
py/dist/py/path/common.py
py/dist/py/path/test/fscommon.py
Log:
The getpymodule() logic discussed on py-dev, with tests.
Modified: py/dist/py/magic/autopath.py
==============================================================================
--- py/dist/py/magic/autopath.py (original)
+++ py/dist/py/magic/autopath.py Tue Nov 9 17:57:56 2004
@@ -1,5 +1,6 @@
import os, sys
-from py.path import local
+from py.path import local
+from py.__impl__.path.common import PathStr
def autopath(globs=None, basefile='__init__.py'):
""" return the (local) path of the "current" file pointed to by globals
@@ -19,9 +20,13 @@
raise ValueError, "cannot compute autopath in interactive mode"
__file__ = os.path.abspath(sys.argv[0])
- ret = local(__file__)
- if ret.ext in ('.pyc', '.pyo'):
- ret = ret.new(ext='.py')
+ custom__file__ = isinstance(__file__, PathStr)
+ if custom__file__:
+ ret = __file__.__path__
+ else:
+ ret = local(__file__)
+ if ret.ext in ('.pyc', '.pyo'):
+ ret = ret.new(ext='.py')
current = pkgdir = ret.dirpath()
while 1:
if basefile in current:
@@ -29,7 +34,7 @@
current = current.dirpath()
if pkgdir != current:
continue
- elif str(current) not in sys.path:
+ elif not custom__file__ and str(current) not in sys.path:
sys.path.insert(0, str(current))
break
ret.pkgdir = pkgdir
Modified: py/dist/py/path/common.py
==============================================================================
--- py/dist/py/path/common.py (original)
+++ py/dist/py/path/common.py Tue Nov 9 17:57:56 2004
@@ -292,8 +292,7 @@
except KeyError:
co = self.getpycodeobj()
mod = py.std.new.module(modname)
- mod.__file__ = str(self)
- #mod.__path__ = [str(self.get('dirname'))]
+ mod.__file__ = PathStr(self)
sys.modules[modname] = mod
exec co in mod.__dict__
return mod
@@ -303,3 +302,64 @@
# XXX str(self) should show up somewhere in the code's filename
return py.magic.dyncode.compile2(s)
+
+class PathStr(str):
+ def __init__(self, path):
+ global old_import_hook
+ self.__path__ = path
+ if old_import_hook is None:
+ import __builtin__
+ old_import_hook = __builtin__.__import__
+ __builtin__.__import__ = custom_import_hook
+
+def relativeimport(p, name, parent=None):
+ names = name.split('.')
+ last_list = [False] * (len(names)-1) + [True]
+ modules = []
+ for name, is_last in zip(names, last_list):
+ if hasattr(parent, name):
+ # shortcut if there is already the correct name
+ # in the parent package
+ submodule = getattr(parent, name)
+ else:
+ if is_last and p.new(basename=name+'.py').check():
+ p = p.new(basename=name+'.py')
+ else:
+ p = p.new(basename=name).join('__init__.py')
+ if not p.check():
+ return None # not found
+ submodule = p.getpymodule()
+ if parent is not None:
+ setattr(parent, name, submodule)
+ modules.append(submodule)
+ parent = submodule
+ return modules # success
+
+
+old_import_hook = None
+
+def custom_import_hook(name, glob=None, loc=None, fromlist=None):
+ __file__ = glob and glob.get('__file__')
+ if isinstance(__file__, PathStr):
+ # try to perform a relative import
+ # for cooperation with py.magic.autopath, first look in the pkgdir
+ modules = None
+ if hasattr(__file__.__path__, 'pkgdir'):
+ modules = relativeimport(__file__.__path__.pkgdir, name)
+ if not modules:
+ modules = relativeimport(__file__.__path__, name)
+ if modules:
+ if fromlist:
+ submodule = modules[-1] # innermost submodule
+ # try to import submodules named in the 'fromlist' if the
+ # 'submodule' is a package
+ p = submodule.__file__.__path__
+ if p.check(basename='__init__.py'):
+ for name in fromlist:
+ relativeimport(p, name, parent=submodule)
+ # failures are fine
+ return submodule
+ else:
+ return modules[0] # outermost package
+ # fall-back
+ return old_import_hook(name, glob, loc, fromlist)
Modified: py/dist/py/path/test/fscommon.py
==============================================================================
--- py/dist/py/path/test/fscommon.py (original)
+++ py/dist/py/path/test/fscommon.py Tue Nov 9 17:57:56 2004
@@ -22,6 +22,21 @@
otherdir = path.ensure('otherdir', dir=1)
otherdir.ensure('__init__.py')
+ module_a = otherdir.ensure('a.py')
+ module_a.write('from b import stuff as result\n')
+ module_b = otherdir.ensure('b.py')
+ module_b.write('stuff="got it"\n')
+ module_c = otherdir.ensure('c.py')
+ module_c.write('''import py; py.magic.autopath()
+import otherdir.a
+value = otherdir.a.result
+''')
+ module_d = otherdir.ensure('d.py')
+ module_d.write('''import py; py.magic.autopath()
+from otherdir import a
+value2 = a.result
+''')
+
class CommonFSTests(common.CommonPathTests):
root = None # subclasses have to provide a current 'root' attribute
@@ -193,3 +208,22 @@
# py.path.extpy
assert not hasattr(self.root, 'resolve')
+ def test_getpymodule_a(self):
+ otherdir = self.root.join('otherdir')
+ mod = otherdir.join('a.py').getpymodule()
+ assert mod.result == "got it"
+
+ def test_getpymodule_b(self):
+ otherdir = self.root.join('otherdir')
+ mod = otherdir.join('b.py').getpymodule()
+ assert mod.stuff == "got it"
+
+ def test_getpymodule_c(self):
+ otherdir = self.root.join('otherdir')
+ mod = otherdir.join('c.py').getpymodule()
+ assert mod.value == "got it"
+
+ def test_getpymodule_d(self):
+ otherdir = self.root.join('otherdir')
+ mod = otherdir.join('d.py').getpymodule()
+ assert mod.value2 == "got it"
More information about the pytest-commit
mailing list