Skip to content

Commit 126164c

Browse files
authored
Merge pull request #6 from nexB/4-improved-expression-parsing-with-names
#4 Improved expression parsing with names
2 parents f0d504f + ab3de00 commit 126164c

29 files changed

Lines changed: 3980 additions & 2740 deletions

.travis.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ os:
66
- osx
77
- linux
88

9-
python:
10-
- "2.7"
11-
- "3.4"
12-
- "3.5"
9+
env:
10+
matrix:
11+
- PYTHON_EXE="`which python2`"
12+
- PYTHON_EXE="`which python3.4`"
13+
- PYTHON_EXE="`which python3.5`"
1314

1415
install:
15-
- PYTHON_EXE=python$TRAVIS_PYTHON_VERSION ./configure
16+
- PYTHON_EXE=$PYTHON_EXE ./configure
1617

1718
script:
1819
- "bin/py.test -vvs"

README.rst

Lines changed: 33 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -57,102 +57,58 @@ The main entry point is the Licensing object.
5757
Usage examples
5858
==============
5959

60-
Parse an expression, then simplify and compare::
60+
For example::
6161

62-
>>> from license_expression import Licensing
62+
>>> from license_expression import Licensing, LicenseSymbol, ExceptionSymbol
6363
>>> l = Licensing()
6464
>>> expr = l.parse(" GPL-2.0 or LGPL 2.1 and mit ")
65-
>>> str(expr)
66-
'GPL-2.0 OR (LGPL 2.1 AND mit)'
67-
>>> l.license_symbols(expr)
68-
[LicenseSymbol('GPL-2.0'), LicenseSymbol('LGPL 2.1'), LicenseSymbol('mit')]
69-
>>> str(expr)
70-
'GPL-2.0 OR (LGPL 2.1 AND mit)'
71-
>>> print(expr.pretty())
72-
OR(
73-
LicenseSymbol('GPL-2.0'),
74-
AND(
75-
LicenseSymbol('LGPL 2.1'),
76-
LicenseSymbol('mit')
77-
)
78-
)
79-
>>> expr2 = l.parse(" GPL-2.0 or (mit and LGPL 2.1) ")
80-
>>> expr2.simplify() == expr.simplify()
81-
True
82-
>>> expr3 = l.parse("mit and LGPL 2.1")
83-
>>> expr3 in expr2
84-
True
65+
>>> expected = 'GPL-2.0 OR (LGPL 2.1 AND mit)'
66+
>>> assert expected == expr.render('{name}')
67+
68+
>>> expected = [
69+
... LicenseSymbol('GPL-2.0', known=False),
70+
... LicenseSymbol('LGPL 2.1', known=False),
71+
... LicenseSymbol('mit', known=False)
72+
... ]
73+
>>> assert expected == l.license_symbols(expr)
74+
75+
>>> symbols = ['GPL-2.0+', 'Classpath', 'BSD']
76+
>>> l = Licensing(symbols)
77+
>>> expr = l.parse("GPL-2.0+ with Classpath or (bsd)")
78+
>>> expected = 'gpl-2.0+ WITH classpath OR bsd'
79+
>>> assert expected == expr.render('{key}')
80+
81+
>>> expected = [
82+
... LicenseSymbol('GPL-2.0+', known=True),
83+
... ExceptionSymbol('Classpath', known=True),
84+
... LicenseSymbol('BSD', known=True)
85+
... ]
86+
>>> assert expected == l.license_symbols(expr)
8587

86-
An expression can be simplified::
8788

88-
>>> expr2 = l.parse(" GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)")
89-
>>> str(expr2.simplify())
90-
'GPL-2.0 OR bsd OR (LGPL 2.1 AND mit)'
89+
And expression can be simplified::
90+
91+
>>> expr2 = l.parse(' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)')
92+
>>> assert str(expr2.simplify()) == 'bsd OR gpl-2.0 OR (lgpl 2.1 AND mit)'
93+
9194

9295
Two expressions can be compared for equivalence and containment::
9396

94-
>>> expr1 = l.parse(" GPL-2.0 or (LGPL 2.1 and mit) ")
95-
>>> expr2 = l.parse(" (mit and LGPL 2.1) or GPL-2.0 ")
97+
>>> expr1 = l.parse(' GPL-2.0 or (LGPL 2.1 and mit) ')
98+
>>> expr2 = l.parse(' (mit and LGPL 2.1) or GPL-2.0 ')
9699
>>> l.is_equivalent(expr1, expr2)
97100
True
98101
>>> expr1.simplify() == expr2.simplify()
99102
True
100-
>>> expr3 = l.parse(" GPL-2.0 or mit or LGPL 2.1")
103+
>>> expr3 = l.parse(' GPL-2.0 or mit or LGPL 2.1')
101104
>>> l.is_equivalent(expr2, expr3)
102105
False
103-
>>> expr4 = l.parse("mit and LGPL 2.1")
106+
>>> expr4 = l.parse('mit and LGPL 2.1')
104107
>>> expr4.simplify() in expr2.simplify()
105108
True
106109
>>> l.contains(expr2, expr4)
107110
True
108111

109-
An expression can be validated and normalized using a list of reference license keys
110-
(or ids), names and aliases::
111-
112-
>>> from license_expression import LicenseRef, Licensing
113-
>>> license_refs = [
114-
... LicenseRef('gpl-2.0', 'GPL-2.0', ['The GNU GPL 20'], False),
115-
... LicenseRef('gpl-2.0+', 'GPL-2.0+', ['The GNU GPL 20 or later'], False),
116-
... LicenseRef('lgpl-2.1', 'LGPL-2.1', ['LGPL v2.1'], False),
117-
... LicenseRef('lgpl-2.1-plus', 'LGPL-2.1+', ['LGPL v2.1 or later', 'LGPL-2.1 or later'], False),
118-
... LicenseRef('mit', 'MIT', ['MIT license'], False),
119-
... LicenseRef('classpath-2.0', 'Classpath-2.0', ['Classpath-2.0 Exception'], True)
120-
... ]
121-
>>> l = Licensing(license_refs)
122-
>>> expr = l.parse("The GNU GPL 20 or LGPL-2.1 and mit")
123-
>>> str(expr)
124-
'The GNU GPL 20 OR (LGPL-2.1 AND mit)'
125-
>>> expr = l.resolve(expr)
126-
>>> str(expr)
127-
'GPL-2.0 OR (LGPL-2.1 AND MIT)'
128-
129-
The cases of a license with an exception or "or later version" are handled correctly::
130-
131-
>>> expr = l.parse("The GNU GPL 20 or later with Classpath-2.0 Exception or LGPL-2.1 or later and mit2")
132-
>>> l.license_symbols(expr)
133-
[LicenseSymbol('The GNU GPL 20 or later WITH Classpath-2.0 Exception'), LicenseSymbol('LGPL-2.1 or later'), LicenseSymbol('mit2')]
134-
>>> expr = l.resolve(expr)
135-
>>> l.unresolved_keys(expr) == ['mit2']
136-
True
137-
>>> str(expr)
138-
'GPL-2.0+ WITH Classpath-2.0 OR (LGPL-2.1+ AND mit2)'
139-
140-
Here if we add `mit2` as an alias, the expression resolves alright::
141-
142-
>>> license_refs = [
143-
... LicenseRef('gpl-2.0', 'GPL-2.0', ['The GNU GPL 20'], False),
144-
... LicenseRef('lgpl-2.1', 'LGPL-2.1', ['LGPL v2.1'], False),
145-
... LicenseRef('lgpl-2.1-plus', 'LGPL-2.1+', ['LGPL v2.1 or later', 'LGPL-2.1 or later'], False),
146-
... LicenseRef('mit', 'MIT', ['MIT license', 'mit2'], False),
147-
... LicenseRef('classpath-2.0', 'Classpath-2.0', ['Classpath-2.0 Exception'], True)
148-
... ]
149-
>>> l = Licensing(license_refs)
150-
>>> expr = l.parse("The GNU GPL 20 with Classpath-2.0 Exception or LGPL-2.1 or later and mit2", resolve=True)
151-
>>> l.resolution_errors(expr)
152-
[]
153-
>>> str(expr)
154-
'GPL-2.0 WITH Classpath-2.0 OR (LGPL-2.1+ AND MIT)'
155-
156112
157113
Development
158114
===========

etc/conf/dev/base.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Testing
2-
pytest
3-
colorama
42
py
3+
colorama
4+
pytest

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
setup(
1919
name='license-expression',
20-
version='0.9',
20+
version='0.10',
2121
license='apache-2.0',
2222
description=desc,
2323
long_description=desc,
@@ -48,6 +48,6 @@
4848
'licence'
4949
],
5050
install_requires=[
51-
'boolean.py >= 3.2, < 4.0.0',
51+
'boolean.py >= 3.3, < 4.0.0',
5252
]
5353
)

0 commit comments

Comments
 (0)