Как настроить python3 venv так, чтобы относительный импорт правильно работал в проекте фристайла Jenkins? - PullRequest
0 голосов
/ 10 марта 2020

У меня есть работа Jenkins, которая извлекает файлы python из разных репозиториев Gitlab в рамках моего проекта Jenkins WORKSPACE. Некоторые из этих сценариев должны быть импортированы другими, но я сталкиваюсь с ошибками при использовании относительного импорта.

ValueError: попытка относительного импорта за пределы пакета верхнего уровня

script1.py

from ..script2/script2 import foo

script2.py

def foo():
    print('Foo!')

Иерархия файлов и каталогов

/var/lib/jenkins/workspace/project_name
    script1/
        script1.py
    script2/
        # script2.py contains 'foo' function
        script2.py

Шаг сборки Дженкинса "Выполнить оболочку"

#!/bin/bash

python3 -m venv ${WORKSPACE}/venv
. ${WORKSPACE}/venv/bin/activate

python ${WORKSPACE}/script1/script1.py 

Что я пропустил?

1 Ответ

1 голос
/ 12 марта 2020

В идеале тесты должны проводиться в «чистой среде». Таким образом, вместо запуска тестов сценариев с относительным импортом, одним из решений является запись setup.py для локальной установки вашего проекта в виде модуля. Затем вы можете написать отдельные тесты, в которых вы можете выполнить from mymodule import script1.script1.

Если вы go по этому пути, вам нужно определиться со структурой проекта. Там нет лучшей структуры (см. здесь ). В качестве примера, вот моя типичная структура:

├── src/
│   ├── script1/
│   │   └── script1.py
│   └── script2/
│       └── script2.py
├── tests/
│   ├── test_script1.py
│   └── test_script2.py
└── venv/

и файл setup.py, подобный следующему:

import os

from setuptools import find_packages, setup

# load desc from readme
def read(fname):
    return open(os.path.join(os.path.dirname(__file__), fname)).read()

setup(
    name="mymodule",
    version="0.0.1",
    author="you",
    author_email="<you@you.com>",
    description=("short description"),
    license="<none>",
    packages=find_packages("src"),
    package_dir={"": "src"},
    long_description=read("README.md"),
    classifiers=[
        "Development Status :: 2 - Pre-Alpha",
        "Topic :: Utilities",
        # "License :: OSI Approved :: MIT License",
    ],
    install_requires=[],
)

. В этом примере вы можете запустить python setup.py install для установки mymodule. и затем запустите все тесты с pytest tests. Это не только проверяет ваши тесты, но и проверяет, правильно ли установлен / установлен ваш пакет. При использовании виртуальной среды setup.py будет установлен здесь вместо всей системы.
Наконец, вы можете использовать относительный импорт во всех ваших файлах, так как у вас будет модуль верхнего уровня "mymodule", и ваша ошибка исчезнет.

PS: если вы не хотите импортировать script1.script1, вы можете написать __init__.py файлов в каталогах, чтобы иметь возможность from mymodule import script1 или даже from mymodule import ClassFromScript1

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