On Feb 7, 2014 1:39 PM, "Clavier" <[email protected]> wrote:
>
>
>
> On Friday, February 7, 2014 8:25:10 AM UTC+9, C Anthony Risinger wrote:
>>
>> On Wed, Feb 5, 2014 at 3:50 PM, Clavier <[email protected]> wrote:
>>>
>>> Hi.
>>>
>>> I am trying to see whether I can implement __getattr__() which is
called when a method does not exist. I have to use a very long unreadable
call in the current version of Pyjs:
>>>
>>>        server=WebRpc('http://server.com/')
>>>        server.request(arg1, arg2)                                     #
Python call
>>>        server.__getattr__('request').__call__(arg1, arg2)     # Pyjs
call because __getattr__() is not automatically called
>>>
>>> I made a class (WebRpc) that a client can access server-side objects,
and this makes client-server programming very simple. In this case,
supporting __getattr__() is important because it makes a server-client call
exactly like a local call. The current Pyjs doesn't support it, so I have
to call it explicitly making the code unreadable.
>>>
>>> I found a previous discussion about it (
https://groups.google.com/forum/#!topic/pyjamas-dev/_aJ2nmFjjas), but I
don't understand why it has a performance issue. I think that a programmer
can avoid it by directly calling the method (i.e.
"obj.__getattr__('request').call()" instead of "obj.request()") if
performance is an issue.
>>>
>>> Please give me your advice about it (how to implement, caveats, or
performance issues, etc).
>>
>>
>> are you building with --enable-accessor-proto? that discussion is from
2009.
>>
>> this code:
>>
>> =========================
>> class Hi(object):
>>
>>     def __getattr__(self, key):
>>         print(key)
>>
>> hi = Hi()
>> print(hi.there)
>> =========================
>>
>> ...will print 'there' and 'null' to the console.
>>
>> --
>>
>> C Anthony
>
>
> Your example(member referencing: hi.there) worked with and
without  --enable-accessor-proto. But my application including method calls
(i.e. hi.there()) building with --enable-accessor-proto still didn't work.
I think that the current Pyjs throws an error on a method call(hi.there()),
but not on member reference (hi.there) regardless of the option.
>
> Following is the simplified code I tested:
>
>> #######################
>> # test __getattr__()
>> class Hi2():
>>     def __init__(self, name):
>>         self.name=name
>>     def __call__(self):
>>         print 'Hi2.%s() was called'% (self.name)
>> class Hi(object):
>>     def __getattr__(self, key):
>>         print 'in Hi.__getattr__(%s)' % key
>>         return Hi2(key)
>> hi = Hi()
>> hi.there                 #member reference
>> hi.there()               #method call
>
>
> Python result :
>>
>> in Hi.__getattr__(there)
>> in Hi.__getattr__(there)
>> Hi2.there() was called
>
>
> Pyjs result (IE and  FireFox):
>>
>>  in Hi.__getattr__(there)
>>
>> Unknown exception: [object Error]
>> Traceback:
>> test_getattr.py, line 17:
>>     hi.there()
>
>
> As you can see, member reference(hi.there) worked, but method call
(hi.there()) threw an exception.

This is expected behavior though?

As your example demonstrates, pyjs does not currently support __call__.
This doesn't mean it isn't handling the __getattr__ call; ultimately it's
failing because you're trying to call an instance (tho I can't comment
offhand why you only see one print) . Try putting a print in the __init__
def of the proxied class, and I believe you will see it created twice.
Also, replace __call__() with call(), then invoke with hi.there.call()...
I'm pretty sure that will work as well.

If you take a look at the generated JavaScript you will see most attribute
access is transformed into getattr() calls; also take a look at
translater_proto.py if you want to explore further, because that is where
getattr (and most other AST magic) is actually handled.

would be nice to have __call__ though...

-- 

C Anthony [mobile]

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"Pyjs.org Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to