Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用setup.py包含非Python文件_Python_Distutils - Fatal编程技术网

使用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