如何使用同名的setuptools包和ext_modules?
How to use setuptools packages and ext_modules with the same name?
我的 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']
即 source/cppimplementation/fastfile.cpp
没有导出 FastFile class,但它有 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__']
即,它有 source/cppimplementation/fastfile.cpp
导出的 FastFile class,但没有 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
下使用相同的包名称而不被一个覆盖另一个?
你不能。第一个导入的获胜。您不能让 scripts/modules/packages/extensions 具有相同的名称 - 一个会覆盖所有其他名称。
但是你可以把一个放在另一个里面。将你的扩展命名为 fastfilepackage.fastfilepackage
然后你可以 import fastfilepackage
导入 Python 包和 import fastfilepackage.fastfilepackage
导入扩展;或 from fastfilepackage import fastfilepackage
.
作为最终解决方案,我完全删除了所有 Python *.py
代码,因为它们导致 C 扩展代码变慢了 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
我只是直接用 C 扩展模块属性替换了 version.py
:
// 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__ ) );
参考文献:
- Define a global in a Python module from a C API
- 原始提交:Deprecated the Python implementation *.py
我的 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']
即 source/cppimplementation/fastfile.cpp
没有导出 FastFile class,但它有 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__']
即,它有 source/cppimplementation/fastfile.cpp
导出的 FastFile class,但没有 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
下使用相同的包名称而不被一个覆盖另一个?
你不能。第一个导入的获胜。您不能让 scripts/modules/packages/extensions 具有相同的名称 - 一个会覆盖所有其他名称。
但是你可以把一个放在另一个里面。将你的扩展命名为 fastfilepackage.fastfilepackage
然后你可以 import fastfilepackage
导入 Python 包和 import fastfilepackage.fastfilepackage
导入扩展;或 from fastfilepackage import fastfilepackage
.
作为最终解决方案,我完全删除了所有 Python *.py
代码,因为它们导致 C 扩展代码变慢了 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
我只是直接用 C 扩展模块属性替换了 version.py
:
// 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__ ) );
参考文献:
- Define a global in a Python module from a C API
- 原始提交:Deprecated the Python implementation *.py