0
# License Expression
1
2
A comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic. This library supports complex boolean operations on license expressions, provides validation and normalization capabilities, and includes complete license databases with SPDX and ScanCode license identifiers.
3
4
## Package Information
5
6
- **Package Name**: license-expression
7
- **Language**: Python
8
- **Installation**: `pip install license-expression`
9
- **Python Version**: >= 3.9
10
- **Dependencies**: boolean.py >= 4.0
11
12
## Core Imports
13
14
```python
15
from license_expression import Licensing, LicenseSymbol
16
```
17
18
For SPDX-compliant licensing:
19
20
```python
21
from license_expression import get_spdx_licensing
22
```
23
24
For ScanCode licensing database:
25
26
```python
27
from license_expression import get_scancode_licensing
28
```
29
30
## Basic Usage
31
32
```python
33
from license_expression import get_spdx_licensing
34
35
# Create SPDX licensing instance
36
licensing = get_spdx_licensing()
37
38
# Parse a license expression
39
expression = 'GPL-2.0 or LGPL-2.1 and MIT'
40
parsed = licensing.parse(expression)
41
42
# Get normalized expression
43
print(str(parsed)) # 'GPL-2.0-only OR (LGPL-2.1-only AND MIT)'
44
45
# Validate expressions
46
result = licensing.validate('MIT and Apache-2.0')
47
print(result.errors) # [] - no errors
48
49
# Check if expressions are equivalent
50
expr1 = licensing.parse('MIT or Apache-2.0')
51
expr2 = licensing.parse('Apache-2.0 or MIT')
52
print(licensing.is_equivalent(expr1, expr2)) # True
53
54
# Simplify complex expressions
55
complex_expr = 'MIT or (GPL-2.0 and MIT) or MIT'
56
simplified = licensing.parse(complex_expr).simplify()
57
print(str(simplified)) # 'MIT'
58
```
59
60
## Architecture
61
62
The license-expression library is built around several key components:
63
64
- **Licensing**: Main orchestrator providing parsing, validation, and comparison operations
65
- **LicenseSymbol**: Represents individual licenses with keys, aliases, and metadata
66
- **LicenseExpression**: Boolean expression trees representing parsed license expressions
67
- **Validation System**: Comprehensive validation with detailed error reporting
68
- **License Databases**: Built-in SPDX and ScanCode license databases for recognition
69
70
The library uses boolean algebra to enable sophisticated license expression analysis, including equivalence testing, containment analysis, and expression simplification.
71
72
## Capabilities
73
74
### Core Licensing Operations
75
76
Main API for parsing, validating, and comparing license expressions. Provides the primary interface for working with license expressions through the Licensing class.
77
78
```python { .api }
79
class Licensing:
80
def parse(self, expression: str, validate: bool = False, strict: bool = False) -> LicenseExpression: ...
81
def validate(self, expression: str) -> ExpressionInfo: ...
82
def is_equivalent(self, expr1, expr2) -> bool: ...
83
def contains(self, expr1, expr2) -> bool: ...
84
```
85
86
[Core Licensing Operations](./licensing.md)
87
88
### License Symbol Management
89
90
Classes and utilities for working with individual license symbols, including standard licenses, license-like symbols, and complex WITH exception constructs.
91
92
```python { .api }
93
class LicenseSymbol:
94
def __init__(self, key: str, aliases: list = None, is_exception: bool = False): ...
95
96
class LicenseWithExceptionSymbol:
97
def __init__(self, license_symbol: LicenseSymbol, exception_symbol: LicenseSymbol): ...
98
```
99
100
[License Symbol Management](./symbols.md)
101
102
### Expression Utilities
103
104
Utility functions for expression manipulation, validation, combination, and analysis. Includes functions for combining multiple expressions and validating symbol collections.
105
106
```python { .api }
107
def combine_expressions(expressions, relation: str = "AND", unique: bool = True, licensing=None) -> LicenseExpression: ...
108
def validate_symbols(symbols, validate_keys: bool = False) -> tuple: ...
109
```
110
111
[Expression Utilities](./expressions.md)
112
113
### Factory Functions
114
115
Convenience functions for creating preconfigured Licensing instances with SPDX or ScanCode license databases.
116
117
```python { .api }
118
def get_spdx_licensing(license_index_location=None) -> Licensing: ...
119
def get_scancode_licensing(license_index_location=None) -> Licensing: ...
120
def get_license_index(license_index_location=None) -> dict: ...
121
```
122
123
[Factory Functions](./factories.md)
124
125
### Constants and Error Handling
126
127
Error codes, token constants, and exception classes for robust error handling and expression parsing.
128
129
```python { .api }
130
class ExpressionError(Exception): ...
131
class ExpressionParseError(ParseError, ExpressionError): ...
132
133
# Parse error constants
134
PARSE_INVALID_EXCEPTION: int
135
PARSE_INVALID_SYMBOL_AS_EXCEPTION: int
136
```
137
138
[Constants and Error Handling](./constants.md)
139
140
## Types
141
142
```python { .api }
143
class ExpressionInfo:
144
original_expression: str
145
normalized_expression: str
146
errors: list
147
invalid_symbols: list
148
149
class LicenseExpression:
150
def pretty(self) -> str: ...
151
def render(self, template: str) -> str: ...
152
def simplify(self) -> 'LicenseExpression': ...
153
```