Skip to content

Commit c304b62

Browse files
committed
Add additional tests for unexpected fields in units
1 parent ff25e73 commit c304b62

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

gemd/units/impl.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ def _scaling_preprocessor(input_string: str) -> str:
2626
tight_division = False
2727
scales = []
2828

29+
if next(token for token in tokens).type == NUMBER:
30+
return input_string # The unit can't have a leading number; scaling factors are internal
31+
2932
for token in tokens:
3033
# Note that while this prevents adding a bunch of numbers to the registry,
3134
# no test would break if the `exponent` logic were removed
@@ -36,8 +39,13 @@ def _scaling_preprocessor(input_string: str) -> str:
3639
if not exponent and token.type == NUMBER:
3740
scales.append([token.string, False])
3841
tight_division = division
39-
exponent = token.type == OP and token.string in {"^", "**"}
40-
division = token.type == OP and token.string in {"/", "//"}
42+
if token.type == OP:
43+
if token.string not in {"+", "-", "*", "/", "//", "^", "**", "(", ")"}:
44+
raise UndefinedUnitError(f"Unrecognized operator: {token.string}")
45+
exponent = token.string in {"^", "**"}
46+
division = token.string in {"/", "//"}
47+
else:
48+
exponent, division = False, False
4149

4250
for scale, division in scales:
4351
# There's probably something to be said for stashing these, but this sin
@@ -103,7 +111,10 @@ def parse_units(units: Union[str, Unit, None]) -> Union[str, Unit, None]:
103111
elif units == '':
104112
return 'dimensionless'
105113
elif isinstance(units, str):
106-
return f"{_REGISTRY(units).u:clean}"
114+
parsed = _REGISTRY(units)
115+
if isinstance(parsed, int) or parsed.magnitude != 1:
116+
raise ValueError("Unit expression cannot have a scaling factor.")
117+
return f"{parsed.u:clean}"
107118
elif isinstance(units, Unit):
108119
return units
109120
else:

gemd/units/tests/test_parser.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,17 @@ def test_parse_unexpected():
4242
5,
4343
"cp", # Removed because of risk of collision with cP
4444
"chain", # Survey units eliminated
45-
"SECONDS" # Not just case insensitivity
45+
"SECONDS", # Not just case insensitivity
46+
"lb : in^3", # Not just case insensitivity
4647
]
4748
for unit in unexpected:
4849
with pytest.raises(UndefinedUnitError):
4950
parse_units(unit)
5051

52+
for unit in ("3 rpm", "16"):
53+
with pytest.raises(ValueError, match="scaling"):
54+
parse_units(unit)
55+
5156

5257
def test_parse_none():
5358
"""Test that None parses as None."""

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
setup(name='gemd',
5-
version='1.13.0',
5+
version='1.13.1',
66
url='http://github.com/CitrineInformatics/gemd-python',
77
description="Python binding for Citrine's GEMD data model",
88
author='Citrine Informatics',

0 commit comments

Comments
 (0)