使用setup.py包含非Python文件
如何使使用setup.py包含非Python文件,python,distutils,Python,Distutils,如何使setup.py包含一个不属于代码的文件?(具体来说,它是一个许可证文件,但也可以是任何其他文件。) 我希望能够控制文件的位置。在原始源文件夹中,文件位于包的根目录中。(即,与最顶层的\uuuu init\uuuu.py处于同一级别)我希望在安装软件包时,无论操作系统如何,它都保持在那里。如何做到这一点?找到了一个解决方法:我将我的lgpl2.1_license.txt重命名为lgpl2.1_license.txt.py,并在文本周围加上一些三重引号。现在,我不需要使用data\u fil
setup.py
包含一个不属于代码的文件?(具体来说,它是一个许可证文件,但也可以是任何其他文件。)
我希望能够控制文件的位置。在原始源文件夹中,文件位于包的根目录中。(即,与最顶层的
\uuuu init\uuuu.py
处于同一级别)我希望在安装软件包时,无论操作系统如何,它都保持在那里。如何做到这一点?找到了一个解决方法:我将我的lgpl2.1_license.txt
重命名为lgpl2.1_license.txt.py
,并在文本周围加上一些三重引号。现在,我不需要使用data\u files
选项,也不需要指定任何绝对路径。让它成为一个Python模块是丑陋的,我知道,但是我认为它比指定绝对路径不那么难看。 < P>也许最好的方法是使用<代码> StupToooS/<代码>代码> PACKAGEDATABASE/COD>指令。这确实意味着使用(或)而不是distutils
,但这是一个非常无缝的“升级”
下面是一个完整(但未经测试)的示例:
请注意此处关键的特定行:
package_data={'': ['license.txt']},
include_package_data=True,
package\u data
是一个模式列表(可以包括glob)中的包名(空=所有包)的dict。例如,如果只想在包中指定文件,也可以这样做:
package_data={'yourpackage': ['*.txt', 'path/to/resources/*.txt']}
这里的解决方案绝对不是用.py
扩展名重命名非py
文件
有关更多信息,请参阅
更新:另一种[更好的]方法
如果您只想控制源发行版(sdist
)的内容,并且在包之外有文件(例如顶级目录),那么另一种方法是在文件中添加一个MANIFEST.in。有关此文件的格式,请参见
自从写了这个响应之后,我发现使用MANIFEST.in
通常是一种不那么令人沮丧的方法,只需确保您的源代码发行版(tar.gz
)具有您需要的文件
例如,如果希望从顶层包含requirements.txt
,则递归地包含顶层“data”目录:
include requirements.txt
recursive-include data *
但是,为了在安装时将这些文件复制到站点软件包内的软件包文件夹中,您需要向setup()
函数提供include\u package\u data=True
。有关更多信息,请参阅。要完成您所描述的内容,需要两个步骤…
- 该文件需要添加到源tarball中
- 需要修改setup.py以将数据文件安装到源路径
步骤1:要将文件添加到源tarball,请将其包含在清单中
在包含setup.py的文件夹中创建模板
清单基本上是一个文本文件,包含源tarball中包含的所有文件的列表
以下是我的项目清单的外观:
- CHANGELOG.txt
- INSTALL.txt
- LICENSE.txt
- pypreprocessor.py
- 自述文件
- setup.py
- test.py
- TODO.txt
注意:尽管如此,我还是更愿意明确地指定它们,以确定它们,而不是预测它做什么和不做什么
步骤2:要将数据文件安装到源文件夹,请修改setup.py
由于您希望将数据文件(LICENSE.txt)添加到源安装文件夹,因此需要修改数据安装路径以匹配源安装路径。这是必要的,因为默认情况下,数据文件安装到与源文件不同的位置
要修改数据安装目录以匹配源安装目录
使用以下命令从distutils中提取安装目录信息:
from distutils.command.install import INSTALL_SCHEMES
修改数据安装目录以匹配源安装目录:
for scheme in INSTALL_SCHEMES.values():
scheme['data'] = scheme['purelib']
然后,将数据文件和位置添加到setup()
注意:上面的步骤应该以标准方式完全完成您描述的内容,而不需要任何扩展库 这里有一个简单的答案,对我来说很有用
首先,根据上面Python开发人员的评论,setuptools不是必需的:
package_data is also available to pure distutils setup scripts
since 2.3. – Éric Araujo
这很好,因为将setuptools要求放在软件包上意味着您也必须安装它。简言之:
from distutils.core import setup
setup(
# ...snip...
packages = ['pkgname'],
package_data = {'pkgname': ['license.txt']},
)
在setup.py中的setup(:
我只是想跟进在Centos 6上使用Python 2.7时发现的一些问题。如上所述添加包_data或数据_文件对我不起作用。我添加了一个MANIFEST.IN,其中包含我想要的文件,将非Python文件放入tarball,但没有通过RPM将它们安装到目标机器上
最后,我能够使用setup/setuptools中的“选项”将文件放入我的解决方案中。选项文件允许您从setup.py修改spec文件的各个部分。如下所示
from setuptools import setup
setup(
name='theProjectName',
version='1',
packages=['thePackage'],
url='',
license='',
author='me',
author_email='me@email.com',
description='',
options={'bdist_rpm': {'install_script': 'filewithinstallcommands'}},
)
文件-MANIFEST.in:
include license.txt
file-filewithinstallcommands:
mkdir -p $RPM_BUILD_ROOT/pathtoinstall/
#this line installs your python files
python setup.py install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
#install license.txt into /pathtoinstall folder
install -m 700 license.txt $RPM_BUILD_ROOT/pathtoinstall/
echo /pathtoinstall/license.txt >> INSTALLED_FILES
在项目根目录中创建MANIFEST.in
,将递归包含到所需目录,或使用文件名创建包含
include LICENSE
include README.rst
recursive-include package/static *
recursive-include package/templates *
我想对其中一个问题发表评论,但我没有足够的声誉这么做>>
以下是对我有效的方法(参考文档后得出):
奇怪的是,最后一行对我来说也是至关重要的(你也可以省略这个关键字参数——它的作用是一样的)
它的作用是复制顶级或根目录中的所有文本文件(从要分发的包mypkg
向上一级)
希望这有帮助!步骤1:在与setup.py位于同一文件夹的
文件中创建一个清单
步骤2:包括要添加到清单中的文件的相对路径。
include README.rst
include docs/*.txt
include funniest/data.json
步骤3:在setup()
函数中设置include\u package\u data=True
,以复制这些文件
mkdir -p $RPM_BUILD_ROOT/pathtoinstall/
#this line installs your python files
python setup.py install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
#install license.txt into /pathtoinstall folder
install -m 700 license.txt $RPM_BUILD_ROOT/pathtoinstall/
echo /pathtoinstall/license.txt >> INSTALLED_FILES
include LICENSE
include README.rst
recursive-include package/static *
recursive-include package/templates *
package_data={
'mypkg': ['../*.txt']
},
include_package_data: False
include README.rst
include docs/*.txt
include funniest/data.json
recursive-include template *
recursive-include template/* [this won't work]
setup(
...
include_package_data=True,
......
)
import os
import setuptools
from setuptools.command.build_py import build_py
from shutil import copyfile
HERE = os.path.abspath(os.path.dirname(__file__))
NAME = "thepackage"
class BuildCommand(build_py):
def run(self):
build_py.run(self)
if not self.dry_run:
target_dir = os.path.join(self.build_lib, NAME)
for fn in ["VERSION", "LICENSE.txt"]:
copyfile(os.path.join(HERE, fn), os.path.join(target_dir,fn))
setuptools.setup(
name=NAME,
cmdclass={"build_py": BuildCommand},
description=DESCRIPTION,
...
)
my-app/
├─ app/
│ ├─ __init__.py
│ ├─ __main__.py
├─ folder-with-extra-stuff/
│ ├─ __init__.py
│ ├─ data_file.json
├─ setup.py
├─ MANIFEST.in