Set up mypy, Flake8, isort and pre-commit hooks

This commit is contained in:
Hugo Locurcio
2023-06-30 12:05:18 +02:00
parent e07127250e
commit be9acfddc4
7 changed files with 91 additions and 15 deletions

9
.editorconfig Normal file
View File

@@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true

3
.flake8 Normal file
View File

@@ -0,0 +1,3 @@
[flake8]
# Black is used for formatting, ignore Flake8's line length limits.
extend-ignore = E501

42
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,42 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
# Generic hooks, relevant for any language.
- id: forbid-new-submodules
- id: fix-byte-order-marker
- id: end-of-file-fixer
- id: trailing-whitespace
- id: mixed-line-ending
args:
- --fix=lf
- id: detect-private-key
- id: check-added-large-files
- id: check-merge-conflict
- id: check-vcs-permalinks
- id: check-json
- id: check-toml
- id: check-xml
- id: check-yaml
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- id: check-case-conflict
- id: check-symlinks
# Python-specific hooks.
- id: requirements-txt-fixer
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8

View File

@@ -65,7 +65,7 @@
}
function getChartColor(label) {
return chartColors[label] ?? '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6);
return chartColors[label] ?? '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6);
}
// Function that sums all values in an array (use with `reduce()`).

31
main.py
View File

@@ -1,23 +1,26 @@
#!/usr/bin/env python3
from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport
from dotenv import load_dotenv
import os
import json
import os
from typing import Any, Dict
from dotenv import load_dotenv
from gql import Client, gql
from gql.transport.aiohttp import AIOHTTPTransport
from typing_extensions import Final
def main() -> None:
load_dotenv()
transport = AIOHTTPTransport(
transport: Final = AIOHTTPTransport(
url="https://api.github.com/graphql",
headers={
"Authorization": f"Bearer {os.getenv('GODOT_ISSUES_STATS_GITHUB_TOKEN')}"
},
)
client = Client(transport=transport, fetch_schema_from_transport=True)
client: Final = Client(transport=transport, fetch_schema_from_transport=True)
results = []
results: Final = []
cursor = None
# Get the 30×100 = 3,000 last issues.
# TODO: Retry requests a few times if they fail.
@@ -52,13 +55,13 @@ def main() -> None:
cursor = result["repository"]["issues"]["edges"][0]["cursor"]
# Array of dictionaries with user and system information string.
user_system_infos = []
user_system_infos: Final = []
# Counters for all statistics (values are a set of usernames).
# A set is used, so that each user may only increment a given counter once.
# A single user may increment multiple counters in the same category,
# as they may report issues with different hardware or operating systems.
statistics = {
statistics: Dict[str, Any] = {
"os": {
"windows": {
"11": set(),
@@ -153,7 +156,6 @@ def main() -> None:
# Number of physical CPU cores.
# On CPUs with hybrid topologies (such as 12th generation Intel and newer),
# this is the sum of P-cores and E-cores.
"1": set(),
"2": set(),
"3": set(),
"4": set(),
@@ -310,7 +312,7 @@ def main() -> None:
# Handle deleted ("ghost") users.
user = (
node["node"]["author"]["login"]
if node["node"]["author"] != None
if node["node"]["author"] is not None
else "ghost"
)
# Fix CRLF line endings causing issues with detection,
@@ -2945,13 +2947,14 @@ def main() -> None:
):
statistics["gpu"]["intel"]["unknown"].add(user)
print(f"Number of scannable reports: {len(user_system_infos)}")
statistics["num_reports"] = len(user_system_infos)
print(f"Number of scannable reports: {statistics['num_reports']}")
output_path = "statistics.json"
output_path: Final = "statistics.json"
with open(output_path, "w") as out_file:
# Serialize Python sets as their length as an integer, since we only need to know how many users
# match each metric (and not who exactly).
def set_default(obj):
def set_default(obj: object) -> int:
if isinstance(obj, set):
return len(obj)
raise TypeError

16
mypy.ini Normal file
View File

@@ -0,0 +1,16 @@
[mypy]
strict = True
disallow_any_unimported = True
disallow_any_decorated = True
warn_unreachable = True
pretty = True
show_column_numbers = True
[mypy-gql]
ignore_missing_imports = True
[mypy-dotenv]
ignore_missing_imports = True
[mypy-gql.transport.aiohttp]
ignore_missing_imports = True

3
requirements.txt Normal file
View File

@@ -0,0 +1,3 @@
gql[all]==3.4.1
python-dotenv==1.0.0
typing_extensions==4.7.0