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.
Bemerkung
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.
Bemerkung
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
$ bin/wsgi.py
Häufige Probleme beim Starten sind:
Class Advice
Relative Imports
Syntax Error beim Import von async
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
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",
...
],
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.