4. Systematic code examples: a guided tour of Transcrypt

One ready-to-run code example is worth more than ten lengthy descriptions. The autotest and demo suite, that is part of the distribution, is a collection of sourcecode fragments called testlets. These testlets are used for automated regression testing of Transcrypt against CPython. Since they systematically cover all language constructs, they are also very effective as a learning tool. The testlets are arranged alphabetically by subject.

Autotest: Transcrypt autotest demo suite
from org.transcrypt.stubs.browser import __pragma__
import org.transcrypt.autotester

import arguments
import attribs_by_name
import builtin_super
import callable_test
import classes
import complex_numbers
import conditional_expressions
import control_structures

__pragma__ ('ifdef', '__py3.6__')   # Needed because Transcrypt imports are compile time
if '__py3.6__' in __symbols__:      # Needed because CPython doesn't understand pragma's
    import dashed_numbers
__pragma__ ('endif')

import data_structures
import decorators
import dict_comprehensions
import dictionaries
import div_issues
import div_pulls
import docstrings
import exceptions
import extended_slices

__pragma__ ('ifdef', '__py3.6__')   # Needed because Transcrypt imports are compile time
if '__py3.6__' in __symbols__:      # Needed because CPython doesn't understand pragma's
    import fstrings
__pragma__ ('endif')

import general_functions
import globals_function
import indices_and_slices

__pragma__ ('ifdef', '__esv6__')
if '__esv6__' in __symbols__:
    import iterators_and_generators
__pragma__ ('endif')

import lambda_functions
import list_comprehensions
import local_classes
import metaclasses
import module_builtin
import module_cmath

__pragma__ ('ifdef', '__esv6__')
if '__esv6__' in __symbols__:
    import module_itertools
__pragma__ ('endif')

import module_math
import modules
import nonlocals
import operator_overloading
import properties
import reprtest

__pragma__ ('ifdef', '__esv6__')
if '__esv6__' in __symbols__:
    import proxies
__pragma__ ('endif')

import set_comprehensions
import simple_and_augmented_assignment
import truthyness
import tuple_assignment

autoTester = org.transcrypt.autotester.AutoTester ()

autoTester.run (arguments, 'arguments')
autoTester.run (attribs_by_name, 'attribs_by_name')
autoTester.run (builtin_super, 'builtin_super')
autoTester.run (callable_test, 'callable')
autoTester.run (classes, 'classes')
autoTester.run (complex_numbers, 'complex_numbers')
autoTester.run (conditional_expressions, 'conditional_expressions')
autoTester.run (control_structures, 'control_structures')

__pragma__ ('ifdef', '__py3.6__')
if '__py3.6__' in __symbols__:
    autoTester.run (dashed_numbers, 'dashed_numbers')
__pragma__ ('endif')

autoTester.run (data_structures, 'data_structures')
autoTester.run (decorators, 'decorators')
autoTester.run (dict_comprehensions, 'dict_comprehensions')
autoTester.run (dictionaries, 'dictionaries')
autoTester.run (div_issues, 'div_issues')
autoTester.run (div_pulls, 'div_pulls')
autoTester.run (docstrings, 'docstrings')
autoTester.run (exceptions, 'exceptions')
autoTester.run (extended_slices, 'extended_slices')

__pragma__ ('ifdef', '__py3.6__')
if '__py3.6__' in __symbols__:
    autoTester.run (fstrings, 'fstrings')
__pragma__ ('endif')

autoTester.run (globals_function, 'globals_function')
autoTester.run (general_functions, 'general_functions')
autoTester.run (indices_and_slices, 'indices_and_slices')

__pragma__ ('ifdef', '__esv6__')
if '__esv6__' in __symbols__:
    autoTester.run (iterators_and_generators, 'iterators_and_generators')
__pragma__ ('endif')
    
autoTester.run (lambda_functions, 'lambda_functions')
autoTester.run (list_comprehensions, 'list_comprehensions')
autoTester.run (local_classes, 'local_classes')
autoTester.run (metaclasses, 'metaclasses')
autoTester.run (module_builtin, 'module_builtin')
autoTester.run (module_cmath, 'module_cmath')

__pragma__ ('ifdef', '__esv6__')
if '__esv6__' in __symbols__:
    autoTester.run (module_itertools, 'module_itertools')
__pragma__ ('endif')
    
autoTester.run (module_math, 'module_math')
autoTester.run (modules, 'modules')
autoTester.run (nonlocals, 'nonlocals')
autoTester.run (operator_overloading, 'operator_overloading')
autoTester.run (properties, 'properties')
autoTester.run (reprtest, 'repr_str')

__pragma__ ('ifdef', '__esv6__')
if '__esv6__' in __symbols__:
    autoTester.run (proxies, 'proxies')
__pragma__ ('endif')

autoTester.run (set_comprehensions, 'set_comprehensions')
autoTester.run (simple_and_augmented_assignment, 'simple_and_augmented_assignment')
autoTester.run (truthyness, 'truthyness')
autoTester.run (tuple_assignment, 'tuple_assignemt')

autoTester.done ()

4.1. Arguments: **kwargs, *args, defaults, at call and def time, also for lambda's

Testlet: arguments
from org.transcrypt.stubs.browser import __pragma__

__pragma__ ('kwargs')

class A:
    def __init__ (self, x = 123, y = 456, *args, m, n = 456, **kwargs):
        self.x = x
        self.y = y
        self.args = args
        self.m = m
        self.n = n
        self.kwargs = kwargs
        self.extra = 'hello'

    def f (self, autoTester):
        autoTester.check (self.x, self.y, self.args, self.m, self.n, self.kwargs, self.extra)
        
class B (A):
    def __init__ (self, x, y = -1, *args, m = -2, n, **kwargs):
        A.__init__ (self, y, x, *args, m = n, n = m, **kwargs)
        
class C:
    __pragma__ ('nokwargs')
    def tricky (self, *args):
        return args
    __pragma__ ('kwargs')
    
def run (autoTester):
    def f (x, y = -1, *args, m = -2, n, **kwargs):
        # BEGIN issue 203, kwargs turned into real dict
        autoTester.check ('#203', kwargs.__class__.__name__)
        autoTester.check ('#203', sorted (kwargs.keys ()))
        # END issue 203
    
        def f2 (x, y = -3, *args, m = -4, n, **kwargs):
            autoTester.check (x, y, args, m, n, kwargs)
        f2 (11, 22, 1010, 2020, m = 100100, n = 200200, p = 10001000, q = 20002000)
        autoTester.check (x, y, args, m, n, kwargs)
        
    f (1, 2, 10, 20, m = 100, n = 200, p = 1000, q = 2000)
    
    b = B (3, 4, 30, 40, m = 300, n = 400, p = 3000, q = 4000)
    b.f (autoTester)
    
    def g (*args, **kwargs):
        autoTester.check (args, kwargs)
        
    g (*(1, 2, 3), **{'p': 'aP', 'q': 'aQ', 'r': 'anR'})
    
    (lambda x, y = -1, *args, m = -2, n, **kwargs: autoTester.check (x, y, args, m, n, kwargs)) (1, 2, 8, 16, m = 128, n = 256.3, p = 1024.3, q = 2048.3)
    
    autoTester.check (C () .tricky (* range (4)))
    autoTester.check ('{}-{}'.format (1, 3, 5, 7, 9))
    autoTester.check ('{}-{}'.format (* range (4)))

4.2. Attribute access by name: getattr, setattr, hasattr

Testlet: attribs_by_name
class A:
    def __init__ (self):
        self.s = 'hello'
        
a = A ()

def run (autoTester):
    autoTester.check (a.s, getattr (a, 's'))
    
    setattr (a, 's', 'goodbye')
    autoTester.check (a.s, getattr (a, 's'))
    
    setattr (a, 't', 'exists')
    autoTester.check (hasattr (a, 't'), a.t, getattr (a, 't'))
    
    delattr (a, 't')
    autoTester.check (hasattr (a, 't'))

4.3. Attribute proxies by name: __getattr__, __setattr__

Testlet: proxies
from org.transcrypt.stubs.browser import __pragma__

def run (autoTester):
    class A:
        def __init__ (self):
            self.p = 1
            self.q = 2
            
    class B (A):
        def __getattr__ (self, name):
            return 'Faked {}'.format (name)
            
    class C (A):
        def __setattr__ (self, name, value):
            autoTester.check ('Set faked {}'.format (name))
            
            A.__setattr__ (self, name, value)
            # Needed for CPython, inherited from class 'object'
            # Transcrypt doesn't need it, if there's no __setattrib__ it will just use self [name] = value
    
    class D (B, C):
        pass
        
    a = A ()
    b = B ()
    c = C ()
    d = D ()
    
    autoTester.check (a.p, a.q)
    a.p = 3
    autoTester.check (a.p, a.q)
    
    autoTester.check (b.p, b.q, b.r, b.s)
    b.p = 4
    b.r = 5
    autoTester.check (b.p, b.q, b.r, b.s)
    
    autoTester.check (c.p, c.q)
    c.p = 6
    c.q = 7
    autoTester.check (c.p, c.q)

    autoTester.check (d.p, d.q, d.r, d.s)
    d.p = 8
    d.q = 9
    d.r = 10
    d.s = 11
    autoTester.check (d.p, d.q, d.r, d.s)   

4.4. Callable or not: using the callable () built-in function

The callable (object) built-in function will tell you if something supports the () operator.

Testlet: callable_test
# Callable built-in method unit tests

from org.transcrypt.stubs.browser import __pragma__

def run(test):
    """
    """

    def func(a,b):
        return(a*b)

    test.check( func(3,4) )
    test.check( callable(func) )

    for a in (True, False):
        test.check( callable(a) )

    a = 1
    test.check( callable(a) )
    a = 2.3
    test.check( callable(a) )
    a = "asdf"
    test.check( callable(a) )

    a = []
    test.check( callable(a) )
    a = [1,2,3,3]
    test.check( callable(a) )
    a = ["asdf", "qwer", "zxcv"]
    test.check( callable(a) )

    a = {"asdf" : 1, "qwer": 2}
    test.check( callable(a) )

    a = set([1,2])
    test.check(callable(a))

    __pragma__('opov')

    class CallObj(object):
        def __init__(self, r):
            self._r = r

        def __call__(self):
            return(self._r)

    test.check( callable(CallObj) )

    obj = CallObj(2)
    test.check(obj())
    test.check( callable(obj) )
    test.check( callable(obj._r) )

    class NonCallObj(object):
        def __init__(self, b):
            self._b = b

        def func(self):
            return(self._b)

    test.check( callable(NonCallObj) )

    obj2 = NonCallObj(2)
    test.check( callable(obj2) )
    test.check( callable(obj2._b) )
    test.check( callable(obj2.func) )

    __pragma__('noopov')

    class NonOpovNonCallObj(object):
        """
        """
        def __init__(self, c):
            self._c = c

        def other(self, b):
            return(self._c * b)

        def _getC(self):
            return(self._c)
        def _setC(self, val):
            self._c = val

        C = property(_getC, _setC)

    obj = NonOpovNonCallObj(4)
    test.check( callable(obj) )
    test.check( callable(obj.other) )
    test.check( callable(obj._c) )
    test.check( callable(obj.C) )

    exc = Exception("asdf")
    test.check( callable(exc) )

4.5. Classes: multiple inheritance and assignment of bound functions

Testlet: classes
def run (autoTester):
    autoTester.check ('<br>General<br>')

    class A:
        p = 123
        def __init__ (self, x):
            self.x = x
            autoTester.check (self.p)

        def show (self, label):
            autoTester.check ('A.show', label, self.x)
            
        def show2 (self, label):
            autoTester.check ('A.show2', label, self.x)
        
    class B:
        p, q = 456, 789
        def __init__ (self, y):
            autoTester.check ('In B constructor')
            self.y = y
            autoTester.check (self.p)
            
        def show (self, label):
            autoTester.check ('B.show', label, self.y)
            
    class C (A, B):
        def __init__ (self, x, y):
            autoTester.check ('In C constructor')
            A.__init__ (self, x)
            B.__init__ (self, y)
            
        def show (self, label):
            A.show (self, label)
            B.show (self, label)
            autoTester.check ('C.show', label, self.x, self.y)
        
    a = A (1001)
    a.show ('america')
    autoTester.check (A.p)
    autoTester.check (a.p)

    b = B (2002)
    b.show ('russia')
    autoTester.check (B.p)
    autoTester.check (b.p)
    autoTester.check (b.q)

    autoTester.check (A.p)
    autoTester.check (a.p)

    c = C (3003, 4004)
    c.show ('netherlands')
    autoTester.check (C.p)
    autoTester.check (c.p)
    autoTester.check (c.q)

    c.show2 ('amsterdam')
    A.show2 (c, 'rotterdam')

    show3 = c.show
    show3 ('copy')
    
    autoTester.check (hasattr (a, 'x'))
    autoTester.check (hasattr (a, 'y'))
    autoTester.check (hasattr (a, 'p'))
    autoTester.check (hasattr (a, 'q'))
    
    autoTester.check ('<br><br>Augmented isinstance<br>')
    # Augmented meaning: compatible with native JavaScript types
        
    simpleTypes = (dict, list, A, B, C, bool, str, float, int)
    tupleTypes = ((dict, list), (bool, int), (bool, A), (C, B))
    for i, types in enumerate ((simpleTypes, tupleTypes)):
        for j, aType in enumerate (types):
            for k, anObject in enumerate (({'a': 1}, [], a, C, c, C, b, True, 'a', 1, 1.2)):
                autoTester.check (i, j, k, isinstance (anObject, aType))
                if types == simpleTypes:
                    autoTester.check (i, j, k, isinstance (anObject, simpleTypes))
                    
    autoTester.check ('<br><br>Method resolution order<br>')
    
    def mro (aClass, result = None):
        ''' Recursively assemble method resolution order from all base classes'''
        last = 0
        if result is None:
            result = [aClass]
            last = 1
        for aBase in aClass.__bases__:
            if not aBase in result and aBase != object:
                result.append (aBase)
                mro (aBase, result)
        if last and object in aClass.__bases__:
            aRoot.append (object)
        return result
        
    autoTester.check ([aClass.__name__ for aClass in mro (C)])
    

4.6. Complex numbers: Python's builtin complex datatype

Testlet: complex_numbers
from org.transcrypt.stubs.browser import __pragma__

def run (autoTester):
    x = 567
    y = -3
    z = 5 * x + 2 * y
    autoTester.check (x, y, z)

    __pragma__ ('opov')
    
    a = 234 + 3j
    b = 4 - 5j
    c = complex (-6, 7)
    autoTester.check (a, b, c)
    
    t = 6 * x - 3 * y + 7   # Just to check, faster with 'noopov'
    autoTester.check (t)
    
    d = 2 * a
    e = x * b
    f = z + d + e
    g = a / b
    h = a - b
    i = x - c
    j = a - x
    k = b + y
    
    autoTester.check (d, e, f, round (g.real, 2), round (g.imag, 2), h, i, j, k)
    
    __pragma__ ('noopov')
    

4.7. Conditional expressions: simple and nested

Testlet: conditional_expressions
def f (x, b):
    return x * x if b else x + x

def run (autoTester):
    bools = (False, True)
    for a in bools:
        for b in bools:
            autoTester.check (f (10 if a else 100, b))
            
    for p in bools:
        for q in bools:
            for r in bools:
                autoTester.check ('a' if p else 'b' if q else 'c' if r else 'd')
                
                a = ((('e' if p else 'f') if q else 'g') if r else 'h')
                b = ('i' if p else ('j' if q else ('k' if r else 'l')))
                c = 'm' if (p if q else r) else 'n'
                d = 'o' if p < q <= r else 'p'
                autoTester.check (a, b, c, d)
                
    odd = [x if x % 2 else x + 1 for x in range (10)]
    noDuplicates = set (odd)
    autoTester.check (odd, noDuplicates)
    

4.8. Control structures: for...else, while...else, if...elif...else, break, continue

Testlet: control_structures
def run (autoTester):
    for index in range (10):
        autoTester.check (index)
        
    for index in range (8, 16):
        autoTester.check (index)
        
    for index in range (8, 16, 2):
        autoTester.check (index)
        
    for index in range (10, 0, -1):
        autoTester.check (index)
        
    for index in range (16, 8, -2):
        autoTester.check (index)
        
    for animal in ('cat', 'dog', 'turtle', 'goldfish'):
        autoTester.check (animal)

    for index, square in enumerate ([x * x for x in range (10) if x % 2]):
        for y in (1, 2, 3):
            for z in (10, 20, 30):
                autoTester.check (square + y, z )

    vehicles = ['bike', 'train', 'boat', 'car', 'plane', 'bus']
                
    for doBreak in (False, True):
        for doContinue in (False, True):
            for index in range (10):
                for index2 in range (0, 100, 10):
                    if doBreak and index2 == 50:
                        autoTester.check ('break2')
                        break
                    if doContinue and index2 == 50:
                        autoTester.check ('continue2')
                        continue
                else:
                    autoTester.check ('noBreak2')
                    
                if doBreak and index == 5:
                    autoTester.check ('break')
                    break
                if doContinue and index == 5:
                    autoTester.check ('continue')
                    continue
            else:
                autoTester.check ('noBreak')
                
            index = 0
            while index < len (vehicles) and vehicles [index] != 'bus':
                autoTester.check (index, vehicles [index])
                if doBreak and vehicles [index] == 'car':
                    autoTester.check ('breakWhile')
                    break
                if doContinue and vehicles [index] == 'car':
                    autoTester.check ('continueWhile')
                    index += 1
                    continue
                index += 1
            else:
                autoTester.check ('noBreakWhile')
                
        for vehicle in vehicles:
            if vehicle == 'bike':
                autoTester.check ('netherlands')
            elif vehicle == 'car':
                autoTester.check ('america')
            elif vehicle == 'boat':
                autoTester.check ('oceania')
            else:
                autoTester.check ('anywhere')

4.9. Data structures: tuple, list, dict, set

Testlet: data_structures
def run (autoTester):
    aList = [1, 2, 3, 'moon', 'stars']
    autoTester.check (aList)
    aList.insert (3, 'sun')
    autoTester.check (aList)
    autoTester.check (aList [2:4:1])
    autoTester.check (aList [:])
    autoTester.check (aList [2:])
    autoTester.check (len (aList))
    aList.append ('milkyway')
    autoTester.check (aList)
    aList.extend (['m1', 'm31'])
    autoTester.check (aList)

    anotherList = list (('a', 'b', 'c'))
    autoTester.check (anotherList)
    autoTester.check ('b' in anotherList)
    autoTester.check ('d' in anotherList)
    
    aDict = {1: 'plant', 'animal': 2}
    autoTester.check (aDict)
    autoTester.check (aDict [1], aDict ['animal'])
    
    def p ():
        return 3
        
    q = 4
    
    autoTester.check ({p (): 'three', q: 'four'})
    
    aTuple = (1, 2, 3, 4, 5)
    autoTester.check(aTuple)
    autoTester.check (len (aTuple))

    anotherTuple = (1,)
    autoTester.check (anotherTuple)

    aSet = {1, 2, 2, 3}
    autoTester.check    (aSet)
    autoTester.check (len (aSet))
    autoTester.check (2 in aSet)
    autoTester.check (4 in aSet)

    anotherSet = set ((4, 5, 5, 6))
    autoTester.check (anotherSet)

    emptySet = set ()
    autoTester.check (emptySet)
    autoTester.check (len (emptySet))
    
    aString = 'c_cis_d_dis_e_f_fis_g_gis_a_ais_b_c'
    autoTester.check ('cis' in aString)
    autoTester.check ('g' in aString)
    autoTester.check ('bes'  in aString)
    autoTester.check ('z' in aString)
    

4.10. Decorators: function and class, with and without parameters

Transcrypt supports decorators on methods and classes. A decorator itself can be a function or an object with an overloaded __call__ operator. Parameterized decorator factories are also supported. Decorators on methods are not supported, except trivially for @classmethod. Methods decorated with @classmethod can be called on an object as demonstrated in the code below, not on a class. All flavours of properties are fully supported, though directly and not through decorator syntax. Extensive use of properties is demonstrated in the properties testlet.

Testlet: decorators
from org.transcrypt.stubs.browser import __pragma__

def run (autoTester):
    def repeat3 (bareFunc):
        __pragma__ ('kwargs')
        def innerFunc (*args, **kwargs):
            autoTester.check ('BEGIN repeat3')
            for i in range (3):
                bareFunc (*args, **kwargs)
            autoTester.check ('END repeat3')
        __pragma__ ('nokwargs')
        return innerFunc
        
    def repeatN (n):
        def repeat (bareFunc):
            __pragma__ ('kwargs')
            def innerFunc (*args, **kwargs):
                autoTester.check ('BEGIN repeatN ({})'.format (n))
                for i in range (n):
                    bareFunc (*args, **kwargs)
                autoTester.check ('END repeatN ({})'.format (n))
            __pragma__ ('nokwargs')
            return innerFunc
        return repeat

    class Repeater:
        def __init__ (self, n):
            self.n = n
            
        def __call__ (self, bareFunc):
            __pragma__ ('kwargs')
            def innerFunc (*args, **kwargs):
                autoTester.check ('BEGIN repeat3')
                for i in range (self.n):
                    bareFunc (*args, **kwargs)
                autoTester.check ('END repeat3')
            __pragma__ ('nokwargs')
            return innerFunc
        
    @repeatN (4)
    @repeat3
    def funcNoArg ():
        autoTester.check ('spam')
        
    funcNoArg ()
    autoTester.check ()

    __pragma__ ('kwargs')
    @repeat3
    @repeatN (2)
    def funcArg (a):
        autoTester.check ('eggs', a)
    __pragma__ ('nokwargs')
        
    funcArg (3)
    autoTester.check ()

    funcArg (a = 4)
    autoTester.check ()

    __pragma__ ('opov')
    @Repeater (3)
    def funcNoArg2 ():
        autoTester.check ('toast')
    __pragma__ ('noopov')

    funcNoArg2 ()
    autoTester.check ()

    __pragma__ ('opov')
    __pragma__ ('kwargs')
    @Repeater (5)
    def funcArg2 (a):
        autoTester.check ('jam', a)
    __pragma__ ('nokwargs')
    __pragma__ ('noopov')

    funcArg2 (3)
    autoTester.check ()

    funcArg2 (a = 4)
    autoTester.check ()

    def next (bareFunc):
        def innerFunc (value):
            return bareFunc (value + 1)
        return innerFunc
        
    @next
    class Number:
        def __init__ (self, value):
            self.value = value
            
    autoTester.check ('two', Number (1) .value)
    
    class Test: 
        @classmethod
        def f (cls, x, y):
            autoTester.check (cls.__name__, x, y)
            
        def g (self, x, y):
            autoTester.check (self.__class__.__name__, x, y)
            
    test = Test ()

    test.f (1, 2)
    test.g (3, 4)
    
    

4.11. Dict comprehensions

Testlet: dict_comprehensions
from org.transcrypt.stubs.browser import __pragma__

__pragma__ ('iconv')    # Convert dict to key list without using keys () method

def run (autoTester):
    original = {'Isaac': 'Newton', 'Albert': 'Einstein', 'Paul': 'Dirac'}
    autoTester.check (original)

    inverted = {original [key]: key for key in original}
    autoTester.check (inverted)

4.12. Dictionaries: dict revisited

Testlet: dictionaries
from org.transcrypt.stubs.browser import __pragma__
__pragma__ ('iconv')

def run (autoTester):
    tel = {'guido': 4127, 'jack': 4098}
    autoTester.check (len (tel))
    tel ['sape'] = 4139

    autoTester.check (tel)
    autoTester.check (tel ['jack'])

    del tel ['sape']
    tel ['irv'] = 4127
    autoTester.check (tel)

    autoTester.check (sorted (list (tel.keys ())), False)
    autoTester.check (sorted (tel.keys ()))

    autoTester.check ('guido' in tel)
    autoTester.check ('jack' not in tel)

    autoTester.check (dict ([('guido', 4127), ('jack', 4098), ('sape', 4139)]))
    autoTester.check (
        autoTester.expectException( lambda: dict(1) )
    )
    autoTester.check (
        autoTester.expectException( lambda: dict(134.34) )
    )
    autoTester.check (
        autoTester.expectException( lambda: dict('asdf') )
    )
    autoTester.check (
        autoTester.expectException( lambda: dict(['1234', 1]) )
    )

    autoTester.check( dict ([]))
    autoTester.check (dict ({}))
    autoTester.check (dict ({'asdf': 1, 'qwer': 2}) )

    # check dict copy, Issue # 221
    b = {'a' : 2.01, 'b': -3.3}
    d = dict (b)
    autoTester.check (d)
    b = {'a' : 2, 'b': [1,2,3]}
    d = dict (b)
    autoTester.check (d)
    b = {'a' : None, 'b': set([1,2,3])}
    d = dict (b)
    autoTester.check (d)
    b = {'a' : {'c': 2}, 'b': (1,2)}
    d = dict (b)
    autoTester.check (d)
    autoTester.check (d['a']['c'])
    autoTester.check (d.get('a').get('c'))
    autoTester.check (b.get('a').get('c'))
    d['a']['c'] = 3
    autoTester.check (d.get('a').get('c'))
    autoTester.check (b.get('a').get('c'))

    knights = {'robin': 'the brave', 'gallahad': 'the pure'}

    for k, v in sorted (knights.items ()):
        autoTester.check (k, v)

    if 'gallahad' in knights:
        autoTester.check ('gallahad is a knight') 

    for k in sorted (knights):
        autoTester.check (k)
        
    knight = {'rudolph': 'the righteous'}
    for k in knight:    # Autotest automatic conversion with one knight, since sort order of dict undefined
        autoTester.check (k)
        
    tel = {'guido': 123}
    tel.update({'edsger': 42})
    autoTester.check (tel.setdefault ('linus', 456))
    autoTester.check (tel ['linus'])
    autoTester.check (tel.setdefault ('guido', 789))
    autoTester.check (tel.pop ('guido', 1))
    autoTester.check (tel.pop ('guido', 1))
    autoTester.check (tel.pop ('edsger', 2))
    autoTester.check (tel.pop ('foo', 'bar'))
    autoTester.check (tel.pop ('foo', None))

    # Check compound keys (issue 281)
    
    d = {}
    d ['a'] = 3777
    d [(1, 2)] = 4777
    autoTester.check (d ['a'], d [(1, 2)])

    __pragma__ ('opov')
    d = {}
    d ['a'] = 3777
    d [(1, 2)] = 4777
    autoTester.check (d ['a'], d [(1, 2)])
    __pragma__ ('noopov')
    
    # Check exceptions
    knights = {'robin': 'the brave', 'gallahad': 'the pure'}
    autoTester.check (
        autoTester.expectException ( lambda: knights.pop("batman") )
    )
    autoTester.check (
        autoTester.expectException ( lambda: knights.pop("batman", None) )
    )
    autoTester.check (
        autoTester.expectException ( lambda: knights.pop("batman", "the gullible") )
    )

4.13. Diverse issues

Testlet: div_issues
from org.transcrypt.stubs.browser import __pragma__, __new__, __envir__, __symbols__

from div_issues.issue55 import *        # Names not exported from package's __init__.py

def run (autoTester):
    autoTester.check ('Issue 24')   # Non keyword switch generates javascript SyntaxError
    switch = False
    autoTester.check (switch)
    
    autoTester.check ('Issue 27')   # Python list.index () not translated correctly
    autoTester.check (['zero', 'one', 'two', 'three', 'four'] .index ('three'))
    
    autoTester.check ('Issue 36')   # Bug in compiling lambda default argument values
    # Workaround for Python closures capturing variables rather than values
    # An extra enclosing scope is created to remember the value of the variable
    results = []
    for i in range (10):
        # results.append (lambda: i)                # Works nowhere
        # results.append (lambda j = i: j)          # Works only in Python
        results.append ((lambda j: lambda: j) (i))  # Works in Python and Transcrypt
    autoTester.check ([result () for result in results])        

    autoTester.check ('Issue 37')   # Python integer division not translated correctly
    autoTester.check (15 // 7)
    
    autoTester.check ('Issue 40')   # Python parentheses dropped during translation
    autoTester.check (65 / (5 * 2))

    autoTester.check ('Issue 50')   # Wrong answer with parentheses moved during translation
    autoTester.check ((240 + 30 - 1) // 30 * 30)
    
    autoTester.check ('Issue 51')   # Wrong answer with set() compare
    a = 1
    b = 1
    autoTester.check (a, b, {a, b} == {1, 2})
    
    autoTester.check ('Issue 52')   # Non keyword 'default' generates javascript SyntaxError
    switch, case, default = 'switch', 'case', 'default'
    autoTester.check (switch, case, default)
    
    autoTester.check ('Issue 54')   # Type dict missing clear(), setdefault()
    aDict = {1: 11, 2: 22, 3: 33}
    autoTester.check (aDict)
    aDict.clear ()
    autoTester.check (aDict)
    
    autoTester.check ('Issue 60')   # Python bool() not translated
    three = 3
    one = three & 1
    seven = three | 4
    eight = one << 3
    four = eight >> 1
    aTrue = bool (three & one)
    aFalse = bool (three & four)
    autoTester.check (3, three, 1, one, 7, seven, 8, eight, 4, four, True, aTrue, False, aFalse)
    
    autoTester.check ('Issue 65')   # Adding two lists with + not supported
    __pragma__ ('opov')
    aList = [4, 5, 6]
    autoTester.check ([1, 2, 3,] + aList + [4, 5, 6])
    autoTester.check (3 * [1, 2, 3])
    autoTester.check ([1, 2, 3] * 3)
    aString = 'Crocodile'
    autoTester.check ('Tiger' + aString + 'Elephant')
    autoTester.check (3 * aString)
    autoTester.check (aString * 3)
    __pragma__ ('noopov')
    
    autoTester.check ('Issue 76')   # Python //= not translated correctly
    initially17 = 17
    autoTester.check (initially17)
    initially17 //= 2
    autoTester.check (initially17)
    initially17 //= 2
    autoTester.check (initially17)
    
    autoTester.check ('Issue 112')  # When using -e6, iterating TypedArrays or other non-list Iterables doesn't work
    try:
        if __envir__.executor_name == __envir__.transpiler_name: # CPython doesn't know Int8Array
            x = __new__ (Int8Array (2))
        else:
            x = [None, None]
        
        x [0] = 3
        x [1] = 2
        for i in x:
            autoTester.check (i)
        
        # Since JavaScript 5 gives no exception for a loop over a non-iterable, following code must only be executed for JavaScript 6
        # Since Transcrypt doesn't get to see all modules loaded by CPython, __ifdef__ cannot be made to do its thing for all modules in an efficient way for CPython
        # But a normal 'if' will work
        if '__esv6__' in __symbols__:
            y = 3
            for j in y:
                autoTester.check (j)
            
    except: # No 'Exception' can be used behind this, since this is a JavaScript exception, and no subclass of Exception. ??? How desirable is this behaviour?
        pass
        # autoTester.check ('Detected iterating over non-iterable') # Minifier masks this exception, so we'll have to pass
        
    if '__esv6__' in __symbols__:   # "if" rather than "__pragma__ ('ifdef')" because CPython doesn't understand pragma's
        autoTester.check ('Issue 122')  # Problem with yield (or rather with slicing beyond list end)
        
        def chunks (aList, chunkLength):
            for index in range (0, len (aList), chunkLength):
                yield aList [index : index + chunkLength]

        for chunk in chunks ([chr (index + 97) for index in range (26)], 10):
            autoTester.check (chunk)

    autoTester.check ('Issue 123')  # Python % shouldn't behave like JS %
    autoTester.check (10 % 3, 10 % -3, -10 % 3, -10 % -3, 10 % 10, 10 % -10, -10 % 10, -10 % -10)
    
    autoTester.check ('Issue 125')  # Strings not iterable
    abc = 'abc'
    
    for index in abc:
        autoTester.check (abc)
        
    autoTester.check ('Issue 127')  # Can't use the key 'keys' in a dict
    autoTester.check ({"include_docs": "true", "keys": ["key1", "key2"], "limit": 50})
    
    autoTester.check ('Issue 134')  # Operator %= translated incorrectly
    x0, x1, x2, x3, x4, x5 = 5, 12, -5, -5, 0, 0
    x0 %= 10; x1 %= 5; x2 %= 2; x3 %= -3; x4 %= 1; x5 %= -1000 
    autoTester.check (x0, x1, x2, x3, x4)
    
    autoTester.check ('Issue 136')  # Method dict.get(key[, default]) not implemented
    aDict = {'a': 'ape', 'b': 'banana'}
    autoTester.check (aDict.get ('a', 'noApe'), aDict.get ('b'), aDict.get ('c', 'noCarot'), aDict.get ('d'))
    
    autoTester.check ('Issue 144')
    __pragma__('opov')
    aList = [x for x in [1, 2, 3]]
    autoTester.check (aList)
    __pragma__('noopov')    
    
    autoTester.check ('<br><br>Issue 145<br>')  # List sorting incorrect in case of multiple columns
    
    class SortTest:
        def __init__ (self):
            self.alphabet = 'abcdefghijklmnopqrstuvwxyz'
            self.nChars = 10
            self.nCols = 10
            self.nRows = 30
            
            self.pseudoRandom = 0
            
            def randomWord ():
                word = ''
                for iChar in range (self.nChars):
                    self.pseudoRandom = (81212 * self.pseudoRandom + 28411) % 134456
#                   self.pseudoRandom = (1234 * self.pseudoRandom + 57) % 137           # Deliberately short period
                    word += self.alphabet [self.pseudoRandom % 26]
                return word 
        
            self.rows = [[randomWord () for iCol in range (self.nCols)] for iRow in range (self.nRows)]
                
        def sort (self):
            for iCol in reversed (range (self.nCols)):
                self.rows.sort (key = lambda row: row [iCol])
            
    sortTest = SortTest ()
    
    autoTester.check ('<br>Unsorted:<br>')
    for row in sortTest.rows:
        autoTester.check ('{}<br>'.format (','.join ([word for word in row])))
        
    sortTest.sort ()
    
    autoTester.check ('<br>Sorted:<br>')
    for row in sortTest.rows:
        autoTester.check ('{}<br>'.format (','.join ([word for word in row])))
        
    autoTester.check ('<br><br>Issue 148<br>')  # Allow key a.o. key 'items' in dict
    
    aDict = {
        'items': [4, 5, 6]
    }

    for aKey, aValue in aDict.items ():
        autoTester.check ('{}: {}'.format (aKey, aValue))   
        
    autoTester.check ('<br><br>Issue 169<br>')  # Add support for float('inf') and float('-inf')
    
    autoTester.check (int (1 / float ('inf')), int (1 / float ('-inf')))
    
    autoTester.check ('<br><br>Issue 178<br>')  # List Comprehensions / Operator Precedence Bug
    
    bitmaps = [
        (2 , ''),
        (4 , ''),
        (8, 'i'),
        (16, 'm'),
        (32, 'y'),
        (64, 'u'),
        (128, 'g')
    ]
    
    for flags in (122, 233, 11, 55, 79, 201, 23, 111, 200, 100, 50, 25, 12, 6):
        autoTester.check  (''.join ([x [1] for x in bitmaps if (x [0] & flags) > 0]))
        
    def issue256 ():
        autoTester.check ('Issue 256')

        class C:
            def __init__ (self, value):
                self.value = value

        def f1 (value):  # Generate parens after return
            return (C (value) .value or 'second') .capitalize () == 'First'
            
        def f2 (value):  # Generate parens after return
            return (C (value) .value or 'second') .capitalize () == 'Second'
            
        def f3 (value):  # Generate NO parens after return
            return C (value) .value or 'second'
            
        def f4 (value):  # Generate NO parens after return
            return (C (value) .value or 'second')
                
        autoTester.check (f1 ('first'))
        autoTester.check (f1 (''))
        autoTester.check (f2 ('first'))
        autoTester.check (f2 (''))
        autoTester.check (f3 ('first'))
        autoTester.check (f4 (''))
        
    issue256 ()
    
    autoTester.check ('Issue 274')
    a = 3
    del a
    autoTester.check ('Still alive')
    
    autoTester.check ('Issue 277')
    new = 3
    autoTester.check (new)
    
    autoTester.check ('Issue 279')
    class A:
        TypeError = 111
        js_TypeError = 222
    autoTester.check (A.TypeError, A.js_TypeError)  # ... Generated code should use py_TypeError and TypeError respectively    
    autoTester.check ('Still alive')

4.14. Diverse pulls

Testlet: div_pulls
# Also contains small enhancements

'This is a single line docstring'
class A:
    '''
    This
    is 
    a 
    multiline
    docstring
    '''
    def __init__ (self, x):
        'This is a single line comment'
        self.x = x
        '''
        This
        is 
        a 
        multiline
        docstring
        '''
    'This is a single line docstring'
'''
This
is 
a 
multiline
docstring
'''

a = A (5.5)

def run (autoTester):   
    autoTester.check ('Pull 56')
    s = 'abcdefghij'
    autoTester.check (s [2:3])
    autoTester.check (s [:3])
    autoTester.check (s [2:])
    autoTester.check (s [::2])
    
    autoTester.check ('Pull 59')
    autoTester.check (list (filter (lambda x: x % 2 == 0, range (10))))
    autoTester.check (list (map (lambda x: x*x, range (0, 31, 3))))
    
    

4.15. Docstrings: __doc__ attribute generated optionally

To keep the generated code lean, generation of __doc__ attributes is controlled per module by __pragma__ ('docat') or by the -d / --docat command line switch, combined with user per module of __pragma__ ('nodocat')

Testlet: docstrings
'''Just a module
to test docstrings'''
'''Not visible'''

from org.transcrypt.stubs.browser import __pragma__
__pragma__ ('docat')

def run (autoTester):
    def f (p):
        '''Just a function
        called f'''
        '''Not visible'''
        autoTester.check (p) 

    class C:
        '''Just a class
        called C'''
        '''Not visible'''
        def g (self, q):
            '''Just a method
            called g'''
            '''Not visible'''
            autoTester.check (q)
        
    autoTester.check (__doc__)
    autoTester.check ()

    autoTester.check (f.__doc__)
    autoTester.check ()

    autoTester.check (C.__doc__)
    autoTester.check ()

    autoTester.check (C.g.__doc__)
    autoTester.check ()

    f ('Doc')
    C () .g ('strings')

4.16. Exceptions: exception class hierarchy, finally

Testlet: exceptions
from org.transcrypt.stubs.browser import __envir__, __new__, __pragma__

if __envir__.executor_name == __envir__.transpiler_name:
    class BaseException:        # ??? Make part of __builtins__ for CPython compliance?
        pass

class Ex1 (Exception):
    pass
        
class Ex2 (Ex1):
    pass
    
class Ex3 (Exception):
    pass
    
class Table (BaseException):    # Any Python exception MUST inherit from BaseException
    def __init__ (self, *args):
        self.fields = args
        
    def __repr__ (self):
        return 'Table' + repr (self.fields) .replace (', ', ',') .replace ('\'', '')

def test1 ():
    raise (Exception ('mary'))
    
def test2 (autoTester):
    try:
        test1 ()
    except Ex1 as exception:
        autoTester.check (111)
        autoTester.check (exception)
    except Exception as exception:
        autoTester.check (222)
        autoTester.check (exception)
        
def run (autoTester):
    test2 (autoTester)
    
    try:
        raise Ex2 ('had')
    except Ex1 as exception:
        autoTester.check ('a')
    except Exception as exception:
        autoTester.check ('little')
        autoTester.check (exception)
        
    autoTester.check (333)
        
    try:
        raise Ex1 ('lamb')
    except Ex2 as exception:
        autoTester.check ('his')
        autoTester.check (exception)
    except Ex1 as exception:
        autoTester.check ('fleece')
        autoTester.check (exception)
    except Exception as exception:
        autoTester.check ('was')
        autoTester.check (exception)
    finally:
        autoTester.check ('white')
        
    autoTester.check (444)

    def test3 ():
        raise Ex3 ('as')
        
    autoTester.check (555)

    try:
        test3 ()
    except Ex1 as exception:
        autoTester.check ('snow')
        autoTester.check (exception)
    except Exception as exception:
        autoTester.check ('and')
        autoTester.check (exception)
    finally:
        autoTester.check ('everywhere')
        
    autoTester.check (666)
    
    try:
        raise Ex3 ('that')
    except Ex1 as exception:
        autoTester.check ('mary')
        autoTester.check (exception)
    except:
        autoTester.check ('went')
    finally:
        autoTester.check ('the')
    
    autoTester.check (777)
    
    try:
        try:
            raise Ex3 ('lamb')
        except Ex1 as exception:
            autoTester.check ('was')
            autoTester.check (exception)
        finally:
            autoTester.check ('to')
    except Ex3 as exception:    # We should get here, exception not swallowed
        autoTester.check ('go')
        autoTester.check (exception)
        
    try:
        raise __new__ (Table ('he', 'followed', 'her'))
    except Ex1 as exception:
        autoTester.check ('to')
        autoTester.check (exception)
    except Table as exception:  # Pure JavaScript exception, if no Python __class__
        autoTester.check ('school')
        autoTester.check (exception)
    except Ex3 as exception:
        autoTester.check ('one')
        autoTester.check (exception)
    finally:
        autoTester.check ('day')
    
    try:
        assert 2 * 8 / 4 == 2, 'Assert error 1'
    except AssertionError as exception:
        autoTester.check (exception)
        
    try:
        assert 2 * 8 / 4 == 4, 'Assert error 2'
    except AssertionError as exception:
        autoTester.check (exception)
        
    try:
        assert 2 * 8 / 4 == 2
    except AssertionError as exception:
        autoTester.check (exception)
        
    try:
        assert 2 * 8 / 4 == 4
    except AssertionError as exception:
        autoTester.check (exception)
        
    autoTester.check (888)
    
    try:
        autoTester.check ('hello world 1')
    except:
        autoTester.check ('error 1')
    else:
        autoTester.check ('no error 1')
        
    i = 1 + 2
    try:
        autoTester.check ('hello world 2')
        if i == 3:  # Prevent unreachable code warning
            raise Exception ()
    except:
        autoTester.check ('error 2')
    else:
        autoTester.check ('no error 2')
        
    for raiseIt in (False, True):
        try:
            try:
                if raiseIt:
                    raise Exception ()
                autoTester.check ('no error 3')
            finally:
                autoTester.check ('anyhow 3')
        except:
            autoTester.check ('error 3')
            

4.17. Extended slices: facilitating NumScrypt and such

Testlet: extended_slices
from org.transcrypt.stubs.browser import *
from org.transcrypt.stubs.browser import __pragma__, __envir__

def indices (key):
    if __envir__.executor_name == __envir__.transpiler_name:
        return tuple (key) if type (key) == list else key
    else:
        try:
            return key.indices (1000000000)
        except:
            try:
                return tuple ([indices (subkey) for subkey in key])
            except:
                return key

class Test:
    def __init__ (self, autoTester):
        self.autoTester = autoTester

    def __getitem__ (self, key):
        self.autoTester.check ('getitem (', indices (key), ')')
        return 1234567
        
    def __setitem__ (self, key, value):
        self.autoTester.check ('setitem (', indices (key), ')', value)

def run (autoTester):
    a = b = c = d = e = f = g = h = i = j = k = l = Test (autoTester)

    __pragma__ ('opov')
            
    a [1:2:3, 4:5:6] = b [7:8:9]
    c [1:2:3] = d [4:5:6, 7:8:9]
    e [1, 1:2:3, 3] = f [4, 4:5:6, 6]
    g [1, 2, 3] = h [1, 2, 3]
    i [1] = j [1]
    k [1:2:3] = l [1:2:3]

4.18. General functions: sort and sorted

Testlet: general_functions
from org.transcrypt.stubs.browser import __pragma__

class A:
    foo='bar'
    def __init__ (self):
        self.foo2 = 'bar2'

class B (A):
    foo3='bar3'
    def __init__ (self):
        self.foo4 = 'bar4'
        
def run (autoTester):
    autoTester.check ('sort and sorted<br>')
    a = [1, 5, 3, 2, -1]
    b = ['sun', 'earth', 'moon']
    
    autoTester.check (sorted (a))
    autoTester.check (sorted (b))
    
    a.sort ()
    autoTester.check (a)
    
    b.sort ()
    autoTester.check (b)

    autoTester.check (sorted (a, reverse = True))
    autoTester.check (sorted (b, reverse = True))
    
    a.sort (reverse = True)
    autoTester.check (a)
    
    b.sort (reverse = True)
    autoTester.check (b)
    
    b.sort (key = lambda x: len (x)) 
    autoTester.check (b)

    b.sort (key = lambda x: len (x), reverse = True) 
    autoTester.check (b)

    autoTester.check ('<br><br>dir<br>')
    autoTester.check ([entry for entry in dir (A) if not entry.startswith ('__')])
    autoTester.check ([entry for entry in dir (A()) if not entry.startswith ('__')])
    autoTester.check ([entry for entry in dir (B) if not entry.startswith ('__')])
    autoTester.check ([entry for entry in dir (B()) if not entry.startswith ('__')])

    autoTester.check ('<br><br>any, all, sum<br>')
    list1 = ['ape', 'node', 'mice']
    list2 = ['vim', '', 'jet']
    list3 = ['', '', '']
    list4 = [[1, 2], [1], []]   # Truthyness into play
    autoTester.check (list1, any (list1), all (list1))
    autoTester.check (list2, any (list2), all (list2))
    autoTester.check (list3, any (list3), all (list3))
    autoTester.check (list4, any (list4), all (list4))
    
    autoTester.check (sum (range (5)))
    
    __pragma__ ('ifdef', '__esv6__')
    if '__esv6__' in autoTester.symbols:    
        def generator1 ():
            for i in range (5):
                yield i;
                
        def generator2 ():
            for i in range (5):
                if i % 2:
                    yield 0
                else:
                    yield i;
                    
        def generator3 ():
            for i in range (5):
                yield 0;
                
        autoTester.check (generator1 (), any (generator1 ()), all (generator1 ()))
        autoTester.check (generator2 (), any (generator2 ()), all (generator2 ()))
        autoTester.check (generator3 (), any (generator3 ()), all (generator3 ()))
        
        autoTester.check (sum (generator1 ()))
    __pragma__ ('endif')

4.19. Global variable access by using globals () [<variable_name>]

The globals () function does the same as its counterpart in CPython, with some restrictions.

In the same module:

  • globals () can retrieve all module-level variables, wether created via globals () or in the normal way
  • module-level variables created via globals () can only be retrieved by globals (), not as a normal variable

From a different module:

  • globals () can retrieve all module-level variables, wether created by globals () or in the normal way
  • module-level variables created by globals () can be retrieved by globals (), but also as a normal variable

Since imports are done (statically) at compile time, from ... import * will not include the variables created (dynamically) via globals (). You can however import the whole module, e.g. import <longName> as <shortName> and then use <shortName>.<dynamicallyCreatedVariable>.

The code below shows what's possible:

Testlet: globals_function, module sub
xxa = 'subXxa'
xxb = 'subXxb'

for name in ('xxp', 'xxq'):
    globals () [name] = 'sub{}'.format (name.capitalize ())

def f ():
    for name in ('xxr', 'xxs'):
        globals () [name] = 'sub{}'.format (name.capitalize ())
        
def run (autoTester):
    f ()
    autoTester.check ('Check sub 1', xxa, xxb)    
    autoTester.check ('Check sub 2', * [globals () [name] for name in ('xxa', 'xxb', 'xxp', 'xxq', 'xxr', 'xxs')])
    autoTester.check ('Check sub 3', * sorted ([value for key, value in globals () .items () if key.startswith ('xx')]))

    
Testlet: globals_function, main program
from globals_function import sub

xxa = 'mainXxa'
xxb = 'mainXxb'

for name in ('xxp', 'xxq'):
    globals () [name] = 'main{}'.format (name.capitalize ())    
    
def f ():
    for name in ('xxr', 'xxs'):
        globals () [name] = 'main{}'.format (name.capitalize ())
        
def run (autoTester):
    f ()                 # All vars of main added
    sub.run (autoTester) # Shouldn't override vars of main
    
    autoTester.check ('Check main 1', xxa, xxb)
    autoTester.check ('Check main 2', * [globals () [name] for name in ('xxa', 'xxb', 'xxp', 'xxq', 'xxr', 'xxs')])
    autoTester.check ('Check main 3', sub.xxa, sub.xxb, sub.xxp, sub.xxq, sub.xxr, sub.xxs)
    autoTester.check ('Check main 4', * sorted ([value for key, value in globals () .items () if key.startswith ('xx')]))
    
    

The output will be:

Output of 'global_functions autotest'

4.20. Indices and slices: LHS, RHS, basic and extended

Testlet: indices_and_slices
def run (autoTester):
    # Right hand side slices
    all = range (32)
    autoTester.check (all)
    
    autoTester.check (all [8 : 24])
    autoTester.check (all [8 : 24 : 2]) 
    
    # Left hand side slices
    aList = [3, 4, 7, 8]
    autoTester.check (aList)
    
    aList [4 : 4] = [9, 10]
    autoTester.check (aList)
    
    aList [2 : 2] = [5, 6]
    autoTester.check (aList)
    
    aList [0 : 0] = [1, 2]
    autoTester.check (aList)
    
    aList [ : : 2] = [x + 0.001 for x in range (10) if x % 2]
    autoTester.check (aList)

4.21. Iterators and generators

Testlet: iterators_and_generators
from org.transcrypt.stubs.browser import __pragma__

class Iterable:
    def __init__ (self, i):
        self.aList = range (0, 50, i)

    def __iter__ (self):
        return Iterator (self) 
        
class Iterator:
    def __init__ (self, iterable):
        self.iterable = iterable
        self.index = -1
        
    def __next__ (self):    # Should be auto-wrapped in a next (self) by the compiler 
        self.index += 1
        
        if self.index > 5:
            raise StopIteration ()
            
        return self.iterable.aList [self.index]
            
    def __iter__ (self):
        return self
        
def exhaustableGenerator (i):
    for i in range (5):
        yield 2 * i

def run (autoTester):
    exhaustableGenExp = (a * a * a for a in [10, 20, 30])   # Currently still converted to iterator on list comprehension, must also be iterable
    # So becomes py_iter (aList).
    # List already has an __iter__ which it will return, it's a __PyIterator__
    # To that __PyIterator__, that will already have a __next__, py_iter first adds a next
    # So exhaustableGenExp is an iterator with a next and a __next__
    # If we call iter on that, py_iter is calle again py_iter, on an object with a next and a next __next__
    # For this reason py_iter needs a recursion prevention check

    iterables = [Iterable (7), exhaustableGenerator (5), [i * 3 for i in range (5)], exhaustableGenExp]

    for iterable in iterables:  
        autoTester.check ('[1]')
        iterator = iter (iterable)
        try:
            while True:
                autoTester.check (next (iterator))
        except Exception as exception:
            autoTester.check (exception.__class__.__name__)

        autoTester.check ('[2]')
        iterator = iter (iterable)
        try:
            while True:
                autoTester.check (next (iterator))
        except Exception as exception:
            autoTester.check (exception.__class__.__name__)
            
    for iterable in iterables:
        autoTester.check ('[3]')
        for n in iterable:
            autoTester.check (n)
            
        autoTester.check ('[4]')
        for n in iterable:
            autoTester.check (n)
            
    # BEGIN issue 196: for loop over iter (), runs OK but needs JavaScript 6. This should be clearly in the docs.
            
    a = 0
    vals = [1,2,3]
    ret = iter (vals)
    for m in ret:
        a += m
    autoTester.check (a)
     
    # END issue 196
                
    # BEGIN 1st example with 'send'
        
    __pragma__ ('gsend')

    def test0 ():
        r = 0
        while True:
            r = r + (yield r)

    gen0 = test0()
    next (gen0)
    autoTester.check (gen0.send (1))
    autoTester.check (gen0.send (2))

    def test1 ():
        r = 0
        while True:
            r = (yield r) + r

    gen1 = test1()
    next (gen1)
    autoTester.check (gen1.send (3))
    autoTester.check (gen1.send (4))
    
    # END 1st example with 'send'
    
    def subGenerator ():
        yield 27
        yield 37
        yield 47
    
    
    def mainGenerator ():
        yield 17
        yield from subGenerator ()
        yield 57
        
    autoTester.check (* [i for i in mainGenerator ()])
    
    def subCoroutine ():
        autoTester.check (38)
        yield
        autoTester.check (48)
        yield
        autoTester.check (58)
        yield
        autoTester.check (68)
    
    
    def mainCoroutine ():
        autoTester.check (18)
        yield
        autoTester.check (28)
        yield from subCoroutine ()
        autoTester.check (78)
        yield
        autoTester.check (88)
        
    m = mainCoroutine ()
    for i in range (5):
        m.send (None)
        

4.22. Lambda functions with all types of args

Testlet: lambda_functions
def run (autoTester):
    z = 1000
    autoTester.check ((lambda x, y: x + y + z) (111, 222))

    def f (list0, list1, aFunc):
        return [aFunc (*elem) for elem in zip (list0, list1)]

    x = f (range (10), range (0, 100, 10), lambda x, y: x + y + z)
    autoTester.check (x)
    
    autoTester.check (f (range (10, 20), range (100, 200, 10), lambda x, y: x * y + 100 * z))
    autoTester.check (f (range (10, 20), range (100, 200, 10), lambda *args: args [0] * args [1] + 100 * z))

4.23. List comprehensions: multi-loop and nested with multiple if's

Testlet: list_comprehensions
def run (autoTester):
    squares = [i * i for i in range (10) if i % 2]
    autoTester.check (squares)
    
    tuples = [
        (x, y, z)
        for x in (100, 200, 300, 400, 500, 600, 700)
            for y in (10, 20, 30, 40, 50, 60, 70) if 20 < y  < 60
                for z in (1, 2, 3, 4, 5, 6, 7) if 200 < x < 600 if 2 < z < 6
    ]
    autoTester.check (tuples)
    
    tricky = [(2 * x, 3 * y) for x, y in ((10, 11), (20, 21))]
    autoTester.check (tricky)
    
    nested = [2 * x for x in [x * x for x in range (3)]]
    autoTester.check (nested)
    
    a = 100
    x = 5
    scopeTest = [x + a for x in range (5)]
    autoTester.check (x)
    autoTester.check (scopeTest)

4.24. Local classes: inside other classes and functions

Testlet: local_classes
def run (autoTester):       
    class A:
        class B:
            class C:
                def __init__ (self, x):
                    self.x = x
                    
                def tell (self):
                    autoTester.check (self.x)
                    autoTester.check (self.e)
                    
                # Limitation: no destructuring assignment inside nested classes
                e = 3
                
            def __init__ (self, x):
                self.x = x
                
            def tell (self):
                autoTester.check (self.x)
                autoTester.check (self.d)
                
            d = 2
                
        c = 1

        def __init__ (self, x):
            self.x = x
            
        def tell (self):
            autoTester.check (self.x)
            autoTester.check (self.c)
            
    def f (x):
        class G:
            class H:
                def __init__ (self, x):
                    self.x = x
                    
                def tell (self):
                    autoTester.check (self.x)
                    autoTester.check (self.i)
                    
                i = 5
        
            def __init__ (self, x):
                self.x = x
                
            def tell (self):
                autoTester.check (self.x)
                
            k = 4
            
        g = G (6)
        g.tell ()
        autoTester.check (g.k)
        
        h = G.H (7)
        h.tell ()
        autoTester.check (h.i)
        
        class P (A.B):
            pass
            
        p = P (7)
        p.tell ()
        autoTester.check (p.d)
                
    a = A (8)
    b = a.B (9)
    c = b.C (10)

    a.tell ()
    b.tell ()
    c.tell ()

    autoTester.check (a.c)
    autoTester.check (b.d)

    f (7)

4.25. Metaclasses: overriding type.__new__ in a descendant metaclass

Testlet: metaclasses
from org.transcrypt.stubs.browser import __pragma__

class UppercaserMeta (type):
    def __new__ (meta, name, bases, attribs):
        __pragma__ ('jsiter')       # Translate for ... in directly to JavaScript for ... in ... and translate {} to bare {} rather than to dict {}
                                    # Using bare {} as attribs parameter to __new__ avoids dict attributes masking regular attributes
                                    # For more flexibility use __pragma__ ('js', '{}', '''...''')
        upperAttribs = {}
        
        for attribKey in attribs:   # Translates to 'for (var attribKey in attribs)' by virtue of __pragma__ ('jsiter'), to iterate over the attributes of a bare JavaScript {}
            upperAttribs [attribKey if  attribKey.startswith ('__') else attribKey.upper ()] = attribs [attribKey]
            
        __pragma__ ('nojsiter')
            
        return type.__new__ (meta, name, bases, upperAttribs)

class Uppercaser (metaclass = UppercaserMeta):
    pass
    
class Animal (Uppercaser):
    class Thoughts:
        quantity = 7

    # Limitation: no destructuring assignment if metaclass has to alter attributes
    color = 'Brown'
    state = 'Moving'

    def move (self):
        return 'Move'

class Plant (Uppercaser):
    class Thoughts:
        quantity = 6

    color = 'Green'
    state = 'Growing'

    def grow (self):
        return 'Grow'
        
class Stone:
    class Thoughts:
        quantity = 5

    color = 'Gray'
    
    def be (self):
        return ('Being')

def run (autoTester):
    animal = Animal ()
    autoTester.check (animal.THOUGHTS.quantity, Animal.COLOR, animal.COLOR, animal.MOVE ())
    
    plant = Plant ()
    autoTester.check (plant.THOUGHTS.quantity, Plant.COLOR, plant.COLOR, plant.GROW ())
    
    stone = Stone ()
    autoTester.check (stone.Thoughts.quantity, Stone.color, stone.color, stone.be ())
    

4.26. Module builtin: a small part of it demo'ed

Testlet: module_builtin
# coding: utf-8

from org.transcrypt.stubs.browser import __envir__

def canonizeString (aString):
    if __envir__.executor_name == 'transcrypt':
        return aString.replace ('\t', '\\t') .replace ('\n', '\\n')
    else:
        return aString

def canonizeStringList (stringList):
    return [canonizeString (aString) for aString in stringList]

def run (autoTester):
    autoTester.check ('min', min (-1.1, -1, -3))
    autoTester.check ('max', max (-1.1, -1, -3))
    autoTester.check ('abs', abs (-1), abs (1), abs (0), abs (-0.1), abs (0.1))
    autoTester.check ('ord', ord ('a'), ord ('e´'[0]))  # This is the 2 codepoint version
    
    autoTester.check ('round',
        round (4.006),
        round (4.006, 2),
        round (4060, -2),
        
        round (-4.006),
        round (-4.006, 2),
        round (-4060, -2),
        
        round (1/2.),
        round (1/2., 1),
        round (1/2, 1),
        round (1/3., 2),
        
        round (-1/2.),
        round (-1/2., 1),
        round (-1/2, 1),
        round (-1/3., 2),
    
        round (0.5),
        round (0.51),
        round (1.5),
        round (1.51),
        round (1.51),
        round (2.5),
        round (2.59),
        round (3.5),
        round (3.59),
        
        round (-0.5),
        round (-0.51),
        round (-1.5),
        round (-1.51),
        round (-1.51),
        round (-2.5),
        round (-2.59),
        round (-3.5),
        round (-3.59)
    )
    
    strings = [
        'der des dem den die der den die das des dem das',
        'an auf hinter ueber    neben vor   zwischen',
        '''
            durch
            fuer
            ohne
            um
            bis
            gegen
            entlang
        ''',
        'eins,zwei,drie,vier,fuenf,sechs,sieben'
    ]
    
    autoTester.check ('<br><br>split')
    for aString in strings:
        autoTester.check (
            canonizeString (aString),
            canonizeStringList (aString.split ()),
            canonizeStringList (aString.split (' ')),
            canonizeStringList (aString.split (' ', 4)),
            canonizeStringList (aString.split ('\t')),
            canonizeStringList (aString.split ('\t', 4)),
            canonizeStringList (aString.split ('\n')),
            canonizeStringList (aString.split ('\n', 4)),
            canonizeStringList (aString.split (',')),
            canonizeStringList (aString.split (',', 4)),
            '<br>'
        )
        
    autoTester.check ('<br>rsplit')
    for aString in strings:
        autoTester.check (
            canonizeString (aString),
            canonizeStringList (aString.rsplit ()),
            canonizeStringList (aString.rsplit (' ')),
            canonizeStringList (aString.rsplit (' ', 4)),
            canonizeStringList (aString.rsplit ('\t')),
            canonizeStringList (aString.rsplit ('\t', 4)),
            canonizeStringList (aString.rsplit ('\n')),
            canonizeStringList (aString.rsplit ('\n', 4)),
            canonizeStringList (aString.rsplit (',')),
            canonizeStringList (aString.rsplit (',', 4)),
            '<br>'
        )
        

4.27. Module cmath: allmost all of Python's cmath module

Testlet: module_cmath
from org.transcrypt.stubs.browser import __pragma__
from cmath import *

twoPi = 2 * pi
nDecs = 5

__pragma__ ('opov')

def run (autoTester):
    autoTester.check (phase (1 + 1j))
    
    aPolar = polar (3 + 5j)
    autoTester.check (round (aPolar [0], nDecs), aPolar [1])
    
    aRect = rect (*aPolar)
    autoTester.check (round (aRect.real), round (aRect.imag))
    
    anExp = exp (-2.2 - 3.3j)
    autoTester.check (round (anExp.real, nDecs), round (anExp.imag, nDecs))
    
    aLog = log (anExp)
    autoTester.check (round (aLog.real, nDecs), round (aLog.imag, nDecs))
    
    anExp10 = aLog ** 10
    autoTester.check (round (anExp10.real, nDecs), round (anExp10.imag, nDecs))
    
    aLog10 = log10 (anExp10)
    autoTester.check (round (aLog10.real, nDecs), round (aLog10.imag, nDecs))
    
    anExpRect = aLog ** aRect
    autoTester.check (round (anExpRect.real, nDecs), round (anExpRect.imag, nDecs))
    
    aLogRect = log (anExpRect, aRect)
    autoTester.check (round (aLogRect.real, nDecs), round (aLogRect.imag, nDecs))
    
    aSqrt = sqrt (1j)
    autoTester.check (round (aSqrt.real, nDecs), round (aSqrt.imag, nDecs))
    autoTester.check (sqrt (4))
    anotherSqrt = sqrt (-4)
    autoTester.check (round (anotherSqrt.real), round (anotherSqrt.imag))
    
    anAsin = asin (1 + 2j)
    autoTester.check (round (anAsin.real, nDecs), round (anAsin.imag, nDecs))

    anAcos = acos (-2 + 3j)
    autoTester.check (round (anAcos.real, nDecs), round (anAcos.imag, nDecs))
    
    anAtan = atan (3 - 4j)
    autoTester.check (round (anAtan.real, nDecs), round (anAtan.imag, nDecs))
    
    aSin = sin (anAsin)
    autoTester.check (round (aSin.real), round (aSin.imag))
    
    aCos = cos (anAcos)
    autoTester.check (round (aCos.real), round (aCos.imag))
    
    aTan = tan (anAtan)
    autoTester.check (round (aTan.real), round (aTan.imag))
    
    anAsinh = asinh (aCos)
    autoTester.check (round (anAsinh.real, nDecs), round (anAsinh.imag, nDecs))

    anAcosh = acosh (aSin)
    autoTester.check (round (anAcosh.real, nDecs), round (anAcosh.imag, nDecs))
    
    anAtanh = atanh (aTan)
    autoTester.check (round (anAtanh.real, nDecs), round (anAtanh.imag, nDecs))
    
    aSinh = sinh (anAsinh)
    autoTester.check (round (aSinh.real), round (aSinh.imag))
    
    aCosh = cosh (anAcosh)
    autoTester.check (round (aCosh.real), round (aCosh.imag))
    
    aTanh = tanh (anAtanh)
    autoTester.check (round (aTanh.real), round (aTanh.imag))
    

4.28. Module itertools: allmost all of Python's itertools module

Testlet: module_itertools
from itertools import *
from math import pow

def fibonacci():
    a, b = 0, 1
    for i in range (10):
        yield a
        a, b = b, a + b

squares = [i * i for i in range (10)]

chars = 'thequickbrownfoxjumpsoverthelazydog'
        
def run (autoTester):
    autoTester.check ('islice count', list (islice (count (10, 2), 4, 40, 3)))
    autoTester.check ('islice cycle', list (islice (cycle (fibonacci ()), 15)))
    autoTester.check ('repeat', list (repeat (3.14, 15)))
    autoTester.check ('islice repeat', list (islice (repeat (2.74), 15)))
    autoTester.check ('accumulate', list (accumulate (range (5))))

    def add (total, element):
        return total + element
    
    autoTester.check ('accumulate', list (accumulate (['alamak', 'mirach', 'sirrah'], add)))
    
    autoTester.check ('chain', list (chain (fibonacci (), squares, chars)))
    autoTester.check ('chain.from_iterable', list (chain.from_iterable (['ape', 'node', 'mice', 'vim', 'sus', 'jet'])))
    
    selectors = [True, True, False, True, False, False, True, True, False, True]
    
    autoTester.check ('compress', list (compress (
        ['{}{}'.format (('take' if selector else 'leave'), index) for index, selector in enumerate (selectors)],
        selectors
    )))
    
    autoTester.check ('dropwhile', list (dropwhile (lambda x: x < 5, [1, 4, 6, 4, 1])))
    autoTester.check ('filterfalse', list (filterfalse (lambda x: x % 2, range (10))))
    
    things = [('animal', 'bear'), ('animal', 'duck'), ('plant', 'cactus'), ('vehicle', 'speed boat'), ('vehicle', 'school bus')]

    for key, group in groupby (things, lambda x: x [0]):
        for thing in group:
            autoTester.check ('A {} is a {}.' .format (thing[1], key))
        autoTester.check (' ')
        
    autoTester.check ('islice', list (islice ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2, 9, 2)))
        
    autoTester.check ('starmap', [int (x) for x in starmap (pow, [(2, 5), (3, 2), (10, 3)])])
    autoTester.check ('takewhile', list (takewhile (lambda x: x < 5, [1, 4, 6, 4, 1])))
    
    i1, i2 = tee (islice (count (), 5))
    autoTester.check ('tee', list (i1), list (i1), list (i2))
    
    autoTester.check ('product', list (product ('ABCD', 'xy')), list (product (range (2), repeat = 3)))

    autoTester.check ('permutations', list (permutations ('ABCD')), list (permutations ('ABCD', 2)))
    
    autoTester.check ('combinations',
        list (combinations ('ABCD', 2)),
        list (combinations ([1, 2, 3, 4, 5], 3)),
        list (combinations (islice (count (), 6), 4))
    )
    
    autoTester.check ('combinations_with_replacement',
        list (combinations_with_replacement ('ABCD', 2)),
        list (combinations_with_replacement ([1, 2, 3, 4, 5], 3)),
        list (combinations_with_replacement (islice (count (), 6), 4))
    )
    

4.29. Module math: allmost all of Python's math module

Testlet: module_math
from math import *

def _check(nr, autoTester):
    # we just compare the first 15 digits of floats due to precision deviations
    # in browser and CPython:
    if isinstance(nr, float):
        nr = str(nr)[:15]
    autoTester.check(nr)


def run (autoTester):
    check = lambda nr: _check(nr, autoTester)
    check (pi)
    check (e)
    
    check (exp (3))
    check (int (expm1 (5)))
    
    check (log (0.2))
    check (round (log (1024, 2)))
    check (log1p (5))
    check (int (log2 (257)))
    check (int (log10 (1001)))
    
    check (pow (3, 4.5))
    check (sqrt (25.1))
    
    check (sin (10))
    check (cos (10))
    check (tan (10))

    check (asin (0.5))
    check (acos (0.5))
    check (atan (0.5))
    check (atan2 (1, 2))
    
    check (int (hypot (3, 4.1)))
    
    check (degrees (pi/2.1))
    check (radians (90))
    
    check (sinh (1))
    check (cosh (1))
    check (tan (1))
    
    check (asinh (70))
    check (acosh (70))
    check (atan (70))
    
    check (floor (3.5))
    check (ceil (3.5))
    check (trunc (3.5))
    
    check (isnan (3))
    check (isnan (nan))
    
    

4.30. Module random: most important functions of Python's random module

Manual_test: module_random
from random import *

result = ''

def output (any):
    result += any + '<br>\n'

for fixedSeed in (False, True):
    if fixedSeed:
        seed (3)
    else:
        seed ()

    output ('------ {} ------'.format ('fixed seed' if fixedSeed else 'auto seed'))
        
    output ('--- randint ---')
    for i in range (20):
        output (randint (10, 20))

    output ('<br>\n--- choice ---')
    for i in range (20):
        output (choice ([1, 2, 3, 4, 5]))

    output ('<br>\n--- random ---')
    for i in range (20):
        output (random ())
        
    output ('<br>\n')
    
document.getElementById ('output') .innerHTML = result

4.31. Modules: hierarchical, both local to the project and global url-based

Testlet: modules
import modules.mod1.mod11.mod111
import modules.mod3
import modules.mod1.mod11.mod112
import modules.mod1
import modules.mod1.mod11
import modules.mod2
import modules.mod2.mod21
import modules.mod2.mod22

import modules.mod1.mod11.mod111 as aliasMod111
import modules.mod1 as aMod1

from modules.mod1.mod11 import mod111, mod112

from modules.mod2 import mod21 as aMod21, mod22 as aMod22

from modules.mod3 import *

from modules.mod1.mod11.mod111 import A

a = modules.mod1.mod11.mod111.A (12345)
pi = modules.mod1.pi
f = modules.mod2.f

def run (autoTester):
    # Import without 'as'
    autoTester.check ('modules')
    autoTester.check (a.f ())
    autoTester.check (modules.mod1.mod11.mod112.f ())
    autoTester.check (modules.mod1.mod11.e)
    autoTester.check (pi)
    autoTester.check (f (102030))
    autoTester.check (modules.mod2.mod21.f ())
    B = modules.mod2.mod22.B
    b = B ()
    autoTester.check (b.x)
    autoTester.check (modules.mod3.x)
    
    # Import with 'as'
    a2 = aliasMod111.A (6789101112)
    autoTester.check (a2.f ())
    autoTester.check (aMod1.pi)
    
    # From ... import without 'as'
    a3 = mod111.A (100.001)
    autoTester.check (a3.f ())
    autoTester.check (mod112.f ())
    
    # From ... import with 'as'
    autoTester.check (aMod21.f ())
    autoTester.check (aMod22.B () .x)
    
    # From ... import *
    autoTester.check (mod3Hundred)
    autoTester.check (mod3GetTwoHundred ())
    autoTester.check (A (123.321) .f ())

    from modules import mod4
    # From ... import within function, with circular import
    autoTester.check(mod4.mod4Add2FromMod5(449))

4.32. Nonlocals

Testlet: nonlocals
def run (autoTester):
    test1 = 1
    test2 = 2
    
    def f ():
        test1 = 10
        
        nonlocal test2
        test2 = 20
        
        autoTester.check (test1, test2)
        
    f ()
    autoTester.check (test1, test2)     

4.33. Operator overloading

Testlet: operator_overloading
from org.transcrypt.stubs.browser import __pragma__

class Matrix:
    def __init__ (self, nRows, nCols, elements = []):
        self.nRows = nRows
        self.nCols = nCols
        
        if len (elements):
            self._ = elements
        else:
            self._ = [[0 for col in range (nCols)] for row in range (nRows)]
        
    def __matmul__ (self, other):
        result = Matrix (self.nRows, other.nCols)
        for iTargetRow in range (result.nRows):
            for iTargetCol in range (result.nCols):
                for iTerm in range (self.nCols):
                    result._ [iTargetRow][iTargetCol] += self._ [iTargetRow][iTerm] * other._ [iTerm][iTargetCol]
        return result
                
    def __imatmul__ (self, other):
        # True in-place multiplication not yet implemented in compiler
        # It currently translates m1 @= m2 to m1 = m1 @ ms and uses __matmul__ instead
        # This fake __imatmul__ is just for CPython , allowing back to back testing
        return self.__matmul__ (other)._
        
    def __mul__ (self, other):
        if type (other) == Matrix:
            result = Matrix (self.nRows, self.nCols)
            for iRow in range (self.nRows):
                for iCol in range (self.nCols):
                    result._ [iRow][iCol] = self._ [iRow][iCol] * other._ [iRow][iCol]   
            return result
        else:  # other is a scalar
            return self.__rmul__ (other)
                
    def __rmul__ (self, scalar):    # Only called if left operand is scalar, all other cases will call __mul__
        result = Matrix (self.nRows, self.nCols)
        for iRow in range (self.nRows):
            for iCol in range (self.nCols): 
                result._ [iRow][iCol] = scalar * self._ [iRow][iCol]
        return result
    
    def __add__ (self, other):
        result = Matrix (self.nRows, self.nCols)
        for iRow in range (self.nRows):
            for iCol in range (self.nCols):
                result._ [iRow][iCol] = self._ [iRow][iCol] + other._ [iRow][iCol]
        return result
        
    def __getitem__ (self, index):
        return self._ [index]

    def __setitem__ (self, index, value):
        self._ [index] = value
        
    def __repr__ (self):
        return repr (self._)
        
class Functor:
    def __init__ (self, factor):
        self.factor = factor
        
    __pragma__ ('kwargs')
    def __call__ (self, x, y = -1, *args, m = -2, n, **kwargs):
        return (
            self.factor * x,
            self.factor * y,
            [self.factor * arg for arg in args],
            self.factor * m,
            self.factor * n,
            # !!! [self.factor * kwargs [key] for key in sorted (kwargs.keys ())] Add supoprt for keys () on kwargs
        )
    __pragma__ ('nokwargs')
    
f = Functor (10)

__pragma__ ('kwargs')
def g (x, y = -1, *args, m = -2, n, **kwargs):
    return (x, y, args, m, n) # !!! , [kwargs [key] for key in sorted (kwargs.keys ())]) Add support for keys () on kwargs
__pragma__ ('nokwargs')
        
def run (autoTester):
    m0 = Matrix (3, 3, [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 10]
    ])
    
    m1 = Matrix (3, 3, [
        [10, 20, 30],
        [40, 50, 60],
        [70, 80, 90]
    ])
    
    m4 = Matrix (3, 3, [
        [1, 1,  2],
        [2, 2,  3],
        [3, 3, -5]
    ])
    
    m5 = Matrix (3, 3, [
        [1, 1,  2],
        [2, 2,  3],
        [3, 3, -5]
    ])
        
    x = 3
    y = x * 4 * x
    fast = 2 * 3
    
    __pragma__ ('opov')
    
    m1 [1][2] = m0 [1][2]
    slow = 2 + 3
    m2 = m0 * m1  + m1 * (m0 + m1)
    m3 = 2 * (2 * m0 * 3 * m1 + m2 * 4) * 2
    autoTester.check (m0 [1][1], m0 [1][2], m1 [1][1], m1 [1][2])
    
    m5 @= m4
    m6 = m0 @ m1
    
    __pragma__ ('noopov')
    
    fast2 = 16 * y + 1
    
    autoTester.check (m0, m1)
    autoTester.check (x, y)
    autoTester.check (m2)
    autoTester.check (m3)
    autoTester.check (m5)
    autoTester.check (fast, slow, fast2)
    
    x = 'marker'
    
    __pragma__ ('opov')
    autoTester.check (f (3, 4, 30, 40, m = 300, n = 400, p = 3000, q = 4000))
    autoTester.check (g (3, 4, 30, 40, m = 300, n = 400, p = 3000, q = 4000))
    
    autoTester.check (set ((1, 2, 3)) == set ((3, 2, 1)))
    autoTester.check (set ((1, 2, 3)) != set ((3, 2, 1)))
    autoTester.check (set ((1, 3)) == set ((3, 2, 1)))
    autoTester.check (set ((1, 3)) != set ((3, 2, 1)))
    autoTester.check (set ((1, 2)) < set ((3, 2, 1)))
    autoTester.check (set ((1, 2, 3)) <= set ((3, 2, 1)))
    autoTester.check (set ((1, 2, 3)) > set ((2, 1)))
    autoTester.check (set ((1, 2, 3)) >= set ((3, 2, 1)))
    
    autoTester.check ((1, 2, 3) == (1, 2, 3))
    autoTester.check ([1, 2, 3] == [1, 2, 3])
    autoTester.check ((1, 2, 3) != (1, 2, 3))
    autoTester.check ([1, 2, 3] != [1, 2, 3])
    autoTester.check ((2, 1, 3) == (1, 2, 3))
    autoTester.check ([2, 1, 3] == [1, 2, 3])
    autoTester.check ((2, 1, 3) != (1, 2, 3))
    autoTester.check ([2, 1, 3] != [1, 2, 3])
    __pragma__ ('noopov')
    
    class Bitwise:
        def __lshift__ (self, other):
            autoTester.check ('lshift')
            
        def __rlshift__ (self, other):
            autoTester.check ('rlshift')
            
        def __rshift__ (self, other):
            autoTester.check ('rshift')
            
        def __rrshift__ (self, other):
            autoTester.check ('rrshift')
            
        def __or__ (self, other):
            autoTester.check ('or') 
            
        def __ror__ (self, other):
            autoTester.check ('ror')
            
        def __xor__ (self, other):
            autoTester.check ('xor')
            
        def __rxor__ (self, other):
            autoTester.check ('rxor')
            
        def __and__ (self, other):
            autoTester.check ('and')
            
        def __rand__ (self, other):
            autoTester.check ('rand') 

    bitwise = Bitwise ()
    
    __pragma__ ('opov')
    
    bitwise << []
    [] << bitwise
    autoTester.check (32 << 2)
    
    bitwise >> []
    [] >> bitwise
    autoTester.check (32 >> 2)
    
    bitwise | []
    [] | bitwise
    autoTester.check (1 | 4)
    
    bitwise ^ []
    [] ^ bitwise
    autoTester.check (11 ^ 13)
    
    bitwise & []
    [] & bitwise
    autoTester.check (12 & 20)
    
    __pragma__ ('noopov')

    autoTester.check (32 << 2)
    autoTester.check (32 >> 2)
    autoTester.check (1 | 4)
    autoTester.check (11 ^ 13)
    autoTester.check (12 & 20)
    

4.34. Properties

Testlet: properties
class A:
    p = 1234
    def getX (self):
        return self._x

    def setX (self, value):
        self._x = value
            
    def getY (self):
        return self._y

    def setY (self, value):
        self._y = 1000 + value  # Weird but should be possible
        
    def getY2 (self):
        return self._y

    def setY2 (self, value):
        self._y = value
        
    def getT    (self):
        return self._t

    def setT (self, value):
        self._t = value
        
    def getU (self):
        return self._u + 10000

    def setU (self, value):
        self._u = value - 5000
            
    x, y, y2 = property (getX, setX), property (getY, setY), property (getY2, setY2)
    t = property (getT, setT)
    u = property (getU, setU)
    
A.q = 5678

class B:
    def getZ (self):
        return self.z_
    
    def setZ (self, value):
        self.z_ = value
        
    z = property (getZ, setZ)
    
class C:
    def __init__ (self):
        self.offset = 1234

    def getW (self):
        return self.w_ + self.offset
        
    def setW (self, value):
        self.w_ = value - self.offset
        
    w = property (getW, setW)
    
def run (autoTester):
    a1 = A ()
    a2 = A ()

    a1.y2 = 1000
    a2.y2 = 2000
    
    a1.x = 5
    a1.y = 6
    
    a2.x = 7
    a2.y = 8

    a1.t = 77
    a1.u = 88
        
    autoTester.check (a1.x, a1.y, a1.y2)
    autoTester.check (a2.x, a2.y, a2.y2)
    autoTester.check (a1.p, a2.p, a1.q, a2.q)
    
    autoTester.check (a1.t, a1.u)
    
    b = B ()
    c = C ()
    
    b.z = 100100
    c.z = 200200
    c.w = 300300
    
    autoTester.check (a1.x, b.z, c.z, c.w)
    
    c.w = 400400
    c.z = 500500
    b.z = 600600
    
    autoTester.check (a1.x, b.z, c.z, c.w)

4.35. Representation as text: the repr and str built-in functions

Testlet: reprtest
def run(test):
    """ Test the repr and string implementations
    """

    v = 1
    test.check( repr(v) )
    test.check( str(v) )
    v = "asdf"
    test.check( repr(v) )
    test.check( str(v) )
    v = True
    test.check( repr(v) )
    test.check( str(v) )
    v = False
    test.check( repr(v) )
    test.check( str(v) )
    v = 1.2
    test.check( repr(v) )
    test.check( str(v) )
    v = -31.2
    test.check( repr(v) )
    test.check( str(v) )
    v = 63e-12
    test.check( repr(v) )
    test.check( str(v) )
    v = 24e37
    test.check( repr(v) )
    test.check( str(v) )
    v = -34e-23
    test.check( repr(v) )
    test.check( str(v) )
    v = -89e32
    test.check( repr(v) )
    test.check( str(v) )
    v = None
    test.check( repr(v) )
    test.check( str(v) )
    v = [None]
    test.check( repr(v) )
    test.check( str(v) )
    v = [None, None]
    test.check( repr(v) )
    test.check( str(v) )
    v = [None, 1.02]
    test.check( repr(v) )
    test.check( str(v) )
    v = [1,3.000234]
    test.check( repr(v) )
    test.check( str(v) )
    v = [1,2,3]
    test.check( repr(v) )
    test.check( str(v) )
    v = [1.04, 2.03, 3.005]
    test.check( repr(v) )
    test.check( str(v) )
    v = ["asdf", 2.00009, "1234"]
    test.check( repr(v) )
    test.check( str(v) )
    v = set([1,2,3])
    test.check( repr(v) )
    test.check( str(v) )
    v = set([])
    test.check( repr(v) )
    test.check( str(v) )
    v = (1,2)
    test.check( repr(v) )
    test.check( str(v) )
    v = (3.4, 4.4)
    test.check( repr(v) )
    test.check( str(v) )
    v = (None, 5.32)
    test.check( repr(v) )
    test.check( str(v) )
    v = {}
    test.check( repr(v) )
    test.check( str(v) )
    v = { "a": 1 }
    test.check( repr(v) )
    test.check( str(v) )

    # @note - in python the dictionary key
    #     ordering is not specified. So the following tests
    #     cannot be reliably completed when there are more than
    #     one key in a dict - so this test coverage was skipped for now.

    d = { "asdf": 3.4 }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "qwer": "qwerqwer qwerqwer" }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "a9342" : None }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "nfdns" : True }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "alel;e;" : False }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "didi" : [True,False,True] }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "bibi" : [1,2,3] }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "gigi" : ["Asdf","qwer","rewer"] }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "hihi" : ("esdf","qwer","rewer") }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "jiji" : [None, None, None] }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "jiji" : (1.3, 3.4) }
    test.check( repr( d ) )
    test.check( str( d ) )

    d = { "jiji" : { "c" : 4 } }
    test.check( repr( d ) )
    test.check( str( d ) )

    class Test1(object):
        def __init__(self, val):
            self._val = val

        def __str__(self):
            return("[Test1 {}]".format(self._val))

        def __repr__(self):
            return(str(self))

    class Test2(object):
        def __init__(self, val):
            self._val = val

        def __repr__(self):
            return("[Test2 {},{}]".format(self._val, self._val*2))

        def __str__(self):
            return( repr(self) )

    class Test3(Test2):
        def __str__(self):
            return("[Test3 {}]".format(self._val))

    class Test4(object):
        def __init__(self, val):
            self._val = val

        def __repr__(self):
            return("[Test4 {}]".format(self._val))


    t1 = Test1(2)
    test.check( repr(t1) )
    test.check( str(t1) )
    t1 = Test1(4.5)
    test.check( repr(t1) )
    test.check( str(t1) )
    t1 = Test1("blarg")
    test.check( repr(t1) )
    test.check( str(t1) )
    t1 = Test1([1,2,3])
    test.check( repr(t1) )
    test.check( str(t1) )

    t2 = Test2(3)
    test.check( repr(t2) )
    test.check( str(t2) )
    t2 = Test2(7.6)
    test.check( repr(t2) )
    test.check( str(t2) )
    t2 = Test2(-8.9)
    test.check( repr(t2) )
    test.check( str(t2) )

    t3 = Test3(8)
    test.check( repr(t3) )
    test.check( str(t3) )

    t3 = Test3(3.4)
    test.check( repr(t3) )
    test.check( str(t3) )

    test.check( repr( [t1,t2,3] ) )

    d = { "irew" : t1 }
    test.check( repr( d ) )
    test.check( str( d ) )
    d = { "irew" : [t1,t2,t3] }
    test.check( repr( d ) )
    test.check( str( d ) )

    t4 = Test4("qwer")
    test.check( repr(t4) )
    test.check( str(t4) )

4.36. Set comprehensions

Testlet: set_comprehensions
def run (autoTester):
    even = {2 * i for i in [0, 9, 1, 7, 2, 8, 3, 6, 4, 5]}
    autoTester.check (even)
    
    odd = {2 * i + 1 for i in [5, 6, 7, 8, 9, 4, 3, 1, 2, 0]}
    autoTester.check (odd)
    
    even.add (12)
    even.add (12)
    autoTester.check (even)
    
    even.discard (12)
    even.discard (12)
    autoTester.check (even)
    
    uni = even.union (odd)
    autoTester.check (uni)
    
    autoTester.check (odd.isdisjoint (even))
    autoTester.check (uni.isdisjoint (even))
        
    autoTester.check (even.issuperset (uni))
    autoTester.check (uni.issuperset (even))
    
    autoTester.check (even.issubset (uni))
    autoTester.check (uni.issubset (even))
    
    first = {4, 1, 0, 5, 3, 2, 6}
    autoTester.check (first)
    
    second = {3, 5, 6, 9, 4, 7, 8}
    autoTester.check (second)
    
    inter = first.intersection (second)
    autoTester.check (inter)
    
    diff = first.difference (second)
    autoTester.check (diff)
    
    symDiff = first.symmetric_difference (second)
    autoTester.check (symDiff)
    
    aSet = {200, 4, 5, 100}
    aSet.update (first, symDiff, second)
    autoTester.check (aSet)
    

4.37. Super

The super () builtin function is supported for cases where there's exactly one path upwards to exactly one matching method. This covers most use cases, even in a diamond class hierarchy, and results in fast and compact code. In case of more than one path, possibly to more than one matching method, use explicit class names, as shown in the example below.

Testlet: builtin_super
def run (autoTester):
    def show (*args):
        autoTester.check (*args)
        # print (*args) # Leave in for debugging purposes

    class R:
        def __init__ (self, a, b):
            self.a = a
            self.b = b
            
    class A (R):
        def __init__ (self, a, b, c):
            super () .__init__ (a, b)
            self.c = c

        def f (self, x, y):
            show ('A.f:', x, y, self.a, self.b, self.c)
            
        def g (self, x, y):
            show ('A.g:', x, y)
            
    class B (R):
        def __init__ (self, a, b, d):
            super () .__init__ (a, b)
            self.d = d

        def f (self, x, y):
            show ('B.f:', x, y, self.a, self.b, self.d)
            
        def h (self, x, y):
            show ('A.h:', x, y, self.a, self.b, self.d)

    class C (A):
        def __init__ (self, a, b, c):
            super () .__init__ (a, b, c)
        
        def f (self, x, y):
            super () .f (x, y)
            show ('C.f:', x, y, self.a, self.b, self.c)
            
    class D (B):
        def __init__ (self, a, b, d):
            super () .__init__ (a, b, d)
        
        def f (self, x, y):
            super () .f (x, y)
            show ('D.f:', x, y, self.a, self.b, self.d)
            
    # Diamond inheritance, use super () only to call exactly one target method via unique path.
    # In case of multiple target methods or multiple paths, don't use super (), but refer to ancestor classes explicitly instead
    class E (C, D):        
        def __init__ (self, a, b, c, d):
            R.__init__ (self, a, b) # Inherited via multiple legs of a diamond, so call explicitly
            self.c = c              # Could also have used C.__init__, but symmetry preferred
            self.d = d              # Don't use both C.__init__ and D.__init__, since R.__init__ will be called by both
                                    # That's harmless here, but not always

        def f (self, x, y):
            C.f (self, x, y)        # Ambiguous part of diamond, don't use super ()
            D.f (self, x, y)        # Ambiguous part of diamond, don't use super ()
            show ('E.f:', x, y, self.a, self.b, self.c, self.d)
            
        def g (self, x, y):
            super () .g (x, y)      # Unique, using super () is OK
            show ('E.g:', x, y, self.a, self.b, self.c, self.d)
            
        def h (self, x, y):
            super () .h (x, y)      # Unique, using super () is OK
            show ('E.h:', x, y, self.a, self.b, self.c, self.d)
           
    rr = R (100, 200)

    show ('--1--')

    a = A (101, 201, 301)
    a.f (711, 811)
    a.g (721, 821)

    show ('--2--')

    b = B (102, 202, 302)
    b.f (712, 812)
    b.h (732, 832)

    show ('--3--')

    c = C (103, 203, 303)
    c.f (713, 813)
    c.g (723, 823)

    show ('--4--')

    d = D (104, 204, 304)
    d.f (714, 814)
    d.h (734, 834)

    show ('--5--')

    e = E (105, 205, 305, 405)
    e.f (715, 815)
    e.g (725, 825)
    e.h (735, 835)

4.38. Simple and augmented assignment

Testlet: simple_and_augmented_assignment
class A:
    def __init__ (self):
        self.i = 0
        
    def f (self):
        return self.i

a = A ()
        
def run (autoTester):
    x = 3
    y = 5
    z = x + y
    autoTester.check (z)
    
    l = [1, 2, 3]
    l [1] = l [2]
    autoTester.check (l)
    
    # Should generate x++
    x += 1
    autoTester.check (x)
    x += +1
    autoTester.check (x)
    x -= -1
    autoTester.check (x)
    
    # Should generate y--
    y -= 1
    autoTester.check (y)
    y -= +1
    autoTester.check (y)
    y += -1
    autoTester.check (y)
    
    x += -3
    autoTester.check (x)
    
    x += 6
    autoTester.check (x)
    
    y -= 3
    autoTester.check (y)
    
    l [1] += l [1]
    autoTester.check (l)
    
    x += y
    y += x
    
    autoTester.check (x, y)
    
    f = a.f
    
    a.i += 1
    autoTester.check (f ())
    
    a.i += 10
    autoTester.check (f ())
    
    a.i += a.i
    autoTester.check (f ())

4.39. Truthyness: optional Python-style evaluation of truthyness, falsyness and non-empty container selection

Testlet: truthyness
from org.transcrypt.stubs.browser import __pragma__

__pragma__ ('tconv')

def run (autoTester):
    autoTester.check (len ({1:2}))

    autoTester.check ('Select nonemtpy container, if any<br>')

    autoTester.check ((0) or (1, 2, 3))
    autoTester.check (() or (1, 2, 3))
    autoTester.check (() or ())
    
    autoTester.check ((-1) or (0) or (1, 2, 3))
    autoTester.check (() or (0) or (1, 2, 3))
    autoTester.check (() or () or (1, 2, 3))
    autoTester.check (() or () or ())
    
    autoTester.check ([0] or [1, 2, 3])
    autoTester.check ([] or [1, 2, 3])
    autoTester.check ([] or [])
    
    autoTester.check ([-1] or [0] or [1, 2, 3])
    autoTester.check ([] or [0] or [1, 2, 3])
    autoTester.check ([] or [] or [1, 2, 3])
    autoTester.check ([] or [] or [])
    
    autoTester.check ({0} or {1, 2, 3, 4})
    autoTester.check (set () or {1, 2, 3, 4})
    autoTester.check (set () or set ())
    
    autoTester.check ({-1} or {0} or {1, 2, 3, 5})
    autoTester.check (set () or {0} or {1, 2, 3, 6})
    autoTester.check (set () or set () or {1, 2, 3, 7})
    autoTester.check (set () or set () or set ())
    
    autoTester.check ({0:10} or {1:11, 2:12, 3:13})
    autoTester.check ({} or {1, 2, 3, 8})
    autoTester.check ({} or {})
    
    autoTester.check ({-1:-11} or {0:10} or {1:11, 2:12, 3:13})
    autoTester.check ({} or {0:10} or {1:11, 2:12, 3:13})
    autoTester.check ({} or {} or {1:11, 2:12, 3:13})
    autoTester.check ({} or {} or {})
    
    autoTester.check ('<br><br>')
    autoTester.check ('Boolean evaluations')
    for expression in (
        '<br> -- falsy -- <br>',
        (),
        [],
        set (),
        {},
        0,
        '',
        3 > 5,
        False,
        '<br> -- truthy -- <br>',
        (1, 2, 3),
        [1, 2, 3],
        {1, 2, 3},
        {'a': 1, 'b': 2, 'c': 3},
        3,
        'hello',
        5 > 3,
        True
    ):
        if expression in ('<br> -- falsy -- <br>', '<br> -- truthy -- <br>'):
            autoTester.check (expression)
        else:
            autoTester.check (expression, ' . . . ')
            autoTester.check ('operators')
            autoTester.check (not not expression)
            autoTester.check (not not (True and expression))
            autoTester.check (not not (False or expression))
            autoTester.check (not not (expression and True))
            autoTester.check (not not (expression and False))
            
            autoTester.check ('if')
            if expression:
                autoTester.check (True)
            else:
                autoTester.check (False)
                
            if expression or expression:
                autoTester.check (True)
            else:
                autoTester.check (False)
                
            if False:
                autoTester.check ('if')
            elif expression:
                autoTester.check ('elif')
            else:
                autoTester.check ('else')
                
            autoTester.check ('while')
            while expression:
                autoTester.check (True)
                break
                
            autoTester.check ('condex')
            autoTester.check (True if expression else False)
            
    if (0.0):
        autoTester.check ('0.0')
    elif (0.1):
        autoTester.check ('0.1')
    else:
        autoTester.check ('Shouldn\'t be here...')
        
    class A:
        pass
        
    autoTester.check (not not A ())
    

4.40. Tuple assignment: recursive and in for-headers using enumerate

Testlet: tuple_assignment
def run (autoTester):
    ((a, b), santa, [c, d], e) = ((1, 2), 'santa-claus', {3, 4}, 5)
    autoTester.check (a, b, c, d, e, santa)
    
    for i, x in enumerate ((0.5, 1.5, 2.5, 3.5)):
        autoTester.check (i, x)
    
    e, pi = 3.14, 2.74
    e, pi = pi, e
    autoTester.check (e, pi)
    
    def f ():
        return [(i, 2 * i) for i in range (7000, 10000, 1000)]
        
    def g ():
        return f
        
    [k, l], [m, n], (o, p) = g () ()
    
    autoTester.check (k, l, m, n, o, p)