================== Python 3-Migration ================== 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 `_. .. Siehe auch * `Best practices for making code compatible with Python2 and Python3 `_