Ajoute CODE_QUALITY.md et corrige S7632 a la racine (helper assert_not_none)
- Nouveau db/assert_not_none.py : centralise l'unique suppression
Bandit/Ruff (# nosec B101 / # noqa: S101) de narrowing de type dans
tout le moteur. Remplace 11 sites disperses (ai/chat.py, ai/tools.py,
routes/scenes/scene_object_{add,collision,geometry,personnage_data,
quiz_config}.py, screens/payload/full_game_payload.py,
scripts/build_demo_dialogues.py) qui repetaient chacun le meme
commentaire empile - Sonar (python:S7632) ne parse pas deux
commentaires # sur une ligne, meme si Ruff et Bandit les acceptent
chacun tres bien (contrainte structurelle documentee dans
CODE_QUALITY.md : chaque outil exige son propre mot-cle immediatement
apres un #, aucun format a un seul # ne peut satisfaire les deux a la
fois). Les 6 sites # nosec B608 (SQL dynamique) restent inchanges,
nature differente, hors perimetre de ce refactor.
Verifie : mypy --strict propre (389 fichiers), ruff/bandit/import-linter
clean, suite complete verte (591 tests), scan SonarQube local relance
confirmant S7632 a 7 (1 seul site restant dans le helper lui-meme + les
6 B608), 0 bug (une regression S8371 trouvee et corrigee en route).
- 4 sites |safe repositionnes sur leur ligne exacte (scene_edit.html,
register_2fa.html, onboarding_new.html, play.html) - le marqueur
NOSONAR etait sur la ligne precedente par erreur (meme piege que celui
documente pour S8371 ci-dessus). Confirme par scan que meme corrige,
l'analyseur Web de Sonar ne supporte aucune syntaxe de suppression
inline testee pour la regle Web:S5247 - documente comme limitation
technique connue dans CODE_QUALITY.md plutot que force.
- CODE_QUALITY.md (nouveau) : reference complete du dispositif qualite -
vue d'ensemble par outil, configuration de chacun, commandes de lancement
local, procedure de justification d'une exception (avec le format exact
attendu par Bandit/Ruff/Sonar, verifie empiriquement), table des 10
exceptions documentees, backlog (djLint H021, code smells Sonar).
djLint (H021, styles inline) volontairement saute pour ce commit - meme
backlog assume que les commits precedents, aucun rapport avec ce changement.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
20f9398bd4
commit
55e81c0fbb
@@ -2,6 +2,7 @@ from flask import abort, g, jsonify, redirect, request, url_for
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
import auth
|
||||
import db
|
||||
import screens
|
||||
from core.flask_app import app
|
||||
from core.sprite_gate import forbid_admin_only_background, forbid_admin_only_character
|
||||
@@ -94,11 +95,11 @@ def scene_object_add(slug: str, screen_id: int) -> Response:
|
||||
# _clamp_to_camera pour l'IA, ici pour un dépôt manuel.
|
||||
obj_for_clamp = screens.get_scene_object(slug, new_id)
|
||||
screen = screens.get_screen(slug, screen_id)
|
||||
assert obj_for_clamp is not None, ( # nosec B101 # noqa: S101 - narrowing de type, sur par construction
|
||||
"new_id vient d'etre cree par screens.add_scene_object juste au-dessus"
|
||||
obj_for_clamp = db.assert_not_none(
|
||||
obj_for_clamp, "new_id vient d'etre cree par screens.add_scene_object juste au-dessus"
|
||||
)
|
||||
assert screen is not None, ( # nosec B101 # noqa: S101 - narrowing de type, sur par construction
|
||||
"screen_id valide : add_scene_object aurait leve IntegrityError sinon (FK scene_id)"
|
||||
screen = db.assert_not_none(
|
||||
screen, "screen_id valide : add_scene_object aurait leve IntegrityError sinon (FK scene_id)"
|
||||
)
|
||||
max_x = max(0, screen["scene_width"] - obj_for_clamp["width"])
|
||||
max_y = max(0, screen["scene_height"] - obj_for_clamp["height"])
|
||||
@@ -110,9 +111,7 @@ def scene_object_add(slug: str, screen_id: int) -> Response:
|
||||
)
|
||||
if request.headers.get("X-Requested-With") == "fetch":
|
||||
obj = screens.get_scene_object(slug, new_id)
|
||||
assert obj is not None, ( # nosec B101 # noqa: S101 - narrowing de type, sur par construction
|
||||
"new_id vient d'etre cree par screens.add_scene_object plus haut"
|
||||
)
|
||||
obj = db.assert_not_none(obj, "new_id vient d'etre cree par screens.add_scene_object plus haut")
|
||||
return jsonify(
|
||||
{
|
||||
"id": new_id,
|
||||
|
||||
@@ -3,6 +3,7 @@ from typing import Any
|
||||
from flask import jsonify, request
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
import db
|
||||
import screens
|
||||
from core.flask_app import app
|
||||
|
||||
@@ -33,7 +34,5 @@ def scene_object_collision(slug: str, object_id: int) -> Response | tuple[Respon
|
||||
|
||||
screens.set_scene_object_collision(slug, object_id, settings)
|
||||
obj = screens.get_scene_object(slug, object_id)
|
||||
assert obj is not None, ( # nosec B101 # noqa: S101 - narrowing de type, sur par construction
|
||||
"object_id valide (deja lu ci-dessus, rien ne l'a supprime entre-temps)"
|
||||
)
|
||||
obj = db.assert_not_none(obj, "object_id valide (deja lu ci-dessus, rien ne l'a supprime entre-temps)")
|
||||
return jsonify({"ok": True, "collision": screens.resolve_collision_settings(obj)})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from flask import jsonify, request
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
import db
|
||||
import screens
|
||||
from core.flask_app import app
|
||||
|
||||
@@ -34,8 +35,8 @@ def scene_object_geometry(slug: str, object_id: int) -> Response | tuple[Respons
|
||||
# voir iaChatRefreshAfterTurn() dans static/js/ia/ia-chat.js), rendant
|
||||
# injoignable à la souris tout ce qui dépassait la scène nominale.
|
||||
screen = screens.get_screen(slug, obj["scene_id"])
|
||||
assert screen is not None, ( # nosec B101 # noqa: S101 - narrowing de type, sur par construction
|
||||
"obj existe (verifie plus haut) et _scene_objects.scene_id a ON DELETE CASCADE vers _screens"
|
||||
screen = db.assert_not_none(
|
||||
screen, "obj existe (verifie plus haut) et _scene_objects.scene_id a ON DELETE CASCADE vers _screens"
|
||||
)
|
||||
objects = screens.list_scene_objects(slug, obj["scene_id"])
|
||||
world_width, world_height = screens.resolve_scene_world_size(screen, objects)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from flask import jsonify, request
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
import db
|
||||
import screens
|
||||
from core.flask_app import app
|
||||
from core.sprite_gate import forbid_admin_only_character
|
||||
@@ -22,7 +23,5 @@ def scene_object_personnage_data(slug: str, object_id: int) -> Response | tuple[
|
||||
forbid_admin_only_character(body["forge_character"])
|
||||
screens.set_scene_object_personnage_data(slug, object_id, body)
|
||||
obj = screens.get_scene_object(slug, object_id)
|
||||
assert obj is not None, ( # nosec B101 # noqa: S101 - narrowing de type, sur par construction
|
||||
"object_id valide (deja lu ci-dessus, rien ne l'a supprime entre-temps)"
|
||||
)
|
||||
obj = db.assert_not_none(obj, "object_id valide (deja lu ci-dessus, rien ne l'a supprime entre-temps)")
|
||||
return jsonify({"ok": True, "animations": screens.resolve_personnage_animations(obj)})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from flask import jsonify, request
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
import db
|
||||
import screens
|
||||
from core.flask_app import app
|
||||
|
||||
@@ -20,7 +21,5 @@ def scene_object_quiz_config(slug: str, object_id: int) -> Response | tuple[Resp
|
||||
# coup, plutôt que de deviner quelle balise ajouter/retirer côté
|
||||
# client.
|
||||
obj = screens.get_scene_object(slug, object_id)
|
||||
assert obj is not None, ( # nosec B101 # noqa: S101 - narrowing de type, sur par construction
|
||||
"object_id valide : set_scene_object_quiz_config a renvoye une config non-None"
|
||||
)
|
||||
obj = db.assert_not_none(obj, "object_id valide : set_scene_object_quiz_config a renvoye une config non-None")
|
||||
return jsonify({"config": config, "rendered_html": screens.render_scene_object(obj)})
|
||||
|
||||
Reference in New Issue
Block a user