diff --git a/CHANGELOG.md b/CHANGELOG.md index ce9e9ca..bc5f771 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ What changed for someone using zig-hocon: the Zig package, the `hocon` command line tool, libhocon for C and the `zig-hocon` Python package, which are released together under one version. The technical detail is in the commits each release links to. +## [Unreleased] + +### Added + +- Python: `zig_hocon.pyhocon`, pyhocon's API over zig-hocon, so moving over is a change of import. Its modules, names, arguments and output are pyhocon 0.3.63's: the tree an `OrderedDict` with `get`, `put`, `pop`, `with_fallback` and `get_list`, `ConfigFactory.parse_URL` and `from_dict`, `HOCONConverter`, and the command line as `python -m zig_hocon.pyhocon.tool`. `30s` is a `timedelta` (a `relativedelta` with python-dateutil) and `0024` the number 24, as in pyhocon. pyhocon's own syntax reads as in pyhocon: `x += [3, 4]` extends a list, `include "conf.d/*.conf"`, `include package(…)` and an include in a list work, and a syntax error is pyparsing's `ParseException` too when pyparsing is installed; the rest reads by the spec. pyhocon's own test suite passes 303 of 308 with the import swapped, and `python/MIGRATING.md` says what the rest are. Parts of it are changed from pyhocon's code and stay under its Apache License 2.0, so the package's license is `BSD-3-Clause AND Apache-2.0`, with both texts in the wheel. + +### Fixed + +- Python: the wheels have `py.typed`, which `pip install python/` had and the release wheels did not, so a type checker reads the package's types. + ## [0.5.3] - 2026-10-26 ### Changed diff --git a/README.md b/README.md index 1ecb107..8c807eb 100644 --- a/README.md +++ b/README.md @@ -216,7 +216,7 @@ b.step("check-config", "Check the config against Config").dependOn(&check.step); | py.hocon hocon-parser 1.14.2 (Python) | 72.1% (398/552) | 70.1% (387/552) | | pyhocon pyhocon 0.3.63 | 63.8% (352/552) | 59.8% (330/552) | | rs.hocon hocon-parser 1.14.2 (Rust) | 72.1% (398/552) | 69.6% (384/552) | -| zig-hocon zig-hocon code@bb9d8e4 | 100% (552/552) | 83.0% (458/552) | +| zig-hocon zig-hocon code@c6118dd | 100% (552/552) | 83.0% (458/552) | The table keeps the best parsers; the others measured, and why they are not in it: [conformance/README.md](conformance/README.md#not-in-the-table). @@ -253,4 +253,4 @@ If you need a HOCON feature that is not there, open a pull request; a failing te ## License -BSD 3-Clause, see [LICENSE](LICENSE). +BSD 3-Clause, see [LICENSE](LICENSE). The Python module `zig_hocon.pyhocon` is changed in parts from [pyhocon](https://github.com/chimpler/pyhocon)'s code and those parts are under pyhocon's Apache License 2.0, in [python/zig_hocon/pyhocon/LICENSE](python/zig_hocon/pyhocon/LICENSE). diff --git a/build.zig b/build.zig index d98bfec..d3c60b0 100644 --- a/build.zig +++ b/build.zig @@ -79,10 +79,13 @@ pub fn build(b: *std.Build) void { // Every line and branch of the package runs, or it fails (`pragma: no // cover` for what no test can reach). `python -m zig_hocon` is left out: // test_main.py runs it as a process, as the conformance adapter does, - // where coverage does not follow. + // where coverage does not follow. dateutil is there for + // zig_hocon.pyhocon's months and years, as pyhocon has them with it, and + // the newest pyhocon for test_pyhocon_compat.py and + // test_pyhocon_signatures.py to hold it against: its next release shows. const python_version = b.option([]const u8, "python", "The Python test-python runs on (default 3.12)") orelse "3.12"; const coverage_file = b.pathFromRoot(".zig-cache/python.coverage"); - const pytest = b.addSystemCommand(&.{ "uv", "run", "--no-project", "--python", python_version, "--with", "pytest", "--with", "coverage", "python", "-m", "coverage", "run", "--branch", "--source=python/zig_hocon", "--omit=python/zig_hocon/__main__.py", "-m", "pytest", "-q", "python/tests" }); + const pytest = b.addSystemCommand(&.{ "uv", "run", "--no-project", "--python", python_version, "--with", "pytest", "--with", "coverage", "--with", "python-dateutil", "--with", "pyhocon", "python", "-m", "coverage", "run", "--branch", "--source=python/zig_hocon", "--omit=python/zig_hocon/__main__.py", "-m", "pytest", "-q", "python/tests" }); pytest.setCwd(b.path(".")); pytest.setEnvironmentVariable("PYTHONPATH", "python"); pytest.setEnvironmentVariable("COVERAGE_FILE", coverage_file); @@ -100,9 +103,19 @@ pub fn build(b: *std.Build) void { mypy.setEnvironmentVariable("PYTHONPATH", "python"); mypy.has_side_effects = true; mypy.step.dependOn(&py_lib.step); - const test_python_step = b.step("test-python", "Run the Python package's tests with coverage, and type check (needs uv)"); + // ruff and ty on the package, as python/pyproject.toml sets them; pinned, + // as a new ruff formats differently. + const ruff_check = b.addSystemCommand(&.{ "uv", "run", "--no-project", "--with", "ruff==0.17.1", "ruff", "check", "python" }); + const ruff_format = b.addSystemCommand(&.{ "uv", "run", "--no-project", "--with", "ruff==0.17.1", "ruff", "format", "--check", "python" }); + const ty = b.addSystemCommand(&.{ "uv", "run", "--no-project", "--with", "ty==0.0.90", "ty", "check", "--project", "python" }); + const test_python_step = b.step("test-python", "Run the Python package's tests with coverage, lint and type check (needs uv)"); test_python_step.dependOn(&coverage.step); test_python_step.dependOn(&mypy.step); + for ([_]*std.Build.Step.Run{ ruff_check, ruff_format, ty }) |run| { + run.setCwd(b.path(".")); + run.has_side_effects = true; + test_python_step.dependOn(&run.step); + } // `zig build wheels`: a wheel for every platform into zig-out/wheels/, // each with libhocon cross-compiled for it, packed by tools/wheel.py. diff --git a/conformance/report.html b/conformance/report.html index 7f9557c..72f263b 100644 --- a/conformance/report.html +++ b/conformance/report.html @@ -130,7 +130,7 @@
Click a card to leave that implementation out of the tables below, and again to bring it back.