[英]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"])]
)
兩個評論:
無需直接向您的產品發送許可證,您可以使用distutils中的許可證元數據來指定此項。
不要在代碼中使用混合的單引號和雙引號:)
從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
文件夾自動。
使用 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.