Namespace-Packages in Python 2.x

Hallo zusammen, auf Arbeit bin ich gerade über ein Phänomen gestolpert, dass ich so fast nicht wahrhaben will. Wir verwenden viele Namespace-Pakete mit einem gemeinsamen, Firmen-bezogene Präfix. Das wird mittels pkgutil ja auch gut unterstützt. In “namespace/__init__.py” schreibt man einfach from pkgutil import extend_path __path__ = extend_path(__path__, __name__) und dadurch wird dann der __path__ zu einer Liste, die auch alle anderen namespace-Pakete enthält. Intern in pkgutil wird das so implementiert, dass einfach über alle sys.path-Verzeichnisse iteriert wird, und fuer jedes darin geschaut wird, ob - ein Unterverzeichnis mit dem Namen ‘namespace’ existiert - darin ein ‘__init__.py’ liegt Und da ist auch schon gleich der Knackpunkt: wir liefern unsere Pakete als pyc-files aus. Und damit schlägt diese Bedingung fehl, und wir haben keine namespaces mehr. Das finde ich schon eine recht grobes Versehen. In der Dokumentation und dem source findet sich nichts dazu. Und auch eine Suche nach Bugs zu dem Thema hat nix ergeben. Hat da jemand Erfahrungen mit? LG Diez

Hallo,
Wir verwenden viele Namespace-Pakete mit einem gemeinsamen, Firmen-bezogene Präfix. Das wird mittels pkgutil ja auch gut unterstützt.
In “namespace/__init__.py” schreibt man einfach
Könnt Ihr ein Python 3.3+ verwenden, das PEP 420 implementiert? Dann genügten leeres Verzeichnise. https://www.python.org/dev/peps/pep-0420/ -- Schönen Gruß Hartmut Goebel Dipl.-Informatiker (univ), CISSP, CSSLP Information Security Management, Security Governance, Secure Software Development Goebel Consult, Landshut http://www.goebel-consult.de Blog: http://www.goebel-consult.de/blog/digitale-burgerrechte-in-der-ara-snowden Kolumne: http://www.cissp-gefluester.de/2010-07-passwoerter-lieben-lernen

Hallo Hartmut,
Hallo,
Wir verwenden viele Namespace-Pakete mit einem gemeinsamen, Firmen-bezogene Präfix. Das wird mittels pkgutil ja auch gut unterstützt.
In “namespace/__init__.py” schreibt man einfach
Könnt Ihr ein Python 3.3+ verwenden, das PEP 420 implementiert? Dann genügten leeres Verzeichnise.
https://www.python.org/dev/peps/pep-0420/ <https://www.python.org/dev/peps/pep-0420/>
Das ist mir bekannt, dass das geht - aber wir heben gerade unser uraltes eingebettetes Python 2.5 auf immerhin 2.7. Das erleichtert aus diversen Gründen den Schritt auf 3.x, aber den zum jetzigen Zeitpunkt zu gehen ist unmöglich (fuer eine Definition von unmöglich im Rahmen von zeitlichen und anderen Randbedingungen wie zB Code von Dritten). Sollten wir irgendwann mal auf 3.x gehen, werde ich das auch ausprobieren. Ich bin mir aber noch nicht so sicher, wie cool ich das Feature finde fuer unseren Fall. Es ist hilfreich, wenn man sowas wie PIP hat. Bei einem eingebetteten Interpreter hat man das aber in aller Regel nicht. Es ist also deutlich einfacher fuer uns, die diversen Pakete aus demselben Namensraum parallel vorzuhalten, und auch genau so in einen Installer zu schieben. Die selbst zu fusionieren geht natürlich, hat aber auch Nervpotential. Wieder eine Schleife mehr… Und letztlich ist’s halt ein Bug - oder sieht das jemand anders? Mit Python3 klappt’s nämlich auch nicht. LG Diez

Am 05.10.2015 um 15:01 schrieb Diez B. Roggisch:
Das ist mir bekannt, dass das geht - aber wir heben gerade unser uraltes eingebettetes Python 2.5 auf immerhin 2.7.
Wenn ihr ein embedd Python benutzt, könnt ihr dann nicht einfach das pkgutil-Modul mit einer gefixten Version austauschen? Habt ihr denn in den __init__.py-Dateien überhaupt Code? Könnt ihr die nicht einfach als .py Dateien ausliefern?
Es ist also deutlich einfacher fuer uns, die diversen Pakete aus demselben Namensraum parallel vorzuhalten, und auch genau so in einen Installer zu schieben.
Vasteh ich net. Also die Namespaces in eine flache Paketstruktur auflösen, oder was? Chris

Hallo Chris,
On 05 Oct 2015, at 17:04, Christopher Arndt <chris@chrisarndt.de> wrote:
Am 05.10.2015 um 15:01 schrieb Diez B. Roggisch:
Das ist mir bekannt, dass das geht - aber wir heben gerade unser uraltes eingebettetes Python 2.5 auf immerhin 2.7.
Wenn ihr ein embedd Python benutzt, könnt ihr dann nicht einfach das pkgutil-Modul mit einer gefixten Version austauschen?
Oh klar können wir. Ist halt ein so offensichtlicher Fehler, dass ich da mal nachhaken wollte. Ausserdem ist sowas immer doof, wenn man ein Changeset fuer Python selbst maintainen muss. Und gerade im akuten Fall ist zB die Komplexität von Python3 in diesem Bereich *massiv* höher (ohne das fuer uns was rausspringt - geht immer noch nicht). Das ist nicht trivial, das zu pflegen.
Habt ihr denn in den __init__.py-Dateien überhaupt Code? Könnt ihr die nicht einfach als .py Dateien ausliefern?
Das ist unser Workaround, weil es im konkreten kein kritischer Code ist, den wir geschlossen halten wollen. Das gilt aber bei weitem nicht fuer allen, den wir schreiben - und da wäre das schon schön etwas zu haben, das funktioniert wie beworben ;)
Es ist also deutlich einfacher fuer uns, die diversen Pakete aus demselben Namensraum parallel vorzuhalten, und auch genau so in einen Installer zu schieben.
Vasteh ich net. Also die Namespaces in eine flache Paketstruktur auflösen, oder was?
Na, das ist halt der Unterschied zwischen “klassischen” Namespace-Paketen und der Art, wie PIP damit umgeht. Erstere benutzen (und daher komme ich/wir) eben pkgutil.extend_path und verteilen ein namespace-Paket auf viele Verzeichnisse. PIP fusioniert die alle - das siehst du in deinem site-packages: die EGG-INFOs werden top-level hingelegt, und zB unser abl-namespace ist nur ein Verzeichnis, und pip hat da alle Pakete reinkopiert. Das ist natürlich etwas, dass wir auch machen können. Ist halt extra Aufwand, muss man wieder ne Logik fuer schreiben, die das entweder von alleine rausfummelt, oder es gibt wieder irgendwo ein magischen Ort, an dem das irgendwie explizit definiert wird. Und prompt vergessen, wenn man das nächste Stück Library dazupacken will. LG Diez

Diez B. Roggisch wrote:
Hallo zusammen,
auf Arbeit bin ich gerade über ein Phänomen gestolpert, dass ich so fast nicht wahrhaben will.
Wir verwenden viele Namespace-Pakete mit einem gemeinsamen, Firmen-bezogene Präfix. Das wird mittels pkgutil ja auch gut unterstützt.
In “namespace/__init__.py” schreibt man einfach
from pkgutil import extend_path __path__ = extend_path(__path__, __name__)
und dadurch wird dann der __path__ zu einer Liste, die auch alle anderen namespace-Pakete enthält.
Intern in pkgutil wird das so implementiert, dass einfach über alle sys.path-Verzeichnisse iteriert wird, und fuer jedes darin geschaut wird, ob
- ein Unterverzeichnis mit dem Namen ‘namespace’ existiert - darin ein ‘__init__.py’ liegt
Und da ist auch schon gleich der Knackpunkt: wir liefern unsere Pakete als pyc-files aus. Und damit schlägt diese Bedingung fehl, und wir haben keine namespaces mehr.
Das finde ich schon eine recht grobes Versehen. In der Dokumentation und dem source findet sich nichts dazu. Und auch eine Suche nach Bugs zu dem Thema hat nix ergeben.
Hat da jemand Erfahrungen mit?
Leider nein. Du kombinierst zwei selten genutzte Techniken. Als Workaround versuche mal pkg-Dateien.

Hallo,
Hat da jemand Erfahrungen mit?
Leider nein. Du kombinierst zwei selten genutzte Techniken.
Als Workaround versuche mal pkg-Dateien.
Nicht wirklich. Ihr Inhalt wird einfach ungeprüft in die __path__-Variable gepumpt. Und es müssen dadurch absolute Pfade sein. Die hab’ ich aber auf einer User-Maschine nicht, müsste dieses File also irgendwie vor Start des eingebetteten Interpreters generieren. Das ist dann eher unschön. Das ist
participants (4)
-
Christopher Arndt
-
Diez B. Roggisch
-
Hartmut Goebel
-
Peter Otten