Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jobs:
uses: neongeckocom/.github/.github/workflows/python_build_tests.yml@master
skill_object_tests:
strategy:
max-parallel: 2
matrix:
python-version: [ 3.9, '3.10', '3.11', '3.12' ]
runs-on: ubuntu-latest
Expand Down
33 changes: 20 additions & 13 deletions neon_utils/packaging_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from typing import Tuple, Optional, List
from tempfile import mkstemp

import pkg_resources
import sysconfig

from os.path import exists, join, isfile
Expand Down Expand Up @@ -63,29 +62,37 @@ def get_package_version_spec(pkg: str):
"""
Locate an installed package and return its reported version
:param pkg: string package name to locate
:returns: Version string as reported by pkg_resources
:raises: ModuleNotFoundError if requested package isn't installed
:returns: Version string as reported by importlib.metadata
:raises: PackageNotFoundError if requested package isn't installed
"""
try:
return pkg_resources.get_distribution(pkg).version
except pkg_resources.DistributionNotFound:
raise ModuleNotFoundError(f"{pkg} not found")
from importlib.metadata import version
except ImportError:
# Fallback for Python < 3.8
from importlib_metadata import version

return version(pkg)


def get_package_dependencies(pkg: str):
"""
Get the dependencies for an installed package
:param pkg: string package name to evaluate
:returns: list of string dependencies (equivalent to requirements.txt)
:raises ModuleNotFoundError if requested package isn't installed
:raises PackageNotFoundError if requested package isn't installed
"""
try:
constraints = pkg_resources.working_set.by_key[pkg].requires()
constraints_spec = [str(c).split('[', 1)[0] for c in constraints]
LOG.debug(constraints_spec)
return constraints_spec
except KeyError:
raise ModuleNotFoundError(f"{pkg} not found")
from importlib.metadata import requires
except ImportError:
# Fallback for Python < 3.8
from importlib_metadata import requires

requirements = requires(pkg)
if requirements is None:
return []
constraints_spec = [req.split('[', 1)[0].split(';', 1)[0] for req in requirements]
LOG.debug(constraints_spec)
return constraints_spec


@deprecated("Reference `neon_core.version.__version__` directly", "2.0.0")
Expand Down
13 changes: 9 additions & 4 deletions tests/packaging_util_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,18 @@ def test_get_packaged_core_version(self):

def test_get_package_dependencies(self):
self_deps = get_package_dependencies("neon-utils")
requirements_file = join(os.path.dirname(os.path.dirname(__file__)),
"requirements", "requirements.txt")
with open(requirements_file) as f:
spec_requirements = f.read().split('\n')
requirements_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "requirements")
spec_requirements = []
for _, _, files in os.walk(requirements_dir):
for file in files:
with open(os.path.join(requirements_dir, file)) as f:
spec_requirements += f.read().split('\n')

spec_requirements = [r for r in spec_requirements
if r and not r.startswith('#')]

# Version specs aren't order-dependent, so they can't be compared
# Also, constraints are normalized so elements cannot be compared
self.assertEqual(len(self_deps), len(spec_requirements))
with self.assertRaises(ModuleNotFoundError):
get_package_dependencies("fakeneongeckopackage")
Expand Down