Skip to content

Commit

Permalink
Feat/upgrade tox and ci setup (#223)
Browse files Browse the repository at this point in the history
* fix: update the tox settings

* fix: one more attempt at failing builds

* fix: one more attempt at coverage

* fix: issues with tox ini

* fix: one more try

* fix: ci

* fix: another try

* fix: one more try

* fix: update tox to emit junit format for coveralls

* fix: try to get python 3.14 to work

* fix: try to fix tox config

* fix: issues with types

* fix: update pre-commit config
  • Loading branch information
vinitkumar authored Dec 17, 2024
1 parent bf6363d commit 76e2ebf
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 88 deletions.
Binary file added .coverage
Binary file not shown.
35 changes: 24 additions & 11 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,56 @@ jobs:
fail-fast: false
matrix:
python-version: [pypy-3.10, '3.10', '3.11' , '3.12', '3.13']
tox-python-version: ['pypy3.10', 'py310', 'py311' , 'py312', 'py313']
os: [
ubuntu-latest,
windows-latest,
macos-latest,
]
include:
# Add exact version 3.14.0-alpha.0 for ubuntu-latest only
- python-version: '3.14.0-alpha.0'
- python-version: '3.14.0-alpha.1'
tox-python-version: py314-full
os: ubuntu-latest
exclude:
# Exclude other OSes with Python 3.14.0-alpha.0
- python-version: '3.14.0-alpha.0'
- python-version: '3.14.0-alpha.1'
tox-python-version: py314-full
os: windows-latest
- python-version: '3.14.0-alpha.0'
- python-version: '3.14.0-alpha.1'
os: macos-latest
tox-python-version: py314-full

steps:
- uses: actions/[email protected]
- uses: actions/checkout@v4
with:
persist-credentials: false

- name: Set up Python ${{ matrix.python-version }}
uses: actions/[email protected]
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
- name: install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-dependency-glob: requirements-dev.txt

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade -r requirements-dev.txt
pip install .
- name: Test with pytest
run: |
pytest --cov --junitxml=junit.xml
run: uv pip install --system tox tox-uv

- name: Run tox targets for ${{ matrix.python-version }}
run: tox -e ${{matrix.tox-python-version}}

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}

- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/test-results-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}

145 changes: 131 additions & 14 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,14 +1,131 @@
.idea
.tox
*.pyc
json2xml.egg-info
build
*.swp
dist/*
.mypy_cache
.eggs
.DS_Store
venv
.vscode
tests/*.ipynb
junit.xml
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

.idea/
64 changes: 64 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
ci:
autofix_commit_msg: |
ci: auto fixes from pre-commit hooks
for more information, see https://pre-commit.ci
autofix_prs: true
autoupdate_commit_msg: 'ci: pre-commit autoupdate'
autoupdate_schedule: monthly

default_language_version:
python: python3.12

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
- id: check-json
- id: check-merge-conflict
- id: check-symlinks
- id: check-toml
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/tox-dev/pyproject-fmt
rev: v2.5.0
hooks:
- id: pyproject-fmt
- repo: https://github.com/tox-dev/tox-ini-fmt
rev: 1.4.1
hooks:
- id: tox-ini-fmt
- repo: https://github.com/rstcheck/rstcheck
rev: v6.2.4
hooks:
- id: rstcheck
additional_dependencies:
- tomli==2.0.1
- repo: https://github.com/asottile/pyupgrade
rev: v3.19.1
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.10.0
hooks:
- id: black
- repo: https://github.com/adamchainz/blacken-docs
rev: 1.19.1
hooks:
- id: blacken-docs
additional_dependencies:
- black==23.1.0
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
name: isort (python)
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.13.0
hooks:
- id: mypy
additional_dependencies:
- django-stubs==5.0.4
4 changes: 2 additions & 2 deletions json2xml/dicttoxml.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,10 @@ def dict2xml_str(
val_attr: dict[str, str] = item.pop("@attrs", attr) # update attr with custom @attr if exists
rawitem = item["@val"] if "@val" in item else item
if is_primitive_type(rawitem):
if isinstance(rawitem, dict):
subtree = escape_xml(str(rawitem))
if isinstance(rawitem, str):
subtree = escape_xml(rawitem)
else:
subtree = rawitem
else:
# we can not use convert_dict, because rawitem could be non-dict
subtree = convert(
Expand Down
1 change: 1 addition & 0 deletions junit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="81" time="0.212" timestamp="2024-12-17T23:32:51.229976+05:30" hostname="Vinits-MacBook-Pro.local"><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_namespaces" time="0.001" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_xmlns_namespaces" time="0.001" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_xsi_location" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_xsi_xmlns" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_item_wrap_true" time="0.001" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_item_wrap_false" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_flat" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_omit_list" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_val_and_custom_attr" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_ampersand" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_ampsersand_and_attrs" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_list_items_with_attrs" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_make_id" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_get_unique_id" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_key_is_valid_xml" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_get_xml_type" time="0.001" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_is_primitive_type" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_escape_xml" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_wrap_cdata" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_list_parent_elements" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_str_list_header" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_list_headers" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_list_headers_nested" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_list_headers_root" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_no_root" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_root" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_custom_root" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_item_func" time="0.001" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_with_item_func_issue_151" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_issue_151" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dict2xml_attr_type" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_get_xml_type_number" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_convert_datetime" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_basic_conversion" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_with_type_attribute" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_with_custom_attributes" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_valid_key" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_convert_kv_with_cdata" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_convert_kv_with_attr_type" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_make_valid_xml_name_with_invalid_key" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_convert_bool_with_attr_type" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_convert_none_with_attr_type" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_make_valid_xml_name_with_numeric_key" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_escape_xml_with_special_chars" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_get_xml_type_with_sequence" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_get_xml_type_with_none" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_dicttoxml_with_xml_namespaces" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_datetime_conversion" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_list_to_xml_with_primitive_items" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_list_to_xml_with_dict_items" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_list_to_xml_with_mixed_items" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_list_to_xml_with_empty_list" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_list_to_xml_with_special_characters" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_datetime_conversion_with_isoformat" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_date_conversion_with_isoformat" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_datetime_conversion_with_attr_type" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_date_conversion_with_attr_type" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_datetime_conversion_with_custom_attributes" time="0.000" /><testcase classname="tests.test_dict2xml.TestDict2xml" name="test_date_conversion_with_custom_attributes" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_read_from_json" time="0.001" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_read_from_invalid_json" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_read_from_invalid_json2" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_read_from_jsonstring" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_read_from_invalid_string1" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_read_from_invalid_string2" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_read_from_invalid_jsonstring" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_json_to_xml_conversion" time="0.001" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_json_to_xml_empty_data_conversion" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_custom_wrapper_and_indent" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_no_wrapper" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_item_wrap" time="0.001" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_no_item_wrap" time="0.001" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_empty_array" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_attrs" time="0.001" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_dicttoxml_bug" time="0.001" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_bad_data" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_read_boolean_data_from_json" time="0.001" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_read_boolean_data_from_json2" time="0.001" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_dict_attr_crash" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_encoding_pretty_print" time="0.000" /><testcase classname="tests.test_json2xml.TestJson2xml" name="test_encoding_without_pretty_print" time="0.000" /></testsuite></testsuites>
53 changes: 53 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,56 @@
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "json2xml"
version = "5.0.5" # Replace with the dynamic version if needed
description = "Simple Python Library to convert JSON to XML"
readme = "README.rst"
requires-python = ">=3.10"
license = { text = "Apache Software License 2.0" }
keywords = ["json2xml"]
authors = [
{ name = "Vinit Kumar", email = "[email protected]" }
]
classifiers = [
"Development Status :: 6 - Mature",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Natural Language :: English",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Libraries :: Python Modules"
]
dependencies = [
"defusedxml",
"urllib3",
"xmltodict>=0.12.0",
"pytest",
"pytest-cov",
"coverage",
"py",
"setuptools",
]

[project.urls]
Homepage = "https://github.com/vinitkumar/json2xml"

[tool.setuptools.packages.find]
include = ["json2xml"]

[project.optional-dependencies]
test = [
"pytest==7.0.1",
"py==1.11.0"
]

[tool.pytest.ini_options]
testpaths = ["tests"]
[tool.ruff]
exclude = [
".env",
Expand Down
Loading

0 comments on commit 76e2ebf

Please sign in to comment.