pyproject.toml devient le point d'entree unique de configuration des outils
(pytest.ini supprime, sa config y est deplacee). Les dependances restent dans
requirements.txt/requirements-dev.txt (deja utilises par setup.bat) plutot que
dupliquees ici : ce projet se distribue par PyInstaller, pas par "pip install".
ruff : configure puis passe sur tout app/ + tests/ (154 corrections
automatiques, purement mecaniques - tri des imports, imports multiples sur une
ligne separes, alias depreciees) suivies de 7 corrections manuelles ciblees :
- app/ssh_connection.py : `raise ... from None` pour le refus explicite de
passphrase (ce n'est pas un echec a diagnostiquer).
- app/controllers/workspace_manager.py : zip() sans strict= documente en
commentaire (deliberement tolerant a un workspace legerement perime).
- tests/test_ai_redaction.py : nom de variable ambigu renomme.
- E702 (construction compacte "widget = X(); widget.setY(...)" dans
sftp_panel.py/tunnel_dialog.py) et E402 (quelques tests qui importent un
symbole juste avant la section qui l'utilise) : ignores explicitement, ce
sont des styles deliberes preexistants, pas des oublis.
`ruff check app main.py tests` est desormais propre.
pyright : mode "basic" (le code n'a jamais ete type). Plus de 200 signalements
sur ~300 etaient le meme faux positif connu de l'ecosysteme PySide6 (acces
plat aux enums Qt, ex. Qt.UserRole, valide a l'execution mais que les stubs ne
reconnaissent que sous leur forme imbriquee) : desactive avec justification en
commentaire. Reste un socle de 77 signalements reels (surtout des acces
Optional non filtres dans app/ui/tabs.py et app/ssh_connection.py) : non
corrige dans cette phase - resserrer le typage la ou pyright a raison est un
travail a part, pas une consequence automatique de l'ajout de l'outil. La CI
le lance en mode informatif (continue-on-error) tant que ce socle n'est pas
resorbe.
.gitea/workflows/ci.yml : lint (ruff, bloquant), tests (pytest, bloquant),
typecheck (pyright, informatif), build (PyInstaller, sur main uniquement,
artefact du dossier portable). Necessite un runner Gitea Actions Windows
enregistre - PySide6/pywinpty/Credential Manager/ACL NTFS sont Windows
uniquement, comme l'application elle-meme ; non verifiable depuis ce poste.
Suite complete revalidee apres coup (33/33) pour confirmer qu'aucune des 154
corrections automatiques n'a modifie de comportement.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
62 lines
2.6 KiB
TOML
62 lines
2.6 KiB
TOML
[project]
|
|
name = "pyssh-client"
|
|
version = "0.1.0"
|
|
description = "Client SSH/SFTP local (PySide6) : terminaux, tunnels, snippets, workspaces, assistant IA optionnel"
|
|
readme = "README.md"
|
|
requires-python = ">=3.10"
|
|
|
|
# Les dependances (runtime et dev) restent dans requirements.txt /
|
|
# requirements-dev.txt, deja utilises par setup.bat et la CI : les dupliquer
|
|
# ici cree un risque de desynchronisation pour aucun benefice reel, puisque
|
|
# le projet se distribue par PyInstaller (voir PySSHClient.spec), pas par
|
|
# "pip install". Ce fichier sert de point d'entree unique pour la
|
|
# configuration des outils (ruff, pytest, pyright).
|
|
|
|
[tool.ruff]
|
|
line-length = 110
|
|
target-version = "py310"
|
|
extend-exclude = ["venv", "build", "dist"]
|
|
|
|
[tool.ruff.lint]
|
|
select = ["E", "F", "I", "UP", "B"]
|
|
ignore = [
|
|
"E501", # ligne trop longue : laisse au formateur, pas bloquant en l'etat
|
|
"E702", # construction compacte "widget = X(); widget.setY(...)" deliberee
|
|
# dans les panneaux SFTP/tunnels (un widget + sa config tiennent sur
|
|
# une ligne) : reecrire l'existant pour ca serait pur churn.
|
|
"E402", # plusieurs tests importent un symbole juste avant la section qui
|
|
# l'utilise pour la premiere fois, plutot qu'en haut du fichier -
|
|
# lisible dans des scripts sequentiels longs, et sans risque tant
|
|
# que l'import n'a pas d'effet de bord ordonne.
|
|
]
|
|
|
|
[tool.ruff.lint.isort]
|
|
known-first-party = ["app"]
|
|
|
|
[tool.pytest.ini_options]
|
|
testpaths = ["tests"]
|
|
python_files = ["test_all_scripts.py"]
|
|
|
|
[tool.pyright]
|
|
include = ["app", "main.py"]
|
|
exclude = ["venv", "build", "dist", "tests"]
|
|
venvPath = "."
|
|
venv = "venv"
|
|
# "basic" plutot que "strict" : le code n'a jamais ete type jusqu'ici, un mode
|
|
# strict noierait les vrais signaux sous des milliers d'avertissements de
|
|
# typage progressif. A resserrer progressivement, fichier par fichier.
|
|
typeCheckingMode = "basic"
|
|
pythonVersion = "3.10"
|
|
reportMissingImports = true
|
|
# Desactive : plus de 200 occurrences sont l'acces "plat" aux enums Qt
|
|
# (Qt.UserRole, QToolButton.InstantPopup...) - un style PyQt5 historique que
|
|
# PySide6 continue de supporter a l'execution, mais que ses stubs ne
|
|
# reconnaissent qu'a travers leur forme imbriquee (Qt.ItemDataRole.UserRole).
|
|
# Utilise partout dans ce projet, sans exception, et sans le moindre risque
|
|
# reel : le desactiver evite de noyer les vrais signaux. Le reste (une
|
|
# vingtaine de cas ou pyright perd le fil sur des patterns dynamiques - le
|
|
# monkey-patching de pyte dans terminal_widget.py, les QWidget generiques de
|
|
# split_pane.py) reste dans le rapport, a regarder au cas par cas plutot que
|
|
# supprime en bloc.
|
|
reportAttributeAccessIssue = false
|