Skip to content

Commit 413d99a

Browse files
committed
Improve doc and code format
Signed-off-by: Philippe Ombredanne <[email protected]>
1 parent a6235aa commit 413d99a

File tree

1 file changed

+71
-38
lines changed

1 file changed

+71
-38
lines changed

src/license_expression/__init__.py

Lines changed: 71 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,22 @@ def simple_tokenizer(self, expression):
576576

577577
def dedup(self, expression):
578578
"""
579-
Return a de-duplicated LicenseExpression given a license expfession
579+
Return a deduplicated LicenseExpression given a license expression
580580
string or LicenseExpression object.
581+
582+
The deduplication process is similar to simplification but is specialized
583+
for working with license expressions. Simplification on the other hand
584+
is a generic boolean operation not aware of the specifis of license expressions.
585+
586+
The deduplication:
587+
588+
- Does not sort the licenses of sub-expression in an expression. They
589+
stay in the same order as in the original.
590+
591+
- Choices (as in MIT or GPL) are kept as-is and not treated as
592+
simplifiable. This way this avoid droping important choice options in
593+
complex expressions which is never desirable.
594+
581595
"""
582596
exp = self.parse(expression)
583597
expressions = []
@@ -600,7 +614,7 @@ def dedup(self, expression):
600614
licensing=self,
601615
)
602616
else:
603-
raise Exception('Unknown expression type: {}'.format(repr(expression)))
617+
raise Exception(f'Unknown expression type: {expression!r}')
604618
return deduped
605619

606620

@@ -717,8 +731,8 @@ def replace_with_subexpression_by_license_symbol(tokens, strict=False):
717731
Check validity of with subexpessions and raise ParseError as needed.
718732
719733
If `strict` is True also raise ParseError if the left hand side
720-
LicenseSymbol has is_exception True or if the right hand side
721-
LicenseSymbol has is_exception False.
734+
LicenseSymbol has is_exception True or if the right hand side LicenseSymbol
735+
has is_exception False.
722736
"""
723737
token_groups = build_token_groups_for_with_subexpression(tokens)
724738

@@ -751,7 +765,7 @@ def replace_with_subexpression_by_license_symbol(tokens, strict=False):
751765

752766
else:
753767
# this should not be possible by design
754-
raise Exception('Licensing.tokenize is internally confused...:' + repr(tval))
768+
raise Exception(f'Licensing.tokenize is internally confused...: {tval!r}')
755769

756770
yield token
757771
continue
@@ -763,8 +777,8 @@ def replace_with_subexpression_by_license_symbol(tokens, strict=False):
763777
raise ParseError(
764778
TOKEN_SYMBOL, string, start, PARSE_INVALID_EXPRESSION)
765779

766-
# from now on we have a tripple of tokens: a WITH sub-expression such as "A with
767-
# B" seq of three tokens
780+
# from now on we have a tripple of tokens: a WITH sub-expression such as
781+
# "A with B" seq of three tokens
768782
lic_token, WITH , exc_token = token_group
769783

770784
token_string = ' '.join([
@@ -818,13 +832,14 @@ class Renderable(object):
818832

819833
def render(self, template='{symbol.key}', *args, **kwargs):
820834
"""
821-
Return a formatted string rendering for this expression using the `template`
822-
format string to render each symbol. The variable available are `symbol.key`
823-
and any other attribute that was attached to a license symbol instance and a
824-
custom template can be provided to handle custom HTML rendering or similar.
835+
Return a formatted string rendering for this expression using the
836+
`template` format string to render each symbol. The variable available
837+
are `symbol.key` and any other attribute that was attached to a license
838+
symbol instance and a custom template can be provided to handle custom
839+
HTML rendering or similar.
825840
826-
For symbols that hold multiple licenses (e.g. a WITH statement) the template
827-
is applied to each symbol individually.
841+
For symbols that hold multiple licenses (e.g. a WITH statement) the
842+
template is applied to each symbol individually.
828843
829844
Note that when render() is called the *args and **kwargs are propagated
830845
recursively to any Renderable object render() method.
@@ -840,9 +855,18 @@ def render_as_readable(self, template='{symbol.key}', *args, **kwargs):
840855
"""
841856
if isinstance(self, LicenseWithExceptionSymbol):
842857
return self.render(
843-
template=template, wrap_with_in_parens=False, *args, **kwargs)
844-
else:
845-
return self.render(template=template, wrap_with_in_parens=True, *args, **kwargs)
858+
template=template,
859+
wrap_with_in_parens=False,
860+
*args,
861+
**kwargs,
862+
)
863+
864+
return self.render(
865+
template=template,
866+
wrap_with_in_parens=True,
867+
*args,
868+
**kwargs,
869+
)
846870

847871

848872
class BaseSymbol(Renderable, boolean.Symbol):
@@ -862,6 +886,7 @@ def __contains__(self, other):
862886
"""
863887
if not isinstance(other, BaseSymbol):
864888
return False
889+
865890
if self == other:
866891
return True
867892

@@ -905,7 +930,8 @@ def __init__(self, key, aliases=tuple(), is_exception=False, *args, **kwargs):
905930
if not is_valid_license_key(key):
906931
raise ExpressionError(
907932
'Invalid license key: the valid characters are: letters and numbers, '
908-
'underscore, dot, colon or hyphen signs and spaces: "%(key)s"' % locals())
933+
f'underscore, dot, colon or hyphen signs and spaces: {key!r}'
934+
)
909935

910936
# normalize for spaces
911937
key = ' '.join(key.split())
@@ -1049,10 +1075,11 @@ def __lt__(self, other):
10491075
@total_ordering
10501076
class LicenseWithExceptionSymbol(BaseSymbol):
10511077
"""
1052-
A LicenseWithExceptionSymbol represents a license "with" an exception as used in
1053-
a license expression. It holds two LicenseSymbols objects: one for the left-hand
1054-
license proper and one for the right-hand exception to this license and deals
1055-
with the specifics of resolution, validation and representation.
1078+
A LicenseWithExceptionSymbol represents a license "with" an exception as
1079+
used in a license expression. It holds two LicenseSymbols objects: one for
1080+
the left-hand license proper and one for the right-hand exception to this
1081+
license and deals with the specifics of resolution, validation and
1082+
representation.
10561083
"""
10571084

10581085
def __init__(self, license_symbol, exception_symbol, strict=False, *args, **kwargs):
@@ -1180,8 +1207,11 @@ def render(self, template='{symbol.key}', *args, **kwargs):
11801207
rendered = arg.render(template, *args, **kwargs)
11811208

11821209
else:
1183-
print('WARNING: object in expression is not renderable: falling back to plain string representation: %(arg)r.')
11841210
# FIXME: CAN THIS REALLY HAPPEN since we only have symbols, or and AND?
1211+
print(
1212+
'WARNING: object in expression is not renderable: '
1213+
f'falling back to plain string representation: {arg!r}.'
1214+
)
11851215
rendered = str(arg)
11861216

11871217
if arg.isliteral:
@@ -1199,7 +1229,8 @@ class AND(RenderableFunction, boolean.AND):
11991229

12001230
def __init__(self, *args):
12011231
if len(args) < 2:
1202-
raise ExpressionError('AND requires two or more licenses as in: MIT AND BSD')
1232+
raise ExpressionError(
1233+
'AND requires two or more licenses as in: MIT AND BSD')
12031234
super(AND, self).__init__(*args)
12041235
self.operator = ' AND '
12051236

@@ -1211,7 +1242,8 @@ class OR(RenderableFunction, boolean.OR):
12111242

12121243
def __init__(self, *args):
12131244
if len(args) < 2:
1214-
raise ExpressionError('OR requires two or more licenses as in: MIT OR BSD')
1245+
raise ExpressionError(
1246+
'OR requires two or more licenses as in: MIT OR BSD')
12151247
super(OR, self).__init__(*args)
12161248
self.operator = ' OR '
12171249

@@ -1389,22 +1421,23 @@ def combine_expressions(
13891421
licensing=Licensing(),
13901422
):
13911423
"""
1392-
Return a combined LicenseExpression object with the `relation`,
1393-
given a list of license `expressions` strings or LicenseExpression.
1394-
If unique is True remove duplicates before combining expressions.
1424+
Return a combined LicenseExpression object with the `relation`, given a list
1425+
of license `expressions` strings or LicenseExpression. If unique is True
1426+
remove duplicates before combining expressions.
13951427
13961428
For example::
1397-
>>> a = 'mit'
1398-
>>> b = 'gpl'
1399-
>>> str(combine_expressions([a, b]))
1400-
'mit AND gpl'
1401-
>>> assert 'mit' == str(combine_expressions([a]))
1402-
>>> combine_expressions([])
1403-
>>> combine_expressions(None)
1404-
>>> str(combine_expressions(('gpl', 'mit', 'apache',)))
1405-
'gpl AND mit AND apache'
1406-
>>> str(combine_expressions(('gpl', 'mit', 'apache',), relation='OR'))
1407-
'gpl OR mit OR apache'
1429+
1430+
>>> a = 'mit'
1431+
>>> b = 'gpl'
1432+
>>> str(combine_expressions([a, b]))
1433+
'mit AND gpl'
1434+
>>> assert 'mit' == str(combine_expressions([a]))
1435+
>>> combine_expressions([])
1436+
>>> combine_expressions(None)
1437+
>>> str(combine_expressions(('gpl', 'mit', 'apache',)))
1438+
'gpl AND mit AND apache'
1439+
>>> str(combine_expressions(('gpl', 'mit', 'apache',), relation='OR'))
1440+
'gpl OR mit OR apache'
14081441
"""
14091442
if not expressions:
14101443
return

0 commit comments

Comments
 (0)