Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python : why a method from super class not seen?

i am trying to implement my own version of a DailyLogFile

from twisted.python.logfile import DailyLogFile

class NDailyLogFile(DailyLogFile):

     def __init__(self, name, directory, rotateAfterN = 1, defaultMode=None):
         DailyLogFile.__init__(self, name, directory, defaultMode)   # why do not use super. here? lisibility maybe?
         #
         self.rotateAfterN = rotateAfterN

    def shouldRotate(self):
         """Rotate when N days have passed since file creation"""
         delta = datetime.date(*self.toDate()) - datetime.date(*self.toDate(self.createdOn)) 
         return delta > datetime.timedelta(self.rotateAfterN)

    def __getstate__(self):
        state = BaseLogFile.__getstate__(self)
        del state["rotateAfterN"]
        return state

threadable.synchronize(NDailyLogFile)

but it looks like i miss a fundamental of Python subclassing process...as i get this error :

Traceback (most recent call last):
  File "/home/twistedtestproxy04.py", line 88, in <module>
    import ndailylogfile
  File "/home/ndailylogfile.py", line 56, in <module>
    threadable.synchronize(NDailyLogFile)
  File "/home/lt/mpv0/lib/python2.6/site-packages/twisted/python/threadable.py", line 71, in synchronize
    sync = _sync(klass, klass.__dict__[methodName])
KeyError: 'write'

so i need to explicitly add and define others methods like Write and rotate method like this:

class NDailyLogFile(DailyLogFile):
     [...]
     def write(self, data): # why must i add these ?
         DailyLogFile.write(self, data)

     def rotate(self): # as we do nothing more than calling the method from the base class!
            DailyLogFile.rotate(self)

threadable.synchronize(NDailyLogFile)

while i thought it would be correctly inherit from the base mother class. Notice that i do nothing, only calling "super",

please can someone explain why i am wrong on my first idea that it was not necessary to add the Write method?

is there a way to say to Python inside my NDailyLogFile that it shoud have all the methods DailyLogFile that are not defined directly from its mother class? So that it prevents this king of error _sync(klass, klass.__dict__[methodName] and that avoid to specify excplicitly ?

( original code of DailyLogFile that inspired me it taken from the twisted source here https://github.com/tzuryby/freespeech/blob/master/twisted/python/logfile.py )

EDIT: about using super, i get:

  File "/home/lt/inwork/ndailylogfile.py", line 57, in write
    super.write(self, data)
exceptions.AttributeError: type object 'super' has no attribute 'write'

so will not use it. My thoughs was it was right... i must have definitively missed something

like image 484
user2468222 Avatar asked Jun 12 '13 20:06

user2468222


2 Answers

There is one workaround, just do:

NDailyLogFile.__dict__ = dict( NDailyLogFile.__dict__.items() + DailyLogFile.__dict__.items() )
threadable.synchronize(NDailyLogFile)

There is a problem here that you are using the class without having instantiated it. This workaround works because you are forcing to change the class attributes before the instantiation.

Another important comment ist that for a subclass of DailyLogFile the command super would not work, since DailyLogFile is a so called "old style class", or "classobj". The super works for the "new style" classes only. See this question for further information about this.

like image 66
Saullo G. P. Castro Avatar answered Sep 29 '22 13:09

Saullo G. P. Castro


I dare say that the twisted/python/threadable.py code has a bug in it. __dict__ only returns the local attributes, not the inherited attributes. Other posts say to use dir() or inspect.getmembers() to get them.

The good news is that you are correct on your first idea that the write method is inherited. The bad news is that Twisted doesn't recognize inherited methods, so you have to write them yourself.

like image 24
Brent Washburne Avatar answered Sep 29 '22 13:09

Brent Washburne