Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Drop support for Python 3.7 #146

Merged
merged 2 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
[flake8]
ignore = W503, C901, ANN101
max-line-length = 88
select = DAR
exclude = copier_template
max-complexity = 10
docstring-convention = google
allow-star-arg-any = true
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11"]

steps:
- uses: actions/checkout@v4
Expand Down
26 changes: 5 additions & 21 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,17 @@ repos:
exclude: (copier_template/.*|docs/.*|samples/.*\.json)
- id: trailing-whitespace

- repo: https://github.com/psf/black
rev: 23.9.1
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.0
hooks:
- id: black
exclude: |
(?x)^(
copier_template/.*
)$

- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
exclude: (copier_template/.*)
- id: ruff
args: [--fix, --exit-non-zero-on-fix, --show-fixes]
- id: ruff-format

- repo: https://github.com/pycqa/flake8
rev: 6.1.0
hooks:
- id: flake8
additional_dependencies:
- darglint==1.8.1
- flake8-annotations==2.9.0
- flake8-docstrings==1.6.0
files: 'meltano/edk/.*'

- repo: https://github.com/asottile/pyupgrade
rev: v3.14.0
hooks:
- id: pyupgrade
args: [--py37-plus, --keep-mock]
1 change: 0 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
"sphinx.ext.autosummary",
"sphinx_rtd_theme",
"sphinx_copybutton",
"myst_parser",
]
Expand Down
10 changes: 7 additions & 3 deletions meltano/edk/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ class DescribeFormat(str, Enum):
class ExtensionBase(metaclass=ABCMeta):
"""Basic extension interface that must be implemented by all extensions."""

def pre_invoke(self, invoke_name: str | None, *invoke_args: ExecArg) -> None:
def pre_invoke( # noqa: B027
self,
invoke_name: str | None,
*invoke_args: ExecArg,
) -> None:
"""Called before the extension is invoked.

Args:
Expand All @@ -33,7 +37,7 @@ def pre_invoke(self, invoke_name: str | None, *invoke_args: ExecArg) -> None:
"""
pass

def initialize(self, force: bool = False) -> None:
def initialize(self, force: bool = False) -> None: # noqa: B027
"""Initialize the extension.

This method is called on-demand by the user to initialize the extension.
Expand All @@ -56,7 +60,7 @@ def invoke(self, command_name: str | None, *command_args: ExecArg) -> None:
"""
pass

def post_invoke(self, invoked_name: str | None, *invoked_args: ExecArg) -> None:
def post_invoke(self, invoked_name: str | None, *invoked_args: ExecArg) -> None: # noqa: B027
"""Called after the extension is invoked.

Args:
Expand Down
10 changes: 5 additions & 5 deletions meltano/edk/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import asyncio
import os
import subprocess
from typing import IO, Any
import typing as t

import structlog

Expand Down Expand Up @@ -40,7 +40,7 @@ def __init__(
self,
bin: str,
cwd: str | None = None,
env: dict[str, Any] | None = None,
env: dict[str, t.Any] | None = None,
) -> None:
"""Minimal invoker for running subprocesses.

Expand All @@ -56,10 +56,10 @@ def __init__(
def run(
self,
*args: ExecArg,
stdout: None | int | IO = subprocess.PIPE,
stderr: None | int | IO = subprocess.PIPE,
stdout: None | int | t.IO = subprocess.PIPE,
stderr: None | int | t.IO = subprocess.PIPE,
text: bool = True,
**kwargs: Any,
**kwargs: t.Any,
) -> subprocess.CompletedProcess:
"""Run a subprocess. Simple wrapper around subprocess.run.

Expand Down
639 changes: 285 additions & 354 deletions poetry.lock

Large diffs are not rendered by default.

44 changes: 32 additions & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand All @@ -42,7 +41,7 @@ packages = [


[tool.poetry.dependencies]
python = "<3.12,>=3.7"
python = ">=3.8,<4"
structlog = ">=21,<24"
PyYAML = "^6.0.0"
pydantic = ">=1.9.0,<2"
Expand All @@ -65,9 +64,10 @@ docs = [
"sphinx-autobuild",
]

[tool.poetry.dev-dependencies]
mock = "^5.1.0"
[tool.poetry.group.dev.dependencies]
copier = ">=8.1.0,<9.0"
pytest = "^7.4.2"
types-pyyaml = "^6.0.12.4"
# Cookiecutter tests
mypy = "^1.4"
black = "^23.3"
Expand All @@ -76,15 +76,35 @@ flake8 = "^3.9.0"
flake8-annotations = "^2.9.1"
flake8-docstrings = "^1.7.0"

[tool.poetry.group.dev.dependencies]
copier = ">=8.1.0,<9.0"
types-pyyaml = "^6.0.12.4"
[tool.ruff]
ignore = [
"ANN101",
]
select = [
"E",
"F",
"B",
"I",
"ANN",
"D",
"UP",
]
target-version = "py38"

[tool.ruff.flake8-annotations]
allow-star-arg-any = true

[tool.ruff.per-file-ignores]
"docs/**" = [
"D",
]
"tests/**" = [
"ANN201",
"D",
]

[tool.isort]
profile = "black"
multi_line_output = 3 # Vertical Hanging Indent
src_paths = "meltano/edk"
known_first_party = ["meltano"]
[tool.ruff.pydocstyle]
convention = "google"

[build-system]
requires = [
Expand Down
2 changes: 1 addition & 1 deletion tests/copier_template/test_generated.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def test_copier_output(outdir: str):
data={
"admin_name": "John Doe",
"cli_prefix": "testflow",
"extension_description": "A meltano utility extension for testflow that wraps the /bin/notreal command.",
"extension_description": "A meltano utility extension for testflow that wraps the /bin/notreal command.", # noqa: E501
"extension_id": "testflow-ext",
"extension_name": "Testflow",
"extension_name_lower": "testflow",
Expand Down
11 changes: 6 additions & 5 deletions tests/test_process.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import asyncio
import typing as t
from unittest.mock import AsyncMock, Mock, patch

import pytest
from mock import AsyncMock, Mock, patch

from meltano.edk.process import Invoker


@pytest.fixture()
def process_mock_factory():
def _factory(name):
def _factory(name: str) -> Mock:
process_mock = Mock()
process_mock.name = name
process_mock.wait = AsyncMock(return_value=0)
Expand All @@ -20,7 +21,7 @@ def _factory(name):


@pytest.fixture()
def process_mock(process_mock_factory):
def process_mock(process_mock_factory: t.Callable[[str], Mock]) -> Mock:
process = process_mock_factory("echo")
process.stdout.at_eof.side_effect = (False, False, False, True)
process.stdout.readline = AsyncMock(
Expand All @@ -34,10 +35,10 @@ def process_mock(process_mock_factory):
return process


def test_exec(process_mock):
def test_exec(process_mock: Mock):
"""Verify that the Invoker._exec method works as expected."""

async def _test_exec():
async def _test_exec() -> None:
inv = Invoker("echo", cwd="/tmp", env={"FOO": "BAR"})
with patch("asyncio.create_subprocess_exec") as mock:
mock.return_value = process_mock
Expand Down