This commit is contained in:
Iliyan Angelov
2025-12-01 06:50:10 +02:00
parent 91f51bc6fe
commit 62c1fe5951
4682 changed files with 544807 additions and 31208 deletions

View File

@@ -0,0 +1,272 @@
Metadata-Version: 2.4
Name: license-expression
Version: 30.4.4
Summary: license-expression is a comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic.
Home-page: https://github.com/aboutcode-org/license-expression
Author: nexB. Inc. and others
Author-email: info@aboutcode.org
License: Apache-2.0
Keywords: open source,license expression,license,spdx,boolean,parse expression,normalize expression,compare expression,licence
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/x-rst
License-File: apache-2.0.LICENSE
License-File: NOTICE
License-File: AUTHORS.rst
License-File: CHANGELOG.rst
License-File: CODE_OF_CONDUCT.rst
License-File: README.rst
Requires-Dist: boolean.py>=4.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.1; extra == "dev"
Requires-Dist: pytest-xdist>=2; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: Sphinx>=5.0.2; extra == "dev"
Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "dev"
Requires-Dist: sphinxcontrib-apidoc>=0.4.0; extra == "dev"
Requires-Dist: sphinx-reredirects>=0.1.2; extra == "dev"
Requires-Dist: doc8>=0.11.2; extra == "dev"
Requires-Dist: sphinx-autobuild; extra == "dev"
Requires-Dist: sphinx-rtd-dark-mode>=1.3.0; extra == "dev"
Requires-Dist: sphinx-copybutton; extra == "dev"
Dynamic: license-file
==================
license-expression
==================
``license-expression`` is a comprehensive utility library to parse, compare,
simplify and normalize license expressions (such as SPDX license expressions)
using boolean logic.
- License: Apache-2.0
- Python: 3.9+
- Homepage: https://github.com/aboutcode-org/license-expression/
- Install: `pip install license-expression` also available in most Linux distro.
Software project licenses are often a combination of several free and open
source software licenses. License expressions -- as specified by SPDX -- provide
a concise and human readable way to express these licenses without having to
read long license texts, while still being machine-readable.
License expressions are used by key FOSS projects such as Linux; several
packages ecosystem use them to document package licensing metadata such as
npm and Rubygems; they are important when exchanging software data (such as with
SPDX and SBOM in general) as a way to express licensing precisely.
``license-expression`` is a comprehensive utility library to parse, compare,
simplify and normalize these license expressions (such as SPDX license expressions)
using boolean logic like in: `GPL-2.0-or-later WITH Classpath-exception-2.0 AND MIT`.
It includes the license keys from SPDX https://spdx.org/licenses/ (version 3.26)
and ScanCode LicenseDB (from scancode-toolkit version 32.3.1, last published on 2025-01-10).
See https://scancode-licensedb.aboutcode.org/ to get started quickly.
``license-expression`` is both powerful and simple to use and is a used as the
license expression engine in several projects and products such as:
- AboutCode-toolkit https://github.com/aboutcode-org/aboutcode-toolkit
- AlekSIS (School Information System) https://edugit.org/AlekSIS/official/AlekSIS-Core
- Conda forge tools https://github.com/conda-forge/conda-smithy
- DejaCode https://enterprise.dejacode.com
- DeltaCode https://github.com/nexB/deltacode
- FenixscanX https://github.com/SmartsYoung/FenixscanX
- FetchCode https://github.com/aboutcode-org/fetchcode
- Flict https://github.com/vinland-technology/flict and https://github.com/vinland-technology
- license.sh https://github.com/webscopeio/license.sh
- liferay_inbound_checker https://github.com/carmenbianca/liferay_inbound_checker
- REUSE https://reuse.software/ and https://github.com/fsfe/reuse-tool
- ScanCode-io https://github.com/aboutcode-org/scancode.io
- ScanCode-toolkit https://github.com/aboutcode-org/scancode-toolkit
- SecObserve https://github.com/MaibornWolff/SecObserve
See also for details:
- https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions
``license-expression`` is also packaged for most Linux distributions. See below.
Alternative:
There is no known alternative library for Python, but there are several similar
libraries in other languages (but not as powerful of course!):
- JavaScript https://github.com/jslicense/spdx-expression-parse.js
- Rust https://github.com/ehuss/license-exprs
- Haskell https://github.com/phadej/spdx
- Go https://github.com/kyoh86/go-spdx
- Ada https://github.com/Fabien-Chouteau/spdx_ada
- Java https://github.com/spdx/tools and https://github.com/aschet/spdx-license-expression-tools
Source code and download
========================
- GitHub https://github.com/aboutcode-org/license-expression.git
- PyPI https://pypi.python.org/pypi/license-expression
Also available in several Linux distros:
- Arch Linux https://archlinux.org/packages/extra/any/python-license-expression/
- Debian https://packages.debian.org/unstable/source/license-expression
- DragonFly BSD https://github.com/DragonFlyBSD/DPorts/tree/master/textproc/py-license-expression
- Fedora https://src.fedoraproject.org/rpms/python-license-expression/
- FreeBSD https://www.freshports.org/textproc/py-license-expression
- NixOS https://github.com/NixOS/nixpkgs/blob/release-21.05/pkgs/development/python-modules/license-expression/default.nix
- openSUSE https://build.opensuse.org/package/show/openSUSE:Factory/python-license-expression
Support
=======
- Submit bugs and questions at: https://github.com/aboutcode-org/license-expression/issues
- Join the chat at: https://gitter.im/aboutcode-org/discuss
Description
===========
This module defines a mini language to parse, validate, simplify, normalize and
compare license expressions using a boolean logic engine.
This supports SPDX license expressions and also accepts other license naming
conventions and license identifiers aliases to resolve and normalize any license
expressions.
Using boolean logic, license expressions can be tested for equality, containment,
equivalence and can be normalized or simplified.
It also bundles the SPDX License list (3.26 as of now) and the ScanCode license
DB (based on latest ScanCode) to easily parse and validate expressions using
the license symbols.
Usage examples
==============
The main entry point is the ``Licensing`` object that you can use to parse,
validate, compare, simplify and normalize license expressions.
Create an SPDX Licensing and parse expressions::
>>> from license_expression import get_spdx_licensing
>>> licensing = get_spdx_licensing()
>>> expression = ' GPL-2.0 or LGPL-2.1 and mit '
>>> parsed = licensing.parse(expression)
>>> print(parsed.pretty())
OR(
LicenseSymbol('GPL-2.0-only'),
AND(
LicenseSymbol('LGPL-2.1-only'),
LicenseSymbol('MIT')
)
)
>>> str(parsed)
'GPL-2.0-only OR (LGPL-2.1-only AND MIT)'
>>> licensing.parse('unknwon with foo', validate=True, strict=True)
license_expression.ExpressionParseError: A plain license symbol cannot be used
as an exception in a "WITH symbol" statement. for token: "foo" at position: 13
>>> licensing.parse('unknwon with foo', validate=True)
license_expression.ExpressionError: Unknown license key(s): unknwon, foo
>>> licensing.validate('foo and MIT and GPL-2.0+')
ExpressionInfo(
original_expression='foo and MIT and GPL-2.0+',
normalized_expression=None,
errors=['Unknown license key(s): foo'],
invalid_symbols=['foo']
)
Create a simple Licensing and parse expressions::
>>> from license_expression import Licensing, LicenseSymbol
>>> licensing = Licensing()
>>> expression = ' GPL-2.0 or LGPL-2.1 and mit '
>>> parsed = licensing.parse(expression)
>>> expression = ' GPL-2.0 or LGPL-2.1 and mit '
>>> expected = 'GPL-2.0-only OR (LGPL-2.1-only AND mit)'
>>> assert str(parsed) == expected
>>> assert parsed.render('{symbol.key}') == expected
Create a Licensing with your own license symbols::
>>> expected = [
... LicenseSymbol('GPL-2.0'),
... LicenseSymbol('LGPL-2.1'),
... LicenseSymbol('mit')
... ]
>>> assert licensing.license_symbols(expression) == expected
>>> assert licensing.license_symbols(parsed) == expected
>>> symbols = ['GPL-2.0+', 'Classpath', 'BSD']
>>> licensing = Licensing(symbols)
>>> expression = 'GPL-2.0+ with Classpath or (bsd)'
>>> parsed = licensing.parse(expression)
>>> expected = 'GPL-2.0+ WITH Classpath OR BSD'
>>> assert parsed.render('{symbol.key}') == expected
>>> expected = [
... LicenseSymbol('GPL-2.0+'),
... LicenseSymbol('Classpath'),
... LicenseSymbol('BSD')
... ]
>>> assert licensing.license_symbols(parsed) == expected
>>> assert licensing.license_symbols(expression) == expected
And expression can be deduplicated, to remove duplicate license subexpressions
without changing the order and without consider license choices as simplifiable::
>>> expression2 = ' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)'
>>> parsed2 = licensing.parse(expression2)
>>> str(parsed2)
'GPL-2.0 OR (mit AND LGPL 2.1) OR BSD OR GPL-2.0 OR (mit AND LGPL 2.1)'
>>> assert str(parsed2.simplify()) == 'BSD OR GPL-2.0 OR (LGPL 2.1 AND mit)'
Expression can be simplified, treating them as boolean expressions::
>>> expression2 = ' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)'
>>> parsed2 = licensing.parse(expression2)
>>> str(parsed2)
'GPL-2.0 OR (mit AND LGPL 2.1) OR BSD OR GPL-2.0 OR (mit AND LGPL 2.1)'
>>> assert str(parsed2.simplify()) == 'BSD OR GPL-2.0 OR (LGPL 2.1 AND mit)'
Two expressions can be compared for equivalence and containment:
>>> expr1 = licensing.parse(' GPL-2.0 or (LGPL 2.1 and mit) ')
>>> expr2 = licensing.parse(' (mit and LGPL 2.1) or GPL-2.0 ')
>>> licensing.is_equivalent(expr1, expr2)
True
>>> licensing.is_equivalent(' GPL-2.0 or (LGPL 2.1 and mit) ',
... ' (mit and LGPL 2.1) or GPL-2.0 ')
True
>>> expr1.simplify() == expr2.simplify()
True
>>> expr3 = licensing.parse(' GPL-2.0 or mit or LGPL 2.1')
>>> licensing.is_equivalent(expr2, expr3)
False
>>> expr4 = licensing.parse('mit and LGPL 2.1')
>>> expr4.simplify() in expr2.simplify()
True
>>> licensing.contains(expr2, expr4)
True
Development
===========
- Checkout a clone from https://github.com/aboutcode-org/license-expression.git
- Then run ``./configure --dev`` and then ``source tmp/bin/activate`` on Linux and POSIX.
This will install all dependencies in a local virtualenv, including
development deps.
- On Windows run ``configure.bat --dev`` and then ``Scripts\bin\activate`` instead.
- To run the tests, run ``pytest -vvs``

View File

@@ -0,0 +1,19 @@
license_expression-30.4.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
license_expression-30.4.4.dist-info/METADATA,sha256=H4_JWtt8L-rW1rUswtoJ1Bd7JL-sBn96Tb3GZucklfs,11186
license_expression-30.4.4.dist-info/RECORD,,
license_expression-30.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
license_expression-30.4.4.dist-info/licenses/AUTHORS.rst,sha256=0oG3fi5t0InegwxiPPHDHgKdgjLQvXYgBb9pvVQX-Ok,491
license_expression-30.4.4.dist-info/licenses/CHANGELOG.rst,sha256=XBUPAwWX_aCC74F4j6aYHZmT7QqF3l89aas_MWtAVRU,3419
license_expression-30.4.4.dist-info/licenses/CODE_OF_CONDUCT.rst,sha256=xXDTFpYY3Y7JoxrWADihieUvhGlwJc_oxsbmLJaBvE4,3422
license_expression-30.4.4.dist-info/licenses/NOTICE,sha256=75fbB-Mvbl00NjRhrPWsx9ctuSRTO849nzuHBGMTNjw,756
license_expression-30.4.4.dist-info/licenses/README.rst,sha256=CxHK2vteNEROO-qdOvYI-JNUoFi7RukRWPcoA3bAO_s,9510
license_expression-30.4.4.dist-info/licenses/apache-2.0.LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
license_expression-30.4.4.dist-info/top_level.txt,sha256=e8SafVMJ6e6nFd_TxBGFQoVk8BCxiewpyXQtDGNWvbE,19
license_expression/__init__.py,sha256=eMb1gWSGcWHMHebmjdj3pjSXjz4Nf_9mLzPEAFlCFnY,62805
license_expression/__pycache__/__init__.cpython-312.pyc,,
license_expression/__pycache__/_pyahocorasick.cpython-312.pyc,,
license_expression/_pyahocorasick.ABOUT,sha256=ddeczPH8MCy0qZvTKqyL1PyAkmsV0x8LqZTRbN-EQDI,880
license_expression/_pyahocorasick.py,sha256=FuJhqpvQ-IB60aBwCT6Rq5egXMGo6sx8rAVMDgqT3YM,20893
license_expression/data/cc-by-4.0.LICENSE,sha256=KoKsm7w-PuBmkIOB6NNziW21pgJdCD-9WWkv6cz7kRE,18651
license_expression/data/license_key_index.json.ABOUT,sha256=-1zh8tvSvtwB-tlQe-ccoZ7De01vjfuVFvv-_uQQ2F0,421
license_expression/data/scancode-licensedb-index.json,sha256=11lCc4JaaLLVZ2120zbFYCEAcvB6d-2xk61ghpQGdZY,971162

View File

@@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: setuptools (80.9.0)
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -0,0 +1,17 @@
The following organizations or individuals have contributed to this code:
- Ayan Sinha Mahapatra @AyanSinhaMahapatra
- Carmen Bianca Bakker @carmenbianca
- Chin-Yeung Li @chinyeungli
- Dennis Clark @DennisClark
- John Horan @johnmhoran
- Jono Yang @JonoYang
- Max Mehl @mxmehl
- nexB Inc. @nexB
- Pablo Castellazzi @pcastellazzi
- Peter Kolbus @pkolbus
- Philippe Ombredanne @pombredanne
- Sebastian Schuberth @sschuberth
- Steven Esser @majurg
- Thomas Druez @tdruez
- Uwe L. Korn @xhochy

View File

@@ -0,0 +1,162 @@
Changelog
=========
v30.4.4 - 2025-01-10
--------------------
This is a minor release with license udpates:
- Update license list to latest ScanCode and SPDX 3.27
v30.4.3 - 2025-06-25
--------------------
This is a minor bugfix release:
- Release license-expression wheels properly
v30.4.2 - 2025-06-25
--------------------
This is a minor release without API changes:
- Use latest skeleton
- Update license list to latest ScanCode
v30.4.1 - 2025-01-10
--------------------
This is a minor release without API changes:
- Use latest skeleton
- Update license list to latest ScanCode and SPDX 3.26
v30.4.0 - 2024-10-21
--------------------
This is a minor release without API changes:
- Use latest skeleton
- Update license list to latest ScanCode and SPDX 3.25
- Drop support for Python 3.8
v30.3.1 - 2024-08-13
--------------------
This is a minor release without API changes:
- Update link references of ownership from nexB to aboutcode-org
v30.3.0 - 2024-03-18
--------------------
This is a minor release without API changes:
- Use latest skeleton
- Update license list to latest ScanCode and SPDX 3.23
- Drop support for Python 3.7
v30.2.0 - 2023-11-29
--------------------
This is a minor release without API changes:
- Use latest skeleton
- Update license list to latest ScanCode and SPDX 3.22
- Add Python 3.12 support in CI
v30.1.1 - 2023-01-16
----------------------
This is a minor dot release without API changes
- Use latest skeleton
- Update license list to latest ScanCode and SPDX 3.20
v30.1.0 - 2023-01-16
----------------------
This is a minor release without API changes
- Use latest skeleton (and updated configure script)
- Update license list to latest ScanCode and SPDX 3.19
- Use correct syntax for python_require
- Drop using Travis and Appveyor
- Drop support for Python 3.7 and add Python 3.11 in CI
v30.0.0 - 2022-05-10
----------------------
This is a minor release with API changes
- Use latest skeleton (and updated configure script)
- Drop using calver
- Improve error checking when combining licenses
v21.6.14 - 2021-06-14
----------------------
Added
~~~~~
- Switch to calver for package versioning to better convey the currency of the
bundled data.
- Include https://scancode-licensedb.aboutcode.org/ licenses list with
ScanCode (v21.6.7) and SPDX licenses (v3.13) keys. Add new functions to
create Licensing using these licenses as LicenseSymbol.
- Add new License.dedup() method to deduplicate and simplify license expressions
without over simplifying.
- Add new License.validate() method to return a new ExpressionInfo object with
details on a license expression validation.
Changed
~~~~~~~
- Drop support for Python 2.
- Adopt the project skeleton from https://github.com/nexB/skeleton
and its new configure script
v1.2 - 2019-11-14
------------------
Added
~~~~~
- Add ability to render WITH expression wrapped in parenthesis
Fixes
~~~~~
- Fix anomalous backslashes in strings
Changed
~~~~~~~
- Update the thirdparty directory structure.
v1.0 - 2019-10-16
------------------
Added
~~~~~
- New version of boolean.py library
- Add ability to leave license expressions unsorted when simplifying
Changed
~~~~~~~
- updated travis CI settings
v0.999 - 2019-04-29
--------------------
- Initial release
- license-expression is small utility library to parse, compare and
simplify and normalize license expressions.

View File

@@ -0,0 +1,86 @@
Contributor Covenant Code of Conduct
====================================
Our Pledge
----------
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our
project and our community a harassment-free experience for everyone,
regardless of age, body size, disability, ethnicity, gender identity and
expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
Our Standards
-------------
Examples of behavior that contributes to creating a positive environment
include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual
attention or advances
- Trolling, insulting/derogatory comments, and personal or political
attacks
- Public or private harassment
- Publishing others private information, such as a physical or
electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
Our Responsibilities
--------------------
Project maintainers are responsible for clarifying the standards of
acceptable behavior and are expected to take appropriate and fair
corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit,
or reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct, or to ban
temporarily or permanently any contributor for other behaviors that they
deem inappropriate, threatening, offensive, or harmful.
Scope
-----
This Code of Conduct applies both within project spaces and in public
spaces when an individual is representing the project or its community.
Examples of representing a project or community include using an
official project e-mail address, posting via an official social media
account, or acting as an appointed representative at an online or
offline event. Representation of a project may be further defined and
clarified by project maintainers.
Enforcement
-----------
Instances of abusive, harassing, or otherwise unacceptable behavior may
be reported by contacting the project team at pombredanne@gmail.com
or on the Gitter chat channel at https://gitter.im/aboutcode-org/discuss .
All complaints will be reviewed and investigated and will result in a
response that is deemed necessary and appropriate to the circumstances.
The project team is obligated to maintain confidentiality with regard to
the reporter of an incident. Further details of specific enforcement
policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in
good faith may face temporary or permanent repercussions as determined
by other members of the projects leadership.
Attribution
-----------
This Code of Conduct is adapted from the `Contributor Covenant`_ ,
version 1.4, available at
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
.. _Contributor Covenant: https://www.contributor-covenant.org

View File

@@ -0,0 +1,37 @@
#
# Copyright (c) nexB Inc. and others.
# SPDX-License-Identifier: Apache-2.0
#
# Visit https://aboutcode.org and https://github.com/aboutcode-org/license-expression
# for support and download.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

View File

@@ -0,0 +1,233 @@
==================
license-expression
==================
``license-expression`` is a comprehensive utility library to parse, compare,
simplify and normalize license expressions (such as SPDX license expressions)
using boolean logic.
- License: Apache-2.0
- Python: 3.9+
- Homepage: https://github.com/aboutcode-org/license-expression/
- Install: `pip install license-expression` also available in most Linux distro.
Software project licenses are often a combination of several free and open
source software licenses. License expressions -- as specified by SPDX -- provide
a concise and human readable way to express these licenses without having to
read long license texts, while still being machine-readable.
License expressions are used by key FOSS projects such as Linux; several
packages ecosystem use them to document package licensing metadata such as
npm and Rubygems; they are important when exchanging software data (such as with
SPDX and SBOM in general) as a way to express licensing precisely.
``license-expression`` is a comprehensive utility library to parse, compare,
simplify and normalize these license expressions (such as SPDX license expressions)
using boolean logic like in: `GPL-2.0-or-later WITH Classpath-exception-2.0 AND MIT`.
It includes the license keys from SPDX https://spdx.org/licenses/ (version 3.26)
and ScanCode LicenseDB (from scancode-toolkit version 32.3.1, last published on 2025-01-10).
See https://scancode-licensedb.aboutcode.org/ to get started quickly.
``license-expression`` is both powerful and simple to use and is a used as the
license expression engine in several projects and products such as:
- AboutCode-toolkit https://github.com/aboutcode-org/aboutcode-toolkit
- AlekSIS (School Information System) https://edugit.org/AlekSIS/official/AlekSIS-Core
- Conda forge tools https://github.com/conda-forge/conda-smithy
- DejaCode https://enterprise.dejacode.com
- DeltaCode https://github.com/nexB/deltacode
- FenixscanX https://github.com/SmartsYoung/FenixscanX
- FetchCode https://github.com/aboutcode-org/fetchcode
- Flict https://github.com/vinland-technology/flict and https://github.com/vinland-technology
- license.sh https://github.com/webscopeio/license.sh
- liferay_inbound_checker https://github.com/carmenbianca/liferay_inbound_checker
- REUSE https://reuse.software/ and https://github.com/fsfe/reuse-tool
- ScanCode-io https://github.com/aboutcode-org/scancode.io
- ScanCode-toolkit https://github.com/aboutcode-org/scancode-toolkit
- SecObserve https://github.com/MaibornWolff/SecObserve
See also for details:
- https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions
``license-expression`` is also packaged for most Linux distributions. See below.
Alternative:
There is no known alternative library for Python, but there are several similar
libraries in other languages (but not as powerful of course!):
- JavaScript https://github.com/jslicense/spdx-expression-parse.js
- Rust https://github.com/ehuss/license-exprs
- Haskell https://github.com/phadej/spdx
- Go https://github.com/kyoh86/go-spdx
- Ada https://github.com/Fabien-Chouteau/spdx_ada
- Java https://github.com/spdx/tools and https://github.com/aschet/spdx-license-expression-tools
Source code and download
========================
- GitHub https://github.com/aboutcode-org/license-expression.git
- PyPI https://pypi.python.org/pypi/license-expression
Also available in several Linux distros:
- Arch Linux https://archlinux.org/packages/extra/any/python-license-expression/
- Debian https://packages.debian.org/unstable/source/license-expression
- DragonFly BSD https://github.com/DragonFlyBSD/DPorts/tree/master/textproc/py-license-expression
- Fedora https://src.fedoraproject.org/rpms/python-license-expression/
- FreeBSD https://www.freshports.org/textproc/py-license-expression
- NixOS https://github.com/NixOS/nixpkgs/blob/release-21.05/pkgs/development/python-modules/license-expression/default.nix
- openSUSE https://build.opensuse.org/package/show/openSUSE:Factory/python-license-expression
Support
=======
- Submit bugs and questions at: https://github.com/aboutcode-org/license-expression/issues
- Join the chat at: https://gitter.im/aboutcode-org/discuss
Description
===========
This module defines a mini language to parse, validate, simplify, normalize and
compare license expressions using a boolean logic engine.
This supports SPDX license expressions and also accepts other license naming
conventions and license identifiers aliases to resolve and normalize any license
expressions.
Using boolean logic, license expressions can be tested for equality, containment,
equivalence and can be normalized or simplified.
It also bundles the SPDX License list (3.26 as of now) and the ScanCode license
DB (based on latest ScanCode) to easily parse and validate expressions using
the license symbols.
Usage examples
==============
The main entry point is the ``Licensing`` object that you can use to parse,
validate, compare, simplify and normalize license expressions.
Create an SPDX Licensing and parse expressions::
>>> from license_expression import get_spdx_licensing
>>> licensing = get_spdx_licensing()
>>> expression = ' GPL-2.0 or LGPL-2.1 and mit '
>>> parsed = licensing.parse(expression)
>>> print(parsed.pretty())
OR(
LicenseSymbol('GPL-2.0-only'),
AND(
LicenseSymbol('LGPL-2.1-only'),
LicenseSymbol('MIT')
)
)
>>> str(parsed)
'GPL-2.0-only OR (LGPL-2.1-only AND MIT)'
>>> licensing.parse('unknwon with foo', validate=True, strict=True)
license_expression.ExpressionParseError: A plain license symbol cannot be used
as an exception in a "WITH symbol" statement. for token: "foo" at position: 13
>>> licensing.parse('unknwon with foo', validate=True)
license_expression.ExpressionError: Unknown license key(s): unknwon, foo
>>> licensing.validate('foo and MIT and GPL-2.0+')
ExpressionInfo(
original_expression='foo and MIT and GPL-2.0+',
normalized_expression=None,
errors=['Unknown license key(s): foo'],
invalid_symbols=['foo']
)
Create a simple Licensing and parse expressions::
>>> from license_expression import Licensing, LicenseSymbol
>>> licensing = Licensing()
>>> expression = ' GPL-2.0 or LGPL-2.1 and mit '
>>> parsed = licensing.parse(expression)
>>> expression = ' GPL-2.0 or LGPL-2.1 and mit '
>>> expected = 'GPL-2.0-only OR (LGPL-2.1-only AND mit)'
>>> assert str(parsed) == expected
>>> assert parsed.render('{symbol.key}') == expected
Create a Licensing with your own license symbols::
>>> expected = [
... LicenseSymbol('GPL-2.0'),
... LicenseSymbol('LGPL-2.1'),
... LicenseSymbol('mit')
... ]
>>> assert licensing.license_symbols(expression) == expected
>>> assert licensing.license_symbols(parsed) == expected
>>> symbols = ['GPL-2.0+', 'Classpath', 'BSD']
>>> licensing = Licensing(symbols)
>>> expression = 'GPL-2.0+ with Classpath or (bsd)'
>>> parsed = licensing.parse(expression)
>>> expected = 'GPL-2.0+ WITH Classpath OR BSD'
>>> assert parsed.render('{symbol.key}') == expected
>>> expected = [
... LicenseSymbol('GPL-2.0+'),
... LicenseSymbol('Classpath'),
... LicenseSymbol('BSD')
... ]
>>> assert licensing.license_symbols(parsed) == expected
>>> assert licensing.license_symbols(expression) == expected
And expression can be deduplicated, to remove duplicate license subexpressions
without changing the order and without consider license choices as simplifiable::
>>> expression2 = ' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)'
>>> parsed2 = licensing.parse(expression2)
>>> str(parsed2)
'GPL-2.0 OR (mit AND LGPL 2.1) OR BSD OR GPL-2.0 OR (mit AND LGPL 2.1)'
>>> assert str(parsed2.simplify()) == 'BSD OR GPL-2.0 OR (LGPL 2.1 AND mit)'
Expression can be simplified, treating them as boolean expressions::
>>> expression2 = ' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)'
>>> parsed2 = licensing.parse(expression2)
>>> str(parsed2)
'GPL-2.0 OR (mit AND LGPL 2.1) OR BSD OR GPL-2.0 OR (mit AND LGPL 2.1)'
>>> assert str(parsed2.simplify()) == 'BSD OR GPL-2.0 OR (LGPL 2.1 AND mit)'
Two expressions can be compared for equivalence and containment:
>>> expr1 = licensing.parse(' GPL-2.0 or (LGPL 2.1 and mit) ')
>>> expr2 = licensing.parse(' (mit and LGPL 2.1) or GPL-2.0 ')
>>> licensing.is_equivalent(expr1, expr2)
True
>>> licensing.is_equivalent(' GPL-2.0 or (LGPL 2.1 and mit) ',
... ' (mit and LGPL 2.1) or GPL-2.0 ')
True
>>> expr1.simplify() == expr2.simplify()
True
>>> expr3 = licensing.parse(' GPL-2.0 or mit or LGPL 2.1')
>>> licensing.is_equivalent(expr2, expr3)
False
>>> expr4 = licensing.parse('mit and LGPL 2.1')
>>> expr4.simplify() in expr2.simplify()
True
>>> licensing.contains(expr2, expr4)
True
Development
===========
- Checkout a clone from https://github.com/aboutcode-org/license-expression.git
- Then run ``./configure --dev`` and then ``source tmp/bin/activate`` on Linux and POSIX.
This will install all dependencies in a local virtualenv, including
development deps.
- On Windows run ``configure.bat --dev`` and then ``Scripts\bin\activate`` instead.
- To run the tests, run ``pytest -vvs``

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.