Skip to content

Linted pyi files #137

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

Merged
merged 18 commits into from
Sep 3, 2022
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
24 changes: 17 additions & 7 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
[flake8]
color=always
max-line-length=120
; Auto generated
exclude=src/gen/
; Linebreak before binary operator
; Allow default value other than "..."
; Allow imports at the bottom of file
ignore=W503,Y015,E402
exclude=
src/gen/, ; Auto generated
typings/cv2-stubs/__init__.pyi, ; External existing stub
ignore=
W503, ; Linebreak before binary operator
E402, ; Allow imports at the bottom of file
Y026, ; Not using typing_extensions
per-file-ignores=
; Docstrings in type stubs
; Function bodys contain other than just ... (eg: raise)
; Single quote docstrings
typings/cv2-stubs/__init__.pyi: Q000,N8,E704, Y021,Y010,Q002

; Quotes
__init__.pyi:Q000
; Allow ... on same line as def
; Line too long
; Naming conventions can't be controlled for external libraries
typings/**: Q000,E704,E501,N8

; PyQt methods
ignore-names=closeEvent,paintEvent,keyPressEvent,mousePressEvent,mouseMoveEvent,mouseReleaseEvent
; McCabe max-complexity is also taken care of by Pylint and doesn't fail the build there
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint-and-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
pip install -r "scripts/requirements.txt"
- run: scripts/compile_resources.bat
- name: Analysing the code with ${{ job.name }}
run: pylint --reports=y --output-format=colorized $(git ls-files '**/*.py*')
run: pylint --reports=y --output-format=colorized $(git ls-files '**/*.py')
Flake8:
runs-on: windows-latest
strategy:
Expand Down
19 changes: 7 additions & 12 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,14 @@
"python.linting.pylintCategorySeverity.convention": "Warning",
"python.linting.pylintCategorySeverity.refactor": "Warning",
"python.linting.flake8Enabled": true,
// pycodestyles
"python.linting.flake8CategorySeverity.E": "Warning",
// Pyflakes
"python.linting.flake8CategorySeverity.F": "Warning",
// PEP8 Naming convention
"python.linting.flake8CategorySeverity.N": "Warning",
// PYI
"python.linting.flake8CategorySeverity.Y": "Warning",
// PyRight obsoletes mypy
"python.linting.mypyEnabled": false,
// Is already wrapped by Flake8, prospector and pylama
Expand All @@ -69,16 +76,4 @@
// Just another wrapper, use Flake8 OR this
"python.linting.pylamaEnabled": false,
"python.linting.banditEnabled": true,
// Copy those over to your user settings
"sonarlint.rules": {
"python:S1192": {
"level": "off"
},
"python:S3776": {
"level": "off"
},
"python:S107": {
"level": "off"
},
},
}
29 changes: 15 additions & 14 deletions PyInstaller/hooks/hook-cv2.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
# ------------------------------------------------------------------
# Copyright (c) 2020 PyInstaller Development Team.
#
# This file is distributed under the terms of the GNU General Public
# License (version 2.0 or later).
#
# The full license is available in LICENSE.GPL.txt, distributed with
# this software.
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ------------------------------------------------------------------
# https://github.com/pyinstaller/pyinstaller-hooks-contrib/blob/master/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-cv2.py

from PyInstaller.utils.hooks import collect_dynamic_libs, collect_data_files
"""
Copyright (c) 2020 PyInstaller Development Team.

This file is distributed under the terms of the GNU General Public
License (version 2.0 or later).

The full license is available in LICENSE.GPL.txt, distributed with
this software.

SPDX-License-Identifier: GPL-2.0-or-later

https://github.com/pyinstaller/pyinstaller-hooks-contrib/blob/master/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-cv2.py
"""

from PyInstaller.utils.hooks import collect_data_files, collect_dynamic_libs

hiddenimports = ["numpy"]

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ This program can be used to automatically start, split, and reset your preferred

### Comparison Method

- There are three comparison methods to choose from: L2 Norm, Histograms, and pHash.
- There are three comparison methods to choose from: L2 Norm, Histograms, and Perceptual Hash (or pHash).
- L2 Norm: This method should be fine to use for most cases. it finds the difference between each pixel, squares it, and sums it over the entire image and takes the square root. This is very fast but is a problem if your image is high frequency. Any translational movement or rotation can cause similarity to be very different.
- Histograms: An explanation on Histograms comparison can be found [here](https://mpatacchiola.github.io/blog/2016/11/12/the-simplest-classifier-histogram-intersection.html). This is a great method to use if you are using several masked images.
- pHash: An explanation on pHash comparison can be found [here](http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html). It is highly recommended to NOT use pHash if you use masked images. It is very inaccurate.
- Perceptual Hash: An explanation on pHash comparison can be found [here](http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html). It is highly recommended to NOT use pHash if you use masked images. It is very inaccurate.

### Full Content Rendering

Expand Down
51 changes: 33 additions & 18 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,24 @@ aggressive = 3
pythonPlatform = "Windows"
typeCheckingMode = "strict"
# Extra strict
reportPropertyTypeMismatch=true
reportUninitializedInstanceVariable=true
reportCallInDefaultInitializer=true
reportImplicitStringConcatenation=true
reportImplicitStringConcatenation="error"
reportCallInDefaultInitializer="error"
reportMissingSuperCall="none" # False positives on base classes
reportPropertyTypeMismatch="error"
reportUninitializedInstanceVariable="error"
reportUnnecessaryTypeIgnoreComment="error"
reportUnusedCallResult="none"
ignore = [
# Auto generated
"src/gen/",
# We expect stub files to be incomplete or contain useless statements as they're external
# We expect stub files to be incomplete or contain useless statements
"typings/",
]
reportMissingTypeStubs = "information"
reportMissingTypeStubs = "warning"
# False positives with TYPE_CHECKING
reportImportCycles = "information"
# PyQt .connect
reportFunctionMemberAccess = "information"
# False positives with PyQt .connect . pylint(no-member) works instead
reportFunctionMemberAccess = "none"
# Extra runtime safety
reportUnnecessaryComparison = "warning"
# Flake8 does a better job
Expand All @@ -42,7 +45,7 @@ reportUnknownMemberType = "none"
# https://pylint.pycqa.org/en/latest/technical_reference/features.html
[tool.pylint.REPORTS]
# Just like default but any error will make drop to 9 or less
evaluation = "10.0 - error - ((float(warning * 10 + refactor + convention) / statement) * 10)"
evaluation = "10.0 - error - ((float((warning + convention) * 10 + refactor ) / statement) * 10)"
[tool.pylint.MASTER]
fail-under = 9.0
# https://pylint.pycqa.org/en/latest/technical_reference/extensions.html
Expand Down Expand Up @@ -70,14 +73,18 @@ load-plugins = [
# "pylint.extensions.comparison_placement",
# "pylint.extensions.for_any_all",
]
ignore-paths = [
# Auto generated (doesn't work)
ignore-paths = ["src/gen/.*"]
# We expect stub files to be incomplete or contain useless statements
ignore-patterns = [
".*\\.pyi",
# Auto generated
"^src/gen/.*$",
# We expect stub files to be incomplete or contain useless statements as they're external
"^typings/.*$",
"about.py",
"design.py",
"resources_rc.py",
"settings.py",
"update_checker.py",
]
# No need to mention the fixmes
disable = ["fixme"]
extension-pkg-allow-list = ["PyQt6", "win32ui"]

[tool.pylint.FORMAT]
Expand All @@ -87,8 +94,8 @@ max-line-length = 120
# Same as SonarLint
max-args = 7
# Arbitrary to 2 bytes
max-attributes = 16
max-locals = 16
max-attributes = 15
max-locals = 15

[tool.pylint.'MESSAGES CONTROL']
# Same as SonarLint
Expand All @@ -103,16 +110,24 @@ good-names = [
# PyQt methods
"closeEvent", "paintEvent", "keyPressEvent", "mousePressEvent", "mouseMoveEvent", "mouseReleaseEvent",
# https://github.com/PyCQA/pylint/issues/2018
"x", "y", "a0", "i", "t0", "t1"]
"id", "x", "y", "a0", "i", "t0", "t1"]
disable = [
# No need to mention the fixmes
"fixme",
"missing-docstring",
# We group imports
"wrong-import-position",
# Already taken care of and grayed out. Also conflicts with Pylance reportIncompatibleMethodOverride
"unused-argument",
# Already taken care of by Flake8
"unused-import",
# Similar lines in 2 files, doesn't really work
"R0801",
]

[tool.pylint.TYPECHECK]
generated-members = "cv2"

[tool.isort]
line_length = 120
combine_as_imports = true
2 changes: 1 addition & 1 deletion res/settings.ui
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@
</item>
<item>
<property name="text">
<string>pHash</string>
<string>Perceptual Hash</string>
</property>
</item>
</widget>
Expand Down
6 changes: 3 additions & 3 deletions scripts/install.bat
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
py -3.9 -m pip install wheel
py -3.9 -m pip install -r "%~p0requirements.txt"
npm install -g pyright
py -3.9 -m pip install wheel --upgrade
py -3.9 -m pip install -r "%~p0requirements.txt" --upgrade
npm install -g pyright@latest
CALL "%~p0compile_resources.bat"
2 changes: 1 addition & 1 deletion scripts/lint.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ if ($LastExitCode -gt 0) {
}

Write-Host "`nRunning Pylint..."
pylint --score=n --output-format=colorized $(git ls-files '**/*.py*')
pylint --score=n --output-format=colorized $(git ls-files '**/*.py')
$exitCodes += $LastExitCode
if ($LastExitCode -gt 0) {
Write-Host "`Pylint failed ($LastExitCode)" -ForegroundColor Red
Expand Down
9 changes: 6 additions & 3 deletions scripts/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ PySide6
pyautogui
pywin32
requests
# Linting and Types
# Linting, formatters and Types
bandit
isort
flake8
flake8-pyi
flake8-quotes
pylint
pywin32-stubs
flake8-isort
pylint>=2.13
git+https://github.com/Avasam/pywin32-stubs.git#egg=pywin32-stubs # https://github.com/kaluluosi/pywin32-stubs/pull/4
simplejson
types-simplejson>=3.17.2
types-requests
Expand Down
7 changes: 5 additions & 2 deletions src/AutoControlledWorker.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from __future__ import annotations

from typing import TYPE_CHECKING
if TYPE_CHECKING:
from AutoSplit import AutoSplit

from PyQt6 import QtCore

import error_messages
import settings_file as settings

if TYPE_CHECKING:
from AutoSplit import AutoSplit


class AutoControlledWorker(QtCore.QObject):
def __init__(self, autosplit: AutoSplit):
Expand Down
41 changes: 18 additions & 23 deletions src/AutoSplit.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,34 @@
# - Externals
# - Internals
from __future__ import annotations
from collections.abc import Callable
from types import FunctionType, TracebackType
from typing import Optional, Union

import sys
import os
import ctypes
import os
import signal
import sys
import traceback
from collections.abc import Callable
from time import time
from types import FunctionType, TracebackType
from typing import Optional, Union

import certifi
import cv2
from PyQt6 import QtCore, QtGui, QtTest
from PyQt6 import QtCore, QtGui
from PyQt6.QtTest import QTest
from PyQt6.QtWidgets import QApplication, QFileDialog, QMainWindow, QMessageBox, QWidget
from win32 import win32gui
from AutoSplitImage import COMPARISON_RESIZE, AutoSplitImage, ImageType

import error_messages
import settings_file as settings
from AutoControlledWorker import AutoControlledWorker
from AutoSplitImage import COMPARISON_RESIZE, AutoSplitImage, ImageType
from capture_windows import capture_region, set_ui_image
from gen import about, design, settings as settings_ui, update_checker
from hotkeys import send_command, after_setting_hotkey
from menu_bar import get_default_settings_from_ui, open_about, VERSION, open_settings, view_help, check_for_updates, \
open_update_checker
from screen_region import select_region, select_window, align_region, validate_before_parsing
from hotkeys import after_setting_hotkey, send_command
from menu_bar import (VERSION, check_for_updates, get_default_settings_from_ui, open_about, open_settings,
open_update_checker, view_help)
from screen_region import align_region, select_region, select_window, validate_before_parsing
from settings_file import FROZEN
from split_parser import BELOW_FLAG, DUMMY_FLAG, PAUSE_FLAG, parse_and_validate_images

Expand Down Expand Up @@ -343,13 +344,11 @@ def __start_image_function(self):
delay_time_left = start_delay - (time() - delay_start_time)
self.current_split_image.setText(
f"Delayed Before Starting:\n {seconds_remaining_text(delay_time_left)}")
# Email sent to [email protected]
QtTest.QTest.qWait(1) # type: ignore
QTest.qWait(1)

self.start_image_status_value_label.setText("started")
send_command(self, "start")
# Email sent to [email protected]
QtTest.QTest.qWait(int(1 / self.settings_dict["fps_limit"])) # type: ignore
QTest.qWait(int(1 / self.settings_dict["fps_limit"]))
self.start_auto_splitter()

# update x, y, width, height when spinbox values are changed
Expand Down Expand Up @@ -605,8 +604,7 @@ def __auto_splitter(self):

# limit the number of time the comparison runs to reduce cpu usage
frame_interval: float = 1 / self.settings_dict["fps_limit"]
# Email sent to [email protected]
QtTest.QTest.qWait(int(frame_interval - (time() - start) % frame_interval)) # type: ignore
QTest.qWait(int(frame_interval - (time() - start) % frame_interval))
QApplication.processEvents()

# comes here when threshold gets met
Expand Down Expand Up @@ -636,8 +634,7 @@ def __auto_splitter(self):
capture = self.__get_capture_for_comparison()
if self.__reset_if_should(capture):
continue
# Email sent to [email protected]
QtTest.QTest.qWait(1) # type: ignore
QTest.qWait(1)

self.waiting_for_split_delay = False

Expand Down Expand Up @@ -691,8 +688,7 @@ def __auto_splitter(self):
send_command(self, "reset")
self.reset()
continue
# Email sent to [email protected]
QtTest.QTest.qWait(1) # type: ignore
QTest.qWait(1)

# loop breaks to here when the last image splits
self.gui_changes_on_reset()
Expand Down Expand Up @@ -760,8 +756,7 @@ def __get_capture_for_comparison(self):
if capture is None:
# Try to recover by using the window name
self.live_image.setText("Trying to recover window...")
# https://github.com/kaluluosi/pywin32-stubs/issues/7
hwnd = win32gui.FindWindow(None, self.settings_dict["captured_window_title"]) # type: ignore
hwnd = win32gui.FindWindow(None, self.settings_dict["captured_window_title"])
# Don't fallback to desktop
if hwnd:
self.hwnd = hwnd
Expand Down
Loading