Skip to content

Commit 0581f2b

Browse files
authored
Merge pull request #433 from ayharano/fastapi_is_current_version_higher_or_equal
Replace FastAPI pure str comparison with SemVer comparison
2 parents 960b5cf + 8af20cf commit 0581f2b

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

rollbar/contrib/fastapi/utils.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,44 @@ def __init__(self, version, reason=''):
2121
return super().__init__(err_msg)
2222

2323

24+
def is_current_version_higher_or_equal(current_version, min_version):
25+
"""
26+
Compare two version strings and return True if the current version is higher or equal to the minimum version.
27+
28+
Note: This function only compares the release segment of the version string.
29+
"""
30+
def parse_version(version):
31+
"""Parse the release segment of a version string into a list of strings."""
32+
parsed = ['']
33+
current_segment = 0
34+
for c in version:
35+
if c.isdigit():
36+
parsed[current_segment] += c
37+
elif c == '.':
38+
current_segment += 1
39+
parsed.append('')
40+
else:
41+
break
42+
if parsed[-1] == '':
43+
parsed.pop()
44+
return parsed
45+
46+
current = tuple(map(int, parse_version(current_version)))
47+
minimum = tuple(map(int, parse_version(min_version)))
48+
return current >= minimum
49+
50+
2451
class fastapi_min_version:
2552
def __init__(self, min_version):
2653
self.min_version = min_version
2754

2855
def __call__(self, func):
2956
@functools.wraps(func)
3057
def wrapper(*args, **kwargs):
31-
if fastapi.__version__ < self.min_version:
58+
if not is_current_version_higher_or_equal(
59+
fastapi.__version__,
60+
self.min_version,
61+
):
3262
raise FastAPIVersionError(
3363
self.min_version, reason=f'to use {func.__name__}() function'
3464
)

rollbar/test/fastapi_tests/test_utils.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,35 @@ async def read_root():
121121
app.include_router(router)
122122

123123
self.assertFalse(has_bare_routing(app))
124+
125+
@unittest.skipUnless(
126+
FASTAPI_INSTALLED and ALLOWED_PYTHON_VERSION, 'FastAPI requires Python3.6+'
127+
)
128+
class UtilsVersionCompareTest(BaseTest):
129+
def test_is_current_version_higher_or_equal(self):
130+
# Copied from https://semver.org/#spec-item-11
131+
versions = [
132+
'1.0.0-alpha',
133+
'1.0.0-alpha.1',
134+
'1.0.0-alpha.beta',
135+
'1.0.0-beta',
136+
'1.0.0-beta.2',
137+
'1.0.0-beta.11',
138+
'1.0.0-rc.1',
139+
'1.0.0',
140+
'1.1.1',
141+
'1.100.0-beta2',
142+
'1.100.0-beta3',
143+
]
144+
145+
from rollbar.contrib.fastapi.utils import is_current_version_higher_or_equal
146+
147+
previous_version = None
148+
for version in versions:
149+
print(f'{version} >= {previous_version}')
150+
if previous_version is None:
151+
previous_version = version
152+
continue
153+
with self.subTest(f'{version} >= {previous_version}'):
154+
self.assertTrue(is_current_version_higher_or_equal(version, previous_version))
155+
previous_version = version

0 commit comments

Comments
 (0)