Changelog

All notable changes to the dictIO project will be documented in this file.
The changelog format is based on Keep a Changelog.

Unreleased

  • -/-

0.4.3 - 2026-02-22

Solved

  • Resolved an issue where attributes in XML nodes, which had an empty string as value, were omitted. The XmlParser and XmlFormatter classes have now been improved to correctly parse and format attributes that have an empty string as value.

Changed

  • GitHub Workflows:

    • Added ‘name: Checkout code’ to uses of ‘actions/checkout’, for better readability and consistency across workflow files.

    • Added ‘name: Download build artifacts’ to uses of ‘actions/download-artifact’, for better readability and consistency across workflow files.

    • Added ‘name: Publish to PyPI’ to uses of ‘pypa/gh-action-pypi-publish’, for better readability and consistency across workflow files.

    • Added ‘name: Upload build artifacts’ to uses of ‘actions/upload-artifact’, for better readability and consistency across workflow files.

    • Changed ‘uv sync –upgrade’ to ‘uv sync -U’

    • Ensured that actions ‘upload-artifact’ and ‘download-artifact’ uniformly specify ‘dist’ as (file)name for the artifact uploaded (or downloaded, respectively), for consistency across workflow files.

    • pull_request_to_main.yml and nightly_build.yml: Added ‘workflow_dispatch:’ in selected workflows to allow manual trigger of the workflow.

    • Removed redundant ‘Set up Python’ steps (no longer needed, as ‘uv sync’ will automatically install Python if not present).

    • Replaced ‘Build source distribution and wheel’ with ‘Build source distribution and wheels’ (plural) in workflow step names.

    • Replaced ‘Run twine check’ with ‘Check build artifacts’ in workflow step names, to better reflect the purpose of the step.

    • Updated the syntax used for the OS and Python matrix in test workflows.

  • pyproject.toml:

    • Removed leading carets and trailing slashes from ‘exclude’ paths

    • Removed upper version constraint from required Python version, i.e. changed the “requires-python” field from “>= 3.11, < 3.15” to “>= 3.11”.
      Detailed background and reasoning in this good yet long post by Henry Schreiner: https://iscinumpy.dev/post/bound-version-constraints/#pinning-the-python-version-is-special
      TLDR: Placing an upper Python version constraint on a Python package causes more harm than it provides benefits. The upper version constraint unnecessarily manifests incompatibility with future Python releases. Removing the upper version constraint ensures the package remains installable as Python evolves. In the majority of cases, the newer Python version will anyhow be backward-compatible. And in the rare case where your package would really not work with a newer Python version, users can at least find a solution manually to resolve the conflict, e.g. by pinning your package to the last version compatible with the environment they install it in. That way, we ensure it remains possible for users to find a solution, instead of rendering it impossible forever.

  • Sphinx Documentation:

    • Sphinx conf.py: Updated year in copyright statement to 2026

  • VS Code Settings:

    • Recommended extensions:

      • Removed ‘njqdev.vscode-python-typehint’ (Python Type Hint). Not maintained since 1 year, and the functionality is now covered by GitHub Copilot.

      • Added ‘ms-python.debugpy’ (Python Debugger).

      • Added ‘ms-python.vscode-python-envs’ (Python Environments).

      • Removed deprecated IntelliCode extension and replaced it by GitHub Copilot Chat as recommended replacement.

    • Updated ‘mypy-type-checker.reportingScope’ to ‘custom’.

  • README.md: Updated year in copyright statement to 2026

  • ruff.toml: Updated target Python version to “py311”

Dependencies

  • .pre-commit-config.yaml: Updated rev of ruff-pre-commit to v0.15.1

  • Updated to furo>=2025.12

  • Updated to jsonschema>=4.26

  • Updated to jupyter-client>=8.8

  • Updated to jupyter>=1.1.1

  • Updated to mypy>=1.19.1

  • Updated to myst-parser>=5.0

  • Updated to nbconvert>=7.17

  • Updated to pre-commit>=4.5

  • Updated to pyright>=1.1.408

  • Updated to pytest>=9.0

  • Updated to ruff>=0.15.1

  • Updated to sourcery>=1.43.0

  • Updated to sphinx-argparse-cli>=1.20.1

  • Updated to sphinx-autodoc-typehints>=3.6

  • Updated to sphinx>=9.0

  • Updated to sphinxcontrib-mermaid>=2.0

  • Updated to types-lxml>=2026.1

0.4.2 - 2025-11-06

Added

  • Added support for Python 3.14

Removed

  • Removed support for Python 3.10

Dependencies

  • Updated to ruff>=0.14.3 (from ruff>=0.9.2)

  • Updated to pyright>=1.1.407 (from pyright>=1.1.392)

  • Updated to sourcery>=1.40 (from sourcery>=1.31)

  • Updated to lxml>=6.0 (from lxml>=5.3)

  • Updated to types-lxml>=2025.8 (from types-lxml>=2024.12)

  • Updated to numpy>=2.3 (removed split version specifiers)

  • Updated to pytest>=8.4 (from pytest>=8.3)

  • Updated to pytest-cov>=7.0 (from pytest-cov>=6.0)

  • Updated to Sphinx>=8.2 (from Sphinx>=8.1)

  • Updated to sphinx-argparse-cli>=1.20 (from sphinx-argparse-cli>=1.19)

  • Updated to sphinx-autodoc-typehints>=3.5 (from sphinx-autodoc-typehints>=3.0)

  • Updated to furo>=2025.9 (from furo>=2024.8)

  • Updated to pre-commit>=4.3 (from pre-commit>=4.0)

  • Updated to mypy>=1.18 (from mypy>=1.14)

  • Updated to checkout@v5 (from checkout@v4)

  • Updated to setup-python@v6 (from setup-python@v5)

  • Updated to setup-uv@v7 (from setup-uv@v5)

  • Updated to upload-artifact@v5 (from upload-artifact@v4)

  • Updated to download-artifact@v5 (from download-artifact@v4)

Changed

  • Do not run code quality checks in nightly builds

  • Included uv.lock file in version control

  • pyproject.toml:

    • added required-environments to uv.tools (windows, linux, macos)

    • updated required Python version to “>= 3.11, < 3.15”

    • updated supported Python versions to 3.11, 3.12, 3.13, 3.14

    • removed deprecated pyright setting ‘reportShadowedImports’

    • removed deprecated mypy plugin ‘numpy.typing.mypy_plugin’

  • GitHub workflow _test.yml:

    • updated Python versions in test matrix to 3.11, 3.12, 3.13, 3.14

  • GitHub workflow _test_future.yml:

    • updated Python version in test_future to 3.15.0-alpha - 3.15.0

  • .pre-commit-config.yaml:

    • updated rev of pre-commit-hooks to v6.0.0

    • updated rev of ruff-pre-commit to v0.14.3

    • updated id of ruff to ruff-check

  • Sphinx conf.py:

    • removed ruff rule exception on file level

  • demos\folder_for_demos.py:

    • removed ruff rule exception

  • .sourcery.yaml:

    • updated the lowest Python version the project supports to ‘3.11’

Solved

  • Resolved issues raised by ruff 0.14.3

0.4.1 - 2025-01-18

Added

  • Added support for Python 3.13

  • Added CITATION.cff

  • pyproject.toml : Added keywords

Solved

  • Resolved issues raised by ruff 0.9.2

Dependencies

  • Updated to ruff>=0.9.2 (from ruff>=0.6.3)

  • Updated to pyright>=1.1.392 (from pyright>=1.1.378)

  • Updated to sourcery>=1.31 (from sourcery>=1.22)

  • Updated to types-lxml>=2024.12 (from types-lxml>=2024.4)

  • Updated to sphinx-autodoc-typehints>=3.0 (from sphinx-autodoc-typehints>=2.2)

  • Updated to mypy>=1.14 (from mypy>=1.13)

  • Updated to setup-uv@v5 (from setup-uv@v2)

  • Updated to lxml>=5.3 (from lxml>=5.2)

  • Updated to jupyter>=1.1 (from jupyter>=1.0)

  • Updated to pytest-cov>=6.0 (from pytest-cov>=5.0)

  • Updated to Sphinx>=8.1 (from Sphinx>=8.0)

  • Updated to sphinx-argparse-cli>=1.19 (from sphinx-argparse-cli>=1.17)

  • Updated to pre-commit>=4.0 (from pre-commit>=3.8)

  • Updated to mypy>=1.14 (from mypy>=1.11.1)

  • numpy: As Python 3.13 requires numpy 2.x, made minimum required numpy version in pyproject.toml dependent on Python version:

    • “numpy>=1.26; python_version < ‘3.13’”,

    • “numpy>=2.2; python_version >= ‘3.13’”,

0.4.0 - 2024-11-11

Breaking changes

  • Renamed modules: Following modules have been renamed in order to comply with PEP8 naming conventions:
    dictIO.dictReader -> dictIO.dict_reader
    dictIO.dictWriter -> dictIO.dict_writer
    dictIO.dictParser -> dictIO.dict_parser
    dictIO.cppDict -> dictIO.cpp_dict

  • Module formatter.py :
    Renamed Formatter.format_type() -> Formatter.format_value()

  • Module parser.py :
    Renamed Parser.parse_type() -> Parser.parse_value()
    Renamed Parser.parse_types() -> Parser.parse_values()

  • class CppDict in module dictIO.cppDict has been replaced with the new class SDict[K, V] in module dictIO.dict.
    In order to maintain backward compatibility, a thin wrapper class named CppDict is kept in version ~0.4.0. It is marked as deprecated, though, and will be removed with release 0.5.0.

  • Where CppDict inherited from UserDict, SDict inherits directly from Python’s dict class, allowing to use it in any context where a dict or any other MutableMapping is expected.

  • SDict is generic: Static type checkers will hence require type arguments when SDict is used.
    Where in dictIO < 0.4.0 you could write
    my_dict: CppDict = CppDict(),
    you will now need to specify the type arguments, e.g.
    my_dict: SDict[str, Any] = SDict().
    With this change, type hinting is in line with how Python’s builtin dict class works, and offers more control in static type checking.

Changed

  • Changed from pip/tox to uv as package manager

  • README.md : Completely rewrote section “Development Setup”, introducing uv as package manager.

  • Changed publishing workflow to use OpenID Connect (Trusted Publisher Management) when publishing to PyPI

  • Updated copyright statement

  • VS Code settings: Turned off automatic venv activation

  • Replaced black formatter with ruff formatter

Solved

  • Sphinx documentation: Resolved issue that documentation of class members was generated twice.

Added

  • Sphinx documentation: Added extension to support Markdown-based diagrams created with Mermaid.

  • Added instance methods dump() and load() to SDict

  • Added mypy as static type checker (in addition to pyright)

GitHub workflows

  • (all workflows): Adapted to use uv as package manager

  • _test_future.yml : updated Python version to 3.13.0-alpha - 3.13.0

  • _test_future.yml : updated name of test job to ‘test313’

Dependencies

  • Updated to ruff>=0.6.3 (from ruff==0.4.2)

  • Updated to pyright>=1.1.378 (from pyright==1.1.360)

  • Updated to sourcery>=1.22 (from sourcery==1.16)

  • Updated to pytest>=8.3 (from pytest>=8.2)

  • Updated to Sphinx>=8.0 (from Sphinx>=7.3)

  • Updated to sphinx-argparse-cli>=1.17 (from sphinx-argparse-cli>=1.16)

  • Updated to myst-parser>=4.0 (from myst-parser>=3.0)

  • Updated to furo>=2024.8 (from furo>=2024.5)

  • updated to setup-python@v5 (from setup-python@v4)

  • updated to actions-gh-pages@v4 (from actions-gh-pages@v3)

  • updated to upload-artifact@v4 (from upload-artifact@v3)

  • Updated to download-artifact@v4 (from download-artifact@v3)

  • updated to checkout@v4 (from checkout@v3)

0.3.4 - 2024-05-22

Dependencies

  • updated to ruff==0.4.2 (from ruff==0.2.1)

  • updated to pyright==1.1.360 (from pyright==1.1.350)

  • updated to sourcery==1.16 (from sourcery==1.15)

  • updated to lxml>=5.2 (from lxml>=5.1)

  • updated to types-lxml>=2024.4 (from types-lxml>=5.1)

  • updated to pytest>=8.2 (from pytest>=7.4)

  • updated to pytest-cov>=5.0 (from pytest-cov>=4.1)

  • updated to Sphinx>=7.3 (from Sphinx>=7.2)

  • updated to sphinx-argparse-cli>=1.15 (from sphinx-argparse-cli>=1.11)

  • updated to myst-parser>=3.0 (from myst-parser>=2.0)

  • updated to furo>=2024.4 (from furo>=2023.9.10)

  • updated to numpy>=1.26,<2.0 (from numpy>=1.26)

  • removed black

Changed

  • replaced black formatter with ruff formatter

  • Changed publishing workflow to use OpenID Connect (Trusted Publisher Management) when publishing to PyPI

  • Updated copyright statement

  • VS Code settings: Turned off automatic venv activation

0.3.3 - 2024-02-21

Hotfix

  • corrected name of cli script (wrong: dictIO correct: dictParser)

0.3.2 - 2024-02-21

Added

  • README.md : Under Development Setup, added a step to install current package in “editable” mode, using the pip install -e option. This removes the need to manually add /src to the PythonPath environment variable in order for debugging and tests to work.

Removed

  • VS Code settings: Removed the setting which added the /src folder to PythonPath. This is no longer necessary. Installing the project itself as a package in “editable” mode, using the pip install -e option, solves the issue and removes the need to manually add /src to the PythonPath environment variable.

Changed

  • Moved all project configuration from setup.cfg to pyproject.toml

  • Moved all tox configuration from setup.cfg to tox.ini.

  • Moved pytest configuration from pyproject.toml to pytest.ini

  • Deleted setup.cfg

Dependencies

  • updated to black[jupyter]==24.1 (from black[jupyter]==23.12)

  • updated to version: ‘==24.1’ (from version: ‘==23.12’)

  • updated to ruff==0.2.1 (from ruff==0.1.8)

  • updated to pyright==1.1.350 (from pyright==1.1.338)

  • updated to sourcery==1.15 (from sourcery==1.14)

  • updated to lxml>=5.1 (from lxml>=4.9)

0.3.1 - 2024-01-09

Solved

  • Solved a bug that led to single character references not being identified (solves #14).

0.3.0 - 2024-01-08

Changed

  • Enabled recognition of strings with nested quotes in it (solves #2)

  • GitHub workflows: Included Python 3.12 release version as standard, and Python 3.13.0a2 as “future” test.

Dependencies

  • updated to black[jupyter]==23.12 (from black[jupyter]==23.11)

  • updated to ruff==0.1.8 (from ruff==0.1.6)

  • updated to pyright==1.1.338 (from pyright==1.1.336)

0.2.9 - 2023-09-20

Dependencies

  • Updated dependencies to latest versions

0.2.8 - 2023-06-22

Changed

  • Modularized GitHub workflows

  • Changed default Python version in GitHub workflows from 3.10 to 3.11

Dependencies

  • requirements-dev.txt: Updated dependencies to latest versions

0.2.7 - 2023-05-04

Changed

  • dependencies: updated dependencies to latest versions

  • ruff: added rule-set “B” (flake8-bugbear)

0.2.6 - 2023-01-11

Changed

  • Added missing DocStrings for public classes, methods and functions

  • Changed links to package documentation to open README.html, not the default index page

0.2.5 - 2023-01-04

Changed

  • Linter: Migrated from flake8 to ruff.
    (Added ruff; removed flake8 and isort)

  • Adjusted GitHub CI workflow accordingly.
    (Added ruff job; removed flake8 and isort jobs)

  • VS Code settings: Adjusted Pylance configuration

  • Sphinx documentation: Rebuilt API documentation

Added

  • Added a batch file ‘qa.bat’ in root folder to ease local execution of code quality checks

0.2.4 - 2022-12-12

Changed

  • Moved dev-only dependencies from requirements.txt to requirements-dev.txt

  • dictIO/__utils__.py : ensured that imported symbols get also exported
    (added “as” clause -> “from x import y as y” instead of only “from x import y”)

  • Configured code quality tools flake8, black, isort, pyright

  • Improved code quality, resolving all warnings and errors flagged by the configured code quality tools (flake8, black, isort, pyright, sourcery)

Added

  • Added support for selected numpy functions (diag, eye, ones, zeros) which can now be used in expressions.
    This is an experimental feature which might be removed or changed in future.

  • Added GitHub workflow ‘main.yml’ for continuous integration (runs all CI tasks except Sphinx)

    • format checks: black, isort

    • lint check: flake8, flake8-bugbear

    • type check: pyright

    • test: uses tox to run pytest on {Windows, Linux, MacOS} with {py39, py310}

    • publish: publishing to PyPI (runs only on push of new tag vx.x.x, and after all other jobs succeeded)

    • merge_to_release_branch: merge tagged commit to release branch (runs after publish)

0.2.3 - 2022-12-01

Changed

  • Code formatting: Changed from yapf to black

  • STYLEGUIDE.md : Adjusted to match black formatting

  • VS Code settings: Updated to use black as formatter

  • requirements.txt: Updated dependencies to their most recent versions

  • GitHub actions (yml files): Updated following actions to their most recent versions:

    • checkout@v1 -> checkout@v3

    • setup-python@v2 -> setup-python@v4

    • cache@v2 -> cache@v3

Added

  • Added sourcery configuration (.sourcery.yaml)

  • Added py.typed file into the package root folder and included it setup.cfg as package_data

  • Documentation: Included sub-package dictIO.utils in documentation

0.2.2 - 2022-11-08

Added

  • JsonParser: JsonParser now supports the usage of references and expressions, similar to the CppParser.

0.2.1 - 2022-10-13

Solved

  • XmlParser: Solved a bug where default namespaces in an XML file would not be parsed correctly.

0.2.0 - 2022-09-29

Added

  • dictIO.utils.path.py: Added two new functions

    • highest_common_root_folder(paths)

    • relative_path(from_path, to_path)

Changed

  • Replaced usages of pathlib.Path.resolve_to() with dictIO.utils.path.relative_path()

Removed

  • dictIO.utils.path.py: Removed obsolete function silent_remove()

0.1.2 - 2022-09-27

Solved

  • XmlParser: Changed how empty XML nodes get parsed.
    The value for an empty node is now saved as an empty dict, i.e. {}, instead of None. This change solves issue #4.
    Problem was that None is not iterable, and code such as the following had caused an exception:

    if '_attributes' in my_parsed_xml_dict[node_key]:
        ...
    

    because my_parsed_xml_dict[node_key] had been None.

    Now, with the code change in place, my_parsed_xml_dict[node_key] would resolve to an empty dict ( {} ) instead of to None. As a dict is formally iterable (even when empty), querying code as above does no longer crash.

0.1.1 - 2022-08-19

Added

  • cppDict:

    • Added method include(dict_to_include). This method adds an include directive for the passed in dict inside the dict the method is called on.

0.1.0 - 2022-05-28

Changed

  • Simplified imports from namespace dictIO. Example:

    • Old (<= v0.0.22):

      from dictIO.dictParser import DictParser
      
    • New:

      from dictIO import DictParser
      
  • parser.py

    • Parser.remove_quotes_from_string()

      • Changed default of ‘all’ argument from True to False
        This change was introduced in order to, by default, protect inner quotes in i.e. a farn filter expression “var in [‘item1’, ‘item2’]” from being removed.

    • CppParser._parse_tokenized_dict()

      • Changed implementation of the conditional code where a key value pair gets parsed.
        This change was introduced in order to better identify invalid key value pairs.
        Two invalid keys were added in test_parser_dict (section ‘invalid’) and a respective test was added.

  • formatter.py

    • JsonFormatter.insert_includes()

      • Changed correction of backslashes, so that backslashes in include paths are not substituted by forwardslashes but actually escaped in Json compliant way.

  • dictWriter.py

    • DictWriter.write()

      • Changed default of ‘mode’ argument from ‘w’ (overwrite) to ‘a’ (append)

  • utils\strings.py

    • plural() function moved to farn package (-> moved into utils\logging.py module in farn)
      It was moved since the plural() function is currently used in farn logging only (neither in dictIO nor in ospx).

0.0.22 - 2022-05-09

  • First public release

0.0.17 - 2022-02-14

Added

  • Added support for Python 3.10