Python, вызывающий локальную функцию в основном коде, нарушает импорт в тестах? - PullRequest
0 голосов
/ 27 августа 2018

У меня уже было это с системой импорта Python ... думал, что я наконец-то получил что-то надежное, и тогда происходит необъяснимое!

Это структура каталогов моего приложения:

/
- my-application/
 - subpackage/
  - __init__.py
  - my_module.py
 - __init__.py
- tests/
 - subpackage/
  - __init__.py
  - test_my_module.py
 - __init__.py
 - conftest.py
 - run.py
 - spark.py

Я запускаю все свои тесты через tests/run.py, который выглядит следующим образом (в попытке решить все проблемы с импортом):

import os
import pytest
import sys

rootdir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))

sys.path.insert(0, os.path.abspath(os.path.join(rootdir, "my-application")))

sys.exit(pytest.main([os.path.join(rootdir, "tests")]))

Это работало как абсолютный шарм, пока ясделал одну модификацию файла /my-application/subpackage/my-module.py - добавил локальный вызов функции.Например, my_module.py:

def foo():
  pass

def run_my_module():
  def bar():
    foo()          <---- Added this line

  bar()
  print("Ran")

ОБНОВЛЕНИЕ : ЭТО работает нормально:

def foo():
  pass

def run_my_module():
  def bar():
    pass

  foo()
  bar()
  print("Ran")

Как только я добавил вызов локальной функции, тесты перестали работать, с ошибкой No module named "subpackage".

test_my_module.py выглядит следующим образом (в основном):

from subpackage.my_module import run_my_module

def basic_test():
    run_my_module()

Обратите внимание, что в test_my_module.py я использую subpackage в качестве первой частимоего оператора импорта, потому что я использую файл run.py, который устанавливает my-application в качестве системного пути.Если я изменю импорт, чтобы начать с my_application, я получу ту же ошибку со ссылкой на my_application.py.

Я все еще изучаю Python, поэтому предложите любые изменения в структуре моего приложения, которые вам нравятся.Я не могу поверить в трудности этой системы импорта - я чувствую, что мне здесь не хватает чего-то простого ...

Заранее спасибо!

1 Ответ

0 голосов
/ 27 августа 2018

Управлять путями импорта вручную сложно.
A setup.py - лучший способ управления пакетами Python.

по соглашениям имена пакетов должны использовать _, а не -.

Создать setup.py с этим содержимым рядом с my_application/

from setuptools import find_packages, setup

setup(
    name='my_application',
    version='0.0.1',
    packages=find_packages(),
)

Я рекомендуюструктура приложения, подобная следующей:

$ tree

├── my_application
│   ├── __init__.py
│   ├── spark.py
│   └── subpackage
│       ├── __init__.py
│       └── my_module.py
├── setup.py
└── tests
    ├── conftest.py
    └── subpackage
        ├── __init__.py
        └── test_my_module.py

Локальная установка пакета

python setup.py develop Это будет символической ссылкой (волшебным образом) устанавливать ваш пакет в путь пакета python
Теперь в любых сценариях выможно использовать пути так, как вы ожидаете, например,

from my_application.subpackage.my_module import run_my_module

также рекомендуем использовать virtualenv

Подробнее о setup.py здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...