Python打包:数据文件正确放在tar.gz文件中,但未安装到虚拟环境中

时间:2021-06-06 13:29:44

I can't properly install the project package_fiddler to my virtual environment.

我无法将项目package_fiddler正确安装到我的虚拟环境中。

I have figured out that MANIFEST.in is responsible for putting the non-.py files in Package_fiddler-0.0.0.tar.gz that is generated when executing python setup.py sdist.

我已经发现MANIFEST.in负责将non.py文件放在执行python setup.py sdist时生成的Package_fiddler-0.0.0.tar.gz中。

Then I did:

然后我做了:

(virt_envir)$ pip install dist/Package_fiddler-0.0.0.tar.gz

(virt_envir)$ pip install dist / Package_fiddler-0.0.0.tar.gz

But this did not install the data files nor the package to /home/username/.virtualenvs/virt_envir/local/lib/python2.7/site-packages.

但是这并没有将数据文件和软件包安装到/home/username/.virtualenvs/virt_envir/local/lib/python2.7/site-packages。

I have tried many configurations of the setup arguments package_data, include_package_data and data_files but I seem to have used the wrong configuration each time.

我已经尝试了许多配置的设置参数package_data,include_package_data和data_files,但我似乎每次都使用了错误的配置。

Which configuration of package_data and/or include_package_data and/or data_files will properly install package_fiddler to my virtual environment?

package_data和/或include_package_data和/或data_files的哪个配置会将package_fiddler正确安装到我的虚拟环境中?

Project tree

项目树

.
├── MANIFEST.in
├── package_fiddler
│   ├── data
│   │   ├── example.html
│   │   └── stylesheets
│   │       └── example.css
│   └── __init__.py
├── README.rst
└── setup.py

setup.py

setup.py

from setuptools import setup


setup(
    name='Package_fiddler',
    entry_points={
    'console_scripts': ['package_fiddler = package_fiddler:main', ],},
    long_description=open('README.rst').read(),
    packages=['package_fiddler',])

MANIFEST.in

MANIFEST.in

include README.rst
recursive-include package_fiddler/data *

Which configurations of setup.py(with code base above) have I tried?

Configuration1

配置1

Adding:

添加:

package_data={"": ['package_fiddler/data/*',]}

Configuration2

Configuration2

Adding:

添加:

package_data={"": ['*.html', '*.css', '*.rst']}

Configuration3

Configuration3

Adding:

添加:

include_package_data=True

Configuration4

Configuration4

Adding:

添加:

package_data={"": ['package_fiddler/data',]}

Removing:

删除:

packages=['package_fiddler',]

Configuration5 (Chris's suggestion)

配置5(克里斯的建议)

Adding:

添加:

package_data={"data": ['package_fiddler/data',]}

Removing:

删除:

packages=['package_fiddler',]

Configuration 6

配置6

Adding:

添加:

package_data={"": ['package_fiddler/data/*',]}

Removing:

删除:

packages=['package_fiddler',]

These configurations all result in no files at all being installed on /home/username/.virtualenvs/virt_envir/local/lib/python2.7/site-packages.

这些配置都导致/home/username/.virtualenvs/virt_envir/local/lib/python2.7/site-packages上没有安装任何文件。

EDIT

Note to Toshio Kuratomi: In my original post I used the simplest tree structure where this problem occurs for clarity but in reality my tree looks more like the tree below. For that tree, strangely if I only put an __init__.py in stylesheets somehow all the data files in the texts folder are also installed correctly!!! This baffles me.

Toshio Kuratomi的注意事项:在我的原始帖子中,我使用了最简单的树结构,为了清楚起见出现了这个问题,但实际上我的树看起来更像下面的树。对于那棵树,奇怪的是如果我只在样式表中放置__init__.py,那么text文件夹中的所有数据文件也都正确安装!这令我感到困惑。

Tree 2 (This installs all data files properly somehow!!)

树2(这会以某种方式正确安装所有数据文件!!)

.
├── MANIFEST.in
├── package_fiddler
│   │── stylesheets
|   |     ├── __init__.py
|   |     ├── example.css  
|   |     └── other
|   |          └── example2.css
|   |__ texts
|   |     ├── example.txt  
|   |     └── other
|   |          └── example2.txt
│   └── __init__.py
├── README.rst
└── setup.py

5 个解决方案

#1


27  

I personally dislike the way setuptools mixes code and data both conceptually and implementation-wise. I think that it's that implementation that is tripping you up here. For setuptools to find and use package_data it needs for the data to reside inside of a python package. A python package can be a directory but there needs to be a __init__.py file in the directory. So it looks like you need the following (empty is fine) files:

我个人不喜欢setuptools在概念和实现方面混合代码和数据的方式。我认为正是这种实现让你在这里绊倒。对于setuptools来查找和使用package_data,需要将数据驻留在python包中。 python包可以是目录,但目录中需要有__init__.py文件。所以看起来你需要以下(空的很好)文件:

./package_fiddler/data/__init__.py
./package_fiddler/data/stylesheets/__init__.py

#2


30  

Found a solution that worked for me here.

找到了一个适合我的解决方案。

Using setuptools==2.0.2 I did:

使用setuptools == 2.0.2我做了:

setuptools.setup(
    ...
    packages=setuptools.find_packages(),
    include_package_data=True,  # use MANIFEST.in during install
    ...
)

#3


8  

The easiest way to include package data in "setup.py" is like so:

在“setup.py”中包含包数据的最简单方法是这样的:

package_data = {'<package name>': ['<path to data file within package dir>']}

So in your example:

所以在你的例子中:

package_data = {'package_fiddler': ['data/*', 'data/stylesheets/*']}

package_data is a dictionary where the keys are the names of the packages included in the installer. The values under these keys should be lists of specific file paths or globs/wildcards within the package directory.

package_data是一个字典,其中键是安装程序中包含的软件包的名称。这些键下的值应该是包目录中特定文件路径或globs /通配符的列表。

You also need to include the flag:

您还需要包含该标志:

zip_safe=False

in setup(...) if you want to be able to resolve file system paths to your data. Otherwise you can use pkg_resources to do this: http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resources

在安装程序(...)中,如果您希望能够解析数据的文件系统路径。否则,您可以使用pkg_resources执行此操作:http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resources

You definitely don't need an __init__.py file in the "data" directory - this directory is not a module and is not meant to be imported.

您绝对不需要“data”目录中的__init__.py文件 - 该目录不是模块,也不是要导入的。

#4


-1  

This works for me. Hope it helps.

这对我有用。希望能帮助到你。

package_data={
    "package_fiddler": [
        '\*.\*',
        '\*/\*.\*',
        '\*/\*/\*.\*',
    ],
},

#5


-2  

use

使用

package_data={"data": ['package_fiddler/data',]}

instead of

代替

packages=['package_fiddler',]

#1


27  

I personally dislike the way setuptools mixes code and data both conceptually and implementation-wise. I think that it's that implementation that is tripping you up here. For setuptools to find and use package_data it needs for the data to reside inside of a python package. A python package can be a directory but there needs to be a __init__.py file in the directory. So it looks like you need the following (empty is fine) files:

我个人不喜欢setuptools在概念和实现方面混合代码和数据的方式。我认为正是这种实现让你在这里绊倒。对于setuptools来查找和使用package_data,需要将数据驻留在python包中。 python包可以是目录,但目录中需要有__init__.py文件。所以看起来你需要以下(空的很好)文件:

./package_fiddler/data/__init__.py
./package_fiddler/data/stylesheets/__init__.py

#2


30  

Found a solution that worked for me here.

找到了一个适合我的解决方案。

Using setuptools==2.0.2 I did:

使用setuptools == 2.0.2我做了:

setuptools.setup(
    ...
    packages=setuptools.find_packages(),
    include_package_data=True,  # use MANIFEST.in during install
    ...
)

#3


8  

The easiest way to include package data in "setup.py" is like so:

在“setup.py”中包含包数据的最简单方法是这样的:

package_data = {'<package name>': ['<path to data file within package dir>']}

So in your example:

所以在你的例子中:

package_data = {'package_fiddler': ['data/*', 'data/stylesheets/*']}

package_data is a dictionary where the keys are the names of the packages included in the installer. The values under these keys should be lists of specific file paths or globs/wildcards within the package directory.

package_data是一个字典,其中键是安装程序中包含的软件包的名称。这些键下的值应该是包目录中特定文件路径或globs /通配符的列表。

You also need to include the flag:

您还需要包含该标志:

zip_safe=False

in setup(...) if you want to be able to resolve file system paths to your data. Otherwise you can use pkg_resources to do this: http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resources

在安装程序(...)中,如果您希望能够解析数据的文件系统路径。否则,您可以使用pkg_resources执行此操作:http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resources

You definitely don't need an __init__.py file in the "data" directory - this directory is not a module and is not meant to be imported.

您绝对不需要“data”目录中的__init__.py文件 - 该目录不是模块,也不是要导入的。

#4


-1  

This works for me. Hope it helps.

这对我有用。希望能帮助到你。

package_data={
    "package_fiddler": [
        '\*.\*',
        '\*/\*.\*',
        '\*/\*/\*.\*',
    ],
},

#5


-2  

use

使用

package_data={"data": ['package_fiddler/data',]}

instead of

代替

packages=['package_fiddler',]