Skip to content

Commit 89f01db

Browse files
committed
fix: pin datamodel-code-generator==0.51.0 and handle empty subclasses
1 parent c58b789 commit 89f01db

2 files changed

Lines changed: 70 additions & 12 deletions

File tree

setup.cfg

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,18 @@ package_dir =
4141
=src
4242

4343
# Require a min/specific Python version (comma-separated conditions)
44-
python_requires = >=3.9
44+
python_requires = >=3.10
4545

4646
# Add here dependencies of your project (line-separated), e.g. requests>=2.2,<3.0.
4747
# Version specifiers like >=2.2,<3.0 avoid problems due to API changes in
4848
# new major versions. This works if the required packages follow Semantic Versioning.
4949
# For more information, check out https://semver.org/.
5050
install_requires =
51-
oold>=0.11.0
51+
oold>=0.11.1
5252
opensemantic
5353
opensemantic.core
54-
pydantic>=1.10.17
55-
datamodel-code-generator>=0.51.0
54+
pydantic[email]>=1.10.17
55+
datamodel-code-generator==0.51.0
5656
ruamel.yaml<0.19.0
5757
mwclient>=0.11.0
5858
rdflib

src/osw/core.py

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -519,14 +519,7 @@ def _fetch_schema(self, fetchSchemaParam: _FetchSchemaParam = None) -> None:
519519
)
520520
schema_str = json.dumps(schemas_for_preprocessing[0])
521521

522-
schema = json.loads(
523-
schema_str.replace("$ref", "dollarref").replace(
524-
# '$' is a special char for root object in jsonpath
525-
'"allOf": [',
526-
'"allOf": [{},',
527-
)
528-
# fix https://github.com/koxudaxi/datamodel-code-generator/issues/1910
529-
)
522+
schema = json.loads(schema_str.replace("$ref", "dollarref"))
530523

531524
jsonpath_expr = parse("$..dollarref")
532525
for match in jsonpath_expr.find(schema):
@@ -725,6 +718,71 @@ def _fetch_schema(self, fetchSchemaParam: _FetchSchemaParam = None) -> None:
725718
# are not v1 compatible mainly by using update_model()
726719
content = re.sub(r"(,?\s*unique_items=True\s*)", "", content)
727720

721+
# Detect empty subclasses, replaces their occurrences with base classes,
722+
# and removes the empty class definitions.
723+
# Only processes subclasses that follow naming patterns:
724+
# - BaseclassModel (e.g., DescriptionModel extends Description)
725+
# - Baseclass<number> (e.g., Label1, Label2 extend Label)
726+
727+
# Pattern to match empty subclasses
728+
# Matches: class SubClass(BaseClass):
729+
# followed by optional whitespace/docstring and pass
730+
pattern = "".join(
731+
(
732+
r"class\s+", # 'class' keyword
733+
r"(\w+)", # capture subclass name
734+
r"\s*\(\s*", # opening parenthesis
735+
r"(\w+)", # capture base class name
736+
r"\s*\)\s*:", # closing parenthesis and colon
737+
r"\s*", # optional whitespace
738+
r'(?:\n\s*(?:""".*?"""|\'\'\'.*?\'\'\')'
739+
# optional docstring (triple quotes)
740+
r"\s*)?", # end optional docstring
741+
r"\n\s*pass\s*", # pass statement
742+
r"(?:\n|$)", # newline or end of string
743+
)
744+
)
745+
746+
# Find all empty subclasses
747+
matches = list(re.finditer(pattern, content, re.MULTILINE | re.DOTALL))
748+
749+
# Filter matches based on naming patterns
750+
valid_matches = []
751+
for match in matches:
752+
subclass_name = match.group(1)
753+
base_class_name = match.group(2)
754+
755+
# Check if subclass follows the naming patterns
756+
if (
757+
subclass_name == base_class_name + "Model" # BaseclassModel pattern
758+
or re.match(
759+
rf"^{re.escape(base_class_name)}\d+$", subclass_name
760+
) # Baseclass<number> pattern
761+
):
762+
valid_matches.append(match)
763+
764+
content = content
765+
replacements = []
766+
767+
# Process matches in reverse order to avoid offset issues when removing
768+
for match in reversed(valid_matches):
769+
subclass_name = match.group(1)
770+
base_class_name = match.group(2)
771+
replacements.append((subclass_name, base_class_name))
772+
773+
# Remove the entire class definition
774+
start, end = match.span()
775+
# Also remove any trailing newlines to avoid extra blank lines
776+
while end < len(content) and content[end] == "\n":
777+
end += 1
778+
779+
content = content[:start] + content[end:]
780+
781+
# Replace all occurrences of subclass names with base class names
782+
for subclass_name, base_class_name in reversed(replacements):
783+
pattern_replace = r"\b" + re.escape(subclass_name) + r"\b"
784+
content = re.sub(pattern_replace, base_class_name, content)
785+
728786
if fetchSchemaParam.mode == "replace":
729787
header = (
730788
"from uuid import uuid4\n"

0 commit comments

Comments
 (0)