Вопрос
Стандартная библиотека явно документирует как напрямую импортировать исходные файлы (учитывая абсолютный путь к исходному файлу), но этот подход делает не работают, если этот исходный файл использует неявный импорт брата, как описано в примере ниже.
Как этот пример можно адаптировать для работы при наличии имплицитных импортных товаров?
Я уже проверил этот и этот другой Вопрос о Stackoverflow по этой теме, но они не адресуют неявный импорт брака в файл, импортируемый вручную.
Настройка/Пример
Здесь иллюстративный пример
Структура каталогов:
root/
  - directory/
    - app.py
  - folder/
    - implicit_sibling_import.py
    - lib.py
 app.py:
import os
import importlib.util
# construct absolute paths
root = os.path.abspath(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
isi_path = os.path.join(root, 'folder', 'implicit_sibling_import.py')
def path_import(absolute_path):
   '''implementation taken from https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly'''
   spec = importlib.util.spec_from_file_location(absolute_path, absolute_path)
   module = importlib.util.module_from_spec(spec)
   spec.loader.exec_module(module)
   return module
isi = path_import(isi_path)
print(isi.hello_wrapper())
 lib.py:
def hello():
    return 'world'
 implicit_sibling_import.py:
import lib # this is the implicit sibling import. grabs root/folder/lib.py
def hello_wrapper():
    return "ISI says: " + lib.hello()
#if __name__ == '__main__':
#    print(hello_wrapper())
Запуск python folder/implicit_sibling_import.py с блоком if __name__ == '__main__': закомментировал выходы ISI says: world в Python 3.6.
Но запуск python directory/app.py дает:
Traceback (most recent call last):
  File "directory/app.py", line 10, in <module>
    spec.loader.exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
  File "/Users/pedro/test/folder/implicit_sibling_import.py", line 1, in <module>
    import lib
ModuleNotFoundError: No module named 'lib'
Обход
Если я добавлю import sys; sys.path.insert(0, os.path.dirname(isi_path)) в app.py, python app.py дает world, как и предполагалось, но я хотел бы избежать по возможности перетащить sys.path.
Требования к ответам
Мне бы хотелось python app.py распечатать ISI says: world, и я хотел бы сделать это, изменив функцию path_import.
Я не уверен в последствиях mangling sys.path. Например. если был directory/requests.py, и я добавил путь к directory в sys.path, я бы не хотел, чтобы import requests начал импортировать directory/requests.py вместо импорта запрашивает библиотеку, которую я установил с помощью pip install requests.
Решение ДОЛЖНО реализовано как функция python, которая принимает абсолютный путь к нужному модулю и возвращает объект модуля .
В идеале решение не должно вводить побочные эффекты (например, если он изменяет sys.path, он должен вернуть sys.path в исходное состояние). Если решение действительно вводит побочные эффекты, оно должно объяснить, почему решение не может быть достигнуто без введения побочных эффектов.
 PYTHONPATH
Если у меня есть несколько проектов, которые делают это, я не хочу забывать устанавливать PYTHONPATH каждый раз, когда я переключаюсь между ними. Пользователь должен просто иметь возможность pip install моего проекта и запускать его без каких-либо дополнительных настроек.
 -m
 -m флаг является рекомендуемым/питоновым подходом, но стандартная библиотека также явно документирует Как напрямую импортировать исходные файлы. Я хотел бы знать, как я могу адаптировать этот подход, чтобы справиться с неявным относительным импортом. Очевидно, что внутренние компоненты Python должны это делать, поэтому как внутренние компоненты отличаются от документации "импортировать исходные файлы напрямую"?
