简体   繁体   English

在没有已知父 package 错误的情况下尝试相对导入

[英]Attempted relative import with no known parent package error

Error: While importing "wsgi-contract-test", an ImportError was raised:

Traceback (most recent call last):
  File "/Users/karl/Development/tral/bin/tral-env/lib/python3.9/site-packages/flask/cli.py", line 236, in locate_app
    __import__(module_name)
  File "/Users/karl/Development/tral/test/contract/inject/wsgi-contract-test.py", line 8, in <module>
    from . import (
ImportError: attempted relative import with no known parent package

ERROR (run-tral): trap on error (rc=2) near line 121
make: *** [component.mk:114: tral-local-run-api-contract-test] Error 2

wsgi-contract-test.py: wsgi-合同-test.py:

from ...libs.tral import app, setup_from_env
from ...libs.tral import routes

I have the regular source files under the libs/tral directory, however the entry file for this test is located under test/contract/inject .我在libs/tral目录下有常规源文件,但是此测试的入口文件位于test/contract/inject下。 I do NOT want to move this test file into libs since this file should be nowhere near production code as it is a rather hazardous file security wise.我不想将这个测试文件移动到库中,因为这个文件应该远离生产代码,因为它是一个相当危险的文件安全性。

In node.js this would of worked fine but there seems to be something with python imports I'm not grasping?在 node.js 中,这可以正常工作,但 python 进口似乎有些东西我没有掌握?

Since tests don't belong inside the src tree, there are basically two approaches.由于测试不属于src树,因此基本上有两种方法。 If you are testing a library you will frequently install it (in a virtualenv) and then just import it exactly the same way you would anywhere else.如果您正在测试一个,您将经常安装它(在 virtualenv 中),然后以与其他任何地方完全相同的方式导入它。 Frequently you also do this with a fresh install for the test: this has the great advantage that your tests mirror real setups, and helps to catch bugs like forgetting to commit/include files (guilty.) and only noticing once you've deployed...通常,您还可以通过全新安装测试来执行此操作:这具有很大的优势,即您的测试反映了真实的设置,并有助于捕获诸如忘记提交/包含文件(有罪)之类的错误,并且只有在部署后才注意到。 ..

The other option is to modify sys.path so that your test is effectively in the same place as your production code:另一种选择是修改sys.path以便您的测试有效地与您的生产代码位于同一位置:

# /test/contract/inject.py
from pathlib import Path
import sys

sys.path.insert(0, str(Path(__file__).parent.parent.parent))

Since sys.path uses strs you may prefer to use os.path , like every single other example on SO.由于sys.path使用 strs 您可能更喜欢使用os.path ,就像 SO 上的每个其他示例一样。 Personally I'm addicted to pathlib.就我个人而言,我沉迷于 pathlib。 Here:这里:

  • __file__ is the absolute path of the current file __file__是当前文件的绝对路径
  • Path(str) wraps it in a pathlib.Path object Path(str)将其包装在pathlib.Path object
  • .parent gets you up the tree, and .parent让你上树,然后
  • str() casts back to the format sys.path expects, or it won't work. str()转换回 sys.path 期望的格式,否则它将不起作用。

Using a test runner使用测试运行器

Normally we use a test runner for tests.通常我们使用测试运行器进行测试。 But these tests need a running instance: No problem:但是这些测试需要一个正在运行的实例:没问题:

# tests/conftest.py
import pytest
from sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent))
# now pytest can find the src
from app import get_instance # dummy

@pytest.fixture
def instance():
    instance = get_instance(some_param)
    # maybe
    instance.do_some_setup()
    yield instance
    # maybe
    instance.do_some_cleanup()

If you don't need to do any cleanup, you can just return the instance rather than yielding it.如果您不需要进行任何清理,则可以只return实例而不是产生它。 Then in another file (for neatness) you write tests like this:然后在另一个文件(为了整洁)中编写如下测试:

# tests/test_instance.py

def test_instance(instance): # note how we requested the fixture
    assert instance.some_method()

And you run your tests with pytest:然后使用 pytest 运行测试:

pytest tests/

Pytest will run the code in conftest.py , discover all test fns starting with test in files whose names start with test , run the tests (supplying all the fixtures you have defined) and report. Pytest 将运行 conftest.py 中的代码,在名称以test开头的文件中发现所有以 test 开头的test conftest.py ,运行测试(提供您定义的所有夹具)并报告。

Fixture Lifetime夹具寿命

Sometimes spinning up a fixture can be expensive.有时旋转固定装置可能很昂贵。 See the docs on fixture scope for telling pytest to keep the fixture around and supply it to multiple tests.请参阅夹具 scope上的文档,告诉 pytest 将夹具保持在周围并将其提供给多个测试。

Using a runner vs. just running a script使用运行器与仅运行脚本

You don't have to use a runner.不必使用跑步者。 But they do have many advantages:但它们确实有很多优点:

  • decent metrics eg code/branch coverage体面的指标,例如代码/分支覆盖率
  • everyone uses them每个人都使用它们
  • parallel testing against different envs (eg python versions)针对不同环境的并行测试(例如 python 版本)
  • tests tend to be a lot neater测试往往更整洁

I took for granted that Python was able to handle simple relative paths;我理所当然地认为 Python 能够处理简单的相对路径; not the case.不是这样。 Instead I just added the path to the packages I wanted to include in the PYTHONPATH variable and walla, it found everything.相反,我只是添加了我想要包含在PYTHONPATH变量和 walla 中的包的路径,它找到了所有内容。

export PYTHONPATH="${PYTHONPATH}:$(pwd)/libs"

Then running it from the root project directory.然后从根项目目录运行它。

I had to change the code to the following though:我不得不将代码更改为以下内容:

from tral import app, setup_from_env
from tral import routes

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 导入错误:尝试在没有已知父项的情况下进行相对导入 package - Import Error : attempted relative import with no known parent package 路径错误 ImportError:尝试在没有已知父 package 的情况下进行相对导入 - path error ImportError: attempted relative import with no known parent package 如何解决 python 中的“在没有已知父包的情况下尝试相对导入”错误 - How to solve "attempted relative import with no known parent package" error in python Python - 尝试在没有已知父包的情况下进行相对导入 - Python - attempted relative import with no known parent package 导入错误:尝试在没有已知父包的情况下进行相对导入? - ImportError: attempted relative import with no known parent package? Python 尝试在没有已知父 package 的情况下进行相对导入 - Python attempted relative import with no known parent package ImportError:尝试在没有已知父 package 的情况下进行相对导入:( - ImportError: attempted relative import with no known parent package :( 尝试在没有已知父项的情况下进行相对导入 package (python) - attempted relative import with no known parent package (python) ImportError:尝试相对导入,没有已知的父包 - ImportError: attempted relative import with no known parent package 导入错误 - 在没有已知父包的情况下尝试相对导入 - ImportError - attempted relative import with no known parent package
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM