Drop deprecated pkg_resources in favor of importlib.metadata and packaging.

This commit is contained in:
Dan Helfman 2023-04-14 21:21:25 -07:00
parent 5dbb71709c
commit 8cb5a42a9e
7 changed files with 61 additions and 19 deletions

View file

@ -1,6 +1,6 @@
from enum import Enum from enum import Enum
from pkg_resources import parse_version from packaging.version import parse
class Feature(Enum): class Feature(Enum):
@ -18,17 +18,17 @@ class Feature(Enum):
FEATURE_TO_MINIMUM_BORG_VERSION = { FEATURE_TO_MINIMUM_BORG_VERSION = {
Feature.COMPACT: parse_version('1.2.0a2'), # borg compact Feature.COMPACT: parse('1.2.0a2'), # borg compact
Feature.ATIME: parse_version('1.2.0a7'), # borg create --atime Feature.ATIME: parse('1.2.0a7'), # borg create --atime
Feature.NOFLAGS: parse_version('1.2.0a8'), # borg create --noflags Feature.NOFLAGS: parse('1.2.0a8'), # borg create --noflags
Feature.NUMERIC_IDS: parse_version('1.2.0b3'), # borg create/extract/mount --numeric-ids Feature.NUMERIC_IDS: parse('1.2.0b3'), # borg create/extract/mount --numeric-ids
Feature.UPLOAD_RATELIMIT: parse_version('1.2.0b3'), # borg create --upload-ratelimit Feature.UPLOAD_RATELIMIT: parse('1.2.0b3'), # borg create --upload-ratelimit
Feature.SEPARATE_REPOSITORY_ARCHIVE: parse_version('2.0.0a2'), # --repo with separate archive Feature.SEPARATE_REPOSITORY_ARCHIVE: parse('2.0.0a2'), # --repo with separate archive
Feature.RCREATE: parse_version('2.0.0a2'), # borg rcreate Feature.RCREATE: parse('2.0.0a2'), # borg rcreate
Feature.RLIST: parse_version('2.0.0a2'), # borg rlist Feature.RLIST: parse('2.0.0a2'), # borg rlist
Feature.RINFO: parse_version('2.0.0a2'), # borg rinfo Feature.RINFO: parse('2.0.0a2'), # borg rinfo
Feature.MATCH_ARCHIVES: parse_version('2.0.0b3'), # borg --match-archives Feature.MATCH_ARCHIVES: parse('2.0.0b3'), # borg --match-archives
Feature.EXCLUDED_FILES_MINUS: parse_version('2.0.0b5'), # --list --filter uses "-" for excludes Feature.EXCLUDED_FILES_MINUS: parse('2.0.0b5'), # --list --filter uses "-" for excludes
} }
@ -37,4 +37,4 @@ def available(feature, borg_version):
Given a Borg Feature constant and a Borg version string, return whether that feature is Given a Borg Feature constant and a Borg version string, return whether that feature is
available in that version of Borg. available in that version of Borg.
''' '''
return FEATURE_TO_MINIMUM_BORG_VERSION[feature] <= parse_version(borg_version) return FEATURE_TO_MINIMUM_BORG_VERSION[feature] <= parse(borg_version)

View file

@ -8,7 +8,11 @@ from queue import Queue
from subprocess import CalledProcessError from subprocess import CalledProcessError
import colorama import colorama
import pkg_resources
try:
import importlib_metadata
except ModuleNotFoundError: # pragma: nocover
import importlib.metadata as importlib_metadata
import borgmatic.actions.borg import borgmatic.actions.borg
import borgmatic.actions.break_lock import borgmatic.actions.break_lock
@ -706,7 +710,7 @@ def main(): # pragma: no cover
global_arguments = arguments['global'] global_arguments = arguments['global']
if global_arguments.version: if global_arguments.version:
print(pkg_resources.require('borgmatic')[0].version) print(importlib_metadata.version('borgmatic'))
sys.exit(0) sys.exit(0)
if global_arguments.bash_completion: if global_arguments.bash_completion:
print(borgmatic.commands.completion.bash_completion()) print(borgmatic.commands.completion.bash_completion())

View file

@ -1,9 +1,13 @@
import os import os
import jsonschema import jsonschema
import pkg_resources
import ruamel.yaml import ruamel.yaml
try:
import importlib_metadata
except ModuleNotFoundError: # pragma: nocover
import importlib.metadata as importlib_metadata
from borgmatic.config import environment, load, normalize, override from borgmatic.config import environment, load, normalize, override
@ -11,8 +15,17 @@ def schema_filename():
''' '''
Path to the installed YAML configuration schema file, used to validate and parse the Path to the installed YAML configuration schema file, used to validate and parse the
configuration. configuration.
Raise FileNotFoundError when the schema path does not exist.
''' '''
return pkg_resources.resource_filename('borgmatic', 'config/schema.yaml') try:
return next(
str(path.locate())
for path in importlib_metadata.files('borgmatic')
if path.match('config/schema.yaml')
)
except StopIteration:
raise FileNotFoundError('Configuration file schema could not be found')
def format_json_error_path_element(path_element): def format_json_error_path_element(path_element):

View file

@ -4,8 +4,6 @@ description_file=README.md
[tool:pytest] [tool:pytest]
testpaths = tests testpaths = tests
addopts = --cov-report term-missing:skip-covered --cov=borgmatic --ignore=tests/end-to-end addopts = --cov-report term-missing:skip-covered --cov=borgmatic --ignore=tests/end-to-end
filterwarnings =
ignore:Deprecated call to `pkg_resources.declare_namespace\('ruamel'\)`.*:DeprecationWarning
[flake8] [flake8]
max-line-length = 100 max-line-length = 100

View file

@ -32,6 +32,7 @@ setup(
install_requires=( install_requires=(
'colorama>=0.4.1,<0.5', 'colorama>=0.4.1,<0.5',
'jsonschema', 'jsonschema',
'packaging',
'requests', 'requests',
'ruamel.yaml>0.15.0,<0.18.0', 'ruamel.yaml>0.15.0,<0.18.0',
'setuptools', 'setuptools',

View file

@ -12,8 +12,10 @@ flake8-use-fstring==1.4
flake8-variables-names==0.0.5 flake8-variables-names==0.0.5
flexmock==0.11.3 flexmock==0.11.3
idna==3.4 idna==3.4
importlib_metadata==6.3.0; python_version < '3.8'
isort==5.12.0 isort==5.12.0
mccabe==0.7.0 mccabe==0.7.0
packaging==23.1
pluggy==1.0.0 pluggy==1.0.0
pathspec==0.11.1; python_version >= '3.8' pathspec==0.11.1; python_version >= '3.8'
py==1.11.0 py==1.11.0
@ -27,3 +29,5 @@ requests==2.28.2
ruamel.yaml>0.15.0,<0.18.0 ruamel.yaml>0.15.0,<0.18.0
toml==0.10.2; python_version >= '3.8' toml==0.10.2; python_version >= '3.8'
typed-ast; python_version >= '3.8' typed-ast; python_version >= '3.8'
typing-extensions==4.5.0; python_version < '3.8'
zipp==3.15.0; python_version < '3.8'

View file

@ -4,6 +4,28 @@ from flexmock import flexmock
from borgmatic.config import validate as module from borgmatic.config import validate as module
def test_schema_filename_finds_schema_path():
schema_path = '/var/borgmatic/config/schema.yaml'
flexmock(module.importlib_metadata).should_receive('files').and_return(
flexmock(match=lambda path: False, locate=lambda: None),
flexmock(match=lambda path: True, locate=lambda: schema_path),
flexmock(match=lambda path: False, locate=lambda: None),
)
assert module.schema_filename() == schema_path
def test_schema_filename_with_missing_schema_path_raises():
flexmock(module.importlib_metadata).should_receive('files').and_return(
flexmock(match=lambda path: False, locate=lambda: None),
flexmock(match=lambda path: False, locate=lambda: None),
)
with pytest.raises(FileNotFoundError):
assert module.schema_filename()
def test_format_json_error_path_element_formats_array_index(): def test_format_json_error_path_element_formats_array_index():
module.format_json_error_path_element(3) == '[3]' module.format_json_error_path_element(3) == '[3]'