封装自由软件许可证的库
项目描述
license是一个Python库,提供有关常见自由软件许可证的一些元数据,例如GNU GPL、MIT等。它与Python 3.3+和遗留Python 2.7兼容。
基本用法
要获取许可证,您可以使用SPDX许可证标识符
import license
mit = license.find('MIT')
每个许可证都是一个静态类,提供一些属性
id - SPDX标识符
name - 许可证的可读名称
python - PyPI分类器
url - 许可证描述或网站链接
mit.python
'License :: OSI Approved :: MIT License'
许可证类还提供了一个静态方法render(),它将输出整个许可证文本。必须向它传递一些变量,通常是name、email和可选的year(省略时使用当前年份)。
mit.render(name='Petr Foo', email='petr@foo.org')
'''The MIT License (MIT)
Copyright (c) 2015 Petr Foo <petr@foo.org>
Permission is hereby granted... (snip)'''
一些许可证(例如来自GPL家族的许可证)也有一个标题文本,该文本应添加到每个源文件中。使用 header() 来渲染它,但请注意,如果许可证没有使用特殊标题,则会引发 AttributeError。
mit.header(name='Petr Foo', email='petr@foo.org')
AttributeError: The MIT license uses no header
如果您想通过某些其他键搜索许可证,您可以使用
bsd = license.find_by_key('rpm', 'BSD')
bsd
[license.licenses.BSD3ClauseLicense, license.licenses.BSD2ClauseLicense]
bsd 现在是一个列表,因为与SPDX标识符不同,其他键可能不一定总是唯一的。如果您只需要具有此类标识符的第一个许可证,可以在 find_by_key() 中传递 multiple=False
bsd = license.find_by_key('rpm', 'BSD', multiple=False)
bsd
license.licenses.BSD3ClauseLicense
如果找不到此类许可证,您将得到 KeyError,这与常规的 find() 相同。
如果您想通过某个键执行大量搜索,您可以构建索引,理论上这将使搜索更快(尚未进行测量)。
license.build_index('rpm')
如果您想删除索引,请使用 license.delete_index(key)。即使索引不存在,调用它也是安全的。
您还可以使用 find_by_function() 来查找与特定表达式匹配的许可证。该函数应接受一个参数(许可证类)并返回一个布尔值,如果许可证应包含在结果中
osi = license.find_by_function(lambda l: l.python.startswith('License :: OSI Approved :: '))
它再次返回一个列表,并有一个 multiple 参数来更改它。
如果简单的函数不够用,您可以使用 license.iter() 遍历所有许可证
for cls in license.iter():
# do something
添加许可证
当前的许可证列表并不算很详尽,所以您的最喜欢的许可证可能不在其中。如果您想改变这一点,将许可证添加到 license/licenses.py 中,并将模板(模板)添加到 license/templates 中,然后向 GitHub 发送 pull request。查看当前许可证以了解如何操作。许可证类看起来像这样
class AGPLv3LaterLicense(license.base.License):
'''
GNU Affero General Public License v3.0 or later
'''
id = 'AGPL-3.0+'
rpm = 'AGPLv3+'
python = 'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)'
url = 'https://gnu.ac.cn/licenses/agpl-3.0.html'
一个许可证可以继承自其他并省略相等的键。请注意,文档字符串很重要,它用作 name 属性。许可证模板命名为 id,标题模板以 __header 后缀命名。
如果您想在代码中添加自定义许可证,也可以这样做。如果您不使用 render() 或 header(),事情很简单。只需在任何地方定义此类并对其调用 license.register()。
但是,如果您随后调用 render() 或 header(),则模板将无法找到。在这种情况下,您必须创建一个具有 jinja2 模板加载器的 Custom Base License。
CustomBaseLicense = license.base.custom_license_base_class(loader=jinja2.FileSystemLoader('path/to/templates'))
class CustomLicense(CustomBaseLicense):
...
license.register(CustomLicense)
该 loader 可以是任何有效的 jinja2 loader。如果您想一次性注册多个类,可以使用 license.autoregister(),该函数将注册给定模块中存在的所有类。您不需要注册您的 CustomBaseLicense,所以您将传递它作为 ignore 参数。
license.autoregister(sys.modules[__name__], ignore=[CustomBaseLicense])
请注意,如果您添加自定义许可证并使用 license.build_index(),您应该在注册它们之后构建索引。多次调用 build_index() 是安全的。
(可能)常见问题解答
为什么许可证以 License 的子类形式表示,而不是其实例?
这样,它更容易在多个许可证之间继承数据。类的定义更容易维护和阅读。
license 不是一个保留名称吗?
是的,它会打印Python的许可证。可能只在交互式Python控制台中使用。通过导入这个库,您正在覆盖它。我们本可以给它起一个酷炫且独特的名字,比如 licenraptor,但我们希望名字尽可能简单。如果您不喜欢这个名字,您也可以这样操作:import license as somethignelse。
难道没有可以渲染许可证文本的Python工具吗?
是的,有。然而,它们都是命令行工具,并为Python程序员提供没有API。
项目详情
license-0.1a3.tar.gz的散列值
算法 | 散列摘要 | |
---|---|---|
SHA256 | b42fa138fcb426390b95041ed683130b31ccadd541a4a7b33d211d11e962ffca |
|
MD5 | b837dd5af07387a46f3667b5b3bab412 |
|
BLAKE2b-256 | 727b18afb18be29a31241a1066158cdd3333e5236b975dfc9c7d8a5bb601ab21 |