Skip to content

Commit 876add5

Browse files
committed
Swift: reject uppercase acronyms in schema
This was causing hardly debuggable errors because names are transformed to underscored lowercase names in the dbscheme and back to camelcase for trap emission classes, which is not a noop in case uppercase acronyms (like SIL or ABI) are in the name. This makes the error be surfaced early with a helpful message.
1 parent 686a1cb commit 876add5

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

swift/codegen/lib/schema/schema.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import functools
1010
import importlib.util
1111
from toposort import toposort_flatten
12+
import inflection
1213

1314

1415
class Error(Exception):
@@ -210,8 +211,12 @@ def modify(self, prop: Property):
210211
def _get_class(cls: type) -> Class:
211212
if not isinstance(cls, type):
212213
raise Error(f"Only class definitions allowed in schema, found {cls}")
213-
if cls.__name__[0].islower():
214-
raise Error(f"Class name must be capitalized, found {cls.__name__}")
214+
# we must check that going to dbscheme names and back is preserved
215+
# In particular this will not happen if uppercase acronyms are included in the name
216+
to_underscore_and_back = inflection.camelize(inflection.underscore(cls.__name__), uppercase_first_letter=True)
217+
if cls.__name__ != to_underscore_and_back:
218+
raise Error(f"Class name must be upper camel-case, without capitalized acronyms, found {cls.__name__} "
219+
f"instead of {to_underscore_and_back}")
215220
if len({b._group for b in cls.__bases__ if hasattr(b, "_group")}) > 1:
216221
raise Error(f"Bases with mixed groups for {cls.__name__}")
217222
if any(getattr(b, "_null", False) for b in cls.__bases__):

swift/codegen/test/test_schema.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,5 +669,16 @@ class Null2(Root):
669669
pass
670670

671671

672+
def test_uppercase_acronyms_are_rejected():
673+
with pytest.raises(schema.Error):
674+
@schema.load
675+
class data:
676+
class Root:
677+
pass
678+
679+
class ROTFLNode(Root):
680+
pass
681+
682+
672683
if __name__ == '__main__':
673684
sys.exit(pytest.main([__file__] + sys.argv[1:]))

0 commit comments

Comments
 (0)