[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
This commit is contained in:
pre-commit-ci[bot] 2024-12-21 10:48:43 +00:00
parent d44e079516
commit 027f55ae8e

View File

@ -47,6 +47,7 @@ import inspect
import json
import os
import sys
from collections import defaultdict
from collections.abc import Sequence
from enum import Enum
@ -59,6 +60,7 @@ try:
import qgis.analysis as qgis_analysis # noqa: F403
import qgis.core as qgis_core # noqa: F403
import qgis.gui as qgis_gui # noqa: F403
from PyQt6 import (
Qsci,
QtCore,
@ -108,7 +110,7 @@ try:
except NameError:
target_modules = None
#TODO REMOVE!!!
# TODO REMOVE!!!
target_modules = None
# qmetatype which have been renamed
@ -177,14 +179,18 @@ rename_function_attributes = {"exec_": "exec"}
rename_function_definitions = {"exec_": "exec"}
import_warnings = {"QRegExp": "QRegExp is removed in Qt6, please use QRegularExpression for Qt5/Qt6 compatibility"}
import_warnings = {
"QRegExp": "QRegExp is removed in Qt6, please use QRegularExpression for Qt5/Qt6 compatibility"
}
qt_enums = {}
ambiguous_enums = defaultdict(set)
def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambiguous_enums: dict) -> int:
def fix_file(
filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambiguous_enums: dict
) -> int:
with open(filename, encoding="UTF-8") as f:
contents = f.read()
@ -246,7 +252,9 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
for i in range(start_index + 1, start_index + 3):
tokens[i] = tokens[i]._replace(src="")
custom_updates[Offset(_node.lineno, _node.col_offset)] = _invalid_qvariant_to_null
custom_updates[Offset(_node.lineno, _node.col_offset)] = (
_invalid_qvariant_to_null
)
elif (
len(_node.args) == 1
and isinstance(_node.args[0], ast.Attribute)
@ -266,7 +274,9 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
for i in range(start_index + 1, start_index + 6):
tokens[i] = tokens[i]._replace(src="")
custom_updates[Offset(_node.lineno, _node.col_offset)] = _fix_null_qvariant
custom_updates[Offset(_node.lineno, _node.col_offset)] = (
_fix_null_qvariant
)
elif isinstance(_node.func, ast.Name) and _node.func.id == "QDateTime":
if len(_node.args) == 8:
# QDateTime(yyyy, mm, dd, hh, MM, ss, ms, ts) doesn't work anymore,
@ -278,7 +288,9 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
i = start_index + 1
assert tokens[i].src == "("
tokens[i] = tokens[i]._replace(src="(QDate(")
while tokens[i].offset < Offset(_node.args[2].lineno, _node.args[2].col_offset):
while tokens[i].offset < Offset(
_node.args[2].lineno, _node.args[2].col_offset
):
i += 1
assert tokens[i + 1].src == ","
i += 1
@ -287,14 +299,22 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
while not tokens[i].src.strip():
tokens[i] = tokens[i]._replace(src="")
i += 1
while tokens[i].offset < Offset(_node.args[6].lineno, _node.args[6].col_offset):
while tokens[i].offset < Offset(
_node.args[6].lineno, _node.args[6].col_offset
):
i += 1
i += 1
assert tokens[i].src == ","
tokens[i] = tokens[i]._replace(src="),")
custom_updates[Offset(_node.lineno, _node.col_offset)] = _fix_qdatetime_construct
elif len(_node.args) == 1 and isinstance(_node.args[0], ast.Call) and _node.args[0].func.id == "QDate":
custom_updates[Offset(_node.lineno, _node.col_offset)] = (
_fix_qdatetime_construct
)
elif (
len(_node.args) == 1
and isinstance(_node.args[0], ast.Call)
and _node.args[0].func.id == "QDate"
):
# QDateTime(QDate(..)) doesn't work anymore,
# so port to more reliable QDateTime(QDate(...), QTime(0,0,0)) form
extra_imports["qgis.PyQt.QtCore"].update({"QTime"})
@ -305,18 +325,24 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
assert tokens[start_index + 2].src == "QDate"
assert tokens[start_index + 3].src == "("
i = start_index + 4
while tokens[i].offset < Offset(_node.args[0].end_lineno, _node.args[0].end_col_offset):
while tokens[i].offset < Offset(
_node.args[0].end_lineno, _node.args[0].end_col_offset
):
i += 1
assert tokens[i - 1].src == ")"
tokens[i - 1] = tokens[i - 1]._replace(src="), QTime(0, 0, 0)")
custom_updates[Offset(_node.lineno, _node.col_offset)] = _fix_qdatetime_construct
custom_updates[Offset(_node.lineno, _node.col_offset)] = (
_fix_qdatetime_construct
)
def visit_attribute(_node: ast.Attribute, _parent):
if isinstance(_node.value, ast.Name):
if _node.value.id == "qApp":
token_renames[Offset(_node.value.lineno, _node.value.col_offset)] = "QApplication.instance()"
token_renames[Offset(_node.value.lineno, _node.value.col_offset)] = (
"QApplication.instance()"
)
extra_imports["qgis.PyQt.QtWidgets"].update({"QApplication"})
removed_imports["qgis.PyQt.QtWidgets"].update({"qApp"})
if _node.value.id == "QVariant" and _node.attr == "Type":
@ -331,7 +357,9 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
tokens[start_index + 2] = tokens[start_index + 2]._replace(src="")
tokens[start_index + 3] = tokens[start_index + 3]._replace(src="")
custom_updates[Offset(node.lineno, node.col_offset)] = _replace_qvariant_type
custom_updates[Offset(node.lineno, node.col_offset)] = (
_replace_qvariant_type
)
if object_types.get(_node.value.id) in ("QFontMetrics", "QFontMetricsF"):
if _node.attr == "width":
sys.stderr.write(
@ -342,8 +370,14 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
elif isinstance(_node.value, ast.Call):
if _node.attr == "width" and (
(isinstance(_node.value.func, ast.Attribute) and _node.value.func.attr == "fontMetrics")
or (isinstance(_node.value.func, ast.Name) and _node.value.func.id == "QFontMetrics")
(
isinstance(_node.value.func, ast.Attribute)
and _node.value.func.attr == "fontMetrics"
)
or (
isinstance(_node.value.func, ast.Name)
and _node.value.func.id == "QFontMetrics"
)
):
sys.stderr.write(
f"{filename}:{_node.lineno}:{_node.col_offset} WARNING: QFontMetrics.width() "
@ -353,7 +387,11 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
def visit_subscript(_node: ast.Subscript, _parent):
if isinstance(_node.value, ast.Attribute):
if _node.value.attr == "activated" and isinstance(_node.slice, ast.Name) and _node.slice.id == "str":
if (
_node.value.attr == "activated"
and isinstance(_node.slice, ast.Name)
and _node.slice.id == "str"
):
sys.stderr.write(
f"{filename}:{_node.lineno}:{_node.col_offset} WARNING: activated[str] "
"has been removed in Qt6. Consider using QComboBox.activated instead if the string is not required, "
@ -405,8 +443,13 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
elif isinstance(node, ast.Assign):
visit_assign(node, parent)
if isinstance(node, ast.FunctionDef) and node.name in rename_function_definitions:
function_def_renames[Offset(node.lineno, node.col_offset)] = rename_function_definitions[node.name]
if (
isinstance(node, ast.FunctionDef)
and node.name in rename_function_definitions
):
function_def_renames[Offset(node.lineno, node.col_offset)] = (
rename_function_definitions[node.name]
)
if (
isinstance(node, ast.Attribute)
@ -435,7 +478,8 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
if not disambiguated:
possible_values = [
f"{node.value.id}.{e}.{node.attr}" for e in ambiguous_enums[(node.value.id, node.attr)]
f"{node.value.id}.{e}.{node.attr}"
for e in ambiguous_enums[(node.value.id, node.attr)]
]
sys.stderr.write(
f'{filename}:{node.lineno}:{node.col_offset} WARNING: ambiguous enum, cannot fix: {node.value.id}.{node.attr}. Could be: {", ".join(possible_values)}\n'
@ -459,7 +503,11 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
):
rename_qt_enums.append(Offset(node.lineno, node.col_offset))
elif isinstance(node, ast.ImportFrom) and node.module and node.module.startswith("PyQt5."):
elif (
isinstance(node, ast.ImportFrom)
and node.module
and node.module.startswith("PyQt5.")
):
fix_pyqt_import.append(Offset(node.lineno, node.col_offset))
for module, classes in extra_imports.items():
@ -514,7 +562,9 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
prev_token_index = token_index - 1
while True:
if tokens[prev_token_index].src.strip() in ("", ","):
tokens[prev_token_index] = tokens[prev_token_index]._replace(src="")
tokens[prev_token_index] = tokens[
prev_token_index
]._replace(src="")
prev_token_index -= 1
else:
break
@ -547,9 +597,13 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
while True:
if tokens[current_index].src in ("\n",):
tokens[current_index] = tokens[current_index]._replace(src="")
tokens[current_index] = tokens[
current_index
]._replace(src="")
break
tokens[current_index] = tokens[current_index]._replace(src="")
tokens[current_index] = tokens[current_index]._replace(
src=""
)
current_index += 1
else:
@ -563,7 +617,9 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
while tokens[token_index].src.strip() in ("", ",", ")"):
tokens[token_index] = tokens[token_index]._replace(src="")
token_index -= 1
tokens[token_index + 1] = tokens[token_index + 1]._replace(src=f", {additional_import_string})")
tokens[token_index + 1] = tokens[token_index + 1]._replace(
src=f", {additional_import_string})"
)
else:
tokens[token_index] = tokens[token_index]._replace(
src=f", {additional_import_string}{tokens[token_index].src}"
@ -585,7 +641,9 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
tokens[i + 2] = tokens[i + 2]._replace(src="qgis.PyQt")
if token.offset in function_def_renames and tokens[i].src == "def":
tokens[i + 2] = tokens[i + 2]._replace(src=function_def_renames[token.offset])
tokens[i + 2] = tokens[i + 2]._replace(
src=function_def_renames[token.offset]
)
if token.offset in token_renames:
tokens[i] = tokens[i]._replace(src=token_renames[token.offset])
@ -594,7 +652,9 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
counter = i
while tokens[counter].src != ".":
counter += 1
tokens[counter + 1] = tokens[counter + 1]._replace(src=member_renames[token.offset])
tokens[counter + 1] = tokens[counter + 1]._replace(
src=member_renames[token.offset]
)
if token.offset in fix_qt_enums:
assert tokens[i + 1].src == "."
@ -602,7 +662,9 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
# make sure we CAN import enum!
try:
eval(f"{_class}.{enum_name}.{value}")
tokens[i + 2] = tokens[i + 2]._replace(src=f"{enum_name}.{tokens[i + 2].src}")
tokens[i + 2] = tokens[i + 2]._replace(
src=f"{enum_name}.{tokens[i + 2].src}"
)
except AttributeError:
# let's see if we can find what the replacement should be automatically...
# print(f'Trying to find {_class}.{value}.')
@ -617,7 +679,9 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
if attr is actual.__class__:
# print(f'Found alias {_class}.{attr_name}')
recovered = True
tokens[i + 2] = tokens[i + 2]._replace(src=f"{attr_name}.{tokens[i + 2].src}")
tokens[i + 2] = tokens[i + 2]._replace(
src=f"{attr_name}.{tokens[i + 2].src}"
)
except AttributeError:
continue
@ -638,7 +702,12 @@ def fix_file(filename: str, in_place, qgis3_compat: bool, qt_enums: dict, ambigu
with open(filename, "w") as f:
f.write(new_contents)
else:
diff = difflib.unified_diff(contents.split("\n"), new_contents.split("\n"), fromfile=filename, tofile="fixed")
diff = difflib.unified_diff(
contents.split("\n"),
new_contents.split("\n"),
fromfile=filename,
tofile="fixed",
)
for line in diff:
print(line)
return new_contents != contents
@ -678,17 +747,28 @@ def get_class_enums(item, qt_enums: dict, ambiguous_enums: dict):
pass
if (matched_class.__name__, ekey) in ambiguous_enums:
if value.__name__ not in ambiguous_enums[(matched_class.__name__, ekey)]:
ambiguous_enums[(matched_class.__name__, ekey)].add(value.__name__)
if (
value.__name__
not in ambiguous_enums[(matched_class.__name__, ekey)]
):
ambiguous_enums[(matched_class.__name__, ekey)].add(
value.__name__
)
continue
existing_entry = qt_enums.get((matched_class.__name__, ekey))
if existing_entry != value.__name__ and existing_entry:
ambiguous_enums[(matched_class.__name__, ekey)].add(existing_entry)
ambiguous_enums[(matched_class.__name__, ekey)].add(value.__name__)
ambiguous_enums[(matched_class.__name__, ekey)].add(
existing_entry
)
ambiguous_enums[(matched_class.__name__, ekey)].add(
value.__name__
)
del qt_enums[(matched_class.__name__, ekey)]
else:
qt_enums[(matched_class.__name__, ekey)] = f"{value.__name__}"
qt_enums[(matched_class.__name__, ekey)] = (
f"{value.__name__}"
)
elif inspect.isclass(value):
enums = get_class_enums(value, qt_enums, ambiguous_enums)
@ -697,9 +777,13 @@ def get_class_enums(item, qt_enums: dict, ambiguous_enums: dict):
def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument("directory", nargs="?", default=os.getcwd())
parser.add_argument("-i", "--in-place", action="store_true", help="Apply changes in place")
parser.add_argument(
"--update-enum-file", action="store_true", help="Update enum file for usage without QGIS available"
"-i", "--in-place", action="store_true", help="Apply changes in place"
)
parser.add_argument(
"--update-enum-file",
action="store_true",
help="Update enum file for usage without QGIS available",
)
parser.add_argument(
"--qgis3-incompatible-changes",
@ -718,14 +802,18 @@ def main(argv: Sequence[str] | None = None) -> int:
my_json_object = json.dump(
{
"qt_enums": {":".join(k): v for k, v in qt_enums.items()},
"ambiguous_enums": {":".join(k): list(v) for k, v in ambiguous_enums.items()},
"ambiguous_enums": {
":".join(k): list(v) for k, v in ambiguous_enums.items()
},
},
enum_file,
)
return
if target_modules is None:
print("PyQt or QGIS classes not available for introspection, loading enums from cached file.")
print(
"PyQt or QGIS classes not available for introspection, loading enums from cached file."
)
filename = inspect.getframeinfo(inspect.currentframe()).filename
path = os.path.dirname(os.path.abspath(filename))
with open(Path(path) / "enums.json") as file:
@ -738,11 +826,17 @@ def main(argv: Sequence[str] | None = None) -> int:
ret = 0
for filename in glob.glob(os.path.join(args.directory, "**/*.py"), recursive=True):
print(f'Processing {filename}')
print(f"Processing {filename}")
if "auto_additions" in filename:
continue
ret |= fix_file(filename, args.in_place, not args.qgis3_incompatible_changes, qt_enums, ambiguous_enums)
ret |= fix_file(
filename,
args.in_place,
not args.qgis3_incompatible_changes,
qt_enums,
ambiguous_enums,
)
return ret