1

How can I replace the ORM class - so it should not cause recursion !!!

Problem:
original class has the super call, when its got replaced - it causes self inheritance and causes maximum recursion depth exceed exception.
i.e. class orm is calling super(orm, self).... and orm has been replaced by another class which inherits original orm....

Package !

addons  __init__.py  osv  run_app.py

./addons:
__init__.py  test_app1.py  test.py

./osv:
__init__.py  orm.py

contents of orm.py

class orm_template(object):
    def __init__(self, *args, **kw):
        super(orm_template, self).__init__()    
    def fields_get(self, fields):
        return fields    
    def browse(self, id):
        return id

class orm(orm_template):
    def __init__(self, *args, **kw):
        super(orm, self).__init__(*args, **kw)    
    def fields_get(self, fields, context = None):
        return super(orm, self).fields_get(fields)    
    def read(self, fields):
        return fields

contents of addons/init.py

import test    
def main(app):
    print "Running..."
    __import__(app, globals(), locals())

contents of addons/test.py

from osv import orm
import osv
class orm(orm.orm):
    def __init__(self, *args, **kw):
        super(orm, self).__init__(*args, **kw)    
    def fields_get(self, *args, **kw):
        print "my fields get................."
        return super(orm, self).fields_get(*args, **kw)    
osv.orm.orm = orm
print "replaced.........................."

contents of test_app1.py

from osv.orm import orm    
class hello(orm):
    _name = 'hellos'    
    def __init__(self, *args, **kw):
        super(hello, self).__init__(*args, **kw)    
print hello('test').fields_get(['name'])

contents of run_app.py

import addons
addons.main('test_app1')

OUTPUT

>>>python run_app.py

replaced..........................
Running...
...
...
super(orm, self).__init__(*args, **kw)
RuntimeError: maximum recursion depth exceeded

I've seen the similar question

Community
  • 1
  • 1
shahjapan
  • 13,637
  • 22
  • 74
  • 104

1 Answers1

5

Your addons/test.py needs to get and keep a reference to the original orm.orm and use that instead of the replaced version. I.e.:

from osv import orm
import osv
original_orm = osv.orm
class orm(original_orm):
    def __init__(self, *args, **kw):
        super(orm, self).__init__(*args, **kw)    
    def fields_get(self, *args, **kw):
        print "my fields get................."
        return super(orm, self).fields_get(*args, **kw)    
osv.orm.orm = orm
print "replaced.........................."

so the monkeypatched-in class inherit from the original rather than from itself, as you had it in your setup. BTW, if you can avoid monkey-patching by better design of the osv module (e.g. w/a setter function to set what's the orm) you'll be happier;-).

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • yess right!, but I don't have permission to touch orm/osv...and I need to alter few functions for integration with another platform using web services.... – shahjapan Sep 23 '10 at 18:38
  • @shahjapan, as I said in my A, "**if** you can avoid", etc -- if you absolutely cannot, then monkeypatching, while a truly terrible approach, can sometimes (not often) be the least of evils (many more details would be needed to determine whether this is one of those rare cases, or the more common one in which simple indirection &c are perfectly adequate, of course). – Alex Martelli Sep 23 '10 at 19:48
  • It worked but also required minor changes in your answer return super(original_orm, self).fields_get(*args, **kw) as mehtods too caused the same Max. recursion depth exceed problem... – shahjapan Sep 24 '10 at 07:01