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

Add mypy to CI pipeline and begin typing modules #435

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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: 5 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ repos:
additional_dependencies:
- [email protected]
args: [src]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.790
hooks:
- id: mypy
files: ^(src/pytest_html|testing)
- repo: local
hooks:
- id: rst
Expand Down
17 changes: 17 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
[bdist_wheel]
universal = 0

[mypy]
check_untyped_defs = True
disallow_any_generics = True
disallow_incomplete_defs = True
disallow_untyped_calls = True
disallow_untyped_decorators = True
disallow_untyped_defs = True
ignore_missing_imports = True
no_implicit_optional = True
no_implicit_reexport = True
show_error_codes = True
strict_equality = True
warn_redundant_casts = True
warn_return_any = True
warn_unreachable = True
warn_unused_configs = True
2 changes: 1 addition & 1 deletion src/pytest_html/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
try:
from . import __version
from . import __version # type: ignore

__version__ = __version.version
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since __version is an optioanl import at the time typecheckers run,
i usggest to typehint __version__ ala

     __version__: str = __version.version 

this makes type checkers aware that __version__ is supposed to be a sting and warn/fail if it is not

except ImportError:
Expand Down
40 changes: 29 additions & 11 deletions src/pytest_html/extras.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from typing import Dict
from typing import Optional

FORMAT_HTML = "html"
FORMAT_IMAGE = "image"
Expand All @@ -10,7 +12,13 @@
FORMAT_VIDEO = "video"


def extra(content, format_type, name=None, mime_type=None, extension=None):
def extra(
content: str,
format_type: str,
name: Optional[str] = None,
mime_type: Optional[str] = None,
extension: Optional[str] = None,
) -> Dict[str, Optional[str]]:
return {
"name": name,
"format_type": format_type,
Expand All @@ -20,41 +28,51 @@ def extra(content, format_type, name=None, mime_type=None, extension=None):
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

html(), image() etc are facades to extra().

to make this more clear, i suggest to define a variable with the return type of extra() as _ExtraResult = Dict[str, Optional[str]]
and use this _ExtraResult where needed for extra(), html() and so on


def html(content):
def html(content: str) -> Dict[str, Optional[str]]:
return extra(content, FORMAT_HTML)


def image(content, name="Image", mime_type="image/png", extension="png"):
def image(
content: str,
name: str = "Image",
mime_type: str = "image/png",
extension: str = "png",
) -> Dict[str, Optional[str]]:
return extra(content, FORMAT_IMAGE, name, mime_type, extension)


def png(content, name="Image"):
def png(content: str, name: str = "Image") -> Dict[str, Optional[str]]:
return image(content, name, mime_type="image/png", extension="png")


def jpg(content, name="Image"):
def jpg(content: str, name: str = "Image") -> Dict[str, Optional[str]]:
return image(content, name, mime_type="image/jpeg", extension="jpg")


def svg(content, name="Image"):
def svg(content: str, name: str = "Image") -> Dict[str, Optional[str]]:
return image(content, name, mime_type="image/svg+xml", extension="svg")


def json(content, name="JSON"):
def json(content: str, name: str = "JSON") -> Dict[str, Optional[str]]:
return extra(content, FORMAT_JSON, name, "application/json", "json")


def text(content, name="Text"):
def text(content: str, name: str = "Text") -> Dict[str, Optional[str]]:
return extra(content, FORMAT_TEXT, name, "text/plain", "txt")


def url(content, name="URL"):
def url(content: str, name: str = "URL") -> Dict[str, Optional[str]]:
return extra(content, FORMAT_URL, name)


def video(content, name="Video", mime_type="video/mp4", extension="mp4"):
def video(
content: str,
name: str = "Video",
mime_type: str = "video/mp4",
extension: str = "mp4",
) -> Dict[str, Optional[str]]:
return extra(content, FORMAT_VIDEO, name, mime_type, extension)


def mp4(content, name="Video"):
def mp4(content: str, name: str = "Video") -> Dict[str, Optional[str]]:
return video(content, name)
1 change: 1 addition & 0 deletions src/pytest_html/hooks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# type: ignore
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a directive for an IDE extension or something? Like, maybe mypy? I am familiar with typing (use it all the time), but not the details of mypy.



def pytest_html_report_title(report):
Expand Down
1 change: 1 addition & 0 deletions src/pytest_html/html_report.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# type: ignore
import bisect
import datetime
import json
Expand Down
15 changes: 12 additions & 3 deletions src/pytest_html/outcome.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
from typing import Optional

from py.xml import html


class Outcome:
def __init__(self, outcome, total=0, label=None, test_result=None, class_html=None):
def __init__(
self,
outcome: str,
total: int = 0,
label: Optional[str] = None,
test_result: Optional[str] = None,
class_html: Optional[str] = None,
) -> None:
self.outcome = outcome
self.label = label or outcome
self.class_html = class_html or outcome
Expand All @@ -12,7 +21,7 @@ def __init__(self, outcome, total=0, label=None, test_result=None, class_html=No
self.generate_checkbox()
self.generate_summary_item()

def generate_checkbox(self):
def generate_checkbox(self) -> None:
checkbox_kwargs = {"data-test-result": self.test_result.lower()}
if self.total == 0:
checkbox_kwargs["disabled"] = "true"
Expand All @@ -27,7 +36,7 @@ def generate_checkbox(self):
**checkbox_kwargs,
)

def generate_summary_item(self):
def generate_summary_item(self) -> None:
self.summary_item = html.span(
f"{self.total} {self.label}", class_=self.class_html
)
1 change: 1 addition & 0 deletions src/pytest_html/plugin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# type: ignore
import os

import pytest
Expand Down
1 change: 1 addition & 0 deletions src/pytest_html/result.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# type: ignore
import json
import os
import re
Expand Down
6 changes: 4 additions & 2 deletions src/pytest_html/util.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import importlib
from functools import lru_cache
from types import ModuleType
from typing import Optional


@lru_cache()
def ansi_support():
def ansi_support() -> Optional[ModuleType]:
try:
# from ansi2html import Ansi2HTMLConverter, style # NOQA
return importlib.import_module("ansi2html")
except ImportError:
# ansi2html is not installed
pass
return None
1 change: 1 addition & 0 deletions testing/test_pytest_html.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# type: ignore
import builtins
import json
import os
Expand Down