2011-07-25 12 views
2

ImportErrorがあり、私を怒らせる可能性があります。状況は次のようになります。パス内のPythonモジュール:makoテンプレートで生成されたImportError

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のテンプレートでは、ファイルのインポートエラーが発生します。これは、他の場合には正常にインポートされます。

$ head -n 5 website/_templates/article.mako 
# -*- coding: utf-8 -*- 
<%! 
from website._webtools.templatedefs import strip_tags 
%> 
<%inherit file="base.mako" /> 

し、テストを実行利回り:

$ 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です。また、のインポートでは、他のすべての展開シナリオでもがうまく機能します。

websiteまたはwebsite._webtoolsをインポートしてもうまくいきます。 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) 

編集:つ以上の診断:私はマコテンプレートをコンパイルしたPythonのファイルは、スタンドアロンで実行してみましょう。魅力のように動作します。私もtemplatedefs.pyを最低限に抑えました(空の文字列を返すだけです)。そうすれば、そのファイルのImportErrors(またはその他の奇妙さ)も除外できます。

システム情報: Ubuntu 11.04、Python 2.7、Mako 0.3.6。

+0

あなたの '__init __。py'sには何がありますか? – agf

+0

完全なテストコードを見ずに何が間違っているか完全にはわからない。 testWebsite.pyでtemplatedefをインポートすると、ビルドが実際に実行されるときにインポートエラーが発生しなくなります。 os.chdirが問題を引き起こしていると思われます。 – stderr

+0

@agfここをクリックしてください:https://github.com/Boldewyn/website/blob/master/website/__init__.py – Boldewyn

答えて

3

これは本当に1つの気違いを引き起こします。

  1. ./nosetests:しかし、ここでいくつかのものがある 、この作品と全9つのテストが

  2. 'templatedefs'はあなたのマコテンプレートに'from website import _webtools'を追加し、比較したときに'_webtools.__dict__'に欠けている唯一の鍵である渡す'nosetests'から'python -m unittest tests.testWebsite' :他の部分は既に先に輸入されていた

  3. sys.pathは、'python -m unittest tests.testWebsite'の中の''(相対パス)ただし、'nosetests'ケースでは発生しません。ここで、sys.pathには絶対パスのみが含まれています。この結果、'website._webtools.__file__'の値は異なります。一方は相対['website/_webtools']であり、他方は絶対['/home/username/tmp/website/_webtools']です。 os.chdirを作成しているので、相対パスはもう機能しません。

SO:あなたは純粋なunittestモジュールを使用する場合は、あなたのテストファイルの先頭に'import website._webtools.templatedefs'を追加することができます。これにより、os.chdirを実行したときにテンプレートエフェクトがインポートされます。そして私は鼻を使うことを提案します。希望が役立ちます。

+0

はい、それは助けて問題でした。説明ありがとう!私の心の状態は救われました:-) – Boldewyn

関連する問題