@@ -57,102 +57,58 @@ The main entry point is the Licensing object.
5757Usage 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
9295Two 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
157113Development
158114===========
0 commit comments