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) { 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()`). // Function that sums all values in an array (use with `reduce()`).

31
main.py
View File

@@ -1,23 +1,26 @@
#!/usr/bin/env python3 #!/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 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: def main() -> None:
load_dotenv() load_dotenv()
transport = AIOHTTPTransport( transport: Final = AIOHTTPTransport(
url="https://api.github.com/graphql", url="https://api.github.com/graphql",
headers={ headers={
"Authorization": f"Bearer {os.getenv('GODOT_ISSUES_STATS_GITHUB_TOKEN')}" "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 cursor = None
# Get the 30×100 = 3,000 last issues. # Get the 30×100 = 3,000 last issues.
# TODO: Retry requests a few times if they fail. # TODO: Retry requests a few times if they fail.
@@ -52,13 +55,13 @@ def main() -> None:
cursor = result["repository"]["issues"]["edges"][0]["cursor"] cursor = result["repository"]["issues"]["edges"][0]["cursor"]
# Array of dictionaries with user and system information string. # 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). # 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 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, # A single user may increment multiple counters in the same category,
# as they may report issues with different hardware or operating systems. # as they may report issues with different hardware or operating systems.
statistics = { statistics: Dict[str, Any] = {
"os": { "os": {
"windows": { "windows": {
"11": set(), "11": set(),
@@ -153,7 +156,6 @@ def main() -> None:
# Number of physical CPU cores. # Number of physical CPU cores.
# On CPUs with hybrid topologies (such as 12th generation Intel and newer), # On CPUs with hybrid topologies (such as 12th generation Intel and newer),
# this is the sum of P-cores and E-cores. # this is the sum of P-cores and E-cores.
"1": set(),
"2": set(), "2": set(),
"3": set(), "3": set(),
"4": set(), "4": set(),
@@ -310,7 +312,7 @@ def main() -> None:
# Handle deleted ("ghost") users. # Handle deleted ("ghost") users.
user = ( user = (
node["node"]["author"]["login"] node["node"]["author"]["login"]
if node["node"]["author"] != None if node["node"]["author"] is not None
else "ghost" else "ghost"
) )
# Fix CRLF line endings causing issues with detection, # Fix CRLF line endings causing issues with detection,
@@ -2945,13 +2947,14 @@ def main() -> None:
): ):
statistics["gpu"]["intel"]["unknown"].add(user) 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: 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 # 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). # match each metric (and not who exactly).
def set_default(obj): def set_default(obj: object) -> int:
if isinstance(obj, set): if isinstance(obj, set):
return len(obj) return len(obj)
raise TypeError 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