Gra*_*yne 14 python django ubuntu virtualenv python-unittest
我一直在努力解决在Ubuntu 14.04上安装在Python virtualenv中的Django测试运行器的问题.相同的软件在MacOS上运行正常,我认为在早期版本的Ubuntu上运行良好.
失败消息是:
ImportError: '<test>' module incorrectly imported from '<base-env>/local/lib/python2.7/site-packages/<package-dir>'. Expected '<base-env>/lib/python2.7/site-packages/<package-dir>'. Is this module globally installed?
Run Code Online (Sandbox Code Playgroud)
并且错误的完整堆栈跟踪是:
Traceback (most recent call last):
File "/home/annalist/anenv/bin/django-admin", line 11, in <module>
sys.exit(execute_from_command_line())
File "/home/annalist/anenv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "/home/annalist/anenv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/annalist/anenv/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 50, in run_from_argv
super(Command, self).run_from_argv(argv)
File "/home/annalist/anenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/home/annalist/anenv/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 71, in execute
super(Command, self).execute(*args, **options)
File "/home/annalist/anenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File "/home/annalist/anenv/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 88, in handle
failures = test_runner.run_tests(test_labels)
File "/home/annalist/anenv/local/lib/python2.7/site-packages/django/test/runner.py", line 147, in run_tests
suite = self.build_suite(test_labels, extra_tests)
File "/home/annalist/anenv/local/lib/python2.7/site-packages/django/test/runner.py", line 96, in build_suite
tests = self.test_loader.discover(start_dir=label, **kwargs)
File "/usr/lib/python2.7/unittest/loader.py", line 206, in discover
tests = list(self._find_tests(start_dir, pattern))
File "/usr/lib/python2.7/unittest/loader.py", line 287, in _find_tests
for test in self._find_tests(full_path, pattern):
File "/usr/lib/python2.7/unittest/loader.py", line 287, in _find_tests
for test in self._find_tests(full_path, pattern):
File "/usr/lib/python2.7/unittest/loader.py", line 267, in _find_tests
raise ImportError(msg % (mod_name, module_dir, expected_dir))
ImportError: 'test_entity' module incorrectly imported from '/home/annalist/anenv/local/lib/python2.7/site-packages/annalist_root/annalist/tests'. Expected '/home/annalist/anenv/lib/python2.7/site-packages/annalist_root/annalist/tests'. Is this module globally installed?
Run Code Online (Sandbox Code Playgroud)
测试用例在开发环境中运行良好,当从源分发工具包安装到MAcOS开发主机上的新virtualenv环境时,它们也运行良好.但是当我在Ubuntu 14.04主机上将相同的软件包安装到新的virtualenv时,测试运行器会因上述消息而失败.
我创建的一个管理实用程序出现了问题,它调用了一些函数django-admin(以及其他一些东西).
Web搜索显示有关virtualenv和posix兼容性的错误的报告,这些错误最近(2013/14)在Ubuntu发行版中通过local在虚拟环境中创建目录而得到解决,该目录又包含也可从顶层访问的目录的符号链接虚拟环境目录.错误消息中显示的路径对应于这些别名目录路径.
(我将此作为一个问题发布,因此我可以发布结果并从我的调查中回答,希望它对其他人有用.因此,我不打算详细描述我的特定软件设置. )
Mar*_*oni 32
我有完全相同的问题,无法弄清楚发生了什么.最后这是一个愚蠢的事情:
我有一个类似于这个的布局:
my_app/
__init__.py
tests.py
tests/
__init__.py
test_foo.py
Run Code Online (Sandbox Code Playgroud)
通过在同一文件夹中同时包含"tests.py"模块和"tests"包来生成问题.
只是删除"tests.py"文件解决了我的问题.
希望能帮助到你.
我的代码中的修复是用于os.path.realpath获取已安装的包路径的规范化版本,并在调用该django-admin实用程序的命令行上传递此值.在我看来,它看起来像这样:
approot = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
Run Code Online (Sandbox Code Playgroud)
和:
with ChangeCurrentDir(approot):
subprocess_command = (
"django-admin test --pythonpath=%s --settings=%s --top-level-directory=%s"%
(approot, settings_module_name, approot)
)
status = subprocess.call(subprocess_command.split())
Run Code Online (Sandbox Code Playgroud)
(其中ChangeCurrentDir是一个上下文处理程序,它使用指定的当前工作目录运行附带的代码).
一些进一步的实验表明,我可以通过战略接替的"修复"的问题os.path.abspath与os.path.realpath在Python和/或Django的库代码.
我发现的核心问题是:
/usr/lib/python2.7/unittest/loader.py
Run Code Online (Sandbox Code Playgroud)
特别:
File "/usr/lib/python2.7/unittest/loader.py", line 267, in _find_tests
raise ImportError(msg % (mod_name, module_dir, expected_dir))
ImportError: 'test_entity' module incorrectly imported from ...
Run Code Online (Sandbox Code Playgroud)
loader.py导致此问题的违规代码是:
if realpath.lower() != fullpath_noext.lower():
module_dir = os.path.dirname(realpath)
mod_name = os.path.splitext(os.path.basename(full_path))[0]
expected_dir = os.path.dirname(full_path)
msg = ("%r module incorrectly imported from %r. Expected %r. "
"Is this module globally installed?")
raise ImportError(msg % (mod_name, module_dir, expected_dir))
Run Code Online (Sandbox Code Playgroud)
如果我if用这个替换语句:
if os.path.realpath(realpath).lower() != fullpath_noext.lower():
Run Code Online (Sandbox Code Playgroud)
一切都很开心.这确认了它是符号链接别名问题,因为它 os.path.realpath()解析了基础路径的任何符号链接.但这不是可安装软件包的解决方案,因为它涉及修改底层Python安装.因此,在探究了潜在的问题之后,我需要一些更易于攻击的东西.
下一个停靠点是Django测试运行器库,它安装在虚拟环境中.
<base-env>/local/lib/python2.7/site-packages/django/test/runner.py
Run Code Online (Sandbox Code Playgroud)
特别是,关注堆栈跟踪的这一部分:
File "/home/annalist/anenv/local/lib/python2.7/site-packages/django/test/runner.py", line 96, in build_suite
tests = self.test_loader.discover(start_dir=label, **kwargs)
Run Code Online (Sandbox Code Playgroud)
挖掘这段代码,我能够确定问题与label参数有关,默认为'.'(即当前目录).这里没有明显的简单修复,但它表明问题可能与运行时使用的当前目录和/或路径有关django-admin.这导致了上述解决方案(可能有点过分 - 我不确定--pythonpath=是否需要该选项,但它对我有用).