PyPi / Versionierung modularer Scripts?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
BlackJack

@grum.py: Aber neue JavaScript-Bibliotheken auf die Version zu testen sehe ich nicht als neues Feature, das ist immer noch der gleiche Funktionsumfang, nur halt mit mehr Daten. Das Programm selbst und seine Fähigkeiten — beliegige Bibliothekenversionen testen für die es Konfigurationsdateien gibt — ändern sich dadurch nicht. Würdest Du zum Beispiel bei einem Virenscanner sagen das *Programm* hat neue Fähigkeiten jedes mal wenn die Datenbank mit den Virensignaturen aktualisiert wurde? Man drückt doch in der Versionsnummer den Zustand des Codes aus, man will daran ablesen wieviel sich am Programm geändert hat. Und in dem Fall das nur Daten von einer Version zur nächsten aktualisiert werden, hat sich am Programm doch gar nichts geändert. Für mich wäre das eindeutig die letzte Stelle der Versionsnummer.

Es gibt das ``autopep8``-Skript das ein paar Formatierungen anpassen kann damit der Quelltext näher am Style Guide for Python Code ist, unter anderem die Einrückung.

Mit `logging` hat man zwar nicht etwas was *genau* das gleiche tut, aber man kann damit die gleichen Ausgaben bekommen. Man muss aber beispielsweise nicht die `settings` für den „log level“ überall übergeben und ``if``-Abfragen machen, denn bei `logging` legt man das Level einmal beim Logger-Objekt fest und hat im Programm dann einfach überall die Log-Aufrufe ohne Bedingungen. Macht das Programm also etwas einfacher. Ausserdem gibt es eine Methode um eine komplette Ausnahme mit Traceback zu protokollieren.

Okay, `thislib` ist die Bibliothek „die gerade dran ist“ — im Gegensatz zu welcher anderen? Es gibt in der Funktion ja nur `thislib` womit das `this` keine für den Leser wichtige Information trägt. Da hätte ich lieber `library` ausgeschrieben.

Es gibt ein einfaches `re.find()` das aber `re.search()` heisst. ;-)

``# definition file broken?`` steht an drei Stellen, zweimal bei generischen ``except Exception`` wo wirklich alles behandelt wird, also auch Ausnahmen die auftreten können wenn die Datei völlig in Ordnung ist, und die dritte Stelle behandelt einen `urllib2.URLError` der ebenfalls bei einer völlig intakten Datei auftreten kann. Wenn das Netzwerk nicht da ist oder der angefragte Server einen internen Fehler liefert hat das ja nichts mit der Definitionsdatei zu tun.

``pass`` tut gar nichts. Also wirklich überhaupt nichts.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

grum.py hat geschrieben:Ich committe ja beinahe nur, wenn ich weiß, dass das, was ich da gebaut habe, auch funktioniert.
Na, das würde ich doch auch sehr empfehlen. Beim Committen neuer Funktionalität muss nicht unbedingt alles perfekt sein. Aber es sollte doch zumindest keinen Fehler werfen, wenn man die neuen Codebereiche anwendet.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

snafu hat geschrieben:
grum.py hat geschrieben:Ich committe ja beinahe nur, wenn ich weiß, dass das, was ich da gebaut habe, auch funktioniert.
Na, das würde ich doch auch sehr empfehlen. Beim Committen neuer Funktionalität muss nicht unbedingt alles perfekt sein. Aber es sollte doch zumindest keinen Fehler werfen, wenn man die neuen Codebereiche anwendet.
Naja dem würde ich nicht unbedingt zustimmen. Sicherlich möchte man keine Commits in master haben, die unvollständig oder "kaputt" sind aber es kann durchaus Sinn machen in Feature Branches zu arbeiten und dort solche Commits zu machen. Das ist vorallem dann sinnvoll wenn man etwas experimentiert oder im Verlauf des Reviewprozesses noch Änderungswünsche hinzukommen. Dies lässt sich dann vor einem Merge problemlos mit rebase usw. korrigieren.
grum.py
User
Beiträge: 137
Registriert: Montag 11. Mai 2015, 15:27

Sirius3 hat geschrieben:@grum.py: für meinen Geschmack hast Du es mit den Funktionen etwas übertrieben, "print_metadata" oder "print_pkg_info", wobei zweitere auch noch einen falschen Doc-String hat.
Ich habe (noch) nicht so auf externe Einbindbarkeit geachtet, natürlich gehört da einiges noch besser dokumentiert. :K
Sirius3 hat geschrieben:Natürlich kann man mit logging exakt die selbe Ausgabe bekommen wie Dein debuglog, aber warum sollte man sich die Mühe machen, da die Default-Ausgabe ausreichend ist.
Gibt es da eine gute Dokumentation für Unbedarfte wie mich?
Sirius3 hat geschrieben:Bei print_library_output hattest Du noch nicht gelernt, dass es format gibt, das würde ich nachziehen.
Stimmt, danke.
Sirius3 hat geschrieben:Die Funktion sollte auch check_version_and_output_package_information heißen. Ich würde auch kein match-Ergebnis als Parameter übergeben, sondern eine newest_version, dann ist auch am Variablennamen klar, was da gemacht wird.
Ich finde so lange Namen irgendwie unästhetisch. :?
Sirius3 hat geschrieben:"not <" ist eigentlich ein ">=".
Stimmt, danke.
Sirius3 hat geschrieben:Statt die verschiedenen Paketmanager per copy-paste im Code zu haben, sollten sie als Struktur z.B. in Deiner Config-Datei stehen.
Ich würde da gern ein einheitliches Format für die Definitionsdateien erzwingen, und die Configdatei ist ja benutzerabhängig.
Sirius3 hat geschrieben:"parse_library" sollte eigentlich "check_library" heißen und läuft immer noch mit einem undefinierten matches weiter.
Stimmt, danke.
Sirius3 hat geschrieben:Welche Exception soll denn in "print_library_output" auftreten, die Du versuchst abzufangen?
Ähm, inzwischen keine mehr. :oops:
Sirius3 hat geschrieben:Warum verwendest Du bei config_file io.open
Was denn sonst?
Sirius3 hat geschrieben:und warum heißt das Fileobjekt data_file?
Wie denn sonst?
grum.py
User
Beiträge: 137
Registriert: Montag 11. Mai 2015, 15:27

BlackJack hat geschrieben:Aber neue JavaScript-Bibliotheken auf die Version zu testen sehe ich nicht als neues Feature, das ist immer noch der gleiche Funktionsumfang, nur halt mit mehr Daten. Das Programm selbst und seine Fähigkeiten — beliegige Bibliothekenversionen testen für die es Konfigurationsdateien gibt — ändern sich dadurch nicht. Würdest Du zum Beispiel bei einem Virenscanner sagen das *Programm* hat neue Fähigkeiten jedes mal wenn die Datenbank mit den Virensignaturen aktualisiert wurde?
Wenn ein Virenscanner neue Signaturen bekommt, die man nutzen möchte, muss man nichts ändern.

Wenn mein Skript neue Definitionen bekommt, die man nutzen möchte, muss man die Konfiguration ändern.

Darum ist der Vergleich vielleicht nicht ganz richtig.
BlackJack hat geschrieben:Es gibt das ``autopep8``-Skript das ein paar Formatierungen anpassen kann damit der Quelltext näher am Style Guide for Python Code ist, unter anderem die Einrückung.
Danke, scheint zu funktionieren.
BlackJack hat geschrieben:Okay, `thislib` ist die Bibliothek „die gerade dran ist“ — im Gegensatz zu welcher anderen? Es gibt in der Funktion ja nur `thislib` womit das `this` keine für den Leser wichtige Information trägt. Da hätte ich lieber `library` ausgeschrieben.
Ja - das war alles mal Teil von main(), darum ... :)
BlackJack hat geschrieben:Es gibt ein einfaches `re.find()` das aber `re.search()` heisst. ;-)
Danke. Das nutz' ich mal.
BlackJack hat geschrieben:``# definition file broken?`` steht an drei Stellen, zweimal bei generischen ``except Exception`` wo wirklich alles behandelt wird, also auch Ausnahmen die auftreten können wenn die Datei völlig in Ordnung ist, und die dritte Stelle behandelt einen `urllib2.URLError` der ebenfalls bei einer völlig intakten Datei auftreten kann. Wenn das Netzwerk nicht da ist oder der angefragte Server einen internen Fehler liefert hat das ja nichts mit der Definitionsdatei zu tun.
Darum das Fragezeichen. ;-)
BlackJack hat geschrieben:``pass`` tut gar nichts. Also wirklich überhaupt nichts.
Warum gibt es das dann?
BlackJack

@grum.py: ``pass`` gibt es weil aus syntaktischen Gründen in jedem Block etwas stehen muss. Wenn man also in einem Block „nichts“ stehen haben möchte, kann dort ``pass`` verwenden. Mehr oder weniger sinnfreies Beispiel:

Code: Alles auswählen

    for thing in things:
        try:
            value = int(thing)
            break
        except ValueError:
            pass  # Intentionally ignored.
    else:
        raise ValueError('no thing could be converted to int')

    do_something_with(value)
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@grum.py: pass braucht man halt dann, wenn man explizit nichts machen will. Das logging-Modul hat eine Dokumentation, inklusive Beispielen. Wenn Du die Paketmanager nicht in eine Config-Datei packen willst, so doch wenigstens als Konstante an den Anfang des Skripts. Dort gehören auch die Default-Settings hin.

Die Konfigurations-Datei muß man doch nur ändern, wenn man selbst neue Bibliotheken verwendet, also ist das ja unabhängig von der Revisions-Nummer.
grum.py
User
Beiträge: 137
Registriert: Montag 11. Mai 2015, 15:27

Wenn man welche reinschreibt, die das Skript noch nicht kennt, dann gibt es aber eine Fehlermeldung, weshalb man das vielleicht nicht so oft macht. :K

Danke für die Erklärungen zu "pass". :)
Antworten