Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

overriding builtins is problematic #237

Open
pyjsorg opened this Issue Apr 27, 2012 · 9 comments

Comments

Projects
None yet
1 participant
Contributor

pyjsorg commented Apr 27, 2012

code which overrides builtins results in scoping errors:

def fn():
dict = {}

results in output:

dict = dict({})

instead of:

dict = pyjslib['dict']

Original issue: http://code.google.com/p/pyjamas/issues/detail?id=482 (August 20, 2010 20:11:38)

Contributor

pyjsorg commented Apr 27, 2012

From luke.lei...@gmail.com on August 20, 2010 20:16:07:
e.g. Location.py makeUrlDict

$ ./build.sh --strict --no-inline-code
$ cp output/Libtest.mozilla.cache.html .
in translator.py s/pyjslib['dict']/@{{dict}}/g
$ ./build.sh --strict --no-inline-code

$ diff -u ./Libtest.mozilla.cache.html output/Libtest.mozilla.cache.html

problem becomes apparent.

Contributor

pyjsorg commented Apr 27, 2012

From luke.lei...@gmail.com on August 20, 2010 20:21:29:

  • work out the RHS (translate to "@{{dict}}({})" which gets translated to "pyjslib'dict'" )
  • then add the LHS to the current scope stack variables
  • then output the assignment statement.
Contributor

pyjsorg commented Apr 27, 2012

From luke.lei...@gmail.com on August 20, 2010 21:10:32:
libtest imports.enumerate breaks due to def dict: tuple = (1, 2)
that ends up as "tuple = tuple" which all goes horribly wrong.

Contributor

pyjsorg commented Apr 27, 2012

From cornelis...@gmail.com on August 21, 2010 08:31:17:
OK. I See.

d1 = {}
dict = {}
def fn():
d2 = {}
dict = {}

gets translated to:
$module['d1'] = pyjslib'dict';
$module['dict'] = $module'dict';
$module['fn'] = function() {
var dict,d2;
d2 = $module'dict';
dict = dict([]);
return null;
};

Contributor

pyjsorg commented Apr 27, 2012

From luke.lei...@gmail.com on August 21, 2010 11:37:07:
yep. i tried adding a test, didn't quite get it right (i.e. it passed :)

i really want to replace all occurrences of "pyjslib['dict']", "pyjslib['tuple']" etc. actually inside translator.py and let Translator.w() do the actual work.

Contributor

pyjsorg commented Apr 27, 2012

From cornelis...@gmail.com on August 21, 2010 17:36:39:
Hmm. I think you can do this everywhere except in the _list/_dict/_tuple methods of the Translator class. That are the locations where the javascript code for []/{}/() is defined.

If you would like do do it there too, explain why, please :-)

Contributor

pyjsorg commented Apr 27, 2012

From luke.lei...@gmail.com on August 21, 2010 20:15:24:
i don't know! i just feel it's silly to have to hard-code pyjslib['dict'] - i feel that translate_escaped_names should be doing that job. [why? because i'd like to consider doing different naming conventions (such as pyjslib_dict) and translate_escaped_names is the right place to do that.]

but, right now, translate_escaped_names is getting it wrong.

ok - it's actually getting it right, except in the case where you have code where builtins get overridden.

dict = {} for example.

Contributor

pyjsorg commented Apr 27, 2012

From cornelis...@gmail.com on August 22, 2010 06:30:03:
On second thought, I think that there should be a difference between {} and dict(), or, in other words, it should be clear for the @{{}} mapping whether the builtin dict code should be called or dict(). Maybe we should use @{{{dict}}} for the builtin?

The _dict method should return the final code for the buuiltin @{{{dict}}}

Contributor

pyjsorg commented Apr 27, 2012

From luke.lei...@gmail.com on August 22, 2010 12:24:26:
git diff 032115a a19b352

pyjslib.py

@@ -1661,7 +1661,7 @@ def float_int(value, radix=None):

JS("""
(function(){

  • var $int = pyjslib['int'] = function (value, radix) {
  • var $int = @{{int}} = function (value, radix) {
    var v, i;
    if (typeof radix == 'undefined' || radix === null) {
    if (typeof value == 'undefined') {
    @@ -1699,7 +1699,7 @@ JS("""
    this.__v = v;
    return this;
    }
  •    return new pyjslib['long'](v);
    
  •    return new @{{long}}(v);
    
    };
    $int.init = function () {};
    $int.number = 0x02;

in combination with this:

def lookup(self, name):
...
if not self.number_classes:
if pyname in ['int', 'long']:
name = 'float_int'
...

that could go recursive. ooops!

so yes, you're absolutely right - separate logic is required to hard-wire builtin types.

l.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment