diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 805ec67..d0593d4 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -4,7 +4,7 @@ on: push jobs: all_checks: - name: Run all tests, lints, etc. (Python 3.10) + name: Run all tests, lints, etc. (Python 3.11) runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, '[skip ci]')" @@ -15,7 +15,7 @@ jobs: - name: Install Python uses: actions/setup-python@v2 with: - python-version: '3.10' + python-version: '3.11' - name: Update pip & setuptools run: python -m pip install -U pip setuptools @@ -43,7 +43,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python: ['3.6', '3.7', '3.8', '3.9'] + python: ['3.8', '3.9', '3.10', '3.11', '3.12'] if: "!contains(github.event.head_commit.message, '[skip ci]')" steps: @@ -68,4 +68,3 @@ jobs: run: | pytest --cov tox -e sdist_install - \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in index de0a14a..8606d0b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,2 @@ -include LICENSE.txt README.rst CHANGELOG.md pyproject.toml +include AUTHORS.md LICENSE.txt README.rst CHANGELOG.md pyproject.toml +include requirements-dev.txt requirements-flake8.txt tox.ini diff --git a/README.rst b/README.rst index 4baf27e..393e0a4 100644 --- a/README.rst +++ b/README.rst @@ -49,13 +49,13 @@ Relative imports raise the ``ABS101`` error code: Available on `PyPI `__ (``pip install flake8-absolute-import``). ``flake8`` should automatically -detect and load the plugin. ``flake8``>=3.7 is required. +detect and load the plugin. ``flake8``>=5.0 is required. Source on `GitHub `__. Bug reports and feature requests are welcomed at the `Issues `__ page there. -Copyright (c) Brian Skinn 2019-2021 +Copyright (c) Brian Skinn 2019-2023 License: The MIT License. See `LICENSE.txt `__ for full license terms. diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 9aae50a..910ca23 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -12,30 +12,31 @@ jobs: - template: azure-coretest.yml parameters: pythons: - py37: - spec: '3.7' py38: spec: '3.8' py39: spec: '3.9' py310: spec: '3.10' + py311: + spec: '3.11' + py312: + spec: '3.12' platforms: [linux, windows, macOs] +- template: azure-sdisttest.yml + - job: flake8 pool: vmImage: 'Ubuntu-latest' steps: - task: UsePythonVersion@0 inputs: - versionSpec: '3.10' + versionSpec: '3.11' - script: pip install -U tox displayName: Install tox - - script: pip install -r requirements-flake8.txt - displayName: Install flake8 & plugins - - script: tox -e flake8 displayName: Lint the codebase @@ -45,7 +46,7 @@ jobs: steps: - task: UsePythonVersion@0 inputs: - versionSpec: '3.10' + versionSpec: '3.11' - script: pip install -r requirements-ci.txt displayName: Install CI requirements diff --git a/azure-sdisttest.yml b/azure-sdisttest.yml new file mode 100644 index 0000000..9f7e2a3 --- /dev/null +++ b/azure-sdisttest.yml @@ -0,0 +1,74 @@ +jobs: +- job: testable_sdist + displayName: Ensure sdist is testable + + variables: + pip_cache_dir: $(Pipeline.Workspace)/.pip + + pool: + vmImage: 'Ubuntu-latest' + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.11' + + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + + - script: python -m pip install build + displayName: Install 'build' package + + - script: | + python -m build -s + ls -lah dist + displayName: Build sdist + + - script: | + mkdir sandbox + displayName: Create sandbox + + - script: | + cp dist/*.gz sandbox/ + cd sandbox + tar xvf *.gz + displayName: Unpack sdist in sandbox + + - script: | + cd sandbox + python -m venv env + displayName: Create venv + + # Only the dir of the unpacked sdist will have a digit in its name + - script: | + cd sandbox + echo $( find . -maxdepth 1 -type d -regex "./.+[0-9].+" ) + displayName: Check unpack dir name + + - script: | + cd sandbox + source env/bin/activate + cd $( find . -maxdepth 1 -type d -regex "./.+[0-9].+" ) + python -m pip install -r requirements-dev.txt + displayName: Install dev req'ts to venv + + - script: | + cd sandbox + source env/bin/activate + cd $( find . -maxdepth 1 -type d -regex "./.+[0-9].+" ) + cd doc + O=-Ean make html + displayName: Build docs in sandbox (skipped, no docs) + condition: false + + - script: | + cd sandbox + source env/bin/activate + cd $( find . -maxdepth 1 -type d -regex "./.+[0-9].+" ) + pytest + displayName: Run test suite in sandbox diff --git a/pyproject.toml b/pyproject.toml index e28a124..d19ef3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,22 +1,94 @@ [build-system] -requires = ["wheel", "setuptools"] +requires = [ + "wheel", + "setuptools>=61.2", +] build-backend = "setuptools.build_meta" +[project] +name = "flake8-absolute-import" +description = "flake8 plugin to require absolute imports" +authors = [ + { name = "Brian Skinn", email = "brian.skinn@gmail.com" }, +] +classifiers = [ + "License :: OSI Approved", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Framework :: Flake8", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "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 :: Quality Assurance", + "Development Status :: 5 - Production/Stable", +] +keywords = [ + "flake8-plugin", + "linting", + "absolute-imports", + "relative-imports", +] +requires-python = ">=3.6" +dependencies = [ + "flake8>=5.0", +] +dynamic = [ + "version", + "readme", +] + +[project.urls] +Homepage = "https://github.com/bskinn/flake8-absolute-import" +Changelog = "https://github.com/bskinn/flake8-absolute-import/blob/main/CHANGELOG.md" +Thank = "https://twitter.com/btskinn" +Donate = "https://github.com/sponsors/bskinn" + +[project.license] +text = "MIT License" + +[project.entry-points."flake8.extension"] +ABS1 = "flake8_absolute_import:Plugin" + +[tool.setuptools] +platforms = [ + "any", +] +license-files = [ + "LICENSE.txt", +] +include-package-data = false + +[tool.setuptools.package-dir] +"" = "src" + +[tool.setuptools.packages.find] +where = [ + "src", +] +namespaces = false + [tool.black] line-length = 88 include = ''' ( - ^/tests/.*[.]py$ - | ^/src/flake8_absolute_import/.*[.]py$ - | ^/setup[.]py - | ^/conftest[.]py + ^tests/.*[.]py$ + | ^src/flake8_absolute_import/.*[.]py$ + | ^setup[.]py + | ^conftest[.]py ) ''' exclude = ''' ( __pycache__ - | ^/[.] - | ^/doc - | ^/env + | ^[.] + | ^doc + | ^env ) ''' diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index fea4b50..0000000 --- a/setup.cfg +++ /dev/null @@ -1,48 +0,0 @@ -[metadata] -name = flake8-absolute-import -description = flake8 plugin to require absolute imports -url = https://github.com/bskinn/flake8-absolute-import -project_urls = - Changelog=https://github.com/bskinn/flake8-absolute-import/blob/main/CHANGELOG.md - Thank=https://twitter.com/btskinn - Donate=https://github.com/sponsors/bskinn -license = MIT License -license_file = LICENSE.txt -platforms = any -author = Brian Skinn -author_email = bskinn@alum.mit.edu -classifiers = - License :: OSI Approved - License :: OSI Approved :: MIT License - Natural Language :: English - Framework :: Flake8 - Intended Audience :: Developers - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3 :: Only - 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 - Programming Language :: Python :: 3.11 - Topic :: Software Development :: Quality Assurance - Development Status :: 5 - Production/Stable -keywords = flake8-plugin, linting, absolute-imports, relative-imports - -[options] -install_requires = - flake8>=3.7 - -python_requires = >=3.4 -packages = find: -package_dir = - =src - -[options.packages.find] -where = src - -[options.entry_points] -flake8.extension = - ABS1=flake8_absolute_import:Plugin diff --git a/setup.py b/setup.py index 2d91920..ed30809 100644 --- a/setup.py +++ b/setup.py @@ -3,18 +3,19 @@ from setuptools import find_packages, setup -with Path("src", "flake8_absolute_import", "version.py").open() as f: - exec(f.read()) +exec_ns = {} +exec( + Path("src", "flake8_absolute_import", "version.py").read_text(encoding="utf-8"), + exec_ns, +) +__version__ = exec_ns["__version__"] NAME = "flake8-absolute-import" - - version_override = None def readme(): - with open("README.rst", "r") as f: - content = f.read() + content = Path("README.rst").read_text() new_ver = version_override if version_override else __version__ @@ -25,19 +26,18 @@ def content_update(content, pattern, sub): # Docs reference updates to current release version, for PyPI # This one gets the badge image content = content_update( - content, r"(?<=/readthedocs/{0}/)\S+?(?=\.svg$)".format(NAME), "v" + new_ver + content, rf"(?<=/readthedocs/{NAME}/)\S+?(?=\.svg$)", "v" + new_ver ) # This one gets the RtD links content = content_update( - content, r"(?<={0}\.readthedocs\.io/en/)\S+?(?=/)".format(NAME), "v" + new_ver + content, rf"(?<={NAME}\.readthedocs\.io/en/)\S+?(?=/)", "v" + new_ver ) return content setup( - name=NAME, version=__version__, long_description=readme(), long_description_content_type="text/x-rst", diff --git a/tests/test_plugin.py b/tests/test_plugin.py index a206235..4db5ca4 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -29,14 +29,14 @@ from flake8_absolute_import import Plugin -def is_relative(s): - """Indicate if a given 'from s' import location is a relative import.""" - return s.startswith(".") +def is_relative(import_source): + """Indicate if a given 'from {source}' import location is a relative import.""" + return import_source.startswith(".") -def format_id(i): +def format_id(id_): """Provide parametrization id formatting for the given id.""" - return "{0} (expect {1}error)".format(i, "" if is_relative(i) else "no ") + return f"{id_} (expect {'' if is_relative(id_) else 'no '}error)" @pytest.mark.parametrize("code", ["import sys", "import flake8_absolute_import"]) @@ -106,11 +106,11 @@ def test_multilevel_relative_import(): def test_func_imports(impfrom): """Confirm plugin works for imports in functions.""" code = dedent( - """ + f""" def func(): - from {} import foo + from {impfrom} import foo """ - ).format(impfrom) + ) tree = ast.parse(code) assert (len(list(Plugin(tree).run())) == 1) == (impfrom.startswith(".")) @@ -120,11 +120,11 @@ def func(): def test_class_imports(impfrom): """Confirm plugin works for imports in class bodies.""" code = dedent( - """ + f""" class Bar: - from {} import foo + from {impfrom} import foo """ - ).format(impfrom) + ) tree = ast.parse(code) assert (len(list(Plugin(tree).run())) == 1) == (impfrom.startswith(".")) @@ -134,12 +134,12 @@ class Bar: def test_method_imports(impfrom): """Confirm plugin works for imports in class methods.""" code = dedent( - """ + f""" class Bar: def baz(self): - from {} import foo + from {impfrom} import foo """ - ).format(impfrom) + ) tree = ast.parse(code) assert (len(list(Plugin(tree).run())) == 1) == (impfrom.startswith(".")) diff --git a/tox.ini b/tox.ini index 88d37aa..21e7494 100644 --- a/tox.ini +++ b/tox.ini @@ -2,8 +2,8 @@ minversion=2.0 isolated_build=True envlist= - py3{6,7,8,9,10,11}-f8_{3_7_0,latest} - py3{10}-f8_3_{7_x,8_x,9_x} + py3{7,8,9,10,11,12}-f8_{min,latest} + py3{11,12}-f8_{5_x} sdist_install [testenv] @@ -15,20 +15,18 @@ deps= pytest f8_latest: flake8 - f8_3_7_x: flake8~=3.7.0 - f8_3_7_0: flake8==3.7.0 - f8_3_8_x: flake8~=3.8.0 - f8_3_9_x: flake8~=3.9.0 + f8_min: flake8==5.0 + f8_5_x: flake8~=5.0 [testenv:linux] platform=linux basepython= + py312: python3.12 py311: python3.11 py310: python3.10 py39: python3.9 py38: python3.8 py37: python3.7 - py36: python3.6 [testenv:sdist_install] commands=