Repository: sloria/sphinx-issues (language: python)

Issue:
Add Sphinx Extension classifier
Add the Sphinx Extension PyPi classifier so that the extension shows up in the correct [PyPi filters](https://pypi.org/search/?c=Framework+%3A%3A+Sphinx+%3A%3A+Extension).


Discussion / hints:

Fix patch:
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..491deae
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,7 @@
+version: 2
+updates:
+- package-ecosystem: pip
+  directory: "/"
+  schedule:
+    interval: daily
+  open-pull-requests-limit: 10
diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml
new file mode 100644
index 0000000..226cd79
--- /dev/null
+++ b/.github/workflows/build-release.yml
@@ -0,0 +1,74 @@
+name: build
+on:
+  push:
+    branches: ["main"]
+    tags: ["*"]
+  pull_request:
+
+jobs:
+  tests:
+    name: ${{ matrix.name }}
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - { name: "3.8", python: "3.8", tox: py38 }
+          - { name: "3.12", python: "3.12", tox: py312 }
+    steps:
+      - uses: actions/checkout@v4.0.0
+      - uses: actions/setup-python@v4.7.0
+        with:
+          python-version: ${{ matrix.python }}
+          allow-prereleases: true
+      - run: python -m pip install --upgrade pip
+      - run: python -m pip install tox
+      - run: python -m tox -e ${{ matrix.tox }}
+  build:
+    if: startsWith(github.ref, 'refs/tags')
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/setup-python@v4
+        with:
+          python-version: "3.11"
+      - name: Install pypa/build
+        run: python3 -m pip install build --user
+      - name: Build a binary wheel and a source tarball
+        run: python3 -m build
+      - name: Store the distribution packages
+        uses: actions/upload-artifact@v3
+        with:
+          name: python-package-distributions
+          path: dist/
+  # this duplicates pre-commit.ci, so only run it on tags
+  # it guarantees that linting is passing prior to a release
+  lint-pre-release:
+    if: startsWith(github.ref, 'refs/tags')
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4.0.0
+      - uses: actions/setup-python@v4.7.0
+        with:
+          python-version: "3.11"
+      - run: python -m pip install --upgrade pip
+      - run: python -m pip install tox
+      - run: python -m tox -e lint
+  publish-to-pypi:
+    name: PyPI release
+    if: startsWith(github.ref, 'refs/tags/')
+    needs: [build, tests, lint-pre-release]
+    runs-on: ubuntu-latest
+    environment:
+      name: pypi
+      url: https://pypi.org/p/sphinx-issues
+    permissions:
+      id-token: write
+    steps:
+      - name: Download all the dists
+        uses: actions/download-artifact@v3
+        with:
+          name: python-package-distributions
+          path: dist/
+      - name: Publish distribution to PyPI
+        uses: pypa/gh-action-pypi-publish@release/v1
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
deleted file mode 100644
index 1a7cb24..0000000
--- a/.github/workflows/lint.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-name: Lint
-
-on: [push, pull_request, workflow_dispatch]
-
-jobs:
-  lint:
-    runs-on: ubuntu-latest
-
-    steps:
-      - uses: actions/checkout@v2
-      - uses: actions/setup-python@v2
-      - uses: pre-commit/action@v2.0.3
diff --git a/.gitignore b/.gitignore
index f0dbb54..65978ed 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,9 @@ output/*/index.html
 # Sphinx
 docs/_build
 README.html
+
+# mypy
+.mypy_cache/
+
+# ruff
+.ruff_cache
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 53e97eb..73e8986 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,20 +1,16 @@
 repos:
-- repo: https://github.com/asottile/pyupgrade
-  rev: v2.31.0
+- repo: https://github.com/astral-sh/ruff-pre-commit
+  rev: v0.1.13
   hooks:
-  - id: pyupgrade
-    args: [--py36-plus]
-- repo: https://github.com/python/black
-  rev: 22.1.0
+    - id: ruff
+    - id: ruff-format
+- repo: https://github.com/python-jsonschema/check-jsonschema
+  rev: 0.27.3
   hooks:
-  - id: black
-- repo: https://gitlab.com/pycqa/flake8
-  rev: 3.9.2
-  hooks:
-  - id: flake8
-    additional_dependencies: [flake8-bugbear==22.1.11]
+    - id: check-github-workflows
+    - id: check-readthedocs
 - repo: https://github.com/asottile/blacken-docs
-  rev: v1.12.1
+  rev: 1.16.0
   hooks:
   - id: blacken-docs
-    additional_dependencies: [black==22.1.0]
+    additional_dependencies: [black==23.12.1]
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5340e14..d57d10e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,32 +2,24 @@
 
 ## Setting up for development
 
-* Create and activate a new virtual environment
-* `pip install -e '.[dev]'`
-* (Optional but recommended) If you're using a Python 3.6 virtual
-    environment, install the pre-commit hooks, which will
-    format and lint your git staged files:
-
+- Create and activate a new virtual environment
+- `pip install -e '.[dev]'`
+- (Optional but recommended) Install the pre-commit hooks, which will
+  format and lint your git staged files:
 
 ```
 # The pre-commit CLI was installed above
 pre-commit install
 ```
 
-* To run tests:
+- To run tests:
 
 ```
 pytest
 ```
 
-* To run syntax checks:
+- To run syntax checks:
 
 ```
 tox -e lint
 ```
-
-* (Optional) To run tests on Python 2.7, 3.5, 3.6, and 3.7 virtual environments (must have each interpreter installed):
-
-```
-tox
-```
diff --git a/LICENSE b/LICENSE
index ad2fc0f..2a7880a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2022 Steven Loria
+Copyright 2024 Steven Loria
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index c74cefe..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,1 +0,0 @@
-include *.rst LICENSE
diff --git a/README.rst b/README.rst
index 150a922..654f972 100644
--- a/README.rst
+++ b/README.rst
@@ -3,16 +3,12 @@ sphinx-issues
 =============
 
 .. image:: https://badgen.net/pypi/v/sphinx-issues
-  :alt: pypi badge
-  :target: https://pypi.org/project/sphinx-issues/
+    :target: https://pypi.org/project/sphinx-issues/
+    :alt: PyPI badge
 
-.. image:: https://github.com/OpenASL/HowSignBot/workflows/.github/workflows/test.yml/badge.svg
-  :alt: github actions status
-  :target: .github/workflows/test.yml
-
-.. image:: https://badgen.net/badge/code%20style/black/000
-   :target: https://github.com/ambv/black
-   :alt: Code style: Black
+.. image:: https://github.com/sloria/sphinx-issues/actions/workflows/build-release.yml/badge.svg
+    :target: https://github.com/sloria/sphinx-issues/actions/workflows/build-release.yml
+    :alt: Build status
 
 A Sphinx extension for linking to your project's issue tracker. Includes roles for linking to issues, pull requests, user profiles, with built-in support for GitHub (though this works with other services).
 
@@ -153,6 +149,13 @@ MIT licensed. See the bundled `LICENSE <https://github.com/sloria/sphinx-issues/
 Changelog
 *********
 
+3.1.0 (unreleased)
+------------------
+
+- Support Python 3.8-3.12. Older versions are no longer supported.
+- Remove `__version__`, `__author__`, and `__license__` attributes.
+  Use `importlib.metadata` to read this metadata instead.
+
 3.0.1 (2022-01-11)
 ------------------
 
diff --git a/RELEASING.md b/RELEASING.md
new file mode 100644
index 0000000..394d6c2
--- /dev/null
+++ b/RELEASING.md
@@ -0,0 +1,8 @@
+# Releasing
+
+1. Bump version in `pyproject.toml` and update the changelog
+   with today's date.
+2. Commit: `git commit -m "Bump version and update changelog"`
+3. Tag the commit: `git tag x.y.z`
+4. Push: `git push --tags origin main`. CI will take care of the
+   PyPI release.
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..dde1fe0
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,55 @@
+[project]
+name = "sphinx-issues"
+version = "3.0.1"
+description = "A Sphinx extension for linking to your project's issue tracker"
+readme = "README.rst"
+license = { file = "LICENSE" }
+authors = [{ name = "Steven Loria", email = "sloria1@gmail.com" }]
+classifiers = [
+  "Framework :: Sphinx :: Extension",
+  "Intended Audience :: Developers",
+  "License :: OSI Approved :: MIT License",
+  "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 :: Documentation",
+]
+keywords = ["sphinx", "issues", "github"]
+requires-python = ">=3.8"
+dependencies = ["sphinx"]
+
+[project.urls]
+Issues = "https://github.com/sloria/sphinx-issues/issues"
+Source = "https://github.com/sloria/sphinx-issues"
+
+[project.optional-dependencies]
+tests = ["pytest"]
+dev = ["sphinx-issues[tests]", "tox", "pre-commit~=3.6"]
+
+[build-system]
+requires = ["flit_core<4"]
+build-backend = "flit_core.buildapi"
+
+[tool.flit.sdist]
+include = ["tests/", "CONTRIBUTING.md", "NOTICE", "tox.ini"]
+exclude = ["docs/_build/"]
+
+[tool.ruff]
+src = ["src"]
+fix = true
+show-fixes = true
+show-source = true
+
+[tool.ruff.lint]
+ignore = ["E203", "E266", "E501", "E731"]
+select = [
+  "B",  # flake8-bugbear
+  "E",  # pycodestyle error
+  "F",  # pyflakes
+  "I",  # isort
+  "UP", # pyupgrade
+  "W",  # pycodestyle warning
+]
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 23ee671..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,9 +0,0 @@
-[metadata]
-# This includes the license file in the wheel.
-license_files = LICENSE
-
-[flake8]
-ignore = E203, E266, E501, W503
-max-line-length = 90
-max-complexity = 18
-select = B,C,E,F,W,T4,B9
diff --git a/setup.py b/setup.py
deleted file mode 100644
index f847ab6..0000000
--- a/setup.py
+++ /dev/null
@@ -1,65 +0,0 @@
-import re
-from setuptools import setup
-
-INSTALL_REQUIRES = ["sphinx"]
-EXTRAS_REQUIRE = {
-    "tests": ["pytest>=6.2.0"],
-    "lint": [
-        "flake8==3.9.2",
-        "flake8-bugbear==20.11.1",
-        "pre-commit~=2.7",
-    ],
-}
-EXTRAS_REQUIRE["dev"] = EXTRAS_REQUIRE["tests"] + EXTRAS_REQUIRE["lint"] + ["tox"]
-
-
-def find_version(fname):
-    """Attempts to find the version number in the file names fname.
-    Raises RuntimeError if not found.
-    """
-    version = ""
-    with open(fname) as fp:
-        reg = re.compile(r'__version__ = [\'"]([^\'"]*)[\'"]')
-        for line in fp:
-            m = reg.match(line)
-            if m:
-                version = m.group(1)
-                break
-    if not version:
-        raise RuntimeError("Cannot find version information")
-    return version
-
-
-def read(fname):
-    with open(fname) as fp:
-        content = fp.read()
-    return content
-
-
-setup(
-    name="sphinx-issues",
-    version=find_version("sphinx_issues.py"),
-    description="A Sphinx extension for linking to your project's issue tracker",
-    long_description=read("README.rst"),
-    install_requires=INSTALL_REQUIRES,
-    extras_require=EXTRAS_REQUIRE,
-    author="Steven Loria",
-    author_email="sloria1@gmail.com",
-    url="https://github.com/sloria/sphinx-issues",
-    license="MIT",
-    keywords="sphinx issues github",
-    python_requires=">=3.6",
-    classifiers=[
-        "Intended Audience :: Developers",
-        "License :: OSI Approved :: MIT License",
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.6",
-        "Programming Language :: Python :: 3.7",
-        "Programming Language :: Python :: 3.8",
-        "Programming Language :: Python :: 3.9",
-        "Programming Language :: Python :: 3.10",
-        "Topic :: Software Development :: Documentation",
-    ],
-    py_modules=["sphinx_issues"],
-    project_urls={"Issues": "https://github.com/sloria/sphinx-issues/issues"},
-)
diff --git a/sphinx_issues.py b/src/sphinx_issues/__init__.py
similarity index 99%
rename from sphinx_issues.py
rename to src/sphinx_issues/__init__.py
index e5a69c6..b5c7bec 100644
--- a/sphinx_issues.py
+++ b/src/sphinx_issues/__init__.py
@@ -1,4 +1,5 @@
 """A Sphinx extension for linking to your project's issue tracker."""
+import importlib.metadata
 import re
 from typing import Callable, Optional, Tuple
 
@@ -6,10 +7,6 @@
 from sphinx.config import Config
 from sphinx.util.nodes import split_explicit_title
 
-__version__ = "3.0.1"
-__author__ = "Steven Loria"
-__license__ = "MIT"
-
 
 def cve_role(name, rawtext, text, lineno, inliner, options=None, content=None):
     """Sphinx role for linking to a CVE on https://cve.mitre.org.
@@ -384,7 +381,7 @@ def setup(app):
     app.add_role("cve", cve_role)
     app.add_role("cwe", cwe_role)
     return {
-        "version": __version__,
+        "version": importlib.metadata.version("sphinx-issues"),
         "parallel_read_safe": True,
         "parallel_write_safe": True,
     }
diff --git a/tox.ini b/tox.ini
index a676add..c57c1ca 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,12 +1,12 @@
 [tox]
-envlist = lint,py36,py37,py38,py39,py310
+envlist = lint,py{38,39,310,311,312}
 
 [testenv]
 extras = tests
 commands = pytest {posargs}
 
 [testenv:lint]
-deps = pre-commit~=2.7
+deps = pre-commit~=3.6
 skip_install = true
 commands = pre-commit run --all-files
 


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
deleted file mode 100644
index 0328fcf..0000000
--- a/.github/workflows/test.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: Test
-
-on: [push, pull_request, workflow_dispatch]
-
-env:
-  FORCE_COLOR: 1
-
-jobs:
-  test:
-    runs-on: ubuntu-latest
-    strategy:
-      fail-fast: false
-      matrix:
-        python-version: ["3.6", "3.10"]
-
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v2
-        with:
-          python-version: ${{ matrix.python-version }}
-          cache: pip
-          cache-dependency-path: "setup.py"
-
-      - name: Install dependencies
-        run: |
-          python -m pip install -U pip
-          python -m pip install -U wheel
-          python -m pip install -U tox
-
-      - name: Tox tests
-        run: |
-          tox -e py
diff --git a/tests/test_sphinx_issues.py b/tests/test_sphinx_issues.py
index 34bff56..8462d1d 100644
--- a/tests/test_sphinx_issues.py
+++ b/tests/test_sphinx_issues.py
@@ -7,10 +7,16 @@
 
 import pytest
 import sphinx.application
-from sphinx_issues import commit_role, cve_role, cwe_role, issue_role, pr_role
-from sphinx_issues import setup as issues_setup
-from sphinx_issues import user_role
 
+from sphinx_issues import (
+    commit_role,
+    cve_role,
+    cwe_role,
+    issue_role,
+    pr_role,
+    user_role,
+)
+from sphinx_issues import setup as issues_setup
 
 BASE_DIR = Path(__file__).parent.absolute()