In `get_enums_of_object()` fehlt das ``return``, und man kann das als „comprehension“ formulieren.
Nur weil's zu selten verwendet wird habe ich mal `contextlib.suppress()` an passender Stelle eingebaut.
Ich würde den Import von `Qsci` auch an den Anfang verschieben. Oder alternativ die Importe nicht mit ``import`` machen, sondern mit `importlib` dynamisch. Jedenfalls alle an einem Ort und nicht zwischen fast ganz oben und fast ganz unten im Code aufgeteilt.
`loop_directory()` macht nicht so wirklich viel ”eigenes”, das würde ich in die Hauptfunktion integrieren und den ”eine Datei Fall” so ändern, dass der Code auch dafür geht.
Zwischenstand (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
import enum
import sys
from contextlib import suppress
from inspect import getmembers
from pathlib import Path
from PyQt6 import QtCore, QtGui, QtWidgets
try:
from PyQt6 import Qsci
except ImportError:
Qsci = object()
def get_enums_of_object(obj):
return {
name: [attribute.name for attribute in member]
for name, member in getmembers(obj)
if isinstance(member, enum.EnumMeta)
}
def parse_pyqt_object(module):
result = {}
for name, obj in getmembers(module):
if not name.startswith("_"):
with suppress(RuntimeError):
result[name] = get_enums_of_object(obj)
return result
def replace_in_file(path, data):
try:
content = path.read_text(encoding="utf8")
except IOError:
print(f"Can't read {path!a}", file=sys.stderr)
return
for module, enums in data.items():
for enum, attributes in enums.items():
for name in attributes:
content = content.replace(
f"{module}.{name}", f"{module}.{enum}.{name}"
)
path.write_text(content, encoding="utf8")
def main():
if len(sys.argv) < 2:
print("Usage: PyQtEnumConverter <file/directory>", file=sys.stderr)
sys.exit(1)
target = Path(sys.argv[1])
if not target.exists():
print(f"{target!a} does not exists", file=sys.stderr)
sys.exit(1)
data = {}
for module in [QtWidgets, QtCore, QtGui, Qsci]:
data.update(parse_pyqt_object(module))
for filename in target.rglob("*.py") if target.is_dir() else [target]:
if filename.is_file():
replace_in_file(filename, data)
if __name__ == "__main__":
main()
Ich würde da noch zwei Ansätze verfolgen/ausprobieten:
a) schauen ob/wie man es hinbekommt das gesamte `PyQt6`-Package rekursiv dynamisch zu importieren, statt manuell Modulnamen in den Code schreiben zu müssen.
b) die Enums versuchen ”von der anderen Seite” her zu ermitteln. Also nicht alle Module und Objekte abklappern, sondern nach dem Importieren von `enum.Enum.__subclasses__()` aus alles zu suchen, dessen voll qualifizierter Name mit `PyQt6` anfängt. Und da dann mal Ergebnisse und Laufzeiten vergleichen. Rein aus interesse.