Hallo zusammen,
gibt es eine automatisierte Lösung, bei Python-Scripten bei der Import-Funktion "from .... import ...", das Python-Paket herauszufinden?
Grüße Nobuddy
Welches Python-Paket steckt hinter Import ...
Hallo __deets__,
Habe ein größeres Python-Projekt und möchte feststellen, welche Python-Pakete dazu benötigt werden.
python3, python3-minimal und python-reportlab habe ich schon ausgemacht.
Um evtl. weiter benötigte Python-Pakete ausfindig zu machen, möchte meine programmierten Module abfragen.
Dazu ein kleines Beispiel:
Zu welchem Python-Paket gehört copy, tkinter, fuctools, datetime .... ?
Damit könnte ich dann genau festlegen, welche Python-Pakete installiert sein müssen, um mein Python-Projekt funktionsfähig zu machen.
Grüße Nobuddy
Habe ein größeres Python-Projekt und möchte feststellen, welche Python-Pakete dazu benötigt werden.
python3, python3-minimal und python-reportlab habe ich schon ausgemacht.
Um evtl. weiter benötigte Python-Pakete ausfindig zu machen, möchte meine programmierten Module abfragen.
Dazu ein kleines Beispiel:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x
import copy
import tkinter as tk
from functools import partial
from datetime import date
Damit könnte ich dann genau festlegen, welche Python-Pakete installiert sein müssen, um mein Python-Projekt funktionsfähig zu machen.
Grüße Nobuddy
Ah. Mit dem ast-Modul kannst du dir prinzipiell die import-statements rausloeten aus deinem Code, und dann die Paket/Modulnamen bekommen. Das Problem ist, dass die nicht unbedingt eindeutig zu einem PyPi-Modul zuzuordnen sind. Das faengt mit dem Namen an. Import foo kann aus dem Paket "pyfoo" kommen, oder aus "FooDingeDieTollSind" - da gibt es keine Vorgaben. Und selbst *wenn* du das heuristisch aufloest, hast du immer noch das Problem, dass du die benoetigte Version nicht ablesen kannst.
Vernuenftige Projekte machen das genau umgekehrt - die haben eine requirements.txt, in der die zu installierenden Pakete aufgefuehrt sind, Version inklusive. Unter Umstaenden ist auch ein Blick in setup.py erhellend.
Vernuenftige Projekte machen das genau umgekehrt - die haben eine requirements.txt, in der die zu installierenden Pakete aufgefuehrt sind, Version inklusive. Unter Umstaenden ist auch ein Blick in setup.py erhellend.
Ja, das habe ich leider verschlafen, das rächt sich nun ...., werde es aber versuchen nachzupflegen!
Könnte es sein dass, Paket/Modulnamen sich auf die im Betriebssystem liegenden Paket bezieht?
Muss das mal mit dem ast-Modul testen, vielleicht komme ich da doch noch auf einen "grünen Zweig" ...
Grüße Nobuddy
Könnte es sein dass, Paket/Modulnamen sich auf die im Betriebssystem liegenden Paket bezieht?
Muss das mal mit dem ast-Modul testen, vielleicht komme ich da doch noch auf einen "grünen Zweig" ...
Grüße Nobuddy
- __blackjack__
- User
- Beiträge: 13107
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Es geht hier ja gar nicht um PyPI-Pakete sondern um Debian/Ubuntu-Pakete. Da hilft auch eine `requirements.txt` nur bedingt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
- __blackjack__
- User
- Beiträge: 13107
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Deswegen schrob ich ja „bedingt“ und nicht „gar nicht“.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@Nobuddy: ich würde gar keine DEB-Pakete für so was benutzen sondern alles via pip installieren. Gründe: bessere Kontrolle über die Version des Python-Moduls unabhängig vom Betriebssystem bzw. in deinem Falle der *buntu-Version, keine systemweite Installations nötig, besser in Virtual Environments kapselbar, besser updatebar, wenn du die Features einer neueren Version des Python-Modul brauchst.
Bei Ubuntu liegen ja sehr viele Python-Pakete in 'universe' in einer vergleichsweise alten Version und bekommen so wie so keine selten Updates. Die Probleme hast du mit pip nicht.
Gruß, noisefloor
@Nobuddy: ich würde gar keine DEB-Pakete für so was benutzen sondern alles via pip installieren. Gründe: bessere Kontrolle über die Version des Python-Moduls unabhängig vom Betriebssystem bzw. in deinem Falle der *buntu-Version, keine systemweite Installations nötig, besser in Virtual Environments kapselbar, besser updatebar, wenn du die Features einer neueren Version des Python-Modul brauchst.
Bei Ubuntu liegen ja sehr viele Python-Pakete in 'universe' in einer vergleichsweise alten Version und bekommen so wie so keine selten Updates. Die Probleme hast du mit pip nicht.
Gruß, noisefloor
@noisefloor:
Und was machst du, wenn ein vom System genutztes Paket ein Update erhält, welches nicht abwärtskompatibel ist und es dadurch bei einem wichtigen Skript knallt? Ich würde solche Tipps daher mit Vorsicht genießen. Wenn es ausschließlich um virtuelle Umgebungen geht, dann ist es okay, aber bei der systemseitig genutzten Interpreter-Version würde ich mir das lieber dreimal überlegen.
Und was machst du, wenn ein vom System genutztes Paket ein Update erhält, welches nicht abwärtskompatibel ist und es dadurch bei einem wichtigen Skript knallt? Ich würde solche Tipps daher mit Vorsicht genießen. Wenn es ausschließlich um virtuelle Umgebungen geht, dann ist es okay, aber bei der systemseitig genutzten Interpreter-Version würde ich mir das lieber dreimal überlegen.
Ich habe mir für so einen Zweck ein Tool geschrieben, dass die py- und pyw-Skripte in einem Verzeichnis ausliest und alle Zeilen mit einem 'import' auswirft. Unter Windows und mit pip habe ich dann pip freeze in die Konsole eingegeben und konnte die Pakete und die Versionen auslesen (das scheint bei dir nicht zu gehen). Der Ansatz findet auch Importe, die sich irgendwo in einer Test-Funktion eines Skripts befinden, was bei mir seltenst vorkommt.
Die Importe, die du oben ausführst, scheinen doch alle aus der Standardbibliothek zu kommen. Außer bei bs4 finde ich die Namen eigentlich immer eindeutig, d. h. ich verstehe schnell, was das für ein Modul ist. Importierte Module haben bei mir eigentlich nie den Namen eines fertigen Moduls, dass ich über pypi laden könnte.
Die Importe, die du oben ausführst, scheinen doch alle aus der Standardbibliothek zu kommen. Außer bei bs4 finde ich die Namen eigentlich immer eindeutig, d. h. ich verstehe schnell, was das für ein Modul ist. Importierte Module haben bei mir eigentlich nie den Namen eines fertigen Moduls, dass ich über pypi laden könnte.
@snafu: ich verstehe deinen Punkt nicht. Noisefloor schlägt venvs und pip vor. Womit man am unabhängigsten vom Paketmanagement ist. Gerade dein Szenario mit dem neuen Systempaket wird dadurch doch adressiert? Und was hat das mit dem Systeminterpreter zu tun? Den benuzt man doch zu 99%, aber dank System Paket Isolation ohne Probleme.
Wenn natürlich zb C++ /C Bibliotheken sich ändern, kann es immer noch zu Problemen kommen. Dann hilft ggf Containerisierung oder die neuen Anwendungsformate flatpack etc.
Wenn natürlich zb C++ /C Bibliotheken sich ändern, kann es immer noch zu Problemen kommen. Dann hilft ggf Containerisierung oder die neuen Anwendungsformate flatpack etc.
Hallo zusammen,
ich glaube nicht, dass ast die richtige Wahl ist, um die für mein Projekt benötigte Python-Pakete feststellen zu können.
Das mit pip und virtualenv, ist wohl einer der Alternativen, um zukünftig nicht mehr vor diesen Problemen stehen zu müssen.
Leider habe ich versäumt, eine Dokumentation für die notwendigen zu installierenden Python-Paketen zu erstellen.
Ich werde mal eine Liste mit den importierten Python-Modulen erstellen.
Vielleicht hat ja jemand von Euch noch eine Idee dazu?
Grüße Nobuddy
ich glaube nicht, dass ast die richtige Wahl ist, um die für mein Projekt benötigte Python-Pakete feststellen zu können.
Das mit pip und virtualenv, ist wohl einer der Alternativen, um zukünftig nicht mehr vor diesen Problemen stehen zu müssen.
Leider habe ich versäumt, eine Dokumentation für die notwendigen zu installierenden Python-Paketen zu erstellen.
Ich werde mal eine Liste mit den importierten Python-Modulen erstellen.
Vielleicht hat ja jemand von Euch noch eine Idee dazu?
Grüße Nobuddy
Code: Alles auswählen
# Importe
if "import" in line:
auswertung["import"].append((i, prettify_code_line(line)))
Mit so etwas könnte man sich Listen der installierten Module machen und dann nach Standardbibliothek und Fremdpaketen unterscheiden. Bei mir reduziert(e) sich die Zahl der interessanten Fremdpakete deutlich - pip freeze liefert bei mir eine lange Liste, aber das hat wesentlich mit den Abhängigkeiten der einzelnen Module zu tun...
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@snafu: Schließe mich __deets__ an - den Punkt
Gruß, noisefloor
@snafu: Schließe mich __deets__ an - den Punkt
verstehe nichts, also welches Szenario da entstehen soll. Bitte mal ausführlicher erklären und ein Beispiel. Thx.Und was machst du, wenn ein vom System genutztes Paket ein Update erhält, welches nicht abwärtskompatibel ist und es dadurch bei einem wichtigen Skript knallt?
Gruß, noisefloor
Ich verstehe nicht so ganz, wo das große Problem ist. Ein einfaches grep
sollte eine Liste aller Importzeilen liefern, die man leicht händisch durchgehen kann.
Relevant ist ja nur die oberste Ebene, die man dank Sortierung schnell findet.
Das kann man noch mit der Liste der eigenen und der Standardmodule (https://docs.python.org/3/library/) abgleichen.
Was übrig bleibt, dürfte nicht mehr all zu viel sein. Im Zweifel mit
nach dem Pfad fragen und den Paketmanager bitten, das Paket zu nennen, das diese Datei installiert hat.
Code: Alles auswählen
grep -r --include '*.py' -h '\bimport\b' . | sort -u
Relevant ist ja nur die oberste Ebene, die man dank Sortierung schnell findet.
Das kann man noch mit der Liste der eigenen und der Standardmodule (https://docs.python.org/3/library/) abgleichen.
Was übrig bleibt, dürfte nicht mehr all zu viel sein. Im Zweifel mit
Code: Alles auswählen
import xyz
print(xyz.__file__)
Habe das soweit umgesetzt, dass ich jetzt alle Importe die Python betrifft, in einer Liste vorliegen.
Beim Versuch, diese weiter zu verarbeiten:
erhalte ich die Fehlermeldung:
was ja auch klar sein dürfte.
Nun habe ich die Frage an Euch, ob es eine Möglichkeit gibt, dies in dieser Art umsetzen zu können?
Ein automatisierter Ablauf, wäre ja von Vorteil.
Weiter habe ich manuell, mit zwei Beispielen getan:
Beim Versuch, diese weiter zu verarbeiten:
Code: Alles auswählen
for modul in sorted(python_moduls):
import modul
print(modul.__file__)
Code: Alles auswählen
ImportError: No module named 'modul'
Nun habe ich die Frage an Euch, ob es eine Möglichkeit gibt, dies in dieser Art umsetzen zu können?
Ein automatisierter Ablauf, wäre ja von Vorteil.
Weiter habe ich manuell, mit zwei Beispielen getan:
Was kann man tun, um bei z.B. 'sys', ein Ergebnis zu erhalten?import sys
sys.__file__
# Ergebnis: AttributeError: 'module' objects has no attribute '__file__'
import reportlab
reportlab.__file__
# Ergebnis: /usr/lib/python3/reportlab/__init__.py
Zu Punkt 1, habe ich diese Lösung gefunden:
Fragt sich nur, was es für den 'AttributeError' und den 'ImportError' für eine Lösung gibt, um auch hier ein Ergebnis zuerhalten?
Code: Alles auswählen
for modul in sorted(python_moduls):
try:
print(__import__(modul).__file__)
except AttributeError:
pass
except ImportError:
pass
Ich poste mal meine Ergebnisse:
Vielleicht könnt Ihr mir einen Tip geben, wie ich jetzt weiter komme?
Code: Alles auswählen
####### python_paths #######
['/usr/lib/python3.4/codecs.py',
'/usr/lib/python3.4/collections/__init__.py',
'/usr/lib/python3.4/copy.py',
'/usr/lib/python3.4/csv.py',
'/usr/lib/python3.4/datetime.py',
'/usr/lib/python3.4/ftplib.py',
'/usr/lib/python3.4/functools.py',
'/usr/lib/python3.4/io.py',
'/usr/lib/python3.4/json/__init__.py',
'/usr/lib/python3.4/os.py',
'/usr/lib/python3.4/platform.py',
'/usr/lib/python3.4/queue.py',
'/usr/lib/python3.4/re.py',
'/usr/lib/python3.4/shutil.py',
'/usr/lib/python3.4/smtplib.py',
'/usr/lib/python3.4/socket.py',
'/usr/lib/python3.4/subprocess.py',
'/usr/lib/python3.4/threading.py',
'/usr/lib/python3.4/tkinter/__init__.py',
'/usr/lib/python3.4/urllib/__init__.py',
'/usr/lib/python3.4/zipfile.py',
'/usr/lib/python3/dist-packages/cups.cpython-34m-x86_64-linux-gnu.so',
'/usr/lib/python3/dist-packages/lxml/__init__.py',
'/usr/lib/python3/dist-packages/reportlab/__init__.py',
'/usr/lib/python3/dist-packages/requests/__init__.py',
'/usr/lib/python3/dist-packages/urllib3/__init__.py',
'/usr/lib/python3/dist-packages/xlrd/__init__.py']
####### AttributeError_names #######
[('atexit', <module 'atexit' (built-in)>),
('sys', <module 'sys' (built-in)>),
('time', <module 'time' (built-in)>)]
Ich habe mal deinen Quellcode für einige bei mir installierte Pakete genutzt:
Liefert dann bei mir:
Ich schließe daraus, dass im Ordner site-packages Module gelandet sind, die du selbst installiert hast und unter lib direkt die Standardbibliothek zu finden ist.
Die folgenden Module müsstest du bei dir mal prüfen, alles andere sieht für mich nach Standardbibliothek aus.:
requests und xlrd (https://pypi.org/project/xlrd/) sind m. E. sicher Fremdbibliotheken, die du installiert hast. atexit, sys und time sind Teil der Standardbibliothek (https://docs.python.org/3.7/library/atexit.html).
Code: Alles auswählen
for modul in sorted(["random", "os", "sys", "pandas", "something"]):
try:
print(__import__(modul).__file__)
except AttributeError:
pass
except ImportError:
pass
Code: Alles auswählen
C:\[...]\Python\Python37\lib\os.py
C:\[...]\Python\Python37\lib\site-packages\pandas\__init__.py
C:\[...]\Python\Python37\lib\random.py
C:\[...]\Python\Python37\lib\site-packages\something.py
Die folgenden Module müsstest du bei dir mal prüfen, alles andere sieht für mich nach Standardbibliothek aus.:
Code: Alles auswählen
'/usr/lib/python3/dist-packages/cups.cpython-34m-x86_64-linux-gnu.so',
'/usr/lib/python3/dist-packages/lxml/__init__.py',
'/usr/lib/python3/dist-packages/reportlab/__init__.py',
'/usr/lib/python3/dist-packages/requests/__init__.py',
'/usr/lib/python3/dist-packages/urllib3/__init__.py',
'/usr/lib/python3/dist-packages/xlrd/__init__.py']