簡體   English   中英

如何在 setup.py 腳本中包含許可證文件?

[英]How to include license file in setup.py script?

我用 C++ 編寫了一個 Python 擴展模塊。 我計划使用 setuptools 分發模塊。 將有 32 位和 64 位 Windows 的二進制分發版(使用setup.py bdist_egg )和類 UNIX 平台的源代碼分發版(使用setup.py sdist構建)。

我計划在 BSD 許可證下授權該模塊。 在我的源代碼樹中,文件 LICENSE.txt 與 setup.py 一起位於頂部文件夾中。 我應該如何將它包含在安裝包中?

我嘗試了以下 setup.py 腳本:

from setuptools import setup, Extension
from glob import glob

setup(
    name = 'Foo',
    version = '0.1.0',
    ext_modules = [Extension('Foo', glob('Source/*.cpp'))],
    package_data = {'': ['LICENSE.txt']}
)

它不起作用,許可證文件不包含在安裝包中。 可能是因為 setup.py 文件沒有定義任何包,只有一個擴展模塊。

我該如何解決?

編寫一個setup.cfg文件並在其中指定:

[metadata]
license_files = LICENSE.txt

為此,似乎需要安裝輪子。 那是:

pip install wheel

如果您已經安裝了wheel並且它不起作用,請嘗試更新它:

pip install --upgrade wheel

然后,當通過pip install <path>安裝軟件包時,將包含 LICENSE 文件。

使用data_files

setup(
    name = "Foo",
    version = "0.1.0",
    ext_modules = [Extension("Foo", glob("Source/*.cpp"))],
    data_files = [("", ["LICENSE.txt"])]
)

兩個評論:

  1. 無需直接向您的產品發送許可證,您可以使用distutils中的許可證元數據來指定此項。

  2. 不要在代碼中使用混合的單引號和雙引號:)

setuptools 42.0.0 開始,您可以使用license_files鍵來指定要包含在分發中的許可證文件列表。 從 56.0.0 版開始,它支持模式匹配,默認為('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*')

請注意,由於實現細節,實際上不需要將此密鑰放入setup.cfg文件中(正如另一個答案所暗示的那樣)。 您可以將其作為參數提供給setup()函數:
(在撰寫本文時文檔尚不清楚)

from setuptools import setup

setup(
    ...
    license_files = ('LICENSE.txt',),
    ...
)

另請注意,雖然這些文件將包含在二進制(wheel)和源代碼分發中,但如果用戶沒有安裝wheel包,它們將不會與您的setup.py風格的源代碼分發包一起安裝!
為確保許可證文件將與您的軟件包一起安裝,您需要對安裝腳本進行一些額外的修改:

from setuptools import setup
from setuptools.command.egg_info import egg_info


class egg_info_ex(egg_info):
    """Includes license file into `.egg-info` folder."""

    def run(self):
        # don't duplicate license into `.egg-info` when building a distribution
        if not self.distribution.have_run.get('install', True):
            # `install` command is in progress, copy license
            self.mkpath(self.egg_info)
            self.copy_file('LICENSE.txt', self.egg_info)

        egg_info.run(self)


setup(
    ...
    license_files = ('LICENSE.txt',),
    cmdclass = {'egg_info': egg_info_ex},
    ...
)

如果您的項目是pyproject.toml風格的項目,並且您認為它將由 PEP 517 兼容的前端(例如pip>=19 )安裝,則會從您的源代碼強制構建一個輪子,並且許可證文件將安裝到.dist-info文件夾自動。

從 61.0.0 版本開始,您可以改為pyproject.toml文件中指定項目元數據和其他配置選項

使用 METADATA.in 文件,許可證可以自動包含在源包和輪子中:

METADATA.in include README.md include COPYING

在此處查看示例: https ://github.com/node40/smsh

新的 setuptools (40.x) 允許將元數據(包括許可證)存儲在setup.cfg 的“元數據”部分中。 如果您使用較舊的 setuptools,您可以使用 setup() 中的“license”命名參數提供許可證:

def read_text(file_name: str):
    return open(os.path.join(base_path, file_name)).read()


setup(
    name = 'Foo',
    version = '0.1.0',
    ext_modules = [Extension('Foo', glob('Source/*.cpp'))],
    # package_data = {'': ['LICENSE.txt']}
    license=read_text("LICENSE.txt")
)

您必須將 LICENSE.txt 文件移動到項目的包目錄中。 它不能駐留在頂層。 部署 Python 目錄,而不是部署工件。 如果您創建一個 python 包,該包實際上包含許多子包。 每個子包必須包含與部署相關的所有文件。

不要使用data_files ,因為它實際上會將文件作為單獨的包分發。 (我聽說package_files有效,但我還沒有看到一個可行的例子來做到這一點)。

例如:

setup(
    ...
    license="ZPL",
    classifiers=[
        ...
        'License :: OSI Approved :: Zope Public License',
        ...
        ],
     ...)

此外,您可以將許可證文本插入“long_description”:

setup(
    ...
    long_description="Package description. \nLicense Text",
    ...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM