Requirements
Alle Third-Party-Add-Ons sollten sowohl Python 2 wie auch Python 3 unterstützen.
Eine Übersicht, welche Add-Ons in Collective bereits auf Python 3 aktualisiert wurden, findet ihr in Python 3 porting state for Plone add-ons.
Zur Python-3-Migration verwenden wir six und modernize.
sie können installiert werden mit:
$ python3 -m venv py3env $ cd py3env $ ./bin/pip install modernize six
precompiler
Zusätzlich verwenden wir plone.recipe.precompiler um Syntaxfehler zu finden. Er kann mit Buildout installiert werden, indem in der py3.cfg-Datei folgendes angegeben wird:
parts += precompiler … [precompiler] recipe = plone.recipe.precompiler eggs = ${instance:eggs} compile-mo-files = true
precompile wird jedes Mal ausgeführt, wenn ihr Bbuildout ausführt. Wenn ihr nur precompile ausführen möchtet, könnt ihr dies mit:
$ bin/buildout -c py3.cfg install precompiler
python-modernize
python-modernize bereitet Python-2-Code automatisch für die Python-3-Portierung vor. Dabei weist euch python-modernize auf Probleme hin, die nicht automatisch gelöst werden können.
Mit bin/python-modernize -x libmodernize.fixes.fix_import src/my.package könnt ihr euch anzeigen lassen, welche Änderungen modernize an eurem Plone-Add-on my.package vornehmen würde.
Note
Ihr könnt python-modernize u.a. mit folgenden Optionen aufrufen:
- -x
- schließt bestimmte Fixers aus.
- -l
- listet euch alle verfügbaren Fixers auf.
Note
Im Cheat Sheet Writing Python 2-3 compatible code erhaltet ihr einen Überblick, wie sich die Syntax von Python 2 zu Python 3 ändert.
Wir verwenden die py3.cfg aus dem Plone-5.2-Branch von vs_buildut:
$ bin/buildout -c py3.cfg
Starten der Plone-Instanz
$ bin/wsgi.py
Häufige Probleme beim Starten sind:
- Class Advice
- Relative Imports
- Syntax Error beim Import von async
Testen
Neben dem manuellen Testen solltet ihr automatisiert Testen mit:
$ bin/test --all -s my.package
Alternativ könnt ihr den Testrunner automatisch den Python-Debugger starten lassen mit:
$ bin/test -s my.package -D
Aktualisieren der Metainformationen
Aktualisiert die classifiers in setup.py aktualisiert:
classifiers=[ … "Framework :: Plone :: 5.2", … "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", … ],
Häufige Probleme
Strings: Text vs. Bytes
Meist wird in Plone Text verwendet und nur in sehr seltenen Fällen Bytes.
Versucht den Code so zu ändern, dass ihr mit Beenden der Python 2-Unterstützung einfach nur das``if``-Statement löschen müsst, z.B.:
if six.PY2 and isinstance(value, six.text_type): value = value.encode('utf8') do_something(value)
Dabei könnt Ihr Hilfsmethoden verwenden wie safe_text, safe_bytes, safe_unicode und safe_encode, z.B.:
from Products.CMFPlone.utils import safe_unicode … obj = self.context.unrestrictedTraverse( safe_unicode(item['_path'].lstrip('/')), None)
python-modernize ändert ebenfalls nicht from StringIO import StringIO obwohl der Import nur in Python-2 funktioniert. Für Python-3 müsst ihr überprüfen, ob es sich um Text- oder Binärdaten handelt und die import-Anweisung entsprechend schreiben:
from six import StringIO
oder:
from six import BytesIO
Weitere Informationen findet ihr im The Conservative Python 3 Porting Guide.