expertenaustausch > comp.lang.* > comp.lang.python

Michael S. (27.01.2019, 19:57)
Hallo Leute,
ich habe hier seit vielen Jahren einen Raspberry PI als Heizungsgregler
eingesetzt. Alles ist in Python umgesetzt.
Was mich nervt, ist, dass bestimmte Programmierfehler durch Python erst
dann entdeckt werden, wenn die Programmausführung diesen Codeteil
durchläuft. Das passiert teilweise aber extrem selten oder jahrelang
auch mal nicht.
Heute wieder einmal einen Fehler entdeckt, wo ich von "self.State"
gelesen habe, statt von "State". "self.State" gab es gar nicht, wird
nirgends angelegt und nie verwendet. Das war einfach falsch
runtergeschrieben. Offenbar analysiert Python den Code vor Ausführung
nicht tief genug, um sowas zu entdecken.

Gibt es eine einfache Möglichkeit, den Python Code dahingehend tiefer
analysieren zu lassen? Jeder C-Compiler bekommt sowas ja auch hin.

Ich nutze Python bisher nur auf dem Raspberry PI ohne
Entwicklungsumgebung. Code wird per Editor geschrieben, ausgeführt dann
direkt in der Konsole.

Michael
Dinu Gherman (27.01.2019, 20:25)
Type Annotations in Python 3 könnten einiges in die Richtung abfangen. Dabei muss man aber einiges an Arbeit reinstecken, wenn die Codebasis großist. Man kann diese Annotations aber auch aus laufendem Code erzeugen (siehe MonkeyType), und sollte die dann aber auch manuell prüfen und ggf. korrigieren. Manche verbreiteten Typen sind aber nur umständlich, wenn überhaupt, zu beschreiben, z.B. ein Äquivalent zu JSON...

Gruß,

Dinu
robert (27.01.2019, 20:40)
>> Am 27.01.2019 um 18:57 schrieb Michael S. <michaely>:
>> Hallo Leute,
>> ich habe hier seit vielen Jahren einen Raspberry PI als Heizungsgregler eingesetzt. Alles ist in Python umgesetzt.
>> Was mich nervt, ist, dass bestimmte Programmierfehler durch Python erst dann entdeckt werden, wenn die Programmausführung diesen Codeteil durchläuft. Das passiert teilweise aber extrem selten oder jahrelang auch mal nicht.
>> Heute wieder einmal einen Fehler entdeckt, wo ich von "self.State" gelesen habe, statt von "State". "self.State" gab es gar nicht, wird nirgends angelegt und nie verwendet. Das war einfach falsch runtergeschrieben. Offenbar analysiert Python den Code vor Ausführung nicht tief genug, um sowas zu entdecken.
>> Gibt es eine einfache Möglichkeit, den Python Code dahingehend tiefer analysieren zu lassen? Jeder C-Compiler bekommt sowas ja auch hin.


Eine grosse Hilfe ist ein guter Editor mit Python und pylint Unterstützung.

Z.B. vs code von Microsoft (opensource)

Der hätte Dir bereits beim Schreiben des Codes zuverlässig angezeigt,
dass State für self nicht definiert ist.

robert
[..]
Christopher Arndt (27.01.2019, 20:44)
Am 27.01.19 um 18:57 schrieb Michael S.:
> Heute wieder einmal einen Fehler entdeckt, wo ich von "self.State"
> gelesen habe, statt von "State". "self.State" gab es gar nicht, wird
> nirgends angelegt und nie verwendet. Das war einfach falsch
> runtergeschrieben.


Diesen Fehler hätte z.B. "pylint" gefunden:



> Offenbar analysiert Python den Code vor Ausführung
> nicht tief genug, um sowas zu entdecken.


Die dynamische Natur von Python macht so etwas schwierig. Z.B. lassen
sich Attribute zu Klassen und Instanzen problemlos während der Laufzeit
hinzufügen und nicht nur von Code, der in der Klasse "lebt". Dabei muss
nicht mal der Name des Attributs als Identifier im Code auftauchen:

class Foo:
pass

f = Foo()
setattr(Foo, '\x73\x70\x61\x6d\x6d', 'ham')
print(f.spamm)

Da ist es für eine Code-Analyzer schwer nachzuvollziehen, dass 'spamm'
in der letzten Zeile ein valider Attributwert ist.

Chris
Stefan Ram (27.01.2019, 21:46)
"Michael S." <michaely> writes:
>Gibt es eine einfache Möglichkeit, den Python Code dahingehend tiefer
>analysieren zu lassen? Jeder C-Compiler bekommt sowas ja auch hin.


Tests?

Ohne Test:

main.py

# encoding: utf-8

def example():
"""Gibt den aktuellen Zustand aus
>>> example()

Ok"""
print( self.State )

Ausgabe

(keine Ausgabe)

Mit Test:

main.py

# encoding: utf-8

def example():
"""Gibt den aktuellen Zustand aus
>>> example()

Ok"""
print( self.State )

from doctest import testmod
testmod()

Ausgabe

************************************************** ********************
File "main.py", line 6, in __main__.example
Failed example:
example()
Exception raised:
Traceback (most recent call last):
File "...\lib\doctest.py", line 1329, in __run
compileflags, 1), test.globs)
File "<doctest __main__.example[0]>", line 1, in <module>
example()
File "main.py", line 9, in example
print( self.State )
NameError: name 'self' is not defined
************************************************** ********************
1 items had failures:
1 of 1 in __main__.example
***Test Failed*** 1 failures.

Nach Korrektur:

main.py

# encoding: utf-8

def example():
"""Gibt den aktuellen Zustand aus
>>> example()

Ok"""
print( 'Ok' )

from doctest import testmod
testmod()

Ausgabe

(keine Ausgabe)
Michael S. (28.01.2019, 00:10)
Am 27.01.2019 um 19:44 schrieb Christopher Arndt:
> Am 27.01.19 um 18:57 schrieb Michael S.:
>> Heute wieder einmal einen Fehler entdeckt, wo ich von "self.State"
>> gelesen habe, statt von "State". "self.State" gab es gar nicht, wird
>> nirgends angelegt und nie verwendet. Das war einfach falsch
>> runtergeschrieben.

> Diesen Fehler hätte z.B. "pylint" gefunden:


Soo, nach vielen Stunden ...
Dem Raspberry habe ich schon seit Jahren kein Update mehr gegönnt, never
Touch a running Heizung ...
Deshalb lies sich pylint darauf nicht installieren, ohne dass ich vorher
Updates fahre, was ich aber definitiv auf den Sommer schieben möchte.

Also ein 2015er Lubuntu aus der VirtualBox hervorgekramt und versucht,
pylint, da zu installieren. Fehlanzeige, System nicht aktuell.
Allerdings auch zu alt, um ein Upgrade auf ein 2018er Lubuntu zu machen.

Deshalb ne neue virtuelle Maschine aufgesetzt und aktuelles Lubuntu
installiert. Darauf dann pylint und das Code-Verzeichnis des Raspberrys.

pylint Main.py -> tausende Meldungen
pylint Main.py -E -> nix

Das dann mit allen eingebundenen py-Files einzeln gemacht und
tatsächlich ist noch ein Fehler aufgetaucht.

Kann man pylint auch sagen, dass es sich da selbst durchhangeln soll und
alle Files, die importet sind, mitscannt?

Michael
Stefan Schwarzer (28.01.2019, 13:30)
On 27/01/2019 23.10, Michael S. wrote:
> Am 27.01.2019 um 19:44 schrieb Christopher Arndt:
> Deshalb ne neue virtuelle Maschine aufgesetzt und aktuelles Lubuntu
> installiert. Darauf dann pylint und das Code-Verzeichnis des Raspberrys.
> pylint Main.py -> tausende Meldungen
> pylint Main.py -E -> nix
> Das dann mit allen eingebundenen py-Files einzeln gemacht und
> tatsächlich ist noch ein Fehler aufgetaucht.
> Kann man pylint auch sagen, dass es sich da selbst durchhangeln soll und
> alle Files, die importet sind, mitscannt?


Das weiß ich nicht, aber du kannst statt eines einzelnen
Moduls ein Package angeben, in der Praxis also ein
Verzeichnis. Pylint hier möchte eine `__init__.py` in
dem Verzeichnis, kennt in der Hinsicht also keine
Namespace Packages (PEP 420).

Viele Grüße
Stefan
Christoph Brinkhaus (28.01.2019, 21:47)
Michael S. <michaely> schrieb:

Hallo Michael!

[..]
> nicht tief genug, um sowas zu entdecken.
> Gibt es eine einfache Möglichkeit, den Python Code dahingehend tiefer
> analysieren zu lassen? Jeder C-Compiler bekommt sowas ja auch hin.


Probier mal pylint aus. In dem oben beschriebenen Fall sollte
pylint über das nicht in __init__ gelistete self.State berichten.
> Ich nutze Python bisher nur auf dem Raspberry PI ohne
> Entwicklungsumgebung. Code wird per Editor geschrieben, ausgeführt dann
> direkt in der Konsole.


Ich bin auch nur auf der Konsole und Editor unterwegs.

In vielen Fällen ist es auch nützlich, Testroutinen für
einzelne Python Dateien zu erstellen, die im
if __name__ == '__main__':
Konstrukt abgearbeitet werden. Damit habe ich mir auch vorab
die eine oder andere Überraschung erspart.

Viele Grüße,
Christoph
Thomas Dreher (18.04.2019, 08:30)
Michael S. <michaely> schrieb:

> Gibt es eine einfache Möglichkeit, den Python Code dahingehend tiefer
> analysieren zu lassen? Jeder C-Compiler bekommt sowas ja auch hin.


Eine IDE wird dir solche Fheler normalerweise zumindest als Warnung
markieren.

Gruß

Thomas
Reimar Bauer (18.04.2019, 08:43)
Wenn ihr Code Fans seit, und alles FOSS ist, macht es keinen Unterschied
ansonsten vllt etwas ohne Telemetrie nutzen.



Ich selbst nutze pycharm.

Liebe Grüße
Reimar

Thomas Dreher <thodre> schrieb am Do., 18. Apr. 2019,
08:35:
[..]
Frank Grellert (18.04.2019, 09:06)
Hallo Michael,

wenn Du den Python-Code mit emacs erstellst und die Erweiterung
elpy/flycheck installiert hast, werden schon bei der Eingabe sehr viele
Fehler abgefangen. Natürlich ist das nur eine formale, keine inhaltliche
Überprüfung Deines Codes.

Grüße

Frank

Am 18.04.19 um 08:30 schrieb Thomas Dreher:
[..]
Ähnliche Themen