json2xml 6.5.1__tar.gz → 7.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. {json2xml-6.5.1 → json2xml-7.0.1}/CONTRIBUTING.rst +8 -12
  2. {json2xml-6.5.1 → json2xml-7.0.1}/HISTORY.rst +27 -0
  3. {json2xml-6.5.1 → json2xml-7.0.1}/MANIFEST.in +1 -1
  4. {json2xml-6.5.1 → json2xml-7.0.1}/PKG-INFO +18 -22
  5. {json2xml-6.5.1 → json2xml-7.0.1}/README.rst +10 -16
  6. json2xml-7.0.1/docs/benchmarks.rst +480 -0
  7. {json2xml-6.5.1 → json2xml-7.0.1}/docs/conf.py +23 -32
  8. {json2xml-6.5.1 → json2xml-7.0.1}/docs/installation.rst +1 -2
  9. {json2xml-6.5.1 → json2xml-7.0.1}/docs/rust_memory_benchmark.rst +2 -2
  10. {json2xml-6.5.1 → json2xml-7.0.1}/docs/usage.rst +8 -2
  11. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml/__init__.py +1 -1
  12. json2xml-7.0.1/json2xml/backend_selector.py +127 -0
  13. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml/cli.py +21 -12
  14. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml/dicttoxml.py +311 -232
  15. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml/dicttoxml_fast.py +41 -5
  16. json2xml-7.0.1/json2xml/json2xml.py +121 -0
  17. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml/types.py +4 -1
  18. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml/utils.py +8 -7
  19. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml.egg-info/PKG-INFO +18 -22
  20. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml.egg-info/SOURCES.txt +2 -2
  21. json2xml-7.0.1/json2xml.egg-info/requires.txt +15 -0
  22. {json2xml-6.5.1 → json2xml-7.0.1}/pyproject.toml +20 -8
  23. json2xml-7.0.1/setup.cfg +4 -0
  24. {json2xml-6.5.1 → json2xml-7.0.1}/setup.py +0 -1
  25. {json2xml-6.5.1 → json2xml-7.0.1}/tests/conftest.py +8 -0
  26. {json2xml-6.5.1 → json2xml-7.0.1}/tests/test_backend_selector.py +6 -1
  27. {json2xml-6.5.1 → json2xml-7.0.1}/tests/test_benchmark_multi_python.py +24 -3
  28. json2xml-7.0.1/tests/test_benchmark_security_hardening.py +84 -0
  29. {json2xml-6.5.1 → json2xml-7.0.1}/tests/test_cli.py +171 -51
  30. {json2xml-6.5.1 → json2xml-7.0.1}/tests/test_dict2xml.py +129 -109
  31. {json2xml-6.5.1 → json2xml-7.0.1}/tests/test_dicttoxml_fast_fallback.py +59 -5
  32. {json2xml-6.5.1 → json2xml-7.0.1}/tests/test_dicttoxml_unit.py +223 -53
  33. {json2xml-6.5.1 → json2xml-7.0.1}/tests/test_json2xml.py +194 -62
  34. {json2xml-6.5.1 → json2xml-7.0.1}/tests/test_missing_coverage.py +9 -2
  35. {json2xml-6.5.1 → json2xml-7.0.1}/tests/test_rust_dicttoxml.py +84 -33
  36. json2xml-7.0.1/tests/test_rust_python_parity.py +262 -0
  37. {json2xml-6.5.1 → json2xml-7.0.1}/tests/test_utils.py +20 -28
  38. json2xml-6.5.1/docs/benchmarks.rst +0 -203
  39. json2xml-6.5.1/json2xml/backend_selector.py +0 -63
  40. json2xml-6.5.1/json2xml/json2xml.py +0 -83
  41. json2xml-6.5.1/json2xml.egg-info/requires.txt +0 -13
  42. json2xml-6.5.1/requirements.in +0 -3
  43. json2xml-6.5.1/setup.cfg +0 -11
  44. {json2xml-6.5.1 → json2xml-7.0.1}/AUTHORS.rst +0 -0
  45. {json2xml-6.5.1 → json2xml-7.0.1}/LICENSE +0 -0
  46. {json2xml-6.5.1 → json2xml-7.0.1}/docs/Makefile +0 -0
  47. {json2xml-6.5.1 → json2xml-7.0.1}/docs/authors.rst +0 -0
  48. {json2xml-6.5.1 → json2xml-7.0.1}/docs/contributing.rst +0 -0
  49. {json2xml-6.5.1 → json2xml-7.0.1}/docs/history.rst +0 -0
  50. {json2xml-6.5.1 → json2xml-7.0.1}/docs/index.rst +0 -0
  51. {json2xml-6.5.1 → json2xml-7.0.1}/docs/json2xml.rst +0 -0
  52. {json2xml-6.5.1 → json2xml-7.0.1}/docs/make.bat +0 -0
  53. {json2xml-6.5.1 → json2xml-7.0.1}/docs/modules.rst +0 -0
  54. {json2xml-6.5.1 → json2xml-7.0.1}/docs/readme.rst +0 -0
  55. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml.egg-info/dependency_links.txt +0 -0
  56. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml.egg-info/entry_points.txt +0 -0
  57. {json2xml-6.5.1 → json2xml-7.0.1}/json2xml.egg-info/top_level.txt +0 -0
  58. {json2xml-6.5.1 → json2xml-7.0.1}/tests/__init__.py +0 -0
@@ -80,8 +80,7 @@ Ready to contribute? Here's how to set up `json2xml` for local development.
80
80
  $ cd json2xml/
81
81
  $ uv venv
82
82
  $ source .venv/bin/activate
83
- $ uv pip install -r requirements-dev.txt
84
- $ uv pip install -e .
83
+ $ uv pip install -e ".[dev]"
85
84
 
86
85
  4. Create a branch for local development::
87
86
 
@@ -96,7 +95,7 @@ Ready to contribute? Here's how to set up `json2xml` for local development.
96
95
 
97
96
  # Or individually:
98
97
  $ ruff check json2xml tests
99
- $ mypy json2xml tests
98
+ $ uvx ty check json2xml tests
100
99
  $ pytest tests/
101
100
 
102
101
  6. Commit your changes and push your branch to GitHub::
@@ -140,7 +139,7 @@ Install Rust and maturin::
140
139
 
141
140
  ::
142
141
 
143
- $ python benchmark_rust.py
142
+ $ python benchmarks/benchmark_rust.py
144
143
 
145
144
  **Rust Code Structure**
146
145
 
@@ -182,12 +181,9 @@ To run a subset of tests::
182
181
  Deploying
183
182
  ---------
184
183
 
185
- A reminder for the maintainers on how to deploy.
186
- Make sure all your changes are committed (including an entry in HISTORY.rst).
187
- Then run::
188
-
189
- Update the version in pyproject.toml and json2xml/__init__.py
190
- $ git push
191
- $ git push --tags
184
+ A reminder for maintainers on how to deploy:
192
185
 
193
- Travis will then deploy to PyPI if tests pass.
186
+ #. Update the version in ``pyproject.toml`` and ``json2xml/__init__.py``.
187
+ #. Add the release notes to ``HISTORY.rst``.
188
+ #. Run ``make test-all`` and ``make dist``.
189
+ #. Publish the verified artifacts with ``uv publish dist/*``.
@@ -1,4 +1,31 @@
1
1
 
2
+ 7.0.1 / 2026-08-28
3
+ ==================
4
+
5
+ * fix: validate explicitly provided empty ``--string``, ``--url``, and file-path inputs instead of silently falling back to stdin
6
+
7
+
8
+ 7.0.0 / 2026-08-23
9
+ ==================
10
+
11
+ * breaking: make compact UTF-8 ``bytes`` the default public and CLI output; callers that require pretty Unicode text must pass ``pretty=True`` or ``--pretty``
12
+ * fix: normalize the parent name a ``list_headers`` dict member borrows, so a rootless list of dictionaries no longer emits the malformed empty tag ``<>``
13
+ * fix: make the optional Rust backend byte-identical to the Python serializer for every payload it accepts, correcting CDATA on numbers, nested list shapes, list member tag names, ``type="dict"`` under ``list_headers``, and names beginning with ``xml``
14
+ * fix: keep payloads the Rust backend cannot reproduce exactly -- non-JSON-native values, parser-resolved key names, and normalized root names -- on the Python serializer
15
+ * perf: run the Rust backend's payload gate natively, cutting a 1,000-record conversion from 1.51 ms to 0.49 ms
16
+ * fix: enforce conversion output limits from generated UTF-8 bytes instead of rejecting valid payloads with a conservative estimate
17
+ * fix: reject unsupported falsy objects consistently instead of serializing them as null
18
+ * fix: keep public scalar converter attribute dictionaries unchanged
19
+ * perf: validate common ASCII XML attribute names without constructing a DOM
20
+ * fix: serialize date-like values consistently at the root, which previously rejected ``datetime.time`` while accepting it inside dicts and lists
21
+ * refactor: dispatch every element writer through a single type classifier
22
+ * docs: record the string-returning public converters as a retained compatibility surface
23
+ * perf: indent pretty output while serializing instead of re-tokenizing generated XML, roughly halving pretty conversion time and removing the last XML parsing path from the library
24
+ * chore: release ``json2xml-rs`` 0.5.0 first and require it from ``json2xml[fast]`` for parity-safe accelerated installs
25
+ * chore: align local pytest, pre-commit, release, and Rust CI configuration with the supported toolchain
26
+ * chore: move benchmark scripts under ``benchmarks/`` and make ``pyproject.toml`` plus ``uv.lock`` the only dependency declaration
27
+
28
+
2
29
  6.5.1 / 2026-08-05
3
30
  ==================
4
31
 
@@ -3,7 +3,7 @@ include CONTRIBUTING.rst
3
3
  include HISTORY.rst
4
4
  include LICENSE
5
5
  include README.rst
6
- include requirements.in
6
+ include pyproject.toml
7
7
  recursive-include tests *
8
8
  recursive-exclude * __pycache__
9
9
  recursive-exclude * *.py[co]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: json2xml
3
- Version: 6.5.1
3
+ Version: 7.0.1
4
4
  Summary: Simple Python Library to convert JSON to XML
5
5
  Author-email: Vinit Kumar <mail@vinitkumar.me>
6
6
  License: Apache Software License 2.0
@@ -26,13 +26,15 @@ Requires-Dist: defusedxml
26
26
  Requires-Dist: urllib3>=2.7.0
27
27
  Provides-Extra: dev
28
28
  Requires-Dist: pytest>=8.4.1; extra == "dev"
29
- Requires-Dist: pytest-cov; extra == "dev"
30
- Requires-Dist: coverage; extra == "dev"
31
- Requires-Dist: setuptools; extra == "dev"
29
+ Requires-Dist: pytest-cov>=7.1.0; extra == "dev"
30
+ Requires-Dist: pytest-xdist>=3.8.0; extra == "dev"
31
+ Requires-Dist: coverage>=7.15.4; extra == "dev"
32
+ Requires-Dist: ruff>=0.16.3; extra == "dev"
33
+ Requires-Dist: setuptools>=80.9.0; extra == "dev"
32
34
  Requires-Dist: pygments>=2.20.0; extra == "dev"
33
- Requires-Dist: xmltodict>=0.12.0; extra == "dev"
35
+ Requires-Dist: xmltodict>=0.14.2; extra == "dev"
34
36
  Provides-Extra: fast
35
- Requires-Dist: json2xml-rs>=0.4.3; extra == "fast"
37
+ Requires-Dist: json2xml-rs>=0.5.0; extra == "fast"
36
38
  Dynamic: license-file
37
39
 
38
40
  .. image:: ./json2xml-hero.png
@@ -295,7 +297,11 @@ boolean ``True`` or choose a smaller limit:
295
297
  Custom Wrappers and Indentation
296
298
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
297
299
 
298
- By default, a wrapper `all` and pretty `True` is set. However, you can easily change this in your code like this:
300
+ By default, a wrapper `all` and compact output (``pretty=False``) are set. Pretty printing can be enabled explicitly:
301
+
302
+ Conversions also default to a nesting limit of 100, an item limit of 100,000,
303
+ and a 10 MiB XML output limit. Pass ``max_depth``, ``max_items``, or
304
+ ``max_output_bytes`` to choose smaller budgets for untrusted workloads.
299
305
 
300
306
  .. code-block:: python
301
307
 
@@ -449,8 +455,7 @@ This project uses modern Python development practices. Here's how to set up a de
449
455
  source .venv/bin/activate # On Windows: .venv\Scripts\activate
450
456
 
451
457
  # Install dependencies
452
- uv pip install -r requirements-dev.txt
453
- uv pip install -e .
458
+ uv pip install -e ".[dev]"
454
459
 
455
460
  **Running Tests and Checks**
456
461
 
@@ -462,25 +467,16 @@ Using Make (recommended):
462
467
 
463
468
  make test # Run tests with coverage
464
469
  make lint # Run linting with ruff
465
- make typecheck # Run type checking with mypy
470
+ make typecheck # Run type checking with ty
466
471
  make check-all # Run all checks (lint, typecheck, test)
467
472
 
468
- Using the development script:
469
-
470
- .. code-block:: console
471
-
472
- python dev.py # Run all checks
473
- python dev.py test # Run tests only
474
- python dev.py lint # Run linting only
475
- python dev.py typecheck # Run type checking only
476
-
477
473
  Using tools directly:
478
474
 
479
475
  .. code-block:: console
480
476
 
481
477
  pytest --cov=json2xml --cov-report=term -xvs tests -n auto
482
478
  ruff check json2xml tests
483
- mypy json2xml tests
479
+ uvx ty check json2xml tests
484
480
 
485
481
  **Rust Extension Development**
486
482
 
@@ -515,7 +511,7 @@ Running Rust benchmarks:
515
511
  .. code-block:: console
516
512
 
517
513
  # After building the extension
518
- python benchmark_rust.py
514
+ python benchmarks/benchmark_rust.py
519
515
 
520
516
  The Rust code is in ``rust/src/lib.rs`` and uses PyO3 for Python bindings.
521
517
 
@@ -565,7 +561,7 @@ The ``json2xml-py`` command-line tool provides an easy way to convert JSON to XM
565
561
  Conversion Options:
566
562
  -w, --wrapper string Wrapper element name (default "all")
567
563
  -r, --root Include root element (default true)
568
- -p, --pretty Pretty print output (default true)
564
+ -p, --pretty Pretty print output (default false)
569
565
  -t, --type Include type attributes (default true)
570
566
  -i, --item-wrap Wrap list items in <item> elements (default true)
571
567
  -x, --xpath Use XPath 3.1 json-to-xml format
@@ -258,7 +258,11 @@ boolean ``True`` or choose a smaller limit:
258
258
  Custom Wrappers and Indentation
259
259
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
260
260
 
261
- By default, a wrapper `all` and pretty `True` is set. However, you can easily change this in your code like this:
261
+ By default, a wrapper `all` and compact output (``pretty=False``) are set. Pretty printing can be enabled explicitly:
262
+
263
+ Conversions also default to a nesting limit of 100, an item limit of 100,000,
264
+ and a 10 MiB XML output limit. Pass ``max_depth``, ``max_items``, or
265
+ ``max_output_bytes`` to choose smaller budgets for untrusted workloads.
262
266
 
263
267
  .. code-block:: python
264
268
 
@@ -412,8 +416,7 @@ This project uses modern Python development practices. Here's how to set up a de
412
416
  source .venv/bin/activate # On Windows: .venv\Scripts\activate
413
417
 
414
418
  # Install dependencies
415
- uv pip install -r requirements-dev.txt
416
- uv pip install -e .
419
+ uv pip install -e ".[dev]"
417
420
 
418
421
  **Running Tests and Checks**
419
422
 
@@ -425,25 +428,16 @@ Using Make (recommended):
425
428
 
426
429
  make test # Run tests with coverage
427
430
  make lint # Run linting with ruff
428
- make typecheck # Run type checking with mypy
431
+ make typecheck # Run type checking with ty
429
432
  make check-all # Run all checks (lint, typecheck, test)
430
433
 
431
- Using the development script:
432
-
433
- .. code-block:: console
434
-
435
- python dev.py # Run all checks
436
- python dev.py test # Run tests only
437
- python dev.py lint # Run linting only
438
- python dev.py typecheck # Run type checking only
439
-
440
434
  Using tools directly:
441
435
 
442
436
  .. code-block:: console
443
437
 
444
438
  pytest --cov=json2xml --cov-report=term -xvs tests -n auto
445
439
  ruff check json2xml tests
446
- mypy json2xml tests
440
+ uvx ty check json2xml tests
447
441
 
448
442
  **Rust Extension Development**
449
443
 
@@ -478,7 +472,7 @@ Running Rust benchmarks:
478
472
  .. code-block:: console
479
473
 
480
474
  # After building the extension
481
- python benchmark_rust.py
475
+ python benchmarks/benchmark_rust.py
482
476
 
483
477
  The Rust code is in ``rust/src/lib.rs`` and uses PyO3 for Python bindings.
484
478
 
@@ -528,7 +522,7 @@ The ``json2xml-py`` command-line tool provides an easy way to convert JSON to XM
528
522
  Conversion Options:
529
523
  -w, --wrapper string Wrapper element name (default "all")
530
524
  -r, --root Include root element (default true)
531
- -p, --pretty Pretty print output (default true)
525
+ -p, --pretty Pretty print output (default false)
532
526
  -t, --type Include type attributes (default true)
533
527
  -i, --item-wrap Wrap list items in <item> elements (default true)
534
528
  -x, --xpath Use XPath 3.1 json-to-xml format