简体   繁体   中英

Importing modules from different folders

I am following the pytest "Get Started" guide, and I just can't make it work. It seems to be something very elementary, but I just cant find it. The problem resides in importing modules from other folders, and, although I am following the official documentation, I cant make it work

Following PyPa and the official documentation , I have assembled the following file structure:

(lpthw) ex47_pypa> tree
.
├── dist
│   ├── example_package_vcmota-0.0.1-py3-none-any.whl
│   └── example_package_vcmota-0.0.1.tar.gz
├── LICENSE
├── pyproject.toml
├── README.md
├── src
│   └── example_package_VCMota
│       ├── example.py
│       └── __init__.py
└── tests
    └── test_example.py

4 directories, 8 files
(lpthw) ex47_pypa> cat src/example_package_VCMota/example.py
def add_one(number):
    return number+1
(lpthw) ex47_pypa> cat tests/test_example.py
# import example
# import example_package_VCMota
# from src/example_package_VCMota import example
# from src import example_package_VCMota/example
# import src
# import importlib

# from src.example_package_VCMota.example import add_one

from ..src.example import add_one

def test_dif():
    assert add_one(2) == 9
(lpthw) ex47_pypa>

That seems to me as an ok implementation of everything in pytest pages, except that it does not work:

(lpthw) ex47_pypa> pytest
=============================================================================================== test session starts ================================================================================================
platform linux -- Python 3.10.8, pytest-7.1.3, pluggy-1.0.0
rootdir: /archive/MyBooks/LearnPython3TheHardWay/mypython/projects/ex47_pypa
collected 0 items / 1 error

====================================================================================================== ERRORS ======================================================================================================
______________________________________________________________________________________ ERROR collecting tests/test_example.py ______________________________________________________________________________________
ImportError while importing test module '/archive/MyBooks/LearnPython3TheHardWay/mypython/projects/ex47_pypa/tests/test_example.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.10/importlib/__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_example.py:8: in <module>
    from example_package_VCMota.example import add_one
E   ModuleNotFoundError: No module named 'example_package_VCMota'
============================================================================================= short test summary info ==============================================================================================
ERROR tests/test_example.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================================================================= 1 error in 0.05s =================================================================================================
(lpthw) ex47_pypa>

The error is due to how I call the function add_one in example.p, and, as you may see in the test_example.py, I have tried every imaginable way of calling this function.

The only thing I know for sure is that the error has nothing to do with pytest: I have assembled another file structure:


teste> tree
.
├── src
│   ├── example.py
│   └── __init__.py
└── tests
    └── test_example.py

2 directories, 3 files
teste> cd tests/
tests> cat test_example.py
# import example
# import example_package_VCMota
# from src/example_package_VCMota import example
# from src import example_package_VCMota/example
# import src
# import importlib

# from src.example_package_VCMota.example import add_one

from ..src.example import add_one


def test_dif():
    assert add_one(2) == 9
tests>

but it still does not work:

tests>python test_example.py
Traceback (most recent call last):
  File "/archive/MyBooks/LearnPython3TheHardWay/mypython/projects/teste/tests/test_example.py", line 10, in <module>
    from ..src.example import add_one
ImportError: attempted relative import with no known parent package
tests>

I am aware that there are multiple other ways of importing modules from other folders, as stated in this 11 years old post from stackoverflow itself, but the dot one is surely the simplest way, and, since it is clearly stated in the official documentation , it should work, but I cant make it work.

Thank you all for your attention.

EDIT:

Following Raphael's comments , I have started to suspect of errors/problems in my python installs, and therefore assembled the following file structure inside a virtual machine running Ubuntu LTS 20:

├── source │ ├── example.py │ └── init .py └── tests └── test_example.py

where I have tried multiple import commands in test_example.py, such as:

from .source.example import add_one
from ...source.example import add_one

and so on, and, again, none have worked. Since I am running Gentoo in my main machine, I suspect that this test indicates that whatever is the issue, it is certainly not with my python installs.

It's a common issue in Python that the tests for a package cannot find the package itself.

The main reason for the issues is your working directory. You cannot just cd into the tests folder and run the tests. In fact, you need to be one level above your project folder, so you need to be in ex47_pypa/.. and then run python -m ex47_pypa.tests.test_example .

This will give Python enough directory hierarchy to actually resolve the relative imports in your tests, so the from..src.example can be resolved.

I've created an experimental, new import library: ultraimport

It gives you more control over your imports and lets you do file system based imports.

In your test_example.py your could then write:

import ultraimport
add_one = ultraimport('__dir__/../src/example_package_VCMota/example.py', 'add_one')

This will always work, no matter how you run your code or what's your current working directory or what's in your sys.path.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM