Search code examples
javascriptpythontranscrypt

Transpiling boolean.py package to javascript with Transcrypt


I would like some help transpiling a relatively simple python package called boolean.py (the package does boolean algebra operations) into javascript using transcrypt as my transpiler of choice.

Things I have done so far:

  1. Dropped using inspect module which seems to not be supported by transcrypt
  2. Switched to explicit SuperClassName.__init__() calls instead of super(SuperClassName, self).__init__() in python code because transcrypt only supports simple single-case inheritance (and python 3 syntax).

You can find the current code here in this github branch called transcrypt.

Now, the good news is that boolean.py is essentially a single .py file under boolean/boolean.py, everything else is just python project structure. The bad news is that boolean.py runs on both python2 and python3 and I don't know if that is what causes the current issue that I am about to describe:

Having read the relevant sections of transcrypt docs, I transpile the file:

cd boolean/ && transcrypt boolean.py

This gives me a single harmless warning about basestring and creates the __javascript__ folder with boolean.js and boolean.min.js. So far, so good.

Next to the __javascript__ folder I create boolean.html to test:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">

        <title>transcrypt boolean.py</title>
    </head>
    <body>
        <script src="__javascript__/boolean.js"></script>
    </body>
</html>

However, when I load boolean.html in firefox, the console gives a warning:

TypeError: can't assign to properties of (new String("all_feature_namesnested_scopes,generators,division,absolute_import,with_statement,print_function,unicode_literals,barry_as_FLUFL,generator_stop")): not an object

Instead, what I am expecting to see is a boolean object that has BooleanAlgebra subobject. Refer to hello and pong examples of transcrypt to see that it creates hello and pong objects on window accordingly.

Could you help explain what I am doing wrong here?


Solution

  • I've spent quite some time trying to get your lib to work with Transcrypt, encountering several issues:

    1. The boolean.py library uses some modules from the CPython distro, like __future__ and unittest which are not yet available for Transcrypt. This is a problem that can be easily circumvented. You may e.g. back to back test the Transcrypt and the CPython version boolean.py by using Transcrypt's autotest facility. Of write a very tuned down version of unittest yourself etc.

    2. The @property decorator is not yet available. But you can use properties in the non-decorator syntax, as indicated in the docs at http://www.transcrypt.org/docs/html/supported_constructs.html#properties

    3. There maybe some errors in your adapted code like the Function constructor calling itself in endless recursion.

    4. Some exception types (like TypeError) aren't yet implemented in Transcrypt.

    5. Transcrypt's type function is currently only defined with one parameter, something like return type(base_class.__name__, (base_class,), {}) will curently not work.

    6. It is not possible to overload the __hash__ operator function in Transcrypt. This is due to the desired interoperability with JavaScript. Something like {'bird': 'egg', 'human': 'baby'} gets compiled in to a JavaScript object literal, facilitating initialisation with object literals as is usual in many JavaScript libraries.

    7. The values () method of class dict was accidentally skipped. It will be added in the next commit of Transcrypt.

    These were the issues I could find. There may be more, but I lack the understanding of boolean.py to find them in reasonable time.

    End result for me is that I can get it to compile, but I cannot get it to run properly after the start of the parsing phase.

    My expectation is that for someone knowing your library well, this can all be solved by doable workarounds, since I've seen no code in your lib that really is beyond reach of Transcrypt.

    Transcrypt will never be 100% CPython compatible, because of the requirement that the generated code should be as fast and compact as native JavaScript. But if you encounter clear omissions like dict.valuesthey will be added. There are also border cases like string.isalpha. As long as they're small functions, I see no reason not to add them. Just add a feature request to the issues at https://github.com/qquick/Transcrypt.

    Something like frozensetis less likely to be added to the core code, although a contribution of such datastructures in a library would of course be welcome.

    Note that you can also insert arbitrary snippets of JavaScript code anywhere, should it be needed.