Skip to content

Commit

Permalink
Introduce typing and run mypy checks - cloes #474
Browse files Browse the repository at this point in the history
  • Loading branch information
fizyk committed Jul 28, 2023
1 parent 4de00c8 commit 47cf89e
Show file tree
Hide file tree
Showing 14 changed files with 238 additions and 118 deletions.
1 change: 1 addition & 0 deletions .github/workflows/linters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ jobs:
pipenv-install-options: "--skip-lock"
ruff: true
black: true
mypy: true
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: true
matrix:
python-version: [3.7, 3.8, 3.9, "3.10", "3.11", pypy-3.8]
python-version: [3.8, 3.9, "3.10", "3.11", pypy-3.8]
env:
OS: ubuntu-latest
PYTHON: ${{ matrix.python-version }}
Expand Down
5 changes: 4 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name = "pypi"

[packages]
pytest = "==7.3.2"
port-for = "==0.7.0"
port-for = "==0.7.1"
mirakuru = "==2.5.1"
elasticsearch = "==8.9"

Expand All @@ -16,3 +16,6 @@ pytest-xdist = "==3.3.1"
pytest-cov = "==4.1.0"
mock = "==5.0.2"
ruff = "==0.0.272"
types-setuptools = "==68.0.0.3"
mypy = "==1.4.1"
types-mock = "==5.1.0.1"
64 changes: 60 additions & 4 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[mypy]
allow_redefinition = False
allow_untyped_globals = False
check_untyped_defs = True
disallow_incomplete_defs = True
disallow_subclassing_any = True
disallow_untyped_calls = True
disallow_untyped_decorators = True
disallow_untyped_defs = True
follow_imports = silent
ignore_missing_imports = False
implicit_reexport = False
no_implicit_optional = True
pretty = True
show_error_codes = True
strict_equality = True
warn_no_return = True
warn_return_any = True
warn_unreachable = True
warn_unused_ignores = True
1 change: 1 addition & 0 deletions newsfragments/474.break.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Dropped support for python 3.7
1 change: 1 addition & 0 deletions newsfragments/474.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Package is fully typed and mypy checked.
25 changes: 15 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ classifiers = [
]
dependencies = [
"pytest >= 6.2",
"port-for >= 0.6.0",
"port-for >= 0.7.1",
"mirakuru",
"elasticsearch",
]
requires-python = ">= 3.7"
requires-python = ">= 3.8"

[project.urls]
"Source" = "https://github.com/ClearcodeHQ/pytest-elasticsearch"
Expand Down Expand Up @@ -80,23 +80,28 @@ single_file=true
filename="CHANGES.rst"
issue_format="`#{issue} <https://github.com/ClearcodeHQ/pytest-elasticsearch/issues/{issue}>`_"

[tool.towncrier.fragment.feature]
name = "Features"
[[tool.towncrier.type]]
directory = "break"
name = "Breaking changes"
showcontent = true

[tool.towncrier.fragment.depr]
[[tool.towncrier.type]]
directory = "depr"
name = "Deprecations"
showcontent = true

[tool.towncrier.fragment.bugfix]
name = "Bugfixes"
[[tool.towncrier.type]]
directory = "feature"
name = "Features"
showcontent = true

[tool.towncrier.fragment.break]
name = "Breaking changes"
[[tool.towncrier.type]]
directory = "bugfix"
name = "Bugfixes"
showcontent = true

[tool.towncrier.fragment.misc]
[[tool.towncrier.type]]
directory = "misc"
name = "Miscellaneus"
showcontent = false

Expand Down
34 changes: 34 additions & 0 deletions pytest_elasticsearch/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from pathlib import Path
from typing import TypedDict, Optional, Any

from pytest import FixtureRequest


class ElasticsearchConfigDict(TypedDict):
"""Typed Config dictionary."""

executable: Path
host: str
port: Optional[int]
transport_tcp_port: Optional[int]
cluster_name: str
network_publish_host: str
index_store_type: str


def get_config(request: FixtureRequest) -> ElasticsearchConfigDict:
"""Return a dictionary with config options."""

def get_elasticsearch_option(option: str) -> Any:
name = "elasticsearch_" + option
return request.config.getoption(name) or request.config.getini(name)

return ElasticsearchConfigDict(
executable=get_elasticsearch_option("executable"),
host=get_elasticsearch_option("host"),
port=get_elasticsearch_option("port"),
transport_tcp_port=get_elasticsearch_option("transport_tcp_port"),
cluster_name=get_elasticsearch_option("cluster_name"),
network_publish_host=get_elasticsearch_option("network_publish_host"),
index_store_type=get_elasticsearch_option("index_store_type"),
)
68 changes: 34 additions & 34 deletions pytest_elasticsearch/executor.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
"""Elasticsearch executor."""

import re
from pathlib import Path
from subprocess import check_output
from typing import Literal, Optional

from mirakuru import HTTPExecutor
from pkg_resources import parse_version
from packaging.version import Version


class NoopElasticsearch: # pylint:disable=too-few-public-methods
"""No operation Elasticsearch executor mock."""

def __init__(self, host, port):
def __init__(self, host: str, port: int) -> None:
"""Initialize Elasticsearch executor mock.
:param str host: hostname under which elasticsearch is available
Expand All @@ -20,7 +22,7 @@ def __init__(self, host, port):
self.port = port

@staticmethod
def running():
def running() -> Literal[True]:
"""Mock method pretending the executor is running."""
return True

Expand All @@ -31,35 +33,35 @@ class ElasticSearchExecutor(HTTPExecutor):

def __init__(
self,
executable,
host,
port,
tcp_port,
pidfile,
logs_path,
works_path,
cluster_name,
network_publish_host,
index_store_type,
timeout,
): # pylint:disable=too-many-arguments
executable: Path,
host: str,
port: int,
tcp_port: int,
pidfile: Path,
logs_path: Path,
works_path: Path,
cluster_name: str,
network_publish_host: str,
index_store_type: str,
timeout: int,
) -> None: # pylint:disable=too-many-arguments
"""Initialize ElasticSearchExecutor.
:param pathlib.Path executable: Executable path
:param str host: hostname under which elasticsearch will be running
:param int port: port elasticsearch listens on
:param int tcp_port: port used for internal communication
:param pathlib.Path pidfile: pidfile location
:param pathlib.Path logs_path: log files location
:param pathlib.Path works_path: workdir location
:param str cluster_name: cluster name
:param str network_publish_host: network host to which elasticsearch
:param executable: Executable path
:param host: hostname under which elasticsearch will be running
:param port: port elasticsearch listens on
:param tcp_port: port used for internal communication
:param pidfile: pidfile location
:param logs_path: log files location
:param works_path: workdir location
:param cluster_name: cluster name
:param network_publish_host: network host to which elasticsearch
publish to connect to cluseter'
:param str index_store_type: type of the index to use in the
:param index_store_type: type of the index to use in the
elasticsearch process fixture
:param int timeout: Time after which to give up to start elasticsearch
:param timeout: Time after which to give up to start elasticsearch
"""
self._version = None
self._version: Optional[Version] = None
self.executable = executable
self.host = host
self.port = port
Expand All @@ -78,11 +80,10 @@ def __init__(
)

@property
def version(self):
def version(self) -> Version:
"""Get the given elasticsearch executable version parts.
:return: Elasticsearch version
:rtype: pkg_resources.Version
"""
if not self._version:
try:
Expand All @@ -95,7 +96,7 @@ def version(self):
"Output is: " + output
)
version = match.groupdict()
self._version = parse_version(
self._version = Version(
".".join([version["major"], version["minor"], version["patch"]])
)
except OSError as exc:
Expand All @@ -104,16 +105,15 @@ def version(self):
) from exc
return self._version

def _exec_command(self):
def _exec_command(self) -> str:
"""Get command to run elasticsearch binary based on the version.
:return: command to run elasticsearch
:rtype: str
"""
port_param = "transport.port"
if self.version < parse_version("7.0.0"):
if self.version < Version("7.0.0"):
raise RuntimeError("This elasticsearch version is not supported.")
elif self.version < parse_version("8.0.0"):
elif self.version < Version("8.0.0"):
port_param = "transport.tcp.port"
else:
port_param = "transport.port"
Expand Down
Loading

0 comments on commit 47cf89e

Please sign in to comment.