banniere.png
Document Actions

11/29/2006

Le coté obscur de la force

EXTERIEUR: PLANETE DAGOBAH -- JOUR

Avec Yoda accroché sur son dos, Luke grimpe sur les vignes qui entourent les marécages, pour atteindre le laboratoire de statistiques de Dagobah. Il continue sa formation, en pratiquant la programmation dirigée par les tests, en faisant des fakes, des mocks...

YODA: Code ! Test ! Oui.  La force d'un programmeur provient de la non-regression. Les tests arrêter tu ne dois jamais. Le coté obscur de la maintenabilité atteindre tu risques sans les tests. Facile à écrire tes paquets Python sans tests sont. Quand à arrêter les tests tu commences, le coté obscure tu te diriges vers. Ta destinée dominée sera.
        
LUKE: Mais ce n'est pas mieux sans tests ?

YODA: Non... non... non.  Plus facile, plus rapide, plus séduisant.

LUKE: Alors pourquoi faire des tests ?

YODA: Tu sauras. Dans six mois. Quand ton code de corriger tu essayeras.
--

adaptation du post Perl vs Python



Categories: tests 0 comments - commenter | Trackbacks (738) |

11/09/2006

Sortie du livre Turbogears

Le livre Rapid web application with Turbogears sort aujourd'hui. Les auteurs ont mis en place un site pour le suivi des errata. Vivement que ce soit dispo sur Amazon.fr..

Categories: documentation, livre 0 comments - commenter | Trackbacks (241) |

11/07/2006

Article: création d'un site de publication avec Zope 3

Avec l'aimable autorisation du magazine Programmation sous Linux, voici l'article "Création d'un site de publication avec Zope 3" paru cet été.

Il a été écrit à l'époque pour Zope 3.2.1, mais reste d'actualité car il introduit les concepts généraux. Il propose un système de publication ultra-light (pas de versions, pas d'historique, pas de lock) basé sur le reStructuredText, qui permet de gérèr son site comme un wiki.

Je joins également le code source du tutorial à ce billet. (validé uniquement sur Zope 3.2.1)

pdf Article  tarball Code source
Categories: coding, documentation, zope 0 comments - commenter | Trackbacks (179) |

Un meta-feed

Il y a quelques mois, j'avais lancé un petit projet appelé Atomisator, épaulé par Olivier Grisel. L'objectif était de fournir un aggrégateur de flux rss un peu plus "intelligent" que les outils existants. Il devait faire le tri de n flux entrants, pour proposer un flux unique sans doublons, puis offrir des fonctionnalités de filtrage.

Ce projet devait fournir un moteur et une interface en wxPython. Le moteur marche à peut prêt, et en attendant que l'interface fonctionne complètement, j'ai mis en ligne une version light, mais fonctionnelle:

http://programmation-python.org/metafeed/buzz

  • Le flux "general" est un merge de quelques 10 flux anglais sur le développement
  • Le flux "python" est basé sur la même collection, mais avec un système de filtre
  • Le "buzz-o-meter" affiche les 50 mots les plus fréquemment rencontrés par le moteur lors de son dernier passage

Le projet a été démarré sur gna! à cet endroit, et ne continuera peut être pas, mais en attendant les flux générés ont bien réduit le nombre de flux dans mon client de feeds.

Si vous voulez tester le système sur vos flux, n'hésitez pas à me contacter pour que je mette en place un flux custom pour vous.


Categories: coding, documentation 0 comments - commenter | Trackbacks (631) |

11/01/2006

Protéger une base de code Python avec Subversion

Dans un projet ouvert à des contributeurs externes, susceptibles de modifier des codes sources, il y a quelques éceuils à éviter pour ne pas que la base de code soit "cassé".

Je ne parle pas ici du code reviewing mais de la prévention qu'il faut mettre en place pour protéger les sources de mauvaises manipulations. Les deux cas les plus fréquents sont:

  • l'insertion de tabulations dans le code
  • l'insertion par certains éditeurs de code sous windows, de carriage return avant les sauts de lignes

Ces deux problèmes peuvent tout simplement provoquer des erreurs, et parasiter le travail des développeurs.

Au lieu de lutter contre ces ajouts, de traquer les responsables ;), le plus simple est de mettre en place un contrôle automatique au niveau du dépôt de code centralisé.

Nettoyer automatiquement les sources entrants n'est pas une bonne solution, car les développeurs qui provoquent ces problèmes peuvent rester dans l'ignorance, et continuer à travailler sans corriger leur éditeur. Le mieux consiste à tout simplement bloquer les commits qui ne sont pas "valides".

Subversion propose un système de hook, qui permet de lancer un script Python à chaque commit, et de renvoyer un message au commiteur en cas d'erreur.

J'ai récupéré un script sur le web, que j'ai adapté. Le voici:
#!/usr/bin/python2.4
# -*- coding: UTF-8 -*-
# adapted from:
# http://blog.wordaligned.org/articles/2006/08/09/a-subversion-pre-commit-hook
# by Tarek Ziadé from subprocess import Popen from subprocess import PIPE import re import os re_options = re.IGNORECASE | re.MULTILINE | re.DOTALL class EOF(object): def findall(self, content): if content.endswith('\n'): return [] return ['\n'] tab_catcher = re.compile(r'^\t', re_options) windows_catcher = re.compile(r'\r\n$', re_options) testers = (('found TAB', tab_catcher), ('found CR/LF', windows_catcher), ('no new line at the end', EOF())) def command_output(cmd): """ Capture a command's standard output.""" return Popen(cmd.split(), stdout=PIPE).communicate()[0] def files_changed(look_cmd): """ List the files added or updated by this transaction.""" def filename(line): return line[4:] def added_or_updated(line): return line and line[0] in ("A", "U") return [filename(line) for line in command_output(look_cmd % "changed").split("\n") if added_or_updated(line)] def file_contents(filename, look_cmd): """Return a file's contents for this transaction""" return command_output("%s %s" % (look_cmd % "cat", filename)) def test_expression(expr, filename, look_cmd): """test regexpr over file""" return len(expr.findall(file_contents(filename, look_cmd))) > 0 def check_file(look_cmd): """checks Python files in this transaction""" def is_python_file(fname): return os.path.splitext(fname)[1] in ".py".split() erroneous_files = [] for file in files_changed(look_cmd): if not is_python_file(file): continue for error_type, tester in testers: if test_expression(tester, file, look_cmd): erroneous_files.append((error_type, file)) num_failures = len(erroneous_files) if num_failures > 0: sys.stderr.write("[ERROR] please check your files:\n") for error_type, file in erroneous_files: sys.stderr.write("[ERROR] %s in %s\n" % (error_type, file)) return num_failures def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-r", "--revision", help="Test mode. TXN actually refers to a revision.", action="store_true", default=False) errors = 0 (opts, (repos, txn_or_rvn)) = parser.parse_args() look_opt = ("--transaction", "--revision")[opts.revision] look_cmd = "svnlook %s %s %s %s" % ( "%s", repos, look_opt, txn_or_rvn) errors += check_file(look_cmd) return errors if __name__ == "__main__": import sys sys.exit(main())
J'ai ajouté aussi un contrôle de new line at end of file.

Ce script est à appeler dans le script pre-commit hook, (référez-vous à la documentation de SVN ou à ce très bon tutoriel, très complet)

L'appel resssemble à:
/chemin/vers/script/svn_check_source.py "$REPOS" "$TXN" || exit 1

Il est ensuite possible d'étendre ce principe en mettant en place des contrôles de qualité de code, avec des outils comme pychecker par exemple, mais de manière non-bloquante: un mail peut par exemple être envoyé lorsque la qualité d'un source est en dessous d'un certain seuil.

*maj* Merci à David (Biologeek) pour un correctif sur le script (il manquait une parenthèse)

Categories: coding, misc 0 comments - commenter | Trackbacks (788) |

Tarek Ziadé. Copyright 2006. Tous droits réservés. Licence contenu site
BuzTrucs
Add to Technorati Favorites