myvyang / pyv8

Automatically exported from code.google.com/p/pyv8
0 stars 0 forks source link

Built-in objects not accessible via the global object #74

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

import PyV8

class Global(PyV8.JSClass):

    def __init__(self):
        self.s = self

    def write(self, val):
        print val

with PyV8.JSContext(Global()) as ctx:
    ctx.eval(""" 
        write(String)
        write(s.String)       
    """)

What is the expected output? What do you see instead?

Output is: None/Undefined
Should output: function String() { [native code] }

Original issue reported on code.google.com by ATM1...@gmail.com on 14 Feb 2011 at 4:00

GoogleCodeExporter commented 9 years ago
As you known, the Global class doesn't equal to the global object in 
Javascript, it is only a backup object when the property doesn't exist in the 
real global object.

Javascript code -> Javascript global object -> Python global object -> Python 
objects

So, if you access the 's' which point to the Python global object, you just 
bypass the Javascript global object. Maybe you could implement your expectation 
it like

ctx.eval("""
this.s = this;
write(s.String);
"""

On the other hand, Python global object can't pass the nonexists property back 
to the Javascript object, because it may cause an infinite loop.

Original comment by flier...@gmail.com on 15 Feb 2011 at 2:03

GoogleCodeExporter commented 9 years ago
Well I was asking because I see some cases where it may help.

For example in your browser script:
http://code.google.com/p/pyv8/source/browse/trunk/demos/browser.py

You define window to be the python global object:

    @property
    def window(self):
        return self

In a real browser though, I am able to do: window.String, window.Date and 
ect... (at least in chrome).  This is not a big deal though.  You can just loop 
through the js global object and assign to the python global object as you say. 

Original comment by ATM1...@gmail.com on 15 Feb 2011 at 3:32

GoogleCodeExporter commented 9 years ago
Ok, I agree it is a little strange, I will think more about it later.

Original comment by flier...@gmail.com on 16 Feb 2011 at 2:01

GoogleCodeExporter commented 9 years ago
I found a more concrete example of this from the mootools Javascript library.

Inside function scope a new variable "window" is declared and assigned to 
"this".  

(function(){

var document = this.document;
var window = document.window = this;  

Inside this scope properties are added to the (local) window which is really 
"this" which is also the global window object:

window.x = 10;

Now outside of the function's scope:

window.x is undefined but it should be 10.  

Original comment by ATM1...@gmail.com on 24 Feb 2011 at 9:26

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I came up with a solution that seems to work o.k.

import PyV8

class Global(PyV8.JSClass):

    def __init__(self):
        self.g = self
        self.globalNames = []

        self.ctx = PyV8.JSContext(self)
        with self.ctx:
            self.ctx.eval("""

                function getGlobalNames() {
                    g.globalNames = Object.getOwnPropertyNames(this);
                }

                a = 10;
                this.b = 11;
                g.c = 12;

                write(g.a);
                write(g.b);
                write(g.c);

                write(a);
                write(b);
                write(c);

                write(this.a);
                write(this.b);
                write(this.c);

                write(g.a === this.a);
                write(a === this.a);
                write(g.a === a);

                write(g.b === this.b);
                write(g.b === b);
                write(b === this.b);

                write(g.c === this.c);
                write(g.c === c);
                write(c === this.c);

                write(g.String)
                write(g.JSON)
                write(g.eval)
            """)

    def write(self, val):

        print val

    def __setitem__(self, key, val):
        setattr(self, key, val)

    def __getitem__(self, key):

        with self.ctx:
            self.ctx.eval("getGlobalNames()")

        if key in self.globalNames:
            with self.ctx:
                return self.ctx.eval("%s" % key)

Global()

The output is:

10
11
12
10
11
12
10
11
12
True
True
True
True
True
True
True
True
True
function String() { [native code] }
[object JSON]
function eval() { [native code] }

Original comment by ATM1...@gmail.com on 31 Mar 2011 at 10:48