diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 950b500..03c419f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,12 +17,12 @@ jobs: python: ["3"] os: ["ubuntu-latest"] include: - - {python: "3.7", os: "ubuntu-22.04"} - - {python: "3.8", os: "ubuntu-22.04"} - {python: "3.9", os: "ubuntu-22.04"} - {python: "3.10", os: "ubuntu-22.04"} - {python: "3.11", os: "ubuntu-22.04"} - {python: "3.12", os: "ubuntu-22.04"} + - {python: "3.13", os: "ubuntu-24.04"} + - {python: "pypy3.10", os: "ubuntu-24.04"} steps: - uses: actions/checkout@v3 - name: "Set up Python ${{ matrix.python }}" @@ -33,7 +33,6 @@ jobs: run: | # python -m pip install --upgrade pip python -m pip install pytest - python -m pip install mock python -m pip install flake8 python -m pip install importlib_metadata python -m pip install "setuptools>=62" @@ -48,7 +47,7 @@ jobs: run: | python -m build --no-isolation pip install dist/dominate*.tar.gz - pytest + pytest --ignore=tests/community - name: Coveralls env: COVERAGE_RCFILE: ".github/workflows/.coveragerc" @@ -56,5 +55,5 @@ jobs: run: | python -m pip install coverage python -m pip install coveralls - coverage run --source=dominate -m pytest + coverage run --source=dominate -m pytest --ignore=tests/community python -m coveralls --service=github || true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9edd348 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,34 @@ + +# 1. Welcome additions + +Anything that is part of the official HTML spec is likely welcome. + +Common patterns of web development, or ease-of-use features are welcome, so long as they are general and are likely to be useful to a broad group and not targetting any specific implimentation. + +## 1.1. Testing + +All PRs must have 100% test coverage of new code. + +New features should include example usage, including motivations. + + + +# 2. Not interested + +For exceptions to these, see #Community + +## 2.2. No 3rd party dependencies + +Do not add 3rd party dependencies. + +## 2.3. No 3rd party integrations + +I am not interested in maintaining integrations with a bunch of random JS/web frameworks/libraries. (i.e. HTMX, Flask, Unpoly, whatever) + + +# 3. Community Packages + +If you wish to add a feature that would otherwise be disallowed by the above, you can make a community package. See `community/htmx.py` for a trivial example. + +Community packages must not be referenced from the main library, and must not do anything unless explicitly imported. + diff --git a/Makefile b/Makefile index 1fe0cc0..2c91660 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ test: - -python2 -m pytest . + python3 -m pytest . --ignore=tests/community + +test-community: python3 -m pytest . publish_old: clean test diff --git a/dominate/_version.py b/dominate/_version.py index b03f5b5..4eb28e3 100644 --- a/dominate/_version.py +++ b/dominate/_version.py @@ -1 +1 @@ -__version__ = '2.9.1' +__version__ = '3.0.0' diff --git a/dominate/community/htmx.py b/dominate/community/htmx.py new file mode 100644 index 0000000..79c70b1 --- /dev/null +++ b/dominate/community/htmx.py @@ -0,0 +1,12 @@ + +from .. import tags + +class HtmxTag: + @classmethod + def clean_attribute(cls, attribute): + attribute = super().clean_attribute(attribute) + if attribute.startswith('hx_'): + attribute = attribute.replace('_', '-') + return attribute + +tags.html_tag.__bases__ = (HtmxTag,) + tags.html_tag.__bases__ diff --git a/dominate/dom_tag.py b/dominate/dom_tag.py index 44ca8ba..dfb6006 100644 --- a/dominate/dom_tag.py +++ b/dominate/dom_tag.py @@ -441,7 +441,7 @@ def clean_attribute(attribute): }.get(attribute, attribute) # Workaround for Python's reserved words - if attribute[0] == '_': + if attribute[0] == '_' and len(attribute) > 1: attribute = attribute[1:] # Workaround for dash diff --git a/tests/community/test_htmx.py b/tests/community/test_htmx.py new file mode 100644 index 0000000..bd0ccd2 --- /dev/null +++ b/tests/community/test_htmx.py @@ -0,0 +1,7 @@ + +from dominate import tags +import dominate.community.htmx + +def test_hx(): + d = tags.div(hx_foo=1) + assert d.render() == '
' diff --git a/tests/test_document.py b/tests/test_document.py index 741f3d1..9f7778d 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -1,6 +1,7 @@ from dominate import document from dominate.tags import * + def test_doc(): d = document() assert d.render() == \ diff --git a/tests/test_dom_tag.py b/tests/test_dom_tag.py index 00dcc9f..3fda86f 100644 --- a/tests/test_dom_tag.py +++ b/tests/test_dom_tag.py @@ -1,8 +1,5 @@ import pytest -try: - import mock -except ImportError: - import unittest.mock as mock +import unittest.mock as mock from dominate.tags import * diff --git a/tests/test_dom_tag_async.py b/tests/test_dom_tag_async.py index 648f9c8..92c2438 100644 --- a/tests/test_dom_tag_async.py +++ b/tests/test_dom_tag_async.py @@ -1,8 +1,9 @@ from asyncio import gather, run, Semaphore -from dominate.dom_tag import async_context_id from textwrap import dedent from dominate import tags +from dominate.dom_tag import async_context_id + # To simulate sleep without making the tests take a hella long time to complete # lets use a pair of semaphores to explicitly control when our coroutines run. @@ -28,7 +29,7 @@ async def merge(): sem_1 = Semaphore(0) sem_2 = Semaphore(0) return await gather( - tag_routine_1(sem_1, sem_2), + tag_routine_1(sem_1, sem_2), tag_routine_2(sem_1, sem_2) ) @@ -67,7 +68,7 @@ async def merge(): """).strip() - + assert tag_2 == dedent("""\goodbye cruel world
''' - + assert p('my 1', sup('st'), ' PR').render() == \ '''my 1st PR
''' diff --git a/tests/test_svg.py b/tests/test_svg.py index ea7d98f..6e06b49 100644 --- a/tests/test_svg.py +++ b/tests/test_svg.py @@ -4,8 +4,6 @@ from dominate.tags import * from dominate.svg import * -import pytest - def base(): return svg(