Aliasing Python модулей - PullRequest
       45

Aliasing Python модулей

0 голосов
/ 30 апреля 2020

Контекст

Я работаю над проектом Python, разделенным на два пакета foo и spam. foo реализует высокоуровневый API; spam - это сложная часть программного обеспечения (поддерживаемая как отдельный проект), объединяющая различные Python модули и расширения. Ожидается, что пользователи будут использовать только foo, spam как внутренний механизм.

Цель

Я хотел бы сделать spam видимым для пользователей как foo.bar, сохраняя при этом строгий тип эквивалентность. Пользователь должен получить доступ к spam.eggs.Eggs, импортировав foo.bar.eggs.Eggs. В то же время я хотел бы, чтобы значение foo.bar.eggs.Eggs is spam.eggs.Eggs было истинным, чтобы не было риска непреднамеренного поведения при выполнении проверок типов (например, при проверке типов с помощью isinstance).

Иллюстративный пример

Этот пример сделан из следующего дерева файлов:

.
├── foo
│   ├── __init__.py
│   └── bar.py
└── spam
    ├── __init__.py
    └── eggs
        ├── __init__.py
        └── rice.py

[File foo/__init__.py]

print("Importing foo")

def hello():
    print("Hello from foo")

[File foo/bar.py (содержит основной импорт код)]

import importlib
import sys

sys.modules["foo.bar"] = importlib.import_module("spam")

del importlib, sys

[Файл spam/__init__.py]

print("Importing spam")

def hello():
    print("Hello from spam")

[Файл spam/eggs/__init__.py]

print("Importing spam.eggs")

def hello():
    print("Hello from spam.eggs")

class Eggs:
    pass

[Файл spam/eggs/rice.py ]

from . import Eggs

print("Importing spam.eggs.rice")

def hello():
    print("Hello from spam.eggs.rice")

class Rice(Eggs):
    pass

Я для удобства собрал пример на GitHub (со скриптами pytest). По какой-то причине скрипт test_module_import.py ведет себя так, как задумано, а test_class_import.py завершается ошибкой. Кажется, что экземпляры classe имеют свой родительский модуль (в соответствии с вызовом import) в своем имени типа. Что я могу сделать, чтобы это изменить?

...