Seite 1 von 1

absurde fehlermeldung

Verfasst: Dienstag 8. August 2006, 20:51
von murph
hi!
habe ich es etwa geschafft, python eine falsche fehlermeldung abzuluchsen?
murph@murphs:~/own_project$ ./servertest.py
Traceback (most recent call last):
File "./servertest.py", line 7, in ?
server.load()
File "/home/murph/own_project/sqliteserver.py", line 169, in load
self.conn.cursor(self.root_sid).execute("SELECT * FROM users")
File "/home/murph/own_project/sqliteserver.py", line 57, in cursor
return self.cur[self.get_uid_from_sid(sid)]
File "/home/murph/own_project/sqliteserver.py", line 48, in get_uid_from_sid
return self.session[sid]
TypeError: dict objects are unhashable
der codeteil funktioniert auf einmal nicht mehr, dass hat der aber aber schon seid wochen.
ich weiß nicht, was ich verändert haben sollte, um diese neuen fehler aus uralten standardfunktionen rauszukitzeln o.0

//edit:
ich habe bewusst erstaml noch keinen text dazugesetzt.
das sind 20,4 kb, wenns nicht anders geht, werd ich das auf ner seite zur verfügung stellen.

Verfasst: Dienstag 8. August 2006, 21:21
von murph
fehler gefunden:
nach dem lesen von http://72.14.221.104/search?q=cache:TDM ... nt=firefox
habe ich einfach mal das dic ausgelassen.
das hatte sich nämlich verändert...allerdings taucht das nicht dort auf, in der fehlermeldung,
das war zufall, dass ich das gefunden habe

Verfasst: Dienstag 8. August 2006, 21:46
von murph
naja, die zweite kommt gleich hinterher^^
naja, muss so ein wald_vor_lauter_bäumen-fehler sein.
ich bekomme immer einen keyerror in einem thread,
wenn ich versuche, auf ein bestehendes dictionairy zuzugreifen.
der code ist :

Code: Alles auswählen

                if ql[0] == 'login':
                    usrsid = self.conn.login(ql[1],ql[2])
                    self.sendpickled(usr_addr, usrsid)
                    print "someone tried to logged in", usrsid
                    thread.start_new_thread(userthread, (usrsid,))
                    self.conn.logout(usrsid)
                    continue
########################
            def userthread(usrsid):
                   def exit_thread(*args, **kwargs):
                       thread.exit()

                   thread_com['old'] = False
                   thread_com[usrsid] = False
                   usrcon = self.conn.connection(usrsid)
                   usrcur = self.conn.cursor(usrsid)
                   [...]

                   while not thread_com['kill']:
                       if thread_com['old'] == thread_com[usrsid]:
                           continue
                       ql = thread_com[usrsid]
                       print "the thread sais the ql is ", ql
                       if ql[1] in commands:
                           command = commands[ql[1]]
                           try:
                               if len(ql)>2:
                                   print ql[1],"(",ql[2:],")"
                                   returned = command(*ql[2:])
                               else: 
                                   returned = command()
                               print ql[1], "is a command and returned", returned
                               self.sendpickled(usr_addr, returned)
                           except sqlite.OperationalError, e:
                                self.sendpickled(usr_addr, e)
                       elif ql[1] in variables: 
                           var = variables[ql[1]]
                           print ql[1], "is a variable"
                           if ql[2] == "varset":
                               varriables[ql[1]] = ql[2]
                               print "i am a varsetter"
                           elif ql[2] == "varget":
                               print "i am a vargetter"
                               self.sendpickled(usr_addr, variables[ql[1]])
                           else:
                               self.forbidden_ip_list.append(usr_addr)
                               print "ATTACK!", ql
                               continue
                       else:    
                           self.forbidden_ip_list.append(usr_addr)
                           print "ATTACK!", ql
                           continue
nun kann userthread im neuen thread leider nicht auf eine korrekte sid zurpckgreifen.

it is Tue Aug 8 22:35:19 2006
server will run till Tue Aug 8 22:35:24 2006
the multithreadversion
someone tried to logged in ]o=��
Unhandled exception in thread started by <function userthread at 0xb7d0bbc4>
Traceback (most recent call last):
File "/home/murph/own_project/sqliteserver.py", line 375, in userthread
usrcon = self.conn.connection(usrsid)
File "/home/murph/own_project/sqliteserver.py", line 60, in connection
return self.conn[self.session[sid]]
KeyError: '\xfc]o\xd0\x13\xfa\xb0=\xaa\xd1U\xa9\xff\xe0\xdb\x98'
ATTACK! Wrong SID! ['\xfc]o\xd0\x13\xfa\xb0=\xaa\xd1U\xa9\xff\xe0\xdb\x98', 'execute', 'SELECT * FROM test']
ATTACK from known user
murph@murphs:~/own_project$

Verfasst: Dienstag 8. August 2006, 22:09
von murph
ich habe über listen das verucht.
die sessionid verändert sich unterwechs nicht.
ich habe einmal mir usrsid == test[1] ausprinten lassen,
das hat mich überzeugt (beim login wurde der wert in test reingeschrieben...0 ist wie immer root :-) ).
aber trotzdem scheint die sessionsid an der stelle unbekannt zu sein,
was ich der fehlermeldung entnehme.
an der einen stelle wird (noch) nicht überprüft, ob die sid funktioniert und existiert.

Verfasst: Donnerstag 10. August 2006, 09:31
von murph
hatte einer von euch schon einmal folgende struktur:

Code: Alles auswählen

class SomeThing:
    def something(self):
        def something_else(self):
            a = my_dic['my_entry']
            print a
gehabt?
ich habe an allen stelle printen lassen, und mir wird gesagt, dass alles klar ist, dass die usrsid gleich dem dic_entry ist, nur bei entry selbst kann ich es nicht aufrufen.
liegt es zufällig abn meiner struktur?

Verfasst: Donnerstag 10. August 2006, 10:01
von keppla
Ich habe zwar nach mehrmaligem Lesen immer noch nicht die geringste ahnung, was dein eigentliches Problem ist, aber

Code: Alles auswählen

class SomeThing:
    def something(self):
        def something_else(self):
            a = my_dic['my_entry']
            print a
Dieses konstrukt tut nichts. "something" erzeugt eine funktion, die es an den namen something_else bindet, und vergisst sie direkt. something_else wird nicht ausgeführt, und kann (mangels bindung) auch nirgendwo mehr aufgerufen werden.
wozu soll das dienen?

Verfasst: Donnerstag 10. August 2006, 10:25
von murph
das konstrukt an sich soll auch gar nichts machen.
das war einfach und kurz.
mein problem ist, dass ein dictionairy nicht gefüllt wird!
ich habe so eine konstruktion, wie du sie gesehen hast,
aber nach dem aufruf der funktion, die das dictionairy füllen soll, sieht alles genauso aus.
aber an sich funktioniert auch die funktion, nur mit der einschränkung,
dass sie nur funktioniert, solange ich entweder nur einen thread habe oder den root-login tätigt.

also hier mal mein print-out:
murph@murphs:~/own_project$ ./servertest.py
load...
6E(�S&
[(0, u'root', u'4829764b4082d0c138feac79de89b24275a769dd', 1), (1, u'murph2', u'ffc6cb613cefc081b38d82bd770ee01fa2ef0446', 0)]
-->[ok]
it is Thu Aug 10 11:46:59 2006
server will run till Thu Aug 10 11:47:19 2006
the multithreadversion
this is the login-sid :ct}��*
someone tried to logged in :ct}��*
the uid: 1
i am the userthread! the usrsid is :ct}��*
Unhandled exception in thread started by <function userthread at 0xb7dadf0c>
Traceback (most recent call last):
File "/home/murph/own_project/sqliteserver.py", line 408, in userthread
usrcon = self.conn.connection(usrsid)
File "/home/murph/own_project/sqliteserver.py", line 62, in connection
uid = self.session[sid]
KeyError: ':c\x92t}\xcb;\x1f\xe3\xc4\xf8\xf9\x10\x02\x16*'
test[1] is the same as usrsid
{'\xfc6\xf9\x83\xa0\x91E(\xa6\x8e\x81\xcb\xf2\xc1\x93&': 0}
ATTACK! Wrong SID! [':c\x92t}\xcb;\x1f\xe3\xc4\xf8\xf9\x10\x02\x16*', 'execute', 'SELECT * FROM test']
ATTACK from known user
durch einige prints werde ich noch mehr verunsichert:
es wird eine sid ermittelt beim login, die wird dreimal angezeigt!
zuerst direkt im login, danach im main-part, danach im userthread.
der userthread kann die uid (userid) ziehen, die man braucht, um auf die datenbanken zuzugreifen.
dann das verwunderliche: ich kann die connection und den cursor nicht "abholen" (code:)

Code: Alles auswählen

    def connection(self,sid):
        uid = self.session[sid]
        return self.conn[uid]

    def cursor(self,sid):
        uid = self.session[sid]
        return self.cur[uid]
das ist an sich einfach nur das returnen von einem dic.inhalt, der beim login festgelegt wurde (die connection aufgebaut, der cursor initialisiert).
aber wie zu sehen ist, ist dort der sid-eintrag auf einmal verschwunden!
danach wird noch ausgegeben, dass die sid gleich der in einer liste abgespeicherten liste angegeben ist.





//edit:
ich habe es aus diesem konstrukt genommen, und es hat funktioniert!
vllt irgendein self oder so, keine ahnung!

Verfasst: Donnerstag 10. August 2006, 10:55
von N317V
keppla hat geschrieben:Ich habe zwar nach mehrmaligem Lesen immer noch nicht die geringste ahnung, was dein eigentliches Problem ist
Musst Du murph dann unbedingt in seinem Monolog stören? *ts* *kopfschüttel* ;-)

SCNR

Verfasst: Donnerstag 10. August 2006, 12:10
von keppla
das konstrukt an sich soll auch gar nichts machen.
das war einfach und kurz.
wozu dient es dann? ist es kunst?
ich meinte das nicht in irgendeinem übertragenen Sinne, von der wirkung her ist

Code: Alles auswählen

sth = SomeThing()
sth.something()
identisch mit
ich habe es aus diesem konstrukt genommen, und es hat funktioniert! vllt irgendein self oder so, keine ahnung!
falls du damit das "SomeThing"-konstrukt meintest, ja, hättest du das problem gelöst, dass es nichts tut, wäre das nächste problem ziemlich sicher das doppelt vergebene self

Verfasst: Donnerstag 10. August 2006, 13:10
von murph
es ging mir dabei NUR um die methode in der methode in der klasse.
übrigens habe ich sogar eine methode in der methode in der methode in einer klasse, aber das tut nicht zur sache...
ich empfinde so etwaws nun mal übersichtlicher, wenn der skript eine entsprechende länge hat, wie es mit der performance bestellt ist, weiß ich nicht, da ich bis jetzt kein gegenstück hatte.

Verfasst: Freitag 11. August 2006, 08:37
von keppla
ich empfinde so etwaws nun mal übersichtlicher, wenn der skript eine entsprechende länge hat, wie es mit der performance bestellt ist, weiß ich nicht, da ich bis jetzt kein gegenstück hatte.
Ich sehe es auch so, dass fast immer Übersichtlichkeit vor Performance geht, wobei ich ehrlich gesagt nicht glaube, dass nested functions prinzipiell inperformat wären.
Allerdings finde ich zu tief verschachteltes nicht sonderlich übersichtlich (wobei das Geschmackssache sein könnte).

Was mich etwas stutzig macht, ist, dass du von "methoden in mehtoden" sprichst, da es eigentlich funktionen in mehthoden sind, und ich dein Post generell so verstehe, als wären die inneren funktionen für dich ein Ersatz für 1st-level-methoden.
Das ist nämlich afaik nicht so.

Verfasst: Freitag 11. August 2006, 12:42
von murph
sry, dafür hatte ich nicht genug fachwissen, um zu wissen, dass das dann wieder funktionen in methodedn sind.
ich habe zb sowas gemacht:

Code: Alles auswählen

class Server:
    def run(**args):
        def run_one_version(self):
            print "test"
            def timer(self):
                #do something else...
            while timer(self):
                print "while-schleife"
                return args['jklö'] == 'jklö':
        if args['asdf'] == 'asdf':
            run_one_version(self)

Verfasst: Freitag 11. August 2006, 14:25
von N317V
murph, Du findest das wirklich übersichtlich?! :shock:

Verfasst: Freitag 11. August 2006, 16:51
von murph
andere finden mich auch komisch^^
aber bei entsprechender länge (ca 500 zeilen) des skriptes finde ich konstrukte dieser art als übersichtlich.

Verfasst: Freitag 11. August 2006, 17:06
von N317V
Lass uns bitte niemals zusammenarbeiten, murph. Ich würde rausfinden wo Du wohnst und Dich im Schlaf erdrosseln. ;-)

Verfasst: Freitag 11. August 2006, 20:10
von Masaru
murph hat geschrieben:

Code: Alles auswählen

class Server:
    def run(**args):
        def run_one_version(self):
            print "test"
            def timer(self):
                #do something else...
            while timer(self):
                print "while-schleife"
                return args['jklö'] == 'jklö':
        if args['asdf'] == 'asdf':
            run_one_version(self)
Mist, nie hänge ich an der richtigen Kiste mit Python ... aber kann die def run(**args): Klassenmethod ohne Klassenparameter self selbst funktionieren?

Wäre mir neu :D.

Was hingegen gar nicht mal so untypisch ist wäre dies hier hingegen:

Code: Alles auswählen

>>> class TestIt(object):
... 	def __init__(self):
... 		pass
... 	def run(self, exec_list=[]):
... 		def do_exec(exec_string):
... 			exec(exec_string)
... 		for this in exec_list:
... 			do_exec(this)
... 			
>>> tester = TestIt()
>>> tester.run(["print 'test'", "print 'it'"])
test
it
>>Masaru<<

Verfasst: Samstag 12. August 2006, 19:27
von keppla

Code: Alles auswählen

class Server:
    def run(**args):
        def run_one_version(self):
            print "test"
            def timer(self):
                #do something else...
            while timer(self):
                print "while-schleife"
                return args['jklö'] == 'jklö':
        if args['asdf'] == 'asdf':
            run_one_version(self)

was bitte ist daran übersichtlicher als die äquivalente version:

Code: Alles auswählen

class Server:
    def run(self, *args):
        if args['asdf'] == 'asdf':
            print "test"
            while True:
                # do something else...
                if condition: break
                return args['jklö'] == 'jklö':
Übersichtlichkeit ist nur bis zu einem gewissen Grad Geschmackssache. Man kann sie messen, lese mal in 3 wochen oder so dieses Post, und Messe die Zeit, die du brauchst, um die snippets zu lesen.
Mist, nie hänge ich an der richtigen Kiste mit Python ... aber kann die def run(**args): Klassenmethod ohne Klassenparameter self selbst funktionieren?
Doch, kann es, das self ist dann halt in args drin. Ich kann mir zwar kaum vorstellen, dass Murph das beabsichtigte, da er in Zeile 12 self benutzt, aber was tut man nicht alles für die Übersichtlichkeit ;)

Verfasst: Samstag 12. August 2006, 19:39
von murph
natürlich habe ich das self vergessen und im orginal ist es enthalten.
mein konstrukt macht aber uach nur sinn, wenn while weitaus mehr argumente bräuchte.
ich habe hier nur ein modell geliefert.
in wikrlichkeit soll für while überprüft werden, dass, falls eine zeit gesetzt wurde, bei ablauf der zeit der server ausgeschaltet wird.
falls zeit nicht gesetzt wurde, läuft einfach alles weiter.
falls andere variablen argumente gegeben werden (mir sind zurzeit keinen anderen eingefallen), sollen ebenfalls die überprüft werden.
natürlich könnte man das zur zeit noch alles dareinschreiben, aber ich bin ein freund von >80 zeilen, nur selten muss ich mehr nehmen...

Verfasst: Samstag 12. August 2006, 20:15
von keppla
mein konstrukt macht aber uach nur sinn, wenn while weitaus mehr argumente bräuchte.
ich habe hier nur ein modell geliefert.
selbst dann halte ich statt

Code: Alles auswählen

def condition(a,b,c):
   doSophisticatedStuffWith(a,b,c)
   doEvenMoreStuff(a,b)
   return theComplicatedResult(a,b,c)

while condition(a,b,c):
   print x
dieses hier

Code: Alles auswählen

while True:
   doSophisticatedStuffWith(a,b,c)
   doEvenMoreStuff(a,b)
   if not theComplicatedResult(a,b,c): break

   print x
für günstiger, da die scopes klarer sind und man "einfach runterlesen" kann, ohne irgendwelche funktionen auf den mentalen stack zu schubsen.
Alternativ könnte die innere funktion eine (private) methode des servers werden, schliesslich hat sie ja eine gewisse allgemeingültigkeit, wenn sie feststellen soll, ob zu gegebenen parametern der server laufen soll.
Wobei ich sagen muss: bei der Whileschleife kann ich noch halbwegs damit leben, wei run_one_version sehe ich nicht den geringsten grund,

um mal den Sprachnazi raushängen zu lassen:
Flat is better than nested
Simple is better than complex

Verfasst: Samstag 12. August 2006, 20:43
von murph
deiner meinung nach sollte ich lieber sagen, dass der nutzer sich run_one_version bzw run__other_version so merken soll?
kann ich mit anfreunden.