Как мне управлять несколькими версиями библиотеки в проекте PythonPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как мне управлять несколькими версиями библиотеки в проекте Python

Сообщение Anonymous »

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

Код: Выделить всё

 .
├──  pyproject.toml
└── 󱧼 src
└──  version_example
├──  __init__.py
├──  bar
│   ├──  __init__.py
│   ├──  bar_1.py
│   └──  bar_2.py
├──  baz
│   ├──  __init__.py
│   ├──  baz_1.py
│   ├──  baz_2.py
│   └──  baz_3.py
├──  foo
│   ├──  __init__.py
│   └──  foo.py
└──  main.py
Вот мой pyproject.toml:

Код: Выделить всё

[tool.poetry]
name = "version_example"
version = "0.0.1"
description = ""
authors = []
packages = [{ include = "version_example", from = "src" }]
А вот main.py:

Код: Выделить всё

import os

from version_example.foo.foo import Foo

if int(os.environ["TARGET_VERSION"]) == 1:
from version_example.bar.bar_1 import Bar
else:
from version_example.bar.bar_2 import Bar

if int(os.environ["TARGET_VERSION"]) == 1:
from version_example.baz.baz_1 import Baz
elif int(os.environ["TARGET_VERSION"]) == 2:
from version_example.baz.baz_2 import Baz
else:
from version_example.baz.baz_3 import Baz

if __name__ == "__main__":
foo = Foo()
foo()
bar = Bar()
bar()
baz = Baz()
baz()
Каждый объект является вызываемым, и при вызове выводится его имя, например:

Код: Выделить всё

# version_example.bar.bar_2
class Bar:
def __call__(self):
print("Bar version 2")
Этот подход не масштабируется с новыми версиями.
Какие изменения мне нужно внести, чтобы вызывающий код не знал об управлении версиями ?
Например. что мне нужно сделать, чтобы добиться чего-то подобного?

Код: Выделить всё

# main.py
from version_pecific.foo import Foo
from version_pecific.bar import Bar
from version_pecific.baz import Baz

if __name__ == "__main__":
foo = Foo()
foo()
bar = Bar()
bar()
baz = Baz()
baz()
Один из вариантов — разбить модуль на три разных модуля:

Код: Выделить всё

 .
├──  poetry.lock
├──  pyproject.toml
├── 󱧼 src
│   └──  version_example
│       ├──  __init__.py
│       └──  main.py
└──  versions
├──  version_1
│   └──  version_pecific
│       ├──  __init__.py
│       ├──  bar.py
│       ├──  baz.py
│       └──  foo.py
├──  version_2
│   └──  version_pecific
│       ├──  __init__.py
│       ├──  bar.py
│       ├──  baz.py
│       └──  foo.py
└──  version_3
└──  version_pecific
├──  __init__.py
├──  bar.py
├──  baz.py
└──  foo.py
Затем мы можем добавить соответствующий модуль версии в PYTHONPATH, например. Export PYTHONPATH=./versions/version_3:$PYTHONPATH.
Однако недостатком этого подхода является то, что у меня есть дубликаты файлов Python, например bar.py будет дублироваться в version_2, version_3, а foo.py будет дублироваться во всех пакетах версий.
Другой подход — переместить проверку TARGET_VERSION в файлы __init__.py.
В качестве примера: src/version_example/bar/__init__.py будет иметь:

Код: Выделить всё

import os

if int(os.environ["TARGET_VERSION"]) == 1:
from version_example.bar.bar_1 import Bar
else:
from version_example.bar.bar_2 import Bar
и src/version_example/bar/__init__.py будут иметь:

Код: Выделить всё

import os

if int(os.environ["TARGET_VERSION"]) == 1:
from version_example.baz.baz_1 import Baz
elif int(os.environ["TARGET_VERSION"]) == 2:
from version_example.baz.baz_2 import Baz
else:
from version_example.baz.baz_3 import Baz
Здесь нам не нужно копировать какой-либо код, и вызывающему коду не обязательно знать версию, однако мы добавили один уровень косвенности, чтобы при чтении через код и после импорта я должен знать значение TARGET_VERSION.
Поэтому мне интересно, могу ли я использовать стихи или любой другой инструмент сборки Python для установки конкретной версии код как пакеты, и для каждого пакета объявить зависимость от более ранней версии, чтобы каждый пакет мог решить, импортировать ли класс из предыдущей версии или переопределить его новой версией?
Мне кажется, что это довольно общая проблема для пакета, который должен поддерживать несколько версий одной и той же библиотеки, но мне не удалось найти удовлетворительного решения этой проблемы.
Будем очень признательны за любые подсказки или ключевые слова для поиска!

Подробнее здесь: https://stackoverflow.com/questions/792 ... on-project
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Управление несколькими версиями SDK Firebase в большом проекте
    Anonymous » » в форуме Javascript
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous
  • Как управлять несколькими виртуальными средами Python в одном проекте VS Code?
    Anonymous » » в форуме Python
    0 Ответы
    20 Просмотры
    Последнее сообщение Anonymous
  • Как управлять несколькими виртуальными средами Python в одном проекте VS -кода?
    Anonymous » » в форуме Python
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • Как я могу управлять разными версиями Python на Mac?
    Anonymous » » в форуме Python
    0 Ответы
    22 Просмотры
    Последнее сообщение Anonymous
  • Как я могу управлять разными версиями Python на Mac?
    Anonymous » » в форуме Python
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»