Как использовать пакеты setuptools и ext_modules с одинаковыми именами? - PullRequest
1 голос
/ 21 мая 2019

Я получил следующую структуру файлов для моего проекта расширения Python C:

.
├── setup.py
├── source
    ├── cppimplementation
    │   └── fastfile.cpp
    └── fastfilepackage
        ├── __init__.py
        └── version.py

И я использую следующий setup.py файл:

from setuptools import setup, Extension

setup(
        name= 'fastfilepackage',
        version= '0.1.1',
        package_dir = {
            '': 'source',
        },

        packages = [
            'fastfilepackage',
        ],

        ext_modules= [
            Extension(
                'fastfilepackage',
                [
                    'source/cppimplementation/fastfile.cpp',
                ]
            )
        ],
    )

Я устанавливаю их с:

$ pip3 --version
pip 19.1.1 (python 3.6)

$ python3 --version
Python 3.6.7

$ pip3 list
Package                Version      
---------------------- -------------
wheel                  0.33.1        
setuptools             40.8.0        
...

fastfilepackage$ pip3 install .

Проблема в том, что при установке мой модуль расширения Python C переопределяется на fastfilepackage/version.py и fastfilepackage/__init__.py, т.е. после его установки я получил следующее:

import fastfilepackage
print( dir( fastfilepackage ) )
# prints ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', 
#         '__name__', '__package__', '__path__', '__spec__', '__version__',
#         'version']

Т.е. класс FastFile не экспортируется source/cppimplementation/fastfile.cpp, но в нем есть файлы fastfilepackage/version.py и fastfilepackage/__init__.py.

Это установленная файловая структура:

.
└── dist-packages
    ├── fastfilepackage
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   ├── __init__.cpython-36.pyc
    │   │   └── version.cpython-36.pyc
    │   └── version.py
    ├── fastfilepackage-0.1.1.dist-info
    │   ├── INSTALLER
    │   ├── LICENSE.txt
    │   ├── METADATA
    │   ├── RECORD
    │   ├── top_level.txt
    │   └── WHEEL
    └── fastfilepackage.cpython-36m-x86_64-linux-gnu.so

Но если я удалю строки package_dir = { '': 'source', }, и packages = [ 'fastfilepackage', ], из моего установочного файла, мой модуль расширения Python C будет установлен правильно:

import fastfilepackage
print( dir( fastfilepackage ) )
# prints ['FastFile', '__doc__', '__file__', '__loader__', '__name__', 
#         '__package__', '__spec__']

Т.е. класс FastFile экспортируется в source/cppimplementation/fastfile.cpp, но нет файлов fastfilepackage/version.py и fastfilepackage/__init__.py.

Это была установленная файловая структура:

.
└── dist-packages
    ├── fastfilepackage-0.1.1.dist-info
    │   ├── INSTALLER
    │   ├── LICENSE.txt
    │   ├── METADATA
    │   ├── RECORD
    │   ├── top_level.txt
    │   └── WHEEL
    └── fastfilepackage.cpython-36m-x86_64-linux-gnu.so

Как я могу поставить ext_modules и packages, чтобы использовать одно и то же имя пакета под моим setup.py без переопределения одного другого?

Ответы [ 2 ]

1 голос
/ 22 мая 2019

В качестве окончательного решения я полностью удалил весь код Python *.py, потому что они заставили код C Extensions стать на 30% медленнее. Теперь мои setup.py стали такими:

from setuptools import setup, Extension

setup(
        name = 'fastfilepackage',
        version = '0.1.1',

        ext_modules = [
            Extension(
                name = 'fastfilepackage',
                sources = [
                    'source/fastfile.cpp',
                ],
                include_dirs = ['source'],
            )
        ],
    )

Структура файла:

.
├── setup.py
├── MANIFEST.in
├── README.md
├── LICENSE.txt
└── source
    ├── fastfile.cpp
    └── version.h

MANIFEST.in

include README.md
include LICENSE.txt

recursive-include source *.h

Это установленная файловая структура: (Нет *.py файлов в любом месте = 100% производительности)

.
└── dist-packages
    ├── fastfilepackage-0.1.1.dist-info
    │   ├── INSTALLER
    │   ├── LICENSE.txt
    │   ├── METADATA
    │   ├── RECORD
    │   ├── top_level.txt
    │   └── WHEEL
    └── fastfilepackage.cpython-36m-x86_64-linux-gnu.so

Я только что заменил version.py напрямую на атрибут модуля C Extensions:

// https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
const char* __version__ = "0.1.1";
PyObject_SetAttrString( thismodule, "__version__", Py_BuildValue( "s", __version__ ) );

Ссылки:

  1. Определение глобала в модуле Python из C API
  2. Исходная фиксация: Устаревшая реализация Python * .py
1 голос
/ 21 мая 2019

Вы не можете.Первый импортировал выигрывает.У вас не может быть скриптов / модулей / пакетов / расширений с одинаковым именем - один переопределяет все остальные.

Но вы можете иметь один внутри другого.Сделайте ваше расширение с именем fastfilepackage.fastfilepackage, и вы сможете import fastfilepackage импортировать пакет Python и import fastfilepackage.fastfilepackage, чтобы импортировать расширение;или from fastfilepackage import fastfilepackage.

...