Skip to content

Commit eef4f16

Browse files
committed
Allow colon ":" in license symbols #33
Otherwise some valid SPDX references are not parsed, such as: DocumentRef-James-1.0:LicenseRef-Eric-2.0 Reported-by: @papadeltasierra Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
1 parent 7ffab9d commit eef4f16

2 files changed

Lines changed: 58 additions & 3 deletions

File tree

src/license_expression/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@ def __contains__(self, other):
846846

847847

848848
# validate license keys
849-
is_valid_license_key = re.compile(r'^[-\w\s\.\+]+$', re.UNICODE).match
849+
is_valid_license_key = re.compile(r'^[-:\w\s\.\+]+$', re.UNICODE).match
850850

851851

852852
# TODO: we need to implement comparison by hand instead
@@ -882,14 +882,15 @@ def __init__(self, key, aliases=tuple(), is_exception=False, *args, **kwargs):
882882
if not is_valid_license_key(key):
883883
raise ExpressionError(
884884
'Invalid license key: the valid characters are: letters and numbers, '
885-
'underscore, dot or hyphen signs and spaces: "%(key)s"' % locals())
885+
'underscore, dot, colon or hyphen signs and spaces: "%(key)s"' % locals())
886886

887887
# normalize for spaces
888888
key = ' '.join(key.split())
889889

890890
if key.lower() in KEYWORDS_STRINGS:
891891
raise ExpressionError(
892-
'Invalid license key: a key cannot be a reserved keyword: "or", "and" or "with: "%(key)s"' % locals())
892+
'Invalid license key: a key cannot be a reserved keyword: "or",'
893+
' "and" or "with: "%(key)s"' % locals())
893894

894895
self.key = key
895896

tests/test_license_expression.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,14 @@ def test_parse_invalid_expression_with_single_leading_or_raise_exception(self):
919919
}
920920
assert expected == _parse_error_as_dict(pe)
921921

922+
def test_Licensing_can_parse_expressions_with_symbols_that_contain_a_colon(self):
923+
licensing = Licensing()
924+
expression = 'DocumentRef-James-1.0:LicenseRef-Eric-2.0'
925+
926+
result = licensing.parse(expression)
927+
expected = 'DocumentRef-James-1.0:LicenseRef-Eric-2.0'
928+
assert expected == result.render('{symbol.key}')
929+
922930

923931
class LicensingParseWithSymbolsSimpleTest(TestCase):
924932

@@ -1752,6 +1760,52 @@ def test_simple_tokenizer(self):
17521760
]
17531761
assert expected == results
17541762

1763+
def test_tokenize_can_handle_expressions_with_symbols_that_contain_a_colon(self):
1764+
licensing = Licensing()
1765+
expression = 'DocumentRef-James-1.0:LicenseRef-Eric-2.0'
1766+
1767+
result = list(licensing.tokenize(expression))
1768+
expected = [
1769+
(LicenseSymbol(u'DocumentRef-James-1.0:LicenseRef-Eric-2.0', is_exception=False),
1770+
u'DocumentRef-James-1.0:LicenseRef-Eric-2.0', 0)
1771+
]
1772+
1773+
assert expected == result
1774+
1775+
def test_tokenize_simple_can_handle_expressions_with_symbols_that_contain_a_colon(self):
1776+
licensing = Licensing()
1777+
expression = 'DocumentRef-James-1.0:LicenseRef-Eric-2.0'
1778+
1779+
result = list(licensing.tokenize(expression, simple=True))
1780+
expected = [
1781+
(LicenseSymbol(u'DocumentRef-James-1.0:LicenseRef-Eric-2.0', is_exception=False),
1782+
u'DocumentRef-James-1.0:LicenseRef-Eric-2.0', 0)
1783+
]
1784+
1785+
assert expected == result
1786+
1787+
def test_tokenize_can_handle_expressions_with_tabs_and_new_lines(self):
1788+
licensing = Licensing()
1789+
expression = 'this\t \tis \n\n an expression'
1790+
result = list(licensing.tokenize(expression, simple=False))
1791+
expected = [
1792+
(LicenseSymbol(u'this is an expression', is_exception=False),
1793+
u'this is an expression', 0)
1794+
]
1795+
assert expected == result
1796+
1797+
def test_tokenize_simple_can_handle_expressions_with_tabs_and_new_lines(self):
1798+
licensing = Licensing()
1799+
expression = 'this\t \tis \n\n an expression'
1800+
result = list(licensing.tokenize(expression, simple=True))
1801+
expected = [
1802+
(LicenseSymbol(u'this', is_exception=False), u'this', 0),
1803+
(LicenseSymbol(u'is', is_exception=False), u'is', 7),
1804+
(LicenseSymbol(u'an', is_exception=False), u'an', 13),
1805+
(LicenseSymbol(u'expression', is_exception=False), u'expression', 16)
1806+
]
1807+
assert expected == result
1808+
17551809
def test_tokenize_step_by_step_does_not_munge_trailing_symbols(self):
17561810
gpl2 = LicenseSymbol(key='GPL-2.0')
17571811
gpl2plus = LicenseSymbol(key='GPL-2.0 or LATER')

0 commit comments

Comments
 (0)