metapensiero / metapensiero.pj

Javascript for refined palates: a Python 3 to ES6 Javascript translator
Other
901 stars 73 forks source link

py2many test cases #61

Open jayvdb opened 3 years ago

jayvdb commented 3 years ago

I am looking for a python to JS implementation to run within or alongside https://github.com/adsharma/py2many , and running pj on the tests in https://github.com/adsharma/py2many/tree/main/tests/cases I found some issues, that I thought worth sharing.

Most obvious is lack of support for __name__, especially if __name__ === "__main__":. This isnt a big problem, as py2many can rewrite this before invoking pj.

Another is that the typing import is not removed, which is already raised at https://github.com/metapensiero/metapensiero.pj/issues/21 .

Beyond that, compilation to ES6 fails for

Many others fail for ES5 mode because they are using imports, usually of stdlib, and especially of stdlib which should just be stripped, especially typing c.f. https://github.com/metapensiero/metapensiero.pj/issues/21#issuecomment-850808455

Invoking the successfully transpiled JS code often fails. e.g. [].append is not translated into the JS equivalent [].push, which is breaking a few of the tests at runtime. After I manually fix that, a fun one is bitops.py which fails because of bitops on booleans is resulting in ints instead of booleans. i.e. pj causes ands to be [ 0, 0, 0, 1 ] which is not equal to [false, false, false, true]. I've found bitops.py trips all of the Python to JavaScript transpilers that I've tried.

The new Set syntax {1, 2} should be easy to implement assuming that set type is already implemented.

stdlib enum support is covered by cases int_enum and str_enum. These are special cases where multiple inheritance is used (mostly) to inform the underlying Python class about behaviour of the members, and could be roughly supported without actually supporting multiple inheritance. e.g. py2many detects specific multiple base combinations for this.

azazel75 commented 3 years ago

Thanks for reporting. The purpose of this project is more that of helping the developer that has to frequently switch from python to js during development, rather than a one-to-one translation of python concepts. For this reason some of the "issues" you have written above probably will not be "fixed", especially because I tried to limit the runtime to a minimum where other projects like transcrypt do come with an accompanying library and runtime that tries to emulate more of python behavior.

In addition to that, listing all your issues in one bug report doesn't help focusing on each one.

Anyway, thanks again

jayvdb commented 3 years ago

I didnt create a bunch of separate isues as I've found that most py->js transpilers have peculiar choices about what Python syntax they indent to support, vs what is out of scope, so some of the bugs I might raise are WONTFIXES, but others are considered to be bugs. I dont mean "peculiar" as derogatory - just each person solving this problem are all making different choices. Even Transcrypt is failing lots of py2many test cases, and seems intent on keeping some of their failings. The transpilers that want to maintain perfect CPython compatibility end up with a horridly large JS runtime shim.

So far it looks like pscript is a better fit for my needs, but only if they add support for set (I've created a PR), but 'pj' is a close second IMO.

The new Set syntax {1, 2} should be easy to implement assuming that set type is already implemented.

I've investigated this a bit further, and it looks like pj already supports set([...]). I havent tested how closely the JS behaves like the Python set, wrt deepcopy and set operations (BitOps) (|, &, ^, etc). If you have no objection, I'd like to try adding support for new set syntax {1, 2} as this is a blocker for me.

azazel75 commented 3 years ago

I've investigated this a bit further, and it looks like pj already supports set([...])

No you're getting it wrong: pj as no special support for sets:

$ pj -s "set([1, 2, 3, 4, 5])"
set([1, 2, 3, 4, 5]);

as you can see it doesn't generates a new Set(), and a JS set lacks most of the Python set api you need, so you would have to implement it, but then, why a set and not a dict? So we would have to implement that as well. but in the end, to have complete support for Python builtins collections a runtime would be needed.

Usually a pj user would just use Set() knowing that it would geneate a new Set().