Changelog

Next

Refactored

  • Refactored as_dict to use dict comprehension.

2.3.1

Added

  • Added doc-strings to Configuration.copy and MutableConfiguration.copy methods.

  • Added parameters to Configuration.__init__ and MutableConfiguration.__init__ documentation

  • Duplicated overloads to improve MutableConfiguration documentation.

Fixed

  • Baked-In Documentation: Corrected grammar in Project description and Readme.

  • EagerIOBinaryFile, EagerIOTextFile: Updated to exclude data from repr and hash.

  • Added Generic Type Parameters to MutableConfiguration

    • Both default to typing.Any, so no behavior change.

    • Should have been updated alongside Configuration.

  • KT is now bound to collections.abc.Hashable

    • Allows type checking to catch what is a runtime error.

2.3.0

Added

  • Added granular_configuration_language.yaml.file_ops module

    • Refactored from private modules.

  • Added EagerIO Feature Set

    • (internal detail) Added SimpleFuture to wrap ThreadPoolExecutor setup and teardown.

    • Added granular_configuration_language.yaml.decorator.eagerio module

    • Added LazyLoadConfiguration.eager_load

    • Added !EagerParseFile and !EagerOptionalParseFile Tags

    • Added Undocumented Tags:

      • !LoadBinary and !EagerLoadBinary Tag to test binary EagerIO

  • Added granular_configuration_language.yaml.decorators.with_tag decorator

    • Rewrote tag attribute tracking to add support.

    • G_CONFIG_ENABLE_TAG_TRACKER environment variable setting removed.

  • Added TagHadUnsupportArgument exception.

    • Inherits from ValueError, which was previously used.

  • Added Generic Type Parameters to Configuration

    • Both default to typing.Any, so no behavior change.

Changed

  • Changes to available_plugins:

    • Added -l, --long option

    • Added eager_io column

    • Added shorten name option for handler, needs_root_condition, and eager_io.

      • Defaults as enabled. -l, --long option disables.

    • Changed internal Tag Function names to be shorter for handler column.

    • Improved --help message.

      • Help message uses python -m granular_configuration_language.available_plugins instead of available_plugins.py (Backported from 3.14)

  • Changes to available_tags:

    • Added eio_inner_type column

    • Improved --help message.

      • Help message uses python -m granular_configuration_language.available_tags instead of available_tags.py (Backported from 3.14)

  • A ValueError raised during the type check of TagDecoratorBase will be converted into a TagHadUnsupportArgument.

Fixed

  • Made the function parameter for all decorators positional-only.

    • This is to enforce clearer usage in the unexpected case of not using @.

  • Changed Configuration.get type signature to match Python 3.12 Mapping.get signature.

    • i.e. key is positional-only. (Runtime does not enforce.)

  • Minor correctness issues caught by Ruff that still past their tests before and after.

2.2.3

Fixed

  • Boolean expression for the without_ref interpolations missing parentheses.

  • !OptionalParseFile is documented to return None. It was returning empty mapping. Changed to result to match documentation.

2.2.2

Added

  • Added needs_root_condition column to available_plugins.

  • G_CONFIG_ENABLE_TAG_TRACKER to Environment Variables.

Changed

  • Made tag attribute tracking optional via G_CONFIG_ENABLE_TAG_TRACKER.

    • available_plugins and available_tags set G_CONFIG_ENABLE_TAG_TRACKER temporarily.

  • !Masked is now lazy, for consistency with interpolate_value_without_ref recommendations.

  • Improved documentation.

2.2.1

Changed

  • SafeConfigurationProxy is now registered as a subclass of Configuration.

  • Updated many doc-strings to improve generated documentation.

2.2.0

Added

  • python -m granular_configuration_language.available_tags is publicly usable now

  • python -m granular_configuration_language.available_plugins

Changed

  • Refactored load_file and make_chain_message to make testing easier

2.1.0

Changed

  • !ParseFile, !OptionalParseFile, and ParseEnv will now actively check if there is a loading loop and throw ParsingTriedToCreateALoop.

    • Previously, this could result in unexpected behaviors, RecursionError, or infinite loops and was not explicitly supported and warned against.

2.0.0

⚠️ Breaking Changes ⚠️

  • YAML Version 1.2 is the default supported version.

    • Reason: Switched from PyYAML to ruamel.yaml, because PyYAML is very dead.

    • yes/no, y/n, on/off is no longer bool

    • Octal support is clearer: 010 means 10, 0o10 means 8.

    • Mitigation: YAML 1.1 support can be explicit enabled by using the %YAML 1.1 --- directive

  • jsonpath-rw cannot be installed aside this library.

    • Reason: Switched from jsonpath-rw to python-jsonpath, because jsonpath-rw is very dead.

      • Both jsonpath-rw and python-jsonpath cannot be installed. jsonpath-rw controls jsonpath_rw and jsonpath modules (despite not explicitly needing the latter). python-jsonpath also controls jsonpath, but looses in jsonpath-rw.

        • ImportError occur on the jsonpath modules when both are installed.

  • Configuration no longer fakes being a subclass of dict.

    • It remains a Mapping.

    • dict inheritance was done for compatible with json.dumps and other libraries that only support the primitive dict, instead of Mapping. However, faking the inheritance has always been sketchy and json.dumps has failed in rare occurrences.

    • Mitigation: Used one of the following methods:

      • json.dumps(config.as_dict())

      • json.dumps(config, default=granular_configuration_language.json_default)

      • config.as_json_string()

  • Configuration is immutable by default now.

    • Configuration and LazyLoadConfiguration are now immutable mappings.

    • Immutable sequences use tuple is used instead of list

    • Mitigation: Use MutableLazyLoadConfiguration in-place of LazyLoadConfiguration.

      • This uses MutableConfiguration instead of Configuration and list for sequences.

      • MutableConfiguration is a subclass of Configuration and MutableLazyLoadConfiguration is a subclass of LazyLoadConfiguration, so any isinstance check can remain as they were.

      • If you need to dynamically set settings at runtime, LazyLoadConfiguration now provides inject_before and inject_after as immutable way of handling this case.

  • Depreciated Features removed:

    • set_config/get_config pattern

    • INI support

    • Configuration patching

    • ConfigurationFiles and ConfigurationMultiNamedFiles classes have been removed. LazyLoadConfiguration only supports paths (e.g. pathlib.Path and str).

      • Mitigation: Just use pathlib.Path or str directly.

  • Renamed Exceptions:

    • ParseEnvErrorParseEnvParsingError

    • ParseEnvEnvironmentVaribleNotFoundEnvironmentVaribleNotFound

    • JSONPathQueryMatchFailedJSONPathQueryFailed

    • JSONPathMustStartFromRootRefMustStartFromRoot

  • Previously, YAML Mappings could not override non-Mappings. This has been changed to be more consistent with merge outcomes being “to merge” or “to replace”.

Changed

  • Switched from PyYAML to ruamel.yaml

    • Note: PyYAML is very dead

    • This primarily means YAML Version 1.2 is the default supported version.

      • yes/no, y/n, on/off is no longer bool

      • Octal support is clearer: 010 means 10, 0o10 means 8.

    • YAML 1.1 support can be explicit enabled by using the %YAML 1.1 --- directive

  • Switched from jsonpath-rw to python-jsonpath

    • Note: jsonpath-rw is very dead

    • Important: Both jsonpath-rw and python-jsonpath cannot be installed. jsonpath-rw controls jsonpath_rw and jsonpath modules (despite not explicitly needing the latter). python-jsonpath also controls jsonpath, but losses in jsonpath-rw.

      • ImportError occur on the jsonpath modules when both are installed.

  • Renamed granular_configuration.yaml_handler module to granular_configuration.yaml

  • Configuration no longer fakes being a subclass of dict.

    • It remains a MutableMapping.

    • dict inheritance was done for compatible with json.dumps and other library that only support the primitive dict, instead of Mapping. However, faking the inheritance has always been sketchy and json.dumps has failed in rare occurrences.

    • json_default is behavior to enable json.dump support.

  • Previously, YAML Mappings could not override non-Mappings. This has been changed to be more consistent with merge outcomes being “to merge” or “to replace”.

  • Renamed Exceptions:

    • ParseEnvErrorParseEnvParsingError

    • ParseEnvEnvironmentVaribleNotFoundEnvironmentVaribleNotFound

    • JSONPathQueryMatchFailedJSONPathQueryFailed

    • JSONPathMustStartFromRootRefMustStartFromRoot

  • (internal detail) LazyEval.run() usage replaced with LazyEval.result

Added

  • Add JSON Pointer support where JSON Path is supported.

  • Added the following tags:

    • Manipulators: !Del, !Merge, !Ref

    • Parsers: !ParseEnvSafe, ParseFile, ParseFileOptional

    • Typers: !Date, !DateTime, !UUID

      • Note: python-dateutil is used for Python 3.10

  • Added Configuration.typed_get

  • Introduced mutable_configuration flag, with immutable as default.

    • Configuration is no longer a MutableMapping, just Mapping.

    • MutableConfiguration has been added to extend back the MutableMapping interface

    • LazyLoadConfiguration no longer provides a MutableMapping interface, just Mapping

    • MutableLazyLoadConfiguration has been added to extend back the MutableMapping interface and remove needing to cast to MutableConfiguration

    • When immutable, tuple is used instead of list

    • LazyLoadConfiguration now provides inject_before and inject_after as immutable way of dynamically setting settings at runtime.

  • Added: JSON Pointer for base_path

  • Added Plugin support for adding external Tags

  • Added G_CONFIG_DISABLE_PLUGINS and G_CONFIG_DISABLE_TAGS as supported environment variables to disable select tags.

  • Added merge to enable multistep configuration loading.

  • Configuration using typing.dataclass_transform to support typed attributes.

    • Configuration.as_typed and LazyLoadConfiguration.as_typed added enable typing.

Fixed

  • (internal detail) Fixed LazyEval making copies of Root

    • Note: Copying with LazyEval still links copies unexpectedly. Now, it is just always connected to the original root (immutability is default now, so only copy immutable configurations).

Removed

  • Removed set_config pattern

  • Removed INI support

  • Completely internalized location logic, removing ConfigurationFiles, ConfigurationMultiNamedFiles. Just use pathlib.Path or str.

1.8.0

Changed

  • Adds !Sub Tag

1.5.0

Changed

  • Adds !ParseEnv Tag

1.4.0

Changed

  • Adds InvalidBasePathException as an exception that can be thrown during the load phase of LazyLoadConfiguration.

    • This subclasses KeyError maintaining compatibility with the state before this exception.

  • LazyLoadConfiguration’s base_path argument now takes a single str in addition to the original typing.Sequence[str]

1.3.1

Changed

  • Adds clear_config

1.3

Changed

  • Adds string path support to LazyLoadConfiguration

  • Adds set_config/get_config pattern

  • Adds Configuration.patch

1.2

Changed

  • Adding INI support

1.1

Changed

  • Adds !Placeholder Tag

  • Makes tags evaluate lazily (i.e. at first use)