Skip to content
root edited this page Jun 27, 2010 · 1 revision

MigrationGuide

Describes the difference between pyjamas code and native python code.

This document applies to Pyjamas 0.6.

Introduction

Pyjamas does python code to javascript translation. This implies that pyjamas code will never be fully python compliant, but it aims at being close to the real thing. Furthermore, pyjamas doesn't (at the time of writing this) support all features of python, you'll need to be aware of what it does and does not support, and how to access features of python in a way that works with pyjamas. For most GUI browser development, which is where, in combination with the Pyjamas Web Widget Set, pyjamas is best utilised, these differences tend to be just annoyances rather than show-stoppers. Also, readers are reminded that development should really be done using Pyjamas-Desktop as well as Pyjamas, in order to avoid falling into browser limitation traps and javascript limitation traps.

There are some translator options that make the generated code more or less pythonic. The two most important are -O and --strict. The first optimizes for speed and omits e.g. attribute checking. The latter tries to get as close as it can to the http://python.org behavior. If you're building a library, try to make it work with --strict _and_ without --strict.

As a general rule, readers are advised to themselves build the pyjamas regression tests using the compiler options of their choice (see pyjsbuild --help) and to check the individual regression tests to see which python language features they require. At the time of writing, there are over 1,600 individual regression tests, in over 20 modules. If a particular python feature is not supported, readers are advised to submit a feature request at http://code.google.com/p/pyjamas/issues submitting a patch which includes a simple test for the feature requested.

Callables

Javascript simply doesn't support callables. For Pyjamas 0.5, fancy wrappers for every function call to support this were not added, because that would make the javascript even slower than it already is. For Pyjamas 0.6, the python --strict option can be applied to enable the workaround. So, without --strict, you can't implement call on your objects, and you can't pass an object where a function is expected.

This used to also applies to classes: for Pyjamas 0.5 and before, if you were passed a class object and you wanted to instantiate it, you needed to use cls.new() to create an instance of the class. However, for Pyjamas 0.6, as can be seen in libtest ClassTest.py testGlobalFactory, even with -O it is now possible to instantiate classes by passing the class object as a variable, and calling it.

Attribute Access and Bound Methods

Atrribute checking is enabled with --attribute-checking (or --strict). Without this option, pyjamas doesn't do anything extra with attributes access. This means that without --strict, we're limited to what javascript does with attribute accesses.

With the option --bound-methods (also enabled with --strict), methods are autometically "bound" to a class instance. Without this option, methods are not automatically "bound" to the object when you access them (unless you do so by calling the method). To get a pointer to a "bound" method, use getattr(obj, "methodName"). This technique results in anythin up to a 100% speed increase over --strict, depending on the browser.

Classes

Class methods, static methods, unbound methods, and class variables are all emulating the python behavior quite well at this time. However, be aware that pyjamas is sensitive to capitalization, and there may be some issues if you have classes that start with a lower case letter.

Undefined

Javascript has the concept of "undefined" when accessing an uninstantiated variable (or method). In python, undefined variables cause a runtime error, whereas browsers are designed to silently return the result "undefined" in order to not scare the pants off of users (presumably, the basis for this stupid decision is that broken web application behaviour is better than an in-your-face error message). So, if you are used to debugging your applications in the expectation that the runtime will catch undefined errors, you will need to be extra careful. Some of the 'undefined' is caught when attribute checking is enabled (catches undefined attributes).

This is one area where it is strongly, strongly advised that PyjamasDesktop be part of the testing and development of the application. An accidental missing call to a base class __init__ for example can result in a set of base class variables being entirely missing. Javascript will *not* help you out; arithmetic will inexplicably continue cheerfully with "undefined" eating its way through all calculations; len(undefined) will itself return "undefined" and thus result in False on boolean tests, and much more.

String construction

In PyjamasJavascript, concatenation using the "+" operator of a string and an integer (or object) will result in the integer (or object) automatically being converted to a string. In python, this results in a runtime error. If you intend ever to use PyjamasDesktop, avoid relying on this javascript-esque feature of automatic argument conversion, and use "%d" % variablename instead

Alternatively, the --operator-funcs (and --strict) option now enables creation of code where "+" is replaced by obj1.__add__(obj2), "-" with __sub__ etc., and string, integer and list objects now have __add__, __sub__, __mul__ etc.

Function arguments

Funtion/method argument checking is enabled with --function-argument-checking (and with --strict). Without this option, the functions/methods behave like javascript functions, i.e, no function argument checking.

Bit operations

In Javascript all numbers are floating point. Bit operations work on emulated integers and are cut-off two 32 bit (where one bit is used for sign).

See http://www.hunlock.com/blogs/The_Complete_Javascript_Number_Reference

A workaround for 3 << 34 (which is 12 in JS) is 3 * Math.pow(2,34), or in Pyjamas: 3 * (234) For 51539607552 >> 34 is the Pyjamas workaround: 3 / (234)

51539607552 | 3 == 3 (should be 51539607555) 51539607556 | 3 == 7 (should be 51539607559)

String multiplication

There's no string multiplication (e.g. 'a' * 4, or 'abc' * 2) A workaround for 'a' * 4 is: ''.ljust(4, 'a') A workaround for 'abc' * 2 is: ''.join(['abc' for i in range(2)])

Update: the --operator-funcs (and --strict) option now enables creation of code where "+" is replaced by obj1.__add__(obj2), "-" with __sub__ etc., and string, integer and list objects now have __add__, __sub__, __mul__ etc. so, "l = 'a' * 5" now works; as does "l = [1,2]; l += [5]".

List addition

List addition is not supported in Pyjamas (e.g. [1,2] + [3,4]) A workaround for a = [1,2];b = a + [3,4] is: b = a[:];b.extend([3,4])

Update: the --operator-funcs (and --strict) option now enables creation of code where "+" is replaced by obj1.__add__(obj2), "-" with __sub__ etc., and string, integer and list objects now have __add__, __sub__, __mul__ etc. so, "l = [0] * 5" now works; as does "l = [1,2]; l += [5]".

Tuple addition

Tuple addition is not supported in Pyjamas (e.g. (1,2) + (3,4)) A workaround for a = (1,2);b = a + (3,4) is: b = list(a)[:];b.extend(list((3,4)));b=tuple(b)