«ModuleNotFoundError» после установки пакета Python

Краткое описание проблемы

Я очень новичок в разработке пакетов Python. Я разработал пакет и опубликовал его на TestPyPI. Я устанавливаю этот пакет через pip без ошибок. Однако python выдает мне «ModuleNotFoundError», когда я пытаюсь его импортировать, и я понятия не имею, почему. Кто-нибудь может мне помочь?

Шаги воспроизведения

Сначала я устанавливаю пакет с:

pip install -i https://test.pypi.org/simple/ spark-map==0.2.76

Затем я открываю новый терминал, запускаю интерпретатор Python и пытаюсь импортировать этот пакет, но Python выдает мне ModuleNotFoundError:

>>> import spark_map
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'spark_map'

Что я открываю

  • Когда я cd захожу в корневую папку пакета, открываю интерпретатор Python и запускаю import spark_map, он работает нормально, без ошибок;

  • Что pip не удалось установить пакет; Однако я проверил это. У меня нет сообщений об ошибках при установке пакета, и когда я запускаю pip list после команды pip install, я вижу spark_map в списке установленных пакетов.

> pip list
... many packages
spark-map                0.2.76
... more packages
  • Папка, в которую был установлен spark_map, может быть вне пути поиска модулей Python; Я проверил и это. pip устанавливает пакет в папку с именем Python310\lib\site-packages, и эта папка включена в переменную sys.path:
>>> import sys
>>> for path in sys.path:
...     print(path)

C:\Users\pedro\AppData\Local\Programs\Python\Python310\python310.zip
C:\Users\pedro\AppData\Local\Programs\Python\Python310\DLLs
C:\Users\pedro\AppData\Local\Programs\Python\Python310\lib
C:\Users\pedro\AppData\Local\Programs\Python\Python310
C:\Users\pedro\AppData\Local\Programs\Python\Python310\lib\site-packages
C:\Users\pedro\AppData\Local\Programs\Python\Python310\lib\site-packages\win32
C:\Users\pedro\AppData\Local\Programs\Python\Python310\lib\site-packages\win32\lib
C:\Users\pedro\AppData\Local\Programs\Python\Python310\lib\site-packages\Pythonwin

Информация о системе

Я на Windows 10, Python 3.10.9, пытаюсь установить и импортировать пакет spark_map версии 0.2.76.(https://test.pypi.org/project/spark-map/).

Информация о коде

Исходный код пакета размещен на GitHub, и структура папок этого пакета по сути такова:

root
│
├───spark_map
│   ├───__init__.py
│   ├───functions.py
│   └───mapping.py
│
├───tests
│   ├───functions
│   └───mapping
│
├───.gitignore
├───LICENSE
├───pyproject.toml
├───README.md
└───README.rst

pyproject.toml файл пакета:

[build-system]
requires = ["setuptools>=61.0", "toml"]
build-backend = "setuptools.build_meta"

[project]
name = "spark_map"
version = "0.2.76"
authors = [
  { name = "Pedro Faria", email = "[email protected]" }
]
description = "Pyspark implementation of `map()` function for spark DataFrames"
readme = "README.md"
requires-python = ">=3.7"
license = { file = "LICENSE.txt" }
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]

dependencies = [
    "pyspark",
    "setuptools",
    "toml"
]

[project.urls]
Homepage = "https://pedropark99.github.io/spark_map/"
Repo = "https://github.com/pedropark99/spark_map"
Issues = "https://github.com/pedropark99/spark_map/issues"


[tool.pytest.ini_options]
pythonpath = [
  "."
]


[tool.setuptools]
py-modules = []

Что я пробовал

Как предложил @Dorian Turba, я переместил исходный код в папку src. Теперь структура пакета такова:

root
├───src
│   └───spark_map
│       ├───__init__.py
│       ├───functions.py
│       └───mapping.py
│
├───tests
├───.gitignore
├───LICENSE
├───pyproject.toml
├───README.md
└───README.rst

После этого я выполнил python -m pip install -e . (лог этой команды на картинке ниже). Пакет был скомпилирован и успешно установлен. Однако, когда я открываю новый терминал в другом месте и пытаюсь запустить python -c "import spark_map", я все равно получаю ту же ошибку.

Я также попытался запустить виртуальную среду (с помощью python -m venv env) и установить пакет внутри этой виртуальной среды (с помощью pip install -e .). Затем я выполнил python -c "import spark_map". Но проблема все еще остается. Я также выполнил pip list, чтобы проверить, был ли установлен пакет. Полный лог команд на картинке ниже:

🤔 А знаете ли вы, что...
В Python есть множество библиотек и фреймворков для разработки веб-приложений.


2
104
4

Ответы:

требуется папка src

Стандартный макет файла следующий (Документ Python: Упаковка проектов Python):

packaging_tutorial/
├── LICENSE
├── pyproject.toml
├── README.md
├── src/
│   └── example_package_YOUR_USERNAME_HERE/
│       ├── __init__.py
│       └── example.py
└── tests/

Вам нужно поместить свой пакет в папку src.

Для вашего проекта это должно выглядеть так:

root
│
├───src/
│   └───spark_map/
│       ├───__init__.py
│       ├───functions.py
│       └───mapping.py
├───tests/
│   ├───functions
│   └───mapping
├───.gitignore
├───LICENSE
├───pyproject.toml
├───README.md
└───README.rst

Вам не нужно создавать дистрибутив колеса, чтобы проверить это, вы можете установить пакет непосредственно в свою среду с помощью pip install . (или в режиме редактирования, если вы хотите, чтобы ваше обновление было доступно напрямую без переустановки pip install -e .).


Убедитесь, что вы используете правильную среду Python

  1. Если вы используете виртуальную среду, убедитесь, что она активирована
  2. Убедитесь, что пакет установлен в этой среде (используя pip list).

Решено

Источник проблемы

Источник проблемы находится в «процессе сборки» пакета. Другими словами, pip install устанавливал «недопустимый пакет».

По сути, я использую setuptools для сборки пакета. Когда я скомпилировал (или «собрал» пакет с помощью python -m build, исходный код пакета (то есть все содержимое каталога src) не был включен в скомпилированный TAR-архив.

Исправить с помощью setuptools

Документация для setuptools рассказывает об этой проблеме поиска исходного кода для вашего проекта. По сути, setuptools не находил исходный код пакета. Поэтому мне нужно было помочь ему найти эти файлы, добавив эти две опции в мой файл pyproject.toml:

[tool.setuptools]
packages = ["spark_map"]
package-dir = {"" = "src"}

Как можно определить эту проблему?

Если у вас возникла аналогичная проблема при установке и импорте пакета, возможно, у вас возникла та же проблема, что и у меня. Чтобы проверить, так ли это, создайте свой проект с помощью python -m build. Затем откройте исходный дистрибутив вашего пакета (то есть архив TAR) и проверьте, есть ли исходный код внутри этого файла TAR. Если нет, то у вас именно эта проблема.


Используйте Hatchling с исходниками в папке src

Измените систему сборки на вылупление

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

Вам также необходимо изменить макет вашего проекта, как описано в этом ответе: требуется папка src.