Skip to content
Open
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
*.egg-info
__pycache__
*.pyc

uv.lock
.venv
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ include ChangeLog
include INSTALL
include Makefile
include python-config.spec
include README
include README.rst
include tests/*.conf
include tests/*.py
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ build:
$(PYTHON) setup.py build

check:
$(PYTHON) setup.py test
$(PYTHON) -m pytest tests

install:
$(PYTHON) setup.py install --skip-build $(INSTALL_FLAGS)
Expand Down
8 changes: 0 additions & 8 deletions README

This file was deleted.

88 changes: 88 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
A library for reading Python configuration files
================================================

About
-----

This library reads configuration files that are represented as Python modules
with restricted syntax. It uses the AST for parsing.
Values can be written back with ``dump`` and ``dumps``.

Two APIs are available:

* ``python_config.load(s)`` / ``dump(s)`` — read and write a **dict** (lowercase keys).

* ``python_config.document.load(s)`` / ``dump(s)`` — read and write a
:class:`~python_config.document.ConfigDocument`. Use this to change option
values from code and save the file back. Top-level options use uppercase names
(e.g. ``doc["LOG_LEVEL"] = 5``). Nested ``list`` and ``dict`` values are
plain Python objects; in-place mutations are reflected on dump.

Supported value types are:
- ``bool``,
- ``int``,
- ``float``,
- ``str``,
- ``list``,
- ``dict`` (with string keys).

Only **uppercase** names that do not start with ``_`` are exposed through the dict API.

Expressions in source files are **evaluated on load**:

* Arithmetic (e.g. ``COUNT = 1 + 2 * 3``)
* F-strings that reference earlier options (e.g. ``ENDPOINT = f"{HOST}:{PORT}"``)

``dump`` and ``dumps`` always emit **literal values** with aggressive formatting applied.
Hand-edited spacing and expression forms are not preserved on save.

Preamble comments, a module-level docstring, and per-assignment docstrings are
preserved through the document API.

.. NOTE::

If you want to validate the configuration values, take a look at
https://github.com/KonishchevDmitry/object-validator project or just use Pydantic.

Interactive viewer
------------------

A terminal UI is included for browsing large configuration files without scrolling
through thousands of lines in an editor. It loads configs through the document API
so f-strings, arithmetic, and comments are shown as in the source.

.. source:: bash

python-config-view /path/to/config.conf
python -m python_config.viewer /path/to/config.conf

Use ``--page-size`` to control pagination (default 20) and ``--no-color`` for
plain output.

Key bindings:

========== ======================================================
Key Action
========== ======================================================
``/`` Search variables or keys at the current level
``n``/``j`` Next item (or next page at end of page)
``p``/``k`` Previous item (or previous page at start of page)
``Enter`` Open a dict/list child or jump to a search result
``1``-``9`` Quick-select an item on the current page
``b`` Go back (or leave search results)
``s`` Expand the current value full-screen (scroll with ``j``/``n`` and ``k``/``p``)
``a`` Toggle assignment source view (top-level variables only)
``q`` Quit
========== ======================================================

Tests
-----

It's recommended to test against python3.6. Assuming here you have .venv36 for this.

.. source:: bash

poe test

# python 3.6
.venv36/bin/pytest -s -vvv tests/
84 changes: 84 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "python-config"
dynamic = ["version"]
description = "A library for reading Python configuration files"
authors = [
{ name = "Dmitry Konishchev", email = "konishchev@gmail.com" },
]
license = { text = "GPL-3.0" }
readme = "README.rst"

keywords = ["python-syntax", "configuration"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Operating System :: MacOS :: MacOS X",
"Operating System :: POSIX",
"Operating System :: Unix",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: Implementation :: CPython",
]

requires-python = ">=3.9"

dependencies = [
"click>=7,<9",
"rich>=10,<13",
]

[project.scripts]
python-config-view = "python_config.viewer.cli:main"

[project.optional-dependencies]
dev = [
"mypy>=1.19.1",
"poethepoet>=0.32",
"pytest>=8",
"ruff>=0.9",
]

[tool.setuptools.packages.find]
include = ["python_config", "python_config.*"]

[tool.setuptools.dynamic]
version = {file = "version.txt"}

[tool.poe.tasks.format]
help = "Format all the code."
shell = "ruff check --fix --select I python_config/ tests/ && ruff format python_config/ tests/"

[tool.poe.tasks.lint]
help = "Lint all the code."
cmd = "ruff check python_config/ tests/"

[tool.poe.tasks.typecheck]
help = "Typecheck all the code."
cmd = "mypy python_config"

[tool.poe.tasks.test]
help = "Run unit tests."
cmd = "pytest --strict-markers -vvv tests/"

[tool.poe.tasks.ci]
help = "Run full CI sequence."
sequence = [
"format",
"lint",
"typecheck",
"test",
]

[tool.ruff]
line-length = 100

[tool.ruff.lint.isort]
lines-after-imports = 2
26 changes: 20 additions & 6 deletions python-config.spec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

%bcond_without tests

%global project_name pcore
%global project_description %{expand:
Python configuration files themselves are actual Python files. The module
reads only values in uppercase from them, checks that they contain only basic
Expand All @@ -13,8 +12,8 @@ Note: if you want to validate the configuration values, take a look at
https://github.com/KonishchevDmitry/object-validator project.}

Name: python-config
Version: 0.1.2
Release: 4.ROCKIT3%{?dist}
Version: 1.0.0
Release: ROCKIT1%{?dist}
Summary: A simple module for reading Python configuration files

Group: Development/Libraries
Expand All @@ -34,7 +33,17 @@ BuildRequires: python%{python3_pkgversion}-devel
BuildRequires: python%{python3_pkgversion}-setuptools
%if 0%{with tests}
BuildRequires: python%{python3_pkgversion}-pytest >= 2.2.4
BuildRequires: python%{python3_pkgversion}-click
BuildRequires: python%{python3_pkgversion}-rich
%if 0%{?rhel} <= 8
BuildRequires: python3-dataclasses
%endif
%endif # with tests
%if 0%{?rhel} <= 8
Requires: python3-dataclasses
%endif
Requires: python%{python3_pkgversion}-click
Requires: python%{python3_pkgversion}-rich
Obsoletes: python36-config
Conflicts: python36-config

Expand All @@ -59,17 +68,22 @@ make PYTHON=%{__python3} check

%files -n python%{python3_pkgversion}-config
%defattr(-,root,root,-)
%{python3_sitelib}/python_config.py
%{python3_sitelib}/__pycache__/python_config.*.py*
%{_bindir}/python-config-view
%{python3_sitelib}/python_config/
%{python3_sitelib}/python_config/__pycache__/
%{python3_sitelib}/python_config-%{version}-*.egg-info
%doc ChangeLog INSTALL README
%doc ChangeLog INSTALL README.rst


%clean
[ "%buildroot" = "/" ] || rm -rf "%buildroot"


%changelog
* Tue May 19 2026 Pavel Kulyov <kulyov.pavel@gmail.com> - 1.0.0-1
- Version 1.0.0: AST-based config parsing (no exec), add loads/dump/dumps
- Restructure the project splitting single-module, update metadata

* Tue Jan 24 2023 Andrey Kulaev <adkulaev@gmail.com> - 0.1.2-4
- Add centos 8.4 support

Expand Down
Loading