Skip to content

Commit d27776e

Browse files
lrafeeiTimPansinomergify[bot]
committed
Package json fix (#1261)
* Filter incompatible version formats * Initial testing * Clean up tests * Enable test for py38+ * Fix linter error * Update newrelic/common/package_version_utils.py Co-authored-by: Timothy Pansino <[email protected]> * Reviewer suggestions * Make tests more comprehensive * Add type check to tests --------- Co-authored-by: Timothy Pansino <[email protected]> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 6b8fb08 commit d27776e

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

newrelic/common/package_version_utils.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414

1515
import sys
1616
import warnings
17-
1817
from functools import lru_cache
1918

20-
2119
# Need to account for 4 possible variations of version declaration specified in (rejected) PEP 396
2220
VERSION_ATTRS = ("__version__", "version", "__version_tuple__", "version_tuple") # nosec
2321
NULL_VERSIONS = frozenset((None, "", "0", "0.0", "0.0.0", "0.0.0.0", (0,), (0, 0), (0, 0, 0), (0, 0, 0, 0))) # nosec
@@ -81,9 +79,13 @@ def _get_package_version(name):
8179
try:
8280
version = getattr(module, attr, None)
8381

84-
# In certain cases like importlib_metadata.version, version is a callable
85-
# function.
86-
if callable(version):
82+
# Some frameworks (such as `pypdfium2`) may use a class
83+
# property to define the version. Because class properties
84+
# are not callable we need to check if the result is
85+
# anything other than a string, tuple, or list. If so,
86+
# we need to skip this method of version retrieval and use
87+
# `pkg_resources` or `importlib.metadata`.
88+
if version and not isinstance(version, (str, tuple, list)):
8789
continue
8890

8991
# Cast any version specified as a list into a tuple.

tests/agent_unittests/test_package_version_utils.py

+32
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,35 @@ def test_version_caching(monkeypatch):
150150
del sys.modules["mymodule"]
151151
version = get_package_version("mymodule")
152152
assert version not in NULL_VERSIONS, version
153+
154+
155+
def test_version_as_class_property(monkeypatch):
156+
# There is no file/module here, so we monkeypatch
157+
# pytest instead for our purposes
158+
class FakeModule:
159+
@property
160+
def version(self):
161+
return "1.2.3"
162+
163+
monkeypatch.setattr(pytest, "version", FakeModule.version, raising=False)
164+
165+
version = get_package_version("pytest")
166+
assert version not in NULL_VERSIONS and isinstance(version, str), version
167+
168+
169+
# This test checks to see if the version is a property of the class
170+
# but also checks to see if the something like version.version_tuple
171+
# has been exported as a tuple.
172+
def test_version_as_class_property_and_version_tuple(monkeypatch):
173+
# There is no file/module here, so we monkeypatch
174+
# pytest instead for our purposes
175+
class FakeModule:
176+
@property
177+
def version(self):
178+
return "1.2.3"
179+
180+
monkeypatch.setattr(pytest, "version", FakeModule.version, raising=False)
181+
monkeypatch.setattr(pytest, "version_tuple", (1, 2, 3), raising=False)
182+
183+
version = get_package_version("pytest")
184+
assert version not in NULL_VERSIONS and isinstance(version, str), version

0 commit comments

Comments
 (0)