правильно импортировать модули, выставить функцию для упаковки и разработки - PullRequest
0 голосов
/ 17 февраля 2019

Цели

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

  1. возможность запуска тестов из командной строки, возможно, после установки переменной окружения PYTHONPATH
  2. возможность запуска/ отладка тестов из IDE, возможно определение переменной среды PYTHONPATH
  3. запуск теста во время CI (Трэвис)
  4. не предоставляет ничего, кроме требуемой функции
  5. предоставляет функцию
  6. вызывается как интерфейс командной строки

Context

Вот структура моего проекта.Мне это нравится, но я с удовольствием поменяю его, чтобы удовлетворить вышеупомянутые требования.Но я бы действительно предпочел не смешивать тесты и исходники, а также ресурсы и код.

.
├── LICENSE
├── README.md
├── mysql_tracer
│   ├── __init__.py
│   ├── __main__.py
│   ├── chest.py
│   ├── cursor_provider.py
│   ├── query.py
│   └── writer.py
├── requirements.txt
├── setup.py
└── tests
    ├── assets
    │   ├── sample-query-executed.csv
    │   ├── sample-query-executed.sql
    │   ├── sample-query.sql
    │   └── sample-template-query.sql
    └── python
        ├── __init__.py
        ├── conftest.py
        ├── test_query.py
        └── test_writer.py

4 directories, 18 files

Разработка

Во время разработки я настраивал 1, 2 и 3. Мне было трудноЭто происходит потому, что импорт между модулями, импорт из тестов и модули-модули все работают по-разному.Я управлял рабочим решением со следующим:

  • module query.py импортирует модуль writer.py, используя import writer
  • module query.py импортирует класс CursorProvider из модуля cursor_provider.py, используяfrom cursor_provider import CursorProvider
  • модуль test_query.py импортирует запрос, используя import query
  • , функция test_result из модуля test_query.py проверяет модуль CursorProvider, импортированный из модуля query.py, используя @mock.patch('query.CursorProvider')
  • .travis.yml определяет тест как:
script:
- export PYTHONPATH=mysql_tracer
- pytest

Эта последняя часть была особенно нелогичной, так как предыдущие настройки, которые я пробовал, позволяли запускать тесты локали из терминала без установки переменной среды, и Idea всегда управлялаработать как-то.Рабочие настройки требовали его настройки для Travis и локального терминала.

Можно было просмотреть мою историю git и увидеть, что мне пришлось попробовать много вещей, прежде чем она заработала:

$ git log 1e5338dfab429d894a109a287f2a087c5d945a90..39c6e093e3bdb4470f374c4eb50d02ec52cb878a --pretty=format:"%h%x09%ad%x09%s"
39c6e09 Mon Feb 11 01:15:04 2019 +0100  travis, just do it please
544e540 Mon Feb 11 01:00:17 2019 +0100  mark it work locally... we'll see for CI later
a38caaa Mon Feb 11 00:10:50 2019 +0100  combine regexes with or
7a1eb88 Sun Feb 10 23:43:35 2019 +0100  travis, you're the last one, just f* works please
042f7c3 Sun Feb 10 23:08:14 2019 +0100  travis, mock, pytest, I changed everything, are you happy now ?
79e45c9 Sun Feb 10 22:54:35 2019 +0100  travis, get your shit together please
17eafaa Sun Feb 10 22:48:39 2019 +0100  another way to expose and import module to please both travis and mock
ea93558 Sun Feb 10 22:39:05 2019 +0100  test
4956d5a Sun Feb 10 21:34:31 2019 +0100  another way to expose Query...
98ff216 Sun Feb 10 21:22:33 2019 +0100  import differently
2426a6d Sun Feb 10 21:20:30 2019 +0100  expose Query
851ea43 Sun Feb 10 21:17:09 2019 +0100  setup.py

Упаковка

Но теперь, когда разработка подходит к концу, я настроил конфигурацию пакета для поддержки 5 и 6. К сожалению, мне не удалось настроить 4 правильно, и я сломал 1, 2 и3.

Мне пришлось изменить импорт между модулями, потому что в противном случае использование моего пакета после его установки локально или из pypi не сработало бы.

  • Вместо того, чтобы делать import writer Iбудет делать from . import writer
  • Вместо того, чтобы делать from cursor_provider import CursorProvider Я бы сделал from .cursor_provider import CursorProvider (обратите внимание на точку перед именем модуля)

Это заставило мой интерфейс Cli работать.После этого я мог бы использовать

$ mysql_tracer -h
... skipped output ...
$ mysql_tracer --host 127.0.0.1 --user aho --database company --destination /home/aho/Downloads /home/aho/sources/sql-test-tools/people.sql

. На этом этапе импорт модуля mysql_tracer будет работать, но он ничего не показывает.Однако при добавлении следующей строки в файл mysql_tracer/__init__.py будет открыт класс Query:

from .query import Query

Но так же все модули определены в пакете mysql_tracer (конец списка):

>>> import mysql_tracer
>>> dir(mysql_tracer)
['Query', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'chest', 'cursor_provider', 'query', 'writer']

Хотя это не слишком беспокоит, это нежелательно.Я имел в виду только атрибут Query, который будет доступен. сундук, cursor_provider, запрос и писатель должны быть скрыты .Обратите внимание, что они были недоступны до того, как я попытался предоставить класс Query.

Но теперь операторы импорта, которые сделали функционал пакета, делают тесты неудачными:

    from . import writer
E   ImportError: attempted relative import with no known parent package

ИтакКак сохранить работоспособность функций (5 и 6) при восстановлении требований к разработке (1,2 и 3)?И, возможно, также функция 4?

Я надеюсь, что предоставил необходимую и достаточную информацию, но если вам нужно больше, пожалуйста, посетите мой проект , пакет или CI page или прокомментируйте и попросите разъяснений.

...