路径中的Python模块:在mako temp中引发ImportError

2024-04-29 10:13:21 发布

您现在位置:Python中文网/ 问答频道 /正文

有一件事很可能让我发疯。情况如下:

tests/
    testWebsite.py
website/
    __init__.py
    __main__.py
    _webtools/
        __init__.py
        templatedefs.py
        ...
    _templates/
        base.mako
        article.mako
        ...

代码(没有tests目录,在问题解决之前,我很犹豫是否提交它)在这里是在线的:https://github.com/Boldewyn/website/

当我调用python -m website.__main__ build时,主例程使用website/_templates下的模板从一些输入的静态HTML文件中创建。这在任何给定的目录中都能正常工作。

然而,在tests/testWebsite.py中,我有一个单元测试,它也应该运行相同的东西。但是Mako模板会引起文件的导入错误,在另一种情况下,这些文件可以很好地导入。

^{pr2}$

然后运行测试得到:

$ python -m unittest tests.testWebsite
...
ERROR: test_initial_build (tests.testWebsite.BuildTestCase)
Check, if building directly after bootstrap works
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests/testWebsite.py", line 99, in test_initial_build
  File "website/_webtools/build.py", line 89, in build
    article.save(articles=articles)
  File "website/_webtools/articles.py", line 514, in save
    template_engine.render_article(self, **ctx)
  File "website/_webtools/templates.py", line 52, in render_article
    r.render_article(article, **ctx)
  File "website/_webtools/templates.py", line 277, in render_article
    tpl = self.lookup.get_template(filename)
  File "/usr/lib/python2.7/dist-packages/mako/lookup.py", line 217, in get_template
    return self._load(srcfile, uri)
  File "/usr/lib/python2.7/dist-packages/mako/lookup.py", line 277, in _load
    **self.template_args)
  File "/usr/lib/python2.7/dist-packages/mako/template.py", line 205, in __init__
    module = self._compile_from_file(path, filename)
  File "/usr/lib/python2.7/dist-packages/mako/template.py", line 249, in _compile_from_file
    filename)
  File "/usr/lib/python2.7/dist-packages/mako/template.py", line 470, in _compile_text
    exec code in module.__dict__, module.__dict__
  File "_templates_article_mako", line 16, in <module>
ImportError: No module named templatedefs

有趣的是,我可以直接从模板打印sys.path

<%!
import sys
print sys.path
from website._webtools.templatedefs import strip_tags
%>

我可以确认,website在路径中。此外,import在其他所有部署场景中都能很好地工作。

导入website或{}也能很好地工作。只有website._webtools.templatedefs部分出错。

有没有人知道,我可以在哪里寻找可能出问题的迹象?

测试代码非常简单:

class BuildTestCase(unittest.TestCase):

    def setUp(self):
        self.tmpdir = tempfile.mkdtemp()
        self.cwd = os.getcwd()
        os.chdir(self.tmpdir)
        bootstrap(self.tmpdir, { # this initiates a new project
          "URL": "localhost",
          "TITLE": "Example",
          "DEFAULTS": {
              "AUTHOR": "John Doe",
          }
        })

    def test_initial_build(self):
        """Check, if building directly after bootstrap works"""
        build()

    def tearDown(self):
        os.chdir(self.cwd)
        shutil.rmtree(self.tmpdir)

编辑:还有一个诊断:我让mako编译模板并独立执行生成的Python文件。很有魅力。我也减少了模板定义.py到最低限度(只有defs返回空字符串),这样我就可以排除该文件中的importer(或其他奇怪的东西)。

系统信息:Ubuntu 11.04、Python2.7、Mako 0.3.6。


Tags: inpybuildself模板makolinearticle
1条回答
网友
1楼 · 发布于 2024-04-29 10:13:21

这确实让人发疯。不过,以下是一些事情:

  1. ./nosetests: 这是有效的,所有9个测试都通过了

  2. 当您向mako模板添加一个'from website import _webtools'并将'nosetests'与{}进行比较时,'templatedefs'是{}中唯一缺少的键:其他部分已经在前面导入了

  3. sys.path'python -m unittest tests.testWebsite'的情况下包含''(相对路径),但在'nosetests'的情况下则不包含,其中sys.path只包含绝对路径。这导致'website._webtools.__file__'的不同值:一个是相对的['website/_webtools'],另一个是绝对的['/home/username/tmp/website/_webtools']。因为你做了一个os.chdir,相对路径不再工作了。

所以:如果您想使用纯unittest,可以在测试文件的开头添加'import website._webtools.templatedefs'。这样可以确保在运行os.chdir时导入templatedef。我建议用鼻子。希望有帮助。在

相关问题 更多 >