diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c927a49..716016d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', 'pypy3.7'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', 'pypy3.9'] os: ['ubuntu-latest'] steps: - uses: actions/checkout@v4 @@ -37,3 +37,7 @@ jobs: run: make distcheck - name: Docs build run: rst2html.py README.rst README.html + if: "matrix.python-version == '3.8'" + - name: Docs build + run: rst2html README.rst README.html + if: "matrix.python-version != '3.8'" diff --git a/NEWS b/NEWS index ea01357..7ad9eaf 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,8 @@ IMPROVEMENTS * Add support for Python 3.12 (Matthew Treinish) +* Drop support for Python 3.7 (Jelmer Vernooij) + 1.4.3 (2023-09-17) --------------------- diff --git a/pyproject.toml b/pyproject.toml index 0e5ec12..3ce225b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,67 @@ [build-system] -requires = ["setuptools>=43.0.0"] +requires = ["setuptools>=61.2", "testtools", "iso8601"] build-backend = "setuptools.build_meta" [tool.ruff] line-length = 120 -target-version = "py37" + +[project] +name = "python-subunit" +description = "Python implementation of subunit test streaming protocol" +readme = "README.rst" +classifiers = [ + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Software Development :: Testing", +] +keywords = ["python", "test", "streaming"] +authors = [{name = "Robert Collins", email = "subunit-dev@lists.launchpad.net"}] +license = {text = "Apache-2.0 or BSD"} +dependencies = [ + "iso8601", + "testtools>=0.9.34", +] +requires-python = ">=3.8" +dynamic = ["version"] + +[project.urls] +Homepage = "http://launchpad.net/subunit" +"Bug Tracker" = "https://bugs.launchpad.net/subunit" +"Source Code" = "https://github.com/testing-cabal/subunit/" + +[project.optional-dependencies] +"docs" = ["docutils"] +"test" = ["fixtures", "testscenarios", "hypothesis"] + +[tool.setuptools.packages.find] +where = ["python"] +include = ["subunit*"] + +[project.scripts] +"subunit-1to2" = "subunit.filter_scripts.subunit_1to2:main" +"subunit-2to1" = "subunit.filter_scripts.subunit_2to1:main" +"subunit-filter" = "subunit.filter_scripts.subunit_filter:main" +"subunit-ls" = "subunit.filter_scripts.subunit_ls:main" +"subunit-notify" = "subunit.filter_scripts.subunit_notify:main" +"subunit-output" = "subunit.filter_scripts.subunit_output:main" +"subunit-stats" = "subunit.filter_scripts.subunit_stats:main" +"subunit-tags" = "subunit.filter_scripts.subunit_tags:main" +"subunit2csv" = "subunit.filter_scripts.subunit2csv:main" +"subunit2disk" = "subunit.filter_scripts.subunit2disk:main" +"subunit2gtk" = "subunit.filter_scripts.subunit2gtk:main" +"subunit2junitxml" = "subunit.filter_scripts.subunit2junitxml:main" +"subunit2pyunit" = "subunit.filter_scripts.subunit2pyunit:main" +"tap2subunit" = "subunit.filter_scripts.tap2subunit:main" + +[tool.setuptools.dynamic] +version = {attr = "subunit.version_string"} + +[tool.setuptools] +license-files = ["COPYING"] diff --git a/python/subunit/__init__.py b/python/subunit/__init__.py index 90269ed..189d2bc 100644 --- a/python/subunit/__init__.py +++ b/python/subunit/__init__.py @@ -124,6 +124,7 @@ def test_script_two(self): from io import UnsupportedOperation as _UnsupportedOperation import iso8601 + from testtools import ExtendedToOriginalDecorator, content, content_type from testtools.compat import _b, _u from testtools.content import TracebackContent @@ -153,6 +154,9 @@ def test_script_two(self): __version__ = (1, 4, 4, "final", 0) +version_string = ".".join(map(str, __version__[:3])) + + __all__ = [ "join_dir", "tags_to_new_gone", diff --git a/python/subunit/filter_scripts/subunit2junitxml.py b/python/subunit/filter_scripts/subunit2junitxml.py index 5d45f25..988b6cc 100755 --- a/python/subunit/filter_scripts/subunit2junitxml.py +++ b/python/subunit/filter_scripts/subunit2junitxml.py @@ -16,7 +16,6 @@ """Filter a subunit stream to get aggregate statistics.""" - import sys from testtools import StreamToExtendedDecorator diff --git a/python/subunit/run.py b/python/subunit/run.py index 4a91526..1a89d6d 100755 --- a/python/subunit/run.py +++ b/python/subunit/run.py @@ -17,7 +17,7 @@ """Run a unittest testcase reporting results as Subunit. - $ python -m subunit.run mylib.tests.test_suite +$ python -m subunit.run mylib.tests.test_suite """ import io diff --git a/python/subunit/tests/test_output_filter.py b/python/subunit/tests/test_output_filter.py index 7f165f9..19bed62 100644 --- a/python/subunit/tests/test_output_filter.py +++ b/python/subunit/tests/test_output_filter.py @@ -217,7 +217,7 @@ def test_file_is_sent_in_single_packet(self): ) def test_can_read_binary_files(self): - with temp_file_contents(b"\xDE\xAD\xBE\xEF") as f: + with temp_file_contents(b"\xde\xad\xbe\xef") as f: result = get_result_for([self.option, self.test_id, "--attach-file", f.name]) self.assertThat( @@ -225,7 +225,7 @@ def test_can_read_binary_files(self): MatchesListwise( [ MatchesStatusCall(call="startTestRun"), - MatchesStatusCall(file_bytes=b"\xDE\xAD\xBE\xEF", eof=True), + MatchesStatusCall(file_bytes=b"\xde\xad\xbe\xef", eof=True), MatchesStatusCall(call="stopTestRun"), ] ), @@ -247,7 +247,7 @@ def test_can_read_empty_files(self): ) def test_can_read_stdin(self): - self.patch(_o.sys, "stdin", TextIOWrapper(BytesIO(b"\xFE\xED\xFA\xCE"))) + self.patch(_o.sys, "stdin", TextIOWrapper(BytesIO(b"\xfe\xed\xfa\xce"))) result = get_result_for([self.option, self.test_id, "--attach-file", "-"]) self.assertThat( @@ -255,7 +255,7 @@ def test_can_read_stdin(self): MatchesListwise( [ MatchesStatusCall(call="startTestRun"), - MatchesStatusCall(file_bytes=b"\xFE\xED\xFA\xCE", file_name="stdin", eof=True), + MatchesStatusCall(file_bytes=b"\xfe\xed\xfa\xce", file_name="stdin", eof=True), MatchesStatusCall(call="stopTestRun"), ] ), diff --git a/setup.py b/setup.py index a42d0fc..229b2eb 100755 --- a/setup.py +++ b/setup.py @@ -1,90 +1,5 @@ #!/usr/bin/env python3 -import os.path - from setuptools import setup - -def _get_version_from_file(filename, start_of_line, split_marker): - """Extract version from file, giving last matching value or None""" - try: - return [x for x in open(filename) if x.startswith(start_of_line)][-1].split(split_marker)[1].strip() - except (IOError, IndexError): - return None - - -VERSION = ( - # Assume we are in a distribution, which has PKG-INFO - _get_version_from_file("PKG-INFO", "Version:", ":") - # Must be a development checkout, so use the Makefile - or _get_version_from_file("Makefile", "VERSION", "=") - or "0.0" -) - - -relpath = os.path.dirname(__file__) -if relpath: - os.chdir(relpath) - -setup( - name="python-subunit", - version=VERSION, - description=("Python implementation of subunit test streaming protocol"), - long_description=open("README.rst").read(), - classifiers=[ - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Topic :: Software Development :: Testing", - ], - keywords="python test streaming", - author="Robert Collins", - author_email="subunit-dev@lists.launchpad.net", - url="http://launchpad.net/subunit", - license="Apache-2.0 or BSD", - project_urls={ - "Bug Tracker": "https://bugs.launchpad.net/subunit", - "Source Code": "https://github.com/testing-cabal/subunit/", - }, - packages=["subunit", "subunit.tests", "subunit.filter_scripts"], - package_dir={"subunit": "python/subunit"}, - python_requires=">=3.7", - install_requires=[ - "iso8601", - "testtools>=0.9.34", - ], - entry_points={ - "console_scripts": [ - "subunit-1to2=subunit.filter_scripts.subunit_1to2:main", - "subunit-2to1=subunit.filter_scripts.subunit_2to1:main", - "subunit-filter=subunit.filter_scripts.subunit_filter:main", - "subunit-ls=subunit.filter_scripts.subunit_ls:main", - "subunit-notify=subunit.filter_scripts.subunit_notify:main", - "subunit-output=subunit.filter_scripts.subunit_output:main", - "subunit-stats=subunit.filter_scripts.subunit_stats:main", - "subunit-tags=subunit.filter_scripts.subunit_tags:main", - "subunit2csv=subunit.filter_scripts.subunit2csv:main", - "subunit2disk=subunit.filter_scripts.subunit2disk:main", - "subunit2gtk=subunit.filter_scripts.subunit2gtk:main", - "subunit2junitxml=subunit.filter_scripts.subunit2junitxml:main", - "subunit2pyunit=subunit.filter_scripts.subunit2pyunit:main", - "tap2subunit=subunit.filter_scripts.tap2subunit:main", - ] - }, - tests_require=[ - "fixtures", - "hypothesis", - "testscenarios", - ], - extras_require={ - "docs": ["docutils"], - "test": ["fixtures", "testscenarios", "hypothesis"], - }, -) +setup()