Skip to content

Commit cc20a65

Browse files
committed
fix(UnityVersion): handle optional postfixes, fixes #369
1 parent e473974 commit cc20a65

2 files changed

Lines changed: 24 additions & 11 deletions

File tree

UnityPy/helpers/UnityVersion.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
from enum import IntEnum
55
from typing import Optional, Tuple, Union
66

7-
VersionPattern = re.compile(r"^(?P<major>\d+)\.(?P<minor>\d+)\.(?P<build>\d+)(?P<type_str>.+?)?(?P<type_number>\d+)?$")
7+
VersionPattern = re.compile(
8+
r"^(?P<major>\d+)\.(?P<minor>\d+)\.(?P<build>\d+)(?P<type_str>.+?)?(?P<type_number>\d+)?(?P<postfix>.*)$",
9+
flags=re.DOTALL,
10+
)
811

912

1013
class UnityVersionType(IntEnum):
@@ -20,6 +23,7 @@ class UnityVersionType(IntEnum):
2023
class UnityVersion(int):
2124
# https://github.com/AssetRipper/VersionUtilities/blob/master/VersionUtilities/UnityVersion.cs
2225
_type_str: Optional[str]
26+
_postfix: Optional[str]
2327

2428
@property
2529
def major(self):
@@ -41,6 +45,10 @@ def type(self):
4145
def type_str(self):
4246
return getattr(self, "_type_str", self.type.name)
4347

48+
@property
49+
def postfix(self):
50+
return getattr(self, "_postfix", "")
51+
4452
@property
4553
def type_number(self):
4654
return self & 0xFF
@@ -56,6 +64,7 @@ def from_str(cls, version: str):
5664
# formats:
5765
# old: 5.0.0, <major>.<minor>.<build>
5866
# new: 2018.1.1f2 <major>.<minor>.<build><type_str><type_number>
67+
# the new format string can be followed by a custom postfix
5968
match = VersionPattern.match(version)
6069
if not match:
6170
raise ValueError(f"Invalid version string: {version}")
@@ -64,6 +73,7 @@ def from_str(cls, version: str):
6473
build = int(match.group("build"))
6574
type_str = match.group("type_str")
6675
type_number = int(match.group("type_number") or 0)
76+
postfix = match.group("postfix")
6777

6878
if type_str is None:
6979
return cls.from_list(major, minor, build)
@@ -72,10 +82,19 @@ def from_str(cls, version: str):
7282
obj = cls.from_list(major, minor, build, type, type_number)
7383
if type is UnityVersionType.u:
7484
obj._type_str = type_str
85+
if postfix:
86+
obj._postfix = postfix
87+
7588
return obj
7689

90+
def __str__(self) -> str:
91+
if self.major <= 5:
92+
return f"{self.major}.{self.minor}.{self.build}"
93+
else:
94+
return f"{self.major}.{self.minor}{self.type_str}{self.type_number}{self.postfix}"
95+
7796
def __repr__(self) -> str:
78-
return f"UnityVersion {self.major}.{self.minor}{self.type_str}{self.type_number}"
97+
return f"UnityVersion {self.__str__()}"
7998

8099
def __getitem__(self, idx: Union[int, slice]) -> Union[int, Tuple[int, ...]]:
81100
values = (

tests/test_UnityVersion.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
("2021.1.0c1", (2021, 1, 0, UnityVersionType.c.value, 1)),
1515
("2022.2.0x1", (2022, 2, 0, UnityVersionType.x.value, 1)),
1616
("2018.1.1z2", (2018, 1, 1, UnityVersionType.u.value, 2)), # unknown type
17+
("2022.3.62f2\n2", (2022, 3, 62, UnityVersionType.f.value, 2)),
1718
],
1819
)
1920
def test_parse_unity_version(version_str, expected_tuple):
@@ -24,6 +25,7 @@ def test_parse_unity_version(version_str, expected_tuple):
2425
assert v.build == expected_tuple[2]
2526
assert v.type.value == expected_tuple[3]
2627
assert v.type_number == expected_tuple[4]
28+
assert UnityVersion.from_list(*expected_tuple) == v
2729

2830

2931
@pytest.mark.parametrize(
@@ -58,6 +60,7 @@ def test_comparison_with_tuple(version_str, compare_tuple):
5860
("2018.1.1f2", "2018.1.1f1"),
5961
("2018.1.1f2", "2018.1.2f2"),
6062
("2018.1.1f2", "2018.2.1f2"),
63+
("2022.3.62f2\n2", "2022.3.62f2"),
6164
],
6265
)
6366
def test_comparison_with_unityversion(version_str, other_str):
@@ -69,12 +72,3 @@ def test_comparison_with_unityversion(version_str, other_str):
6972
assert (v1 <= v2) == (v1.as_tuple() <= v2.as_tuple())
7073
assert (v1 > v2) == (v1.as_tuple() > v2.as_tuple())
7174
assert (v1 >= v2) == (v1.as_tuple() >= v2.as_tuple())
72-
73-
74-
def test_repr_and_str():
75-
v = UnityVersion.from_str("2018.1.1f2")
76-
assert "UnityVersion" in repr(v)
77-
assert str(v.major) in repr(v)
78-
assert str(v.minor) in repr(v)
79-
assert v.type_str in repr(v)
80-
assert str(v.type_number) in repr(v)

0 commit comments

Comments
 (0)