[FIX] analyse: make the module checker executable, and guard it
It shipped without the execute bit while carrying a shebang and a main, so it only ran when prefixed with python3 — and nothing said so before the attempt. The new test ties the two together in BOTH directions: a library module marked executable invites a run it cannot serve. --- FR --- Livré sans le bit d'exécution alors qu'il porte un shebang et un main : il ne se lançait qu'en le préfixant de python3, et rien ne le signalait avant l'essai. Le test neuf lie les deux dans LES DEUX SENS — un module de bibliothèque marqué exécutable invite à un lancement impossible. Assisted-by: Claude Opus 5
This commit is contained in:
parent
97d2ebec65
commit
50366673c2
2 changed files with 26 additions and 0 deletions
0
script/analyse/check_module_package.py
Normal file → Executable file
0
script/analyse/check_module_package.py
Normal file → Executable file
|
|
@ -566,5 +566,31 @@ class TestTheWiring(unittest.TestCase):
|
|||
self.assertEqual(entrees, branches)
|
||||
|
||||
|
||||
class TestThePermissions(unittest.TestCase):
|
||||
"""Shebang et exécutable vont ensemble, dans les deux sens.
|
||||
|
||||
Un outil livré sans le bit d'exécution ne se lance qu'en le préfixant
|
||||
de `python3`, et rien ne le signale avant l'essai. Un module de
|
||||
bibliothèque marqué exécutable invite à le lancer alors qu'il n'a pas
|
||||
de `main` — l'inverse est tout aussi trompeur.
|
||||
"""
|
||||
|
||||
DOSSIER = os.path.normpath(
|
||||
os.path.join(os.path.dirname(__file__), "..", "script", "analyse")
|
||||
)
|
||||
|
||||
def test_shebang_and_executable_bit_agree(self):
|
||||
import glob
|
||||
import stat
|
||||
|
||||
for chemin in sorted(glob.glob(os.path.join(self.DOSSIER, "*.py"))):
|
||||
with io.open(chemin, encoding="utf-8") as handle:
|
||||
shebang = handle.readline().startswith("#!")
|
||||
executable = bool(
|
||||
stat.S_IMODE(os.stat(chemin).st_mode) & stat.S_IXUSR
|
||||
)
|
||||
self.assertEqual(shebang, executable, os.path.basename(chemin))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Reference in a new issue