Can't set attribute?!

dolgion ch dolgion1 at gmail.com
Tue Sep 1 22:22:22 EDT 2009


Hi there,

i'm new to Python, and i don't understand why following exception
occurs in this code:

class NETRPCGateway(RPCGateway):
    """NETRPC Implementation.
    """

    def __init__(self, host, port):
        self.host = host
        self.port = port
        super(NETRPCGateway, self).__init__(self.host, self.port,
'socket')

    def listdb(self):
        sock = tiny_socket.mysocket()
        try:
            sock.connect(self.host, self.port)
            sock.mysend(('db', 'list'))
            res = sock.myreceive()
            sock.disconnect()
            return res
        except Exception, e:
            return -1

    def login(self, db, user, password):
        sock = tiny_socket.mysocket()
        self.db = db
        self.password = password
        self.user = user
        try:
            sock.connect(self.host, self.port)
            sock.mysend(('common', 'login', db, user, password))
            res = sock.myreceive()
            sock.disconnect()
        except Exception, e:
            return -1

        return res

    def _execute(self, obj, method, args=(), noauth=False):
        sock = tiny_socket.mysocket()
        try:
            sock.connect(self.host, self.port)
            if not noauth:
                print "in noauth"
                args = (self.db, self.uid, self.password) + args
            sock.mysend((obj, method) + args)
            res = sock.myreceive()
            sock.disconnect()
            return res

        except xmlrpclib.Fault, err:
            raise RPCException(err.faultCode, err.faultString)

        except tiny_socket.Myexception, err:
            raise RPCException(err.faultCode, err.faultString)

    def execute(self, obj, method, *args):
        return self._execute(obj, method, args)

    def execute_noauth(self, obj, method, *args):
        return self._execute(obj, method, args, noauth=True)

    def execute_db(self, method, *args):
        sock = tiny_socket.mysocket()
        sock.connect(host, port)
        sock.mysend(('db', method) + args)
        res = sock.myreceive()
        sock.disconnect()
        return res


class RPCSession(object):
    """This is a wrapper class that provides Pythonic way to handle
RPC (remote procedure call).
    It also provides a way to store session data into different kind
of storage.
    """

    __slots__ = ['host', 'port', 'protocol', 'storage', 'gateway']

    def __init__(self, host, port, protocol='socket', storage={}):
        """Create new instance of RPCSession.

        @param host: the openerp-server host
        @params port: the openerp-server port
        @params protocol: the openerp-server protocol
        @param storage: a dict like storage that will be used to store
session data
        """
        self.host = host
        self.port = port
        self.protocol = protocol
        self.storage = storage
        print "RPCSession ", host, port,protocol

        if protocol == 'http':
            self.gateway = XMLRPCGateway(host, port, 'http')

        elif protocol == 'https':
            self.gateway = XMLRPCGateway(host, port, 'https')

        elif protocol == 'socket':
            self.gateway = NETRPCGateway(host, port)

        else:
            raise common.message(_("Connection refused!"))

    def __getattr__(self, name):
        try:
            return super(RPCSession, self).__getattribute__(name)
        except:
            pass

        return self.storage.get(name)

    def __setattr__(self, name, value):
        if name in self.__slots__:
            super(RPCSession, self).__setattr__(name, value)
        else:
            self.storage[name] = value

    def __getitem__(self, name):
        return self.storage.get(name)

    def __setitem__(self, name, value):
        self.storage[name] = value

    def __delitem__(self, name):
        try:
            del self.storage[name]
        except:
            pass

    def get(self, name, default=None):
        return self.storage.get(name, default)

    def get_url(self):
        return self.gateway.get_url()

    def listdb(self):
        return self.gateway.listdb()

    def login(self, db, user, password):

        if password is None:
            return -1

        uid = self.gateway.login(db, user or '', password or '')

        if uid <= 0:
            return -1

        self.uid = uid
        self.db = db
        self.password = password
        self.open = True

        #self.gateway.db = db
        #self.gateway.uid = uid
        #self.gateway.password = password

        # read the full name of the user
        self.user_name = self.execute('object', 'execute',
'res.users', 'read', [uid], ['name'])[0]['name']

        # set the context
        self.context_reload()

        return uid

    def logout(self):
        try:
            self.storage.clear()
        except Exception, e:
            pass

    def is_logged(self):
        return self.uid and self.open

    def getmac(self):
            s = socket.socket(socket.AF_PACKET,socket.SOCK_RAW)
            s.bind(("eth0",9999))
            socObj=s.getsockname()
            mac = socObj[-1]
            mac_str = ":".join(["%02x" % ord(x) for x in mac])
            print "HW : %s"%mac_str
            return mac_str
    def context_reload(self):
        """Reload the context for the current user
        """

        self.context = {'client': 'pos','mac':self.getmac()}
        self.timezone = 'utc'

        # self.uid
        context = self.execute('object', 'execute', 'res.users',
'context_get')
        self.context.update(context or {})

        if self.context.get('tz', False):
            self.timezone = self.execute('common', 'timezone_get')
            try:
                import pytz
            except:
                raise common.warning(_('You select a timezone but
OpenERP could not find pytz library!\nThe timezone functionality will
be disable.'))

        # set locale in session
        self.locale = self.context.get('lang')

    def __convert(self, result):

        if isinstance(result, basestring):
            # try to convert into unicode string
            try:
                return ustr(result)
            except Exception, e:
                return result

        elif isinstance(result, list):
            return [self.__convert(val) for val in result]

        elif isinstance(result, tuple):
            return tuple([self.__convert(val) for val in result])

        elif isinstance(result, dict):
            newres = {}
            for key, val in result.items():
                newres[key] = self.__convert(val)

            return newres

        else:
            return result

    def execute(self, obj, method, *args):
        print "in execute: ", obj, method, args
        if not self.is_logged():
            raise common.warning('Not logged...', 'Authorization
Error!')

        try:

            #print "TERP-CALLING:", obj, method, args
            result = self.gateway.execute(obj, method, *args)
            #print "TERP-RESULT:", result
            return self.__convert(result)

        except socket.error, (e1, e2):
            raise common.message(_(u'Холболт салгагдлаа!'))

        except RPCException, err:

            if err.type in ('warning', 'UserError'):
                raise common.warning(err.data)
            else:
                raise common.error(u'Програмын алдаа!', err.backtrace)

        except Exception, e:
            raise common.error(u'Програмын  алдаа!', str(e))

    def execute_noauth(self, obj, method, *args):
        return self.gateway.execute_noauth(obj, method, *args)

    def execute_db(self, method, *args):
        return self.gateway.execute_db(method, *args)


my script is:

import session

session = session.RPCSession("localhost", 8070)
res = session.listdb()
print "listdb: ",res
uid = session.login("openerp", "admin", "admin")
print uid

So i instantiate a RPCSession object, i call listdb() on it without
problem.
The when i call the login() method, i get the AttributeError
exception:


RPCSession  localhost 8070 socket
listdb:  ['openerp']
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    uid = session.login("openerp", "admin", "admin")
  File "/home/dolgion/workspace/erpj/current/POS/src/session.py", line
337, in login
    uid = self.gateway.login(db, user or '', password or '')
  File "/home/dolgion/workspace/erpj/current/POS/src/session.py", line
214, in login
    self.db = db
AttributeError: can't set attribute

the NETRPCGateway attribute self.db can't be set? why not? i've tried
changing the RPCSession login function
to set the variable like this as well:

self.gateway.db = db

which doesn't work either, same exception.....

any suggestions?



More information about the Python-list mailing list