Примечание : С тех пор как я задал этот вопрос, позже я обнаружил, что python -m pip install -e .
установит расширение к cmod
с .venv/lib/python3.8/site-packages/hello-c-extension.egg-link
, указывающим на проект в текущем каталоге. Я также переключился на макет src
в последующих коммитах и обнаружил, что https://pythonwheels.com/ является отличным справочником для высококачественных пакетов, которые раздают колеса. Тем не менее, мне все еще интересно узнать о поведении подкоманд setup.py
.
В рамках некоторых исследований many linux я использую игрушечный проект для создания различных колес платформы для модуля расширения C ++.
Кажется, что при сборке и установке локально я не могу импортировать модуль расширения C ++, если мой текущий каталог является каталогом проекта root. Это мешает мне запускать юнит-тесты, между прочим. Я полагаю, что причина этого в том, что .
становится первым компонентом sys.path
, и поэтому берется чистая версия Python, а скомпилированное расширение - нет.
Как это можно исправить ? Я правильно запускаю локальную сборку / установку?
Структура пакета выглядит следующим образом:
$ tree hello-c-extension/
hello-c-extension/
├── LICENSE
├── Makefile
├── README.md
├── cmod
│ ├── __init__.py
│ ├── _cmodule.cc
│ └── pymod.py
├── setup.py
└── tests
├── __init__.py
└── test_cext.py
У меня также есть проект на GitHub; Я задал этот вопрос начиная с 29fef5b .
. Для сборки / установки я использую:
cd hello-c-extension
python -m venv .venv
source ./.venv/bin/activate
python -m pip install -U pip wheel setuptools
python setup.py build install
Теперь из текущего каталога я могу импортировать Python модуль, но не соответствующий модуль расширения. Модуль Python выбирается как модуль в текущем каталоге, а не как в site-packages
:
$ python -c 'from cmod import pymod; print(pymod)'
<module 'cmod.pymod' from '/Users/brad/Scripts/python/projects/bsolomon1124/hello-c-extension/cmod/pymod.py'>
$ python -c 'from cmod import _cmod; print(_cmod)'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: cannot import name '_cmod' from 'cmod' (/Users/brad/Scripts/python/projects/bsolomon1124/hello-c-extension/cmod/__init__.py)
Удачное удаление элемента PWD sys.path
исправляет это:
>>> import sys
>>> sys.path
['', '/Users/brad/.pyenv/versions/3.8.1/lib/python38.zip', '/Users/brad/.pyenv/versions/3.8.1/lib/python3.8', '/Users/brad/.pyenv/versions/3.8.1/lib/python3.8/lib-dynload', '/Users/brad/Scripts/python/projects/bsolomon1124/hello-c-extension/.venv/lib/python3.8/site-packages', '/Users/brad/Scripts/python/projects/bsolomon1124/hello-c-extension/.venv/lib/python3.8/site-packages/hello_c_extension-0.4-py3.8-macosx-10.15-x86_64.egg']
>>> del sys.path[0]
>>> from cmod import _cmod; print(_cmod)
<module 'cmod._cmod' from '/Users/brad/Scripts/python/projects/bsolomon1124/hello-c-extension/.venv/lib/python3.8/site-packages/hello_c_extension-0.4-py3.8-macosx-10.15-x86_64.egg/cmod/_cmod.cpython-38-darwin.so'>
И, наконец, смена каталога также устраняет проблему go:
$ cd ..
$ python -c 'from cmod import _cmod; print(_cmod)'
<module 'cmod._cmod' from '/Users/brad/Scripts/python/projects/bsolomon1124/hello-c-extension/.venv/lib/python3.8/site-packages/hello_c_extension-0.4-py3.8-macosx-10.15-x86_64.egg/cmod/_cmod.cpython-38-darwin.so'>
Это действительно ... как это должно работать? Каков будет правильный способ запуска модульных тестов для модуля расширения в этом случае?
Информация о системе:
$ python -V
Python 3.8.1
$ uname -mrsv
Darwin 19.4.0 Darwin Kernel Version 19.4.0: Wed Mar 4 22:28:40 PST 2020; root:xnu-6153.101.6~15/RELEASE_X86_64 x86_64