From 80e6b446f8088cab8f017f30a94f11738a1fe649 Mon Sep 17 00:00:00 2001 From: Tommy Yu Date: Sat, 6 Sep 2025 16:45:59 +1200 Subject: [PATCH 1/5] Use `importlib` where available. - This does change the shape of the `ply_dist` object inside util but users shouldn't normally and have no reason to depend on that. Fixes #47 --- src/calmjs/parse/tests/__init__.py | 24 ++++++++------ src/calmjs/parse/utils.py | 51 +++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/calmjs/parse/tests/__init__.py b/src/calmjs/parse/tests/__init__.py index a010c8a..25b3f47 100644 --- a/src/calmjs/parse/tests/__init__.py +++ b/src/calmjs/parse/tests/__init__.py @@ -8,7 +8,6 @@ from io import StringIO from os.path import basename from os.path import dirname -from pkg_resources import get_distribution examples = { '/tmp/html4.js': dedent(""" @@ -63,14 +62,21 @@ def open(p, flag='r'): doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS ) - dist = get_distribution('calmjs.parse') - if dist: - if dist.has_metadata('PKG-INFO'): - pkgdesc = dist.get_metadata('PKG-INFO').replace('\r', '') - elif dist.has_metadata('METADATA'): - pkgdesc = dist.get_metadata('METADATA').replace('\r', '') - else: - pkgdesc = '' + try: + from importlib import metadata + pkgdesc = metadata.metadata('calmjs.parse').get('description') + pkgdesc = pkgdesc.replace('\r', '') if pkgdesc else '' + except ImportError: + from pkg_resources import get_distribution + dist = get_distribution('calmjs.parse') + if dist: + if dist.has_metadata('PKG-INFO'): + pkgdesc = dist.get_metadata('PKG-INFO').replace('\r', '') + elif dist.has_metadata('METADATA'): + pkgdesc = dist.get_metadata('METADATA').replace('\r', '') + else: + pkgdesc = '' + pkgdesc_tests = [ t for t in parser.parse(pkgdesc) if isinstance(t, doctest.Example)] diff --git a/src/calmjs/parse/utils.py b/src/calmjs/parse/utils.py index 51d82c9..cf3ee96 100644 --- a/src/calmjs/parse/utils.py +++ b/src/calmjs/parse/utils.py @@ -9,20 +9,47 @@ from os.path import normpath from os.path import relpath + +class _Distribution(object): + def __init__(self, project_name, version): + self.project_name = project_name + self.version = version + + try: - from pkg_resources import working_set - from pkg_resources import Requirement - ply_dist = working_set.find(Requirement.parse('ply')) - # note that for **extremely** ancient versions of setuptools, e.g. - # setuptools<0.6c11, or some very non-standard environment that does - # not include the required metadata (e.g. pyinstaller without the - # required metadata), will require the following workaround... - if ply_dist is None: # pragma: no cover - from pkg_resources import Distribution - import ply - ply_dist = Distribution(project_name='ply', version=ply.__version__) + from importlib import metadata + try: + ply_version = metadata.version('ply') + except Exception: # pragma: no cover + ply_dist = None + else: + ply_dist = _Distribution(project_name='ply', version=ply_version) except ImportError: # pragma: no cover - ply_dist = None + try: + from pkg_resources import working_set + from pkg_resources import Requirement + ply_dist = working_set.find(Requirement.parse('ply')) + # note that for **extremely** ancient versions of setuptools, e.g. + # setuptools<0.6c11, or some very non-standard environment that does + # not include the required metadata (e.g. pyinstaller without the + # required metadata), will require the following workaround... + if ply_dist: + # convert to our private version class + ply_dist = _Distribution( + project_name='ply', + version=ply_dist.version, + ) + else: + try: + import ply + ply_dist = _Distribution( + project_name='ply', + version=ply.__version__, + ) + except ImportError: + ply_dist = None + except ImportError: # pragma: no cover + ply_dist = None py_major = sys.version_info.major unicode = unicode if py_major < 3 else None # noqa: F821 From 8fa01bc0fbd1bd01a43196f7ea6e40e4ba778170 Mon Sep 17 00:00:00 2001 From: Tommy Yu Date: Sat, 6 Sep 2025 16:49:05 +1200 Subject: [PATCH 2/5] Bump python versions for CI. --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 73aa928..dd2927c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.10"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.11"] include: - os: windows-latest python-version: "3.11" @@ -30,11 +30,11 @@ jobs: python-version: "3.13" exclude: - os: macos-latest - python-version: 3.9 + python-version: 3.12 - os: macos-latest - python-version: 3.10 + python-version: 3.13 - os: macos-latest - python-version: "pypy3.10" + python-version: "pypy3.11" steps: From fa885c41575831588a1b86118131184efb095ab8 Mon Sep 17 00:00:00 2001 From: Tommy Yu Date: Fri, 3 Oct 2025 16:50:26 +1300 Subject: [PATCH 3/5] Clean up test matrix. - Let's not mix up include/exclude to reduce confusion... --- .github/workflows/build.yml | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dd2927c..861c065 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,21 +19,23 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest] - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.11"] + os: [ubuntu-latest, macos-latest, windows-latest] + # This should include the latest 3 stable releases + python-version: ["3.11", "3.12", "3.13"] include: + # Use Linux only to test older releases to limit CI time + - os: ubuntu-latest + python-version: "3.9" + - os: ubuntu-latest + python-version: "3.10" + # uncomment when 3.11 is bumped off by "3.14" + # - os: ubuntu-latest + # python-version: "3.11" + + # Include pypy3.11 for Windows and Linux - os: windows-latest - python-version: "3.11" - - os: windows-latest - python-version: "3.12" - - os: windows-latest - python-version: "3.13" - exclude: - - os: macos-latest - python-version: 3.12 - - os: macos-latest - python-version: 3.13 - - os: macos-latest + python-version: "pypy3.11" + - os: ubuntu-latest python-version: "pypy3.11" From 495440b24bf4e5f67645f90144c538560f5bff38 Mon Sep 17 00:00:00 2001 From: Tommy Yu Date: Thu, 9 Oct 2025 01:42:31 +1300 Subject: [PATCH 4/5] Include Python 3.14 for CI --- .github/workflows/build.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 861c065..85e21f8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,16 +21,15 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] # This should include the latest 3 stable releases - python-version: ["3.11", "3.12", "3.13"] + python-version: ["3.12", "3.13", "3.14"] include: # Use Linux only to test older releases to limit CI time - os: ubuntu-latest python-version: "3.9" - os: ubuntu-latest python-version: "3.10" - # uncomment when 3.11 is bumped off by "3.14" - # - os: ubuntu-latest - # python-version: "3.11" + - os: ubuntu-latest + python-version: "3.11" # Include pypy3.11 for Windows and Linux - os: windows-latest From a3bec4235570266f781888e5e9185378ab28ba79 Mon Sep 17 00:00:00 2001 From: Tommy Yu Date: Thu, 9 Oct 2025 01:50:07 +1300 Subject: [PATCH 5/5] Package metadata. --- CHANGES.rst | 9 +++++++++ setup.py | 1 + 2 files changed, 10 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index daa4de2..8272886 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,15 @@ Changelog ========= +1.3.4 - 2025-10-?? +------------------ + +- Avoid use of the deprecated ``pkg_resources`` module. [ + `#47 `_ + `#48 `_ + ] +- Ensure Python 3.14 support. + 1.3.3 - 2025-01-29 ------------------ diff --git a/setup.py b/setup.py index 4686676..66e1274 100644 --- a/setup.py +++ b/setup.py @@ -40,6 +40,7 @@ def __init__(self, *a, **kw): Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.12 Programming Language :: Python :: 3.13 +Programming Language :: Python :: 3.14 """.strip().splitlines() long_description = (