diff --git a/HISTORY.rst b/HISTORY.rst index d3d7885..165ab45 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,7 +2,13 @@ History ======= -0.4.0 () +0.5.0 () +------------------ +* Removed Python 2 support, min version tested is Python 3.8 +* Removed Six dependency +* Upgraded Python-Box + +0.4.0 (2024-11-12) ------------------ * Added support for `ruamel.yaml>0.18` diff --git a/setup.py b/setup.py index bc1c6f9..6d45667 100644 --- a/setup.py +++ b/setup.py @@ -11,8 +11,7 @@ history = history_file.read() requirements = [ - "six<2", - "python-box<4", + "python-box<8", ] extras = { @@ -60,15 +59,14 @@ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.6", - "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ], test_suite="tests", tests_require=extras["test"], diff --git a/yapconf/__init__.py b/yapconf/__init__.py index d2e075e..a57a991 100644 --- a/yapconf/__init__.py +++ b/yapconf/__init__.py @@ -4,16 +4,10 @@ import re import sys -import six from box import Box -if six.PY3: - from collections.abc import MutableMapping +from collections.abc import MutableMapping - unicode = str -else: - from collections import MutableMapping - from io import open # Setup feature flags for use throughout the package. yaml_support = True @@ -171,10 +165,8 @@ def _dump(data, stream, file_type, **kwargs): if str(file_type).lower() == "json": dumped = json.dumps(data, **kwargs) - if isinstance(dumped, unicode): + if isinstance(dumped, str): stream.write(dumped) - else: - stream.write(six.u(dumped)) elif str(file_type).lower() == "yaml": # Depending on the yaml module loaded, need to handle arguments differently if type(yaml).__name__ == "YAML": diff --git a/yapconf/items.py b/yapconf/items.py index 09559e8..c1ea29b 100644 --- a/yapconf/items.py +++ b/yapconf/items.py @@ -5,8 +5,6 @@ import logging import sys -import six - import yapconf from yapconf.actions import AppendBoolean, AppendReplace, MergeAction from yapconf.exceptions import (YapconfDictItemError, YapconfItemError, @@ -46,7 +44,7 @@ def from_specification( """ items = {} - for item_name, item_info in six.iteritems(specification): + for item_name, item_info in specification.items(): names = copy.copy(parent_names) if parent_names else [] items[item_name] = _generate_item( item_name, item_info, env_prefix, separator, names @@ -698,7 +696,7 @@ def convert_config_value(self, value, label): Returns: """ - if isinstance(value, six.string_types): + if isinstance(value, str): value = value.lower() if value in self.TRUTHY_VALUES: @@ -921,7 +919,7 @@ def add_argument(self, parser, bootstrap=False): def get_config_value(self, overrides, skip_environment=False): converted_value = { child_name: child_item.get_config_value(overrides, skip_environment) - for child_name, child_item in six.iteritems(self.children) + for child_name, child_item in self.children.items() } self._validate_value(converted_value) return converted_value @@ -940,7 +938,7 @@ def apply_filter(self, **kwargs): return None filtered_items = {} - for child_name, child_item in six.iteritems(self.children): + for child_name, child_item in self.children.items(): result = child_item.apply_filter(**kwargs) if result is not None: filtered_items[child_name] = result @@ -969,7 +967,7 @@ def migrate_config( def convert_config_value(self, value, label): return { child_name: child_item.get_config_value([(label, value)]) - for child_name, child_item in six.iteritems(self.children) + for child_name, child_item in self.children.items() } def _has_cli_support(self, child_of_list=False): diff --git a/yapconf/sources.py b/yapconf/sources.py index 1f96b74..a97b773 100644 --- a/yapconf/sources.py +++ b/yapconf/sources.py @@ -8,7 +8,6 @@ import warnings from argparse import ArgumentParser -import six from watchdog.observers import Observer import yapconf @@ -100,8 +99,7 @@ def get_source(label, source_type, **kwargs): raise NotImplementedError("No implementation for source type %s" % source_type) -@six.add_metaclass(abc.ABCMeta) -class ConfigSource(object): +class ConfigSource(metaclass=abc.ABCMeta): """Base class for a configuration source. Config sources will be used to generate overrides during configuration diff --git a/yapconf/spec.py b/yapconf/spec.py index 8a225a4..1992c83 100644 --- a/yapconf/spec.py +++ b/yapconf/spec.py @@ -3,7 +3,6 @@ import os import sys -import six from box import Box import yapconf @@ -73,7 +72,7 @@ def __init__( self._sources = {} def _load_specification(self, specification): - if isinstance(specification, six.string_types): + if isinstance(specification, str): specification = yapconf.load_file( specification, file_type=self._file_type, @@ -91,7 +90,7 @@ def _load_specification(self, specification): return specification def _validate_specification(self, specification): - for item_name, item_info in six.iteritems(specification): + for item_name, item_info in specification.items(): if not isinstance(item_info, dict): raise YapconfSpecError( "Invalid specification. {0} is not a " @@ -244,7 +243,7 @@ def update_defaults(self, new_defaults, respect_none=False): constitute an update to the default. """ - for key, value in six.iteritems(new_defaults): + for key, value in new_defaults.items(): item = self.get_item(key) if item is None: raise YapconfItemNotFound( @@ -305,7 +304,7 @@ def load_filtered_config(self, *args, **kwargs): """ overrides = self._generate_overrides(*args) filtered_items = {} - for item_name, item in six.iteritems(self._yapconf_items): + for item_name, item in self._yapconf_items.items(): result = item.apply_filter(**kwargs) if result is not None: filtered_items[item_name] = result @@ -584,7 +583,7 @@ def _extract_string_source(self, label, value, file_type): def _extract_source(self, index, override): label, unpacked_value, file_type = self._explode_override(override) - if isinstance(unpacked_value, six.string_types): + if isinstance(unpacked_value, str): return self._extract_string_source(label, unpacked_value, file_type) elif isinstance(unpacked_value, dict):