Alternative zu eval() ?

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.
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. April 2008, 13:01

Ich möchte, das ein User Daten eingeben kann, die aber nur vom Typ unicode, string, number, float, tuple, dict usw. sind.
In dem Fall eval() zu benutzten ist zwar nächstliegend, aber doof. Wie kann ich das anders machen???

btw. Der User kann die Daten über ein html Formular eingeben, aber das ist eigentlich egal.

EDIT: Doch noch was gefunden:
safe_eval: http://aspn.activestate.com/ASPN/Cookbo ... ipe/496746 - macht aber ehr eine blackliste... Ein versuch es mit einer whitelist zu probieren:
http://www.python-forum.de/post-45714.html#45714 - das schaue ich mir mal näher an...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Montag 28. April 2008, 13:11

jens hat geschrieben:Ich möchte, das ein User Daten eingeben kann, die aber nur vom Typ unicode, string, number, float, tuple, dict usw. sind.
Würde dir da vielleicht ein JSON-Parser weiterhelfen? JSON kann doch eigentlich alles genannte, und das auch syntaktisch gleich zu python. (ok, unicodestrings nich, aber sofern du nicht "bytearrays" brauchst ist das doch sogar ein gewinn)
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. April 2008, 14:36

Gute Idee. Aber ich möchte erstmal bei der Python Syntax bleiben. Ich sollte das aber mal im Hinterkopf behalten...

Ich hab noch was gefunden: http://aspn.activestate.com/ASPN/Cookbo ... ipe/364469

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Montag 28. April 2008, 14:49

Du suchst nicht zufällig etwas zur Form-Validierung wie etwa WTForms?
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 28. April 2008, 14:57

Ne, da nehme ich django's newforms ;)

Also um was es eigentlich geht: In PyLucid gibt es die "Preferences" Tabelle. Einstellungen, die Plugins und das Basis System hinterlegen können. Damit das ganze sehr flexibel ist, nutzte ich pickle... Bisher gibt es keine Möglichkeiten die Einstellungen zu verändern :(
Als erster Schritt, damit der Admin die Einstellungen bearbeiten kann, ist halt einfach alles mittels pprint in einer html Form editierbar zu machen. (Also pro Einstellung, ein Text-Input).
Auch wenn das nur der Admin darf, möchte ich aber ehr ungern eval() benutzen um die Eingaben in Python Objekte zu wandeln... Deswegen die Frage hier ;)

Auf langer Sicht gesehen, sollte ein Plugin allerdings newforms dafür nutzten, macht ja eigentlich auch mehr Sinn... Dennoch sollte es diese Form der editierbarkeit dennoch zusätzlich geben...

EDIT: Das ist daraus geworden:
http://pylucid.net:8080/pylucid/browser ... ta_eval.py

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Dienstag 29. April 2008, 15:01

Ich würde sowas so lösen, dass zu jedem Konfigurationswert, der z.B. in der Datenbank oder anderswo definiert ist, zugleich auch ein Typ und evtl. ein Default-Wert festgelegt sind. Möchte ein Benutzer einen Wert ändern, wird anhand des zugewiesenen Typs versucht, aus dem Eingabestring dieser Typ zu erzeugen. Klappt das, gut; wenn nicht, Fehlermeldung ausgeben. Deckt das nicht die von dir gewünschte Flexibilität ab?
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dienstag 29. April 2008, 15:07

Naja, ich muss da generell nochmal intensiver drüber nachdenken.

Evtl. gebe ich bei jedem Einstellungswert direkt auch den passenden newforms-Field an. Dann könnte man sehr einfach eine passende html-form mit Validierung erzeugen...

Am besten erstelle ich erstmal eine Liste mit potenziellen Einstellungswerten, um zu sehen, was überhaupt i.d.R. gespeichert werde muß...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 30. April 2008, 08:28

Auch wenn ich es vielleicht nicht brauchen werde, hab ich in data_eval.py die Unterstützung für datetime und timedelta Einträge implementiert:

http://pylucid.net:8080/pylucid/changeset/1542

Keine Ahnung ob das die beste Variante ist, es zu implementieren, aber es funktioniert so und ist druch das dict ALLOWED_CALLABLES erweiterbar...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Mittwoch 30. April 2008, 09:53

Ich würde dafür einen eigenen Parser schreiben. Ich habe 2x ein Microrahmenwerk für PEGs aka Parserkombinatoren gepostet, damit sollte das in 1-2 Stunden realisierbar sein.

Stefan
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 30. April 2008, 10:00

Warum sollte ich mir einen eigenen Parser schreiben, wenn es compile schon für mich erledigt?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Mittwoch 30. April 2008, 10:21

Weil eval() prinzipbedingt unsicher ist. Ich dachte, den auszuführenden Code könnten User eingeben. Da würde ich nur meinem eigenen Parser trauen.

Stefan
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 30. April 2008, 10:22

Hast du dir die sourcen überhaupt angesehen?
http://pylucid.net:8080/pylucid/browser ... ta_eval.py

Ich nutzte kein eval()

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Mittwoch 30. April 2008, 10:35

Sollte es ast.py in die Stdlib schaffen kannst du "ast.literal_eval" nutzen: http://dev.pocoo.org/hg/sandbox/file/tip/ast/ast.py
TUFKAB – the user formerly known as blackbird
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Mittwoch 30. April 2008, 10:42

Ich habe ehrlich gesagt, auf die Überschrift reagiert und das, was du in deinem ersten Posting von ASPN erwähnt hast, nicht deine fertige Lösung. In Google AppEngine-Zeiten würde ich ja empfehlen, nicht auf `import compiler` zu bauen. Warum enthält der UnitTest `testLineendings` eigentlich keine Asserts?

Stefan
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Mittwoch 30. April 2008, 10:48

Die Sache schreit doch: Wenn man `eval()` benutzt, muss man einen verdammt guten Grund haben, und ich sehe hier keinen, im Gegenteil (User-Input). Also muss da was anderes her.

P.S.: Das hier bezieht sich ebenfalls auf den Titel und die ursprüngliche Frage. Nur, damit spätere Leser das nicht falsch verstehen können.
Antworten