Workflow pour maintenir différentes versions de codebase pour différentes versions de Python

Je développe une application open source appelée GarlicSim .

Jusqu'à présent, je l'ai développé uniquement pour Python 2.6. Il semble ne pas fonctionner sur une autre version.

J'ai décidé qu'il était important d'en produire des versions compatibles avec d'autres versions de Python. Je pense que je vais faire une version pour 2.5, 3.1 et peut-être 2.4.

J'ai donc plusieurs questions:

  1. Quel serait un bon moyen d'organiser la structure de dossier de mon repo pour inclure ces différentes versions?
  2. Quel serait un bon moyen de «merge» les modifications que je fais dans une version du code à d'autres versions? Je sais comment faire des fusions dans mon SCM (qui est git), mais ce sont des dossiers qui sont tous dans le même repo, et je veux faire une fusion entre eux. Il y a bien sûr la possibilité d'avoir un repo pour chaque version, mais je pense que ce n'est pas une bonne idée.

Est-ce que quelqu'un a des suggestions?

Solutions Collecting From Web of "Workflow pour maintenir différentes versions de codebase pour différentes versions de Python"

Vous avez besoin de twigs séparées pour les versions séparées uniquement dans les cas les plus rares. Vous parlez des gestionnaires de context, et ils sont géniaux, et il serait difficile de ne pas les utiliser, et vous avez raison. Mais pour Python 2.4, vous ne devrez pas les utiliser. Alors ça va être nul. Donc, si vous voulez supporter Python 2.4, vous devrez écrire une version sans gestionnaire de context. Mais celui-là fonctionnera aussi sous Python 2.6, donc il ne sert à rien d'avoir des versions séparées là-bas.

Comme pour Python 3, avoir une twig séparée, il y a une solution, mais généralement pas la meilleure. Pour le support de Python 3, il y a quelque chose qui s'appelle 2to3 qui va convertir votre code Python 2 en code Python 3. Ce n'est pas parfait, donc souvent vous devrez modifier le code Python 2 pour générer du code Python 3, mais le code Python 2 a tendance à s'améliorer de toute façon.

Avec Dissortingbute (une fourchette entretenue de setuptools), vous pouvez effectuer cette conversation automatiquement pendant l'installation. De cette façon, vous n'avez pas besoin d'avoir une twig séparée, même pour Python 3. Voir http://bitbucket.org/tarek/dissortingbute/src/tip/docs/python3.txt pour les docs sur ce sujet.

Comme l'écrit Paul McGuire, il est même possible de supporter Python 3 et Python 2 avec le même code sans utiliser 2to3, mais je ne le reorderais pas si vous voulez supporter autre chose que 2.6 et 3.x. Vous obtenez trop de ces hacks spéciaux laids. Avec 2.6, il y a suffisamment de compatibilité avant avec Python 3 pour permettre d'écrire du code de bonne qualité et supporter à la fois Python 2.6 et 3.x, mais pas Python 2.5 et 3.x.

Je voudrais essayer de maintenir une twig pour couvrir tous les python 2.4-2.6

Les différences ne sont pas si grandes, après tout, si vous devez écrire un tas de code supplémentaire pour 2.4 pour faire quelque chose qui est facile dans 2.6, il vous faudra less de travail à long terme pour utiliser la version 2.4 pour les versions 2.5 et 2.6. .

Python 3 devrait avoir une twig différente, vous devriez toujours essayer de garder autant de code en commun que vous le pouvez.

Si votre code ne dépend pas trop des performances d'exécution des gestionnaires d'exceptions, vous pouvez même vous en passer sans avoir de twig distincte pour Py3. J'ai réussi à conserver une version de pyparsing pour toutes mes versions de Py2.x, bien que je devais m'en tenir à l'approche du «plus petit dénominateur commun», ce qui signifie que je dois renoncer à utiliser certaines constructions comme des expressions de générateur, et votre point, les gestionnaires de context. J'utilise des dicts à la place des sets, et toutes mes expressions de générateur sont enveloppées comme des compréhensions de list, donc elles fonctionneront toujours en remontant vers Python 2.3. J'ai un bloc en haut de mon code qui prend en charge un certain nombre de problèmes de 2vs3 (consortingbution de Robert A Clark, user de pypars):

 _PY3K = sys.version_info[0] > 2 if _PY3K: _MAX_INT = sys.maxsize basessortingng = str unichr = chr unicode = str _str2dict = set alphas = ssortingng.ascii_lowercase + ssortingng.ascii_uppercase else: _MAX_INT = sys.maxint range = xrange def _str2dict(strg): return dict( [(c,0) for c in strg] ) alphas = ssortingng.lowercase + ssortingng.uppercase 

La plus grande difficulté que j'ai eu a été avec la syntaxe incompatible pour attraper des exceptions, qui a été introduite dans Py3, en changeant de

 except exceptiontype,varname: 

à

 except exceptionType as varname: 

Bien sûr, si vous n'avez pas vraiment besoin de la variable d'exception, vous pouvez simplement écrire:

 except exceptionType: 

et cela fonctionnera sur Py2 ou Py3. Mais si vous avez besoin d'accéder à l'exception, vous pouvez toujours find une syntaxe compatible avec les versions croisées:

 except exceptionType: exceptionvar = sys.exc_info()[1] 

Cela a une pénalité d'exécution mineure, ce qui le rend inutilisable à certains endroits dans pyparsing, donc je dois toujours maintenir des versions séparées de Py2 et Py3. Pour la fusion de sources, j'utilise l'utilitaire WinMerge , que je trouve très bien pour garder les directorys du code source en synchro.

Donc, même si je garde deux versions de mon code, certaines de ces techniques d'unification m'aident à garder les différences au minimum absolu incompatible.

J'ai finalement décidé d'avoir 4 fourchettes différentes pour mon projet, pour 2.4, 2.5, 2.6 et 3.1. Ma principale priorité est 2.6 et je ne veux pas compromettre l'élégance de ce code pour le 2.4. Donc, les hacks de compatibilité moche seront sur les versions inférieures, pas les versions supérieures.