Package: javascripthon
(image courtesy offossBytes)It is based on previous work byAndrew Schaaf.author:Alberto Berticontact:alberto@metapensiero.itlicense:GNU General Public License version 3 or laterTable of ContentsIntroductionBrief list of the supported Python semanticsLicenseInstallationUsageReporting BugsConversions Rosetta StoneSimple stuffforstatementFunctionsFunction’s args and call parametersClassestry...except...finallystatementimportstatementsAbout JSdefaultexportandimportStringsVerbatim JSExamplesTestingHow to contributeContributingExternal contributionsTodoDoneExternal documentationToolsNotesChanges0.12 (2022-07-19)0.11 (2020-03-30)0.10 (2018-05-12)0.9 (2018-04-19)0.8 (2017-11-16)0.7 (2017-09-08)0.6 (2017-05-09)0.5 (2016-11-23)0.4 (2016-11-15)0.3 (2016-04-08)0.2 (2016-03-29)0.1 (2016-03-21)IntroductionJavaScripthon is a small and simple Python 3.5+ translator to JavaScript which
aims to be able to translate most of the Python’s core semantics without
providing a full python-in-js environment, as most existing translators do. It
tries to emit code which is simple to read and check. It does so by switching
to ES6 construct when possible/required. This allows to simplify the needs of
polyfills for many of the expected Python behaviors.It is designed to be the first step in a pipeline that translates your Pyhton
code into something that a browser can understand. Usually it is used with
tools likeBabelJSandWebpackto prepare the final bundle that will
be served to the browser. The steps from the source code to the bundle are the
following:JavaScripthon converts your Python 3.5+ code to ES6 JavaScript modules;the BabelJS loader (configured inside Webpack or standalone) translates the
ES6 JavaScript to ES5 so that the browser can understand it;Webpack parses the resulting source code and packages your source code with
its dependencies by analyzingimportstatements and emits abundle.jsready to be served to the browser.Along this process the correspondingsource mapsare read and integrated at
every step, allowing you to place breakpoints on your original Python source
files when working with the developer tools of your browser.An example of such setup is provided in theexamplesdirectory.In addition to that, you can choose to do most these steps without using
external JS tools. It comes with anembedded js interpreterthat loads a
standalone version of BabelJS and converts your code to ES5 JavaScript without
the need to install anything else. In fact most of the the test you can find
intests/test_evaljs.pyuse the embedded interpreter to dual evaluate the
source code (one time in Python, one time in JavaScript) and simply check that
the results are the same.Thanks to that, JavaScripthon can also be used as a server-side library to
translate single functions or classes that you want your browser to load and
evaluate.The interface with the JS world is completely flat, just import the modules
or use the expected globals (window,document, etc…) as you
would do in JavaScript.Brief list of the supported Python semanticsThe fact that JavaScripthon doesn’treinvent the wheelby reimplementing in
Python many of the features available with JavaScript translators/transpilers
allows it to be lean while implementing quite a decent set of the core Python
semantics. These are, briefly:Misclist slices;list’sappend();dict’scopy(),update();len();print();str();type(instance);yieldandyield from;asyncandawait;importandfrom...importto use any JS module (seeimport
statements);callable();hasattr(),getattr(),setattr();template literals withtmpl('astring with${substitution}');simple Python 3.6+f-strings(seeStrings);template literals and tagged_templates (seeStrings);names starting withd_anddd_will have that part replaced with$and$$, respectively;names ending with an underscore will have it removed. Useful for example
with the AVA ES6 test runner which has a check namedis;__instancecheck__to[Symbol.hasInstance];inttoparseInt;floattoparseFloat;dictionary keys are unambiguous when ES6 translation is
enabled. For example the following code gets translated correctly:a='foo'd={a:1}print(d[a])prints1in both Python and JavaScript, while it printsundefinedwhen translated and evaluated in JavaScript without
ES6.Comparisons (see sectionSimple stufffor the details)most of the basics;isinstance()andissubclass();element in containerfor use with lists, objects, strings and the new
ES6 collections likeMap,Setand so on;identity checks:foo is bar;chained comparisons likex < y <= z;Statements (see sectionSimple stuffandfor statementfor the
details)if...elif...else;whileloop;forover list, over range, over plain js objects, over iterables (JS
iterables);try...except...finallywith pythonesque behavior (seetry…except…finally statementsection for the details);assertstatement;Functions (seeFunctionssection)standard functions, generator functions, async functions;parameters defaults;keyword parameters;parameters accumulators (*argsand**kwargs), with some
restrictions;functions in methods are usually converted to “arrow functions” (the new
ES6 syntax like(foo, bar) => foo * bar;) because they automatically
keepthisfrom the enclosing scope. Appending_fnto a function
declaration will force the translation to a normal function;Classes (seeClassessection)single inheritance;Exception classes for use withexceptstatement;class decorators and method decorators;property descriptors;special handling ofpropertyandclassmethoddescriptors;async methods, generator methods;non-function body members (i.e.member_of_class_Foo = bar);LicenseThis package is covered by theGNU General Public License version
3 or later. The code produced by it (i.e. the transpiled
JavaScript) isyourcode, andyouare free to choose whatever
license you like. The onlyruntimethat exists is the filesnippets.pyfrom which some utility functions are picked when
necessary and transpiled together with your code. While it’s
distributed with the same license as the other source code, in itstranspiledform will have the license you choose.So, to summarize, the license of the this tool is GPL, but it doesn’t
extends to the products of this tool, on which you are free to decide.InstallationPython 3.5 is required because Python’s AST has changed between 3.4
and 3.5 and as of now supporting multiple Python versions is not one
of my priorities.To install the package execute the following command:$ pip install javascripthonor, if you want install it from sources:$ git clone https://github.com/azazel75/metapensiero.pj
$ pip install -r metapensiero.pj/requirements.txt
$ pip install metapensiero.pjUsageTocompileortranspilea python source module, use the
commandline:$python-mmetapensiero.pjsource.pyor:$python-mmetapensiero.pj-5source.pyto transpile.Apjconsole script is also automatically installed:$pj--helpusage:pj[-h][--disable-es6][--disable-stage3][-5][--transform-runtime][-oOUTPUT][-d][--pdb][-sSTRING][-e][file[file...]]APython3.5+toES6JavaScriptcompilerpositionalarguments:filePythonsourcefile(s)ordirectory(ies)toconvert.Whenitisadirectoryitwillbeconvertedrecursivelyoptionalarguments:-h,--helpshowthishelpmessageandexit--disable-es6DisableES6featuresduringconversion(Ignoredif--es5isspecified)--disable-stage3DisableES7stage3featuresduringconversion-5,--es5AlsotranspiletoES5usingBabelJS.--transform-runtimeAddtrasformruntimeaspluginduringtranspile-oOUTPUT,--outputOUTPUTOutputfile/directorywheretosavethegeneratedcode-d,--debugEnableerrorreporting--pdbEnterpost-mortemdebugwhenanerroroccurs-sSTRING,--stringSTRINGConvertastring,usefulforsmallsnippets.Ifthestringis'-'willbereadfromthestandardinput.-e,--evalEvaluatethestringsuppliedwiththe-susingtheembeddedinterpreterandreturnthelastresult.Thiswillconverttheinputstringwithalltheextensionsenabled(comparabletoaddingthe'-5'option)andsoitwilltakesometimebecauseofBabelJSloadtimes.This offers many ways to test the framework, both the string conversion and
the evaluation using the embedded JavaScript interpreter are very handy. For
example:$pj-s'"foo" if True else "bar"'(true?"foo":"bar");and evaluating the same statement:$pj-s'"foo" if True else "bar"'-efooYou can even try more fancy ES6 features, like destructuring assignment:$pj-s"a, b, c = (2, 3, 5) \na+b+c"-e10You can use metapensiero.pj in python code as well.frommetapensiero.pj.__main__importtransform_stringtransform_string("print()")Reporting BugsThe main development repository is the one ongitlab, the one on
github is just a mirror so please report issues and feature requeststhere.Conversions Rosetta StoneHere is a brief list of examples of the conversions the tool applies,
just some, but not all.Simple stuffMost are obviousPythonJavaScriptx<y<=z<5((x<y)&&(y<=z)&&(z<5))deffoo():return[True,False,None,1729,"foo",r"foo\bar",{}]functionfoo(){return[true,false,null,1729,"foo","foo\\bar",{}];}whilelen(foo)>0:print(foo.pop())while((foo.length>0)){console.log(foo.pop());}iffoo>0:....eliffoo<0:....else:....if((foo>0)){....}else{if((foo<0)){....}else{....}}str(x)x.toString()yieldfooyield fromfooyieldfooyield*fooThen there are special cases. Here you can see some of these
conversions. JavaScripthon cannot do a full trace of the sources, so
some shortcuts are taken about the conversion of some core, specific
Python’s semantics. For example Python’sselfis always converted
to JavaScript’sthis, no matter where it’s found. Orlen(foo)is always translated tofoo.length. Albeit this an API specific of
just some objects (Strings, Arrays, etc…), it is considered wide
adopted and something the user may consider obvious.The rules of thumb to treat things especially are:Is it possible to think of a conversion that covers most of the use
cases?Is ts possible to find a convention widely used on the Python world
to express this special case?There are special casesPythonJavaScript=====!=!==2**3Math.pow(2,3)'docstring'/* docstring */selfthislen(...)(...).lengthprint(...)console.log(...)isinstance(x,y)isinstance(x,(y,z))(xinstanceofy)(xinstanceofy||xinstanceofz)typeof(x)(typeofx)type(x)Object.getPrototypeOf(x)FirstCharCapitalized(...)new(any_function(...))newFirstCharCapitalized(...)newany_function(...)fooinbarvar_pj;function_pj_snippets(container){functionin_es6(left,right){if(((rightinstanceofArray)||((typeofright)==="string"))){return(right.indexOf(left)>(-1));}else{if(((rightinstanceofMap)||(rightinstanceofSet)||(rightinstanceofWeakMap)||(rightinstanceofWeakSet))){returnright.has(left);}else{return(leftinright);}}}container["in_es6"]=in_es6;returncontainer;}_pj={};_pj_snippets(_pj);_pj.in_es6(foo,bar);foo[3:]foo[:3]foo.slice(3);foo.slice(0,3);list(foo).append(bar)foo.push(bar);dict(foo).update(bar)Object.assign(foo,bar);dict(foo).copy()Object.assign({},foo);forstatementTheforstatement by default is translated as if the object of the
cycle is a list but has two special cases:forloopsPythonJavaScriptnotesforelindict(a_dict):print(el)var_pj_a=a_dict;for(varelin_pj_a){if(_pj_a.hasOwnProperty(el)){console.log(el);}}With this kind of loop if you usedict(a_dict, True)the check onhasOwnProperty()will not be added, so the loop will includeinherited(andenumerable) properties.forelinan_array:print(el)for(varel,_pj_c=0,_pj_a=an_array,_pj_b=_pj_a.length;(_pj_c<_pj_b);_pj_c+=1){el=_pj_a[_pj_c];console.log(el);}foriinrange(5):print(i)for(vari=0,_pj_a=5;(i<_pj_a);i+=1){console.log(i);}foreliniterable(a_set):print(el)var_pj_a=a_set;for(varelof_pj_a){console.log(el);}This will loop over all the iterables, like instances ofArray,Map,Set, etc.but not over normal objects.FunctionsFunctions are very well supported. This should be obvious, you can say. Really
it is not so simple, if we mean functions in their broader meaning, including
theasync functionsandgenerator functions.The various types of functions at playPythonJavaScriptnotesdeffoo(a,b,c):passfunctionfoo(a,b,c){}Normal functionsdeffoo(a,b,c):foriinrange(a,b,c):yieldiforiiniterable(foo(0,5,2)):print(i)function*foo(a,b,c){for...{// loop control omitted for brevityyieldi;}}for(varioffoo(0,5,2)){console.log(i);}Generator functions. They return an iterable and to correctly loop over
it you should use theiterable(...)call, so that the Python’sfor...inwill be converted into afor...ofasyncdeffoo(a,b,c):awaitsome_promise_based_asyncasyncfunctionfoo(a,b,c){awaitsome_promised_base_async;}Async functions. They make use of the newPromiseclass, which is
also available.Function’s args and call parametersParmeters defaults and keyword parameters are supported and so is*fooaccumulator, which is translated into the ES6 rest expression (...foo).The only caveat is that JS support for keyword args sucks, so you will have toremember to fill in all the arguments before specifying keywords.On function definitions,**kwargsis supported if it’s alone, i.e. without
either keyword arguments or*args.function’s args and call parametersPythonJavaScriptdeffoo(a=2,b=3,*args):passfunctionfoo(a=2,b=3,...args){}defbar(c,d,*,zoo=2):passfunctionbar(c,d,{zoo=2}={}){}foo(5,*a_list)foo(5,...a_list);bar('a','b',zoo=5,another='c')bar("a","b",{zoo:5,another:"c"});defzoo(e,**kwargs):print(kwargs['bar'])functionzoo(e,kwargs={}){console.log(kwargs['bar'])}zoo(4,bar=6)zoo(4,{bar:6})ClassesClasses are translated to ES6 classes as much as they can support. This means:no direct support multi-class inheritance, you have to come up with your own
solution for now. Many established frameworks support this in a way or
another so just use those facilities for now. I’ve read of some attempts,
see for example the suggestion onMozilla developeror the other aboutsimple mixinsonExploring ES6.external implementation for class-level non assignment members. Assignment
members are those on the body of a class which are defined with:a_label = an_expressionlike:classFoo:bar='zoo'# or any kind of expressionThese members are removed from the translated body and submitted to a
snippet of code that will run after class creation in JS land. This serves
two purposes: if the value issimple, i.e. it isn’t an instance ofObject, it will be setup as adata descriptor, and it will work mostly
like you are used to in Python. The most noticeable caveat is that it will
not be accessible through the class as it is in Python, you will have to
access the class’prototype, so in the case above i meanFoo.prototype.bar.The other purpose is to check foraccessor descriptors. If the value on
the right side of the assignment implements agetfunction, it will be
installed as a property as-is, and itsgetandsetmembers will be used
to manage the value with thebarname.external implementation for method decorators whose name is different frompropertyorclassmethod(more on these later on), because these are
already supported by the ES6 class notation.external implementation for class decorators. One caveat here is that the
return value of the decorator has always to be a function with a prototype:
unfortunately anewstatement seems not to bedelegablein any way. So
for example a class decorator implemented like the following:deftest_class_deco():counter=0defdeco(cls):defwrapper(self,*args):counter+=1# side effectreturncls(*args)returnwrapper@decoclassFoo:passwill never work. This will work instead:defdeco(cls):defwrapper(self,*args):counter+=1# side effectreturncls.prototype.constructor.call(self,*args)wrapper.prototype=cls.prototypereturnwrapperSo either return the original class or setup the wrapper appropriately.Methods can be functions or async-functions although the latters aren’t
officially supported yet by the JavaScript specification. You can disable them
adding a--disable-stage3to the command line utility.Python`ssuper()calls are converted accordingly to the type of
their surrounding method:super().__init__(foo)becomessuper(foo)in constructors.Functions inside methods are translated to arrow functions so that
they keep thethisof the surrounding method.@propertyand@a_property.setterare translated to ES6 properties.Methods decorated with@classmethodare translated tostaticmethods.Special methods__str__and__len__are translated totoString()method andget length()property, respectively.Arrow method expression to retain thethisat method level aren’t
implemented yet.ClassesPythonJavaScriptclassFoo(bar):def__init__(self,zoo):super().__init__(zoo)defmeth(self,zoo):super().meth(zoo)defcool(a,b,c):print(self.zoo)asyncdefsomething(self,a_promise):result=awaita_promisedefgenerator_method(self):yieldsomething@propertydeffoo(self):returnself._foo@foo.setterdeffoo(self,value):self._foo=value@classmethoddefbar(self,val):do_something()def__len__(self):return1def__str__(self):return'Foo instance'classFooextendsbar{constructor(zoo){super(zoo);}meth(zoo){super.meth(zoo);varcool;cool=(a,b,c)=>{console.log(this.zoo);};}asyncsomething(a_promise){varresult;result=awaita_promise;}*generator_method(){yieldsomething;}getfoo(){returnthis._foo;}setfoo(value){self._foo=value;}staticbar(val){do_something()}getlength(){return1;}toString(){return"Foo instance";}}Only direct descendants ofExceptionare treated especially, but
just for them to be meaningful in JS land and to be detectable withinstanceofin catch statements.ExceptionsPythonJavaScriptclassMyError(Exception):passraiseMyError("An error occurred")functionMyError(message){this.name="MyError";this.message=(message||"Custom error MyError");if(((typeofError.captureStackTrace)==="function")){Error.captureStackTrace(this,this.constructor);}else{this.stack=newError(message).stack;}}MyError.prototype=Object.create(Error.prototype);MyError.prototype.constructor=MyError;thrownewMyError("An error occurred");try...except...finallystatementThe conversion of this statement is mostly obvious with the only
exception of theexceptpart: it translates to acatchpart
containing oneifstatement for each non catchallexcept. If a
catchallexceptisn’t present, the error will be re-thrown, to mimic
Python’s behavior.try...catch...finallystatementPythonJavaScripttry:foo.bar()exceptMyError:recover()exceptMyOtherError:recover_bad()finally:foo.on_end()try{foo.bar();}catch(e){if((einstanceofMyError)){recover();}else{if((einstanceofMyOtherError)){recover_bad()}else{throwe;}}}finally{foo.on_end();}importstatementsimportandfrom ... importstatements are converted to ES6
imports, and the declaration of an__all__member on the module
top level is translated to ES6 named exports.import and exportsPythonJavaScriptimportfoo,barimportfoo.barasbfromfoo.barimporthelloash,byeasbbfrom..foo.zooimportbarfrom.importfoofrom.fooimportbarfromfoo__barimportzoofrom__foo.zooimportbarfromfooimport__default__asbarfrom__globals__importtest_name# this should not trigger variable definitiontest_name=2# this instead should do ittest_foo=True__all__=['test_name','test_foo']__default__='test_name'vartest_foo;import*asfoofrom'foo';import*asbarfrom'bar';import*asbfrom'foo/bar';import{helloash,byeasbb}from'foo/bar';import{bar}from'../foo/zoo';import*asfoofrom'./foo';import{bar}from'./foo';import{zoo}from'foo-bar';import{bar}from'@foo/zoo';importbarfrom'foo';test_name=2;test_foo=true;export{test_name,test_foo};exportdefaulttest_name;About JSdefaultexportandimportIf you want to export something asdefault exportin your modules,
declare a__default__member and assign to it the string of the
symbol you want to export. To clarify:foo=42bar="hello"__all__=['foo','bar']# foo and bar will be exported as named exports__default__='bar'# bar will also be exported as the *default*This becomes:varbar,foo;foo=42;bar="hello";export{foo,bar};exportdefaultbar;For what concerns theimport, you can import the default export of
a module using thedefaultname, as defined by the ES6
spec. However, as there were some issues reported to me with bundlers
not supporting the named import of the default export, a specialimportstatement using__default__ as namehas been added that
directly translates to the more common form of ES6 default import. So:fromfooimportdefaultasbarfromfooimport__default__aszooTranslates to:import{defaultasbar}from'foo';importzoofrom'foo';The two imports should work the same, seeexploring js sectionand
the linked spec. But if you encounter problems with the former use
the latter instead. Keep in mind that you cannot mix the__default__import with others (i.e. it needs to be on a line of
its own) and that you always need to specify an... as name ...part.StringsJavascripthon supports converting Python 3.6+f-stringsto ES6template literals. The expression in the braces gets converted, but
neitherconversionnorformat_specare supported:f"Value of {a}"becomes`Value of ${a}`andf"Value of {self.foo}"becomes`Value of ${this.foo}`.You can also writerawtemplate literals by using the functiontmpl()it does only a conversion of the string markers, from those
used in Python’s literal string notation to template literal notation.There is also the way to expresstagged templates, template literals
that are parsed using a provided function. This is done by using the
function__. So for example:__('A template ${string}with foo',bar)gets translated to:bar`A template${string}with foo`barwill be executed with the value of${string}as a
parameter, see the link fortemplate literalsfor help.Verbatim JSYou can intermix Python and JS by using theJS('Your-JS-code-here')marker function. It will not be touched by
the ES6 transcoder but if you choose to also transpile it to ES5, il
will be considered by Babel.ExamplesExecutemakeinside theexamplesdirectory.TestingTo run the tests you should run the following at the package root:python setup.py testHow to contributeSo you like this project and want to contribute? Good!These are the terse guidelines:There are some TODO points in the readme, or even the issue #6 is
quite simple to fix. Feel free to pick what you like.

The guidelines are to follow PEP8 for coding where possible, so use
CamelCase for classes and snake_case for variables, functions and
members, and UPPERCASE for constants.

An exception to this rules are the function names inside
``metapensiero.pj.transformations`` subpackage. Those are matched
against names of the AST objects coming from the ``ast`` module in
standard lib, so they have to to match even in case.

Try to keep lines lengths under 79 chars, more or less ;-)

The workflow is to fork the project, do your stuff, maybe add a test
for it and then submit a pull request.

Have funContributingAny contribution is welcome, drop me a line or file a pull request.External contributionsBrainBaconhas made aJavaScripthon loaderfor WebPack;icaritohas contributed support for JavaScripthon to thepython-webpack-loaderfor WebPack (Every valid JS package has at
least two implementations! ROTFL);icaritohas alsointegrated JavaScripthon with Nuxt.js and
Vue.js;chfwhas integratedJavaScripthon into pyechartsto allow
Python function translation.TodoThis is a brief list of what needs to be done:refactor the comprehensions conversion to use the snippets facility;refactor snippets rendering to write them as a module and import
them in the module when tree conversion is enabled;convertdict()calls to ES6Mapobject creation;convertsetliterals to ES6Setobjects. Also, update
“foo in bar” to use bar.has(foo) for sets;DoneStuff that was previously in the todo:translateimportstatements to ES6;translate__all__definition to ES6 module exports;write a command line interface to expose the api;make try…except work again and implement try…finally;convertasyncandawaitto the same proposed features for js
(see BabelJS documentation);convert argument defaults on functions to ES6;convert call keyword arguments;convert*iterablesyntax to ES6 destructuring;use arrow functions for functions created in functions;properties to ES6 properties (getter and setter);take advantage of new duckpy features to use a JS execution context
that lasts multiple calls. This way the BabelJS bootstrap affects
only the initial execution;class and method decorators;implementyield,yield fromand generator functions;update “foo in bar” to use bar.has(foo) for maps;External documentationA good documentation and explanation of ES6 features can be found on
the bookExploring ES6by Axel Rauschmayer (donate if you can).Anextensive documentationabout Python’s AST objects, very handy.ToolsHave a look atECMAScript 6 Toolsby Addy Osmani.To debugsource mapshave a look atsource-map-visualizationand
itspackageon npm.Still i found these links to be helpful:BASE64 VLQ CODEC (COder/DECoder)Testing Source MapsHere is anexampleof the latter tool showing code generated by
JavaScripthon, have fun!NotesApostabout proposed solutions to use ES6 classes withBackbone. See also thebugopen on github.Abenchmark of ES6 featuresanddiscussion about iton
hacker’s news.Acompatibility table of ES6 featuresshowing completeness of
support feature by feature.A storyabout ES6 craziest stuff… symbolsChanges0.12 (2022-07-19)remove macropyfix evaluation from commandlinedeprecate Python 3.5 and 3.6tested on Python 3.100.11 (2020-03-30)update test infrastructure to work with latestpytest;add support for Python 3.7 and 3.8 (thanks to Richard Höchenberger).do not crash when translating source with assignment typehints (
with the help of Sirenfal)0.10 (2018-05-12)use Macropy3 version 1.1.0b2 to avoid issues with Django0.9 (2018-04-19)add a--source-nameoptions to be used together with--inline-mapwhen using-s;move main repository to gitlab.com/metapensiero;add support for default export and import;add documentation for theJS()marker function;refactor of the JS AST nodes;fix path splitting and joining on Windows (thanks to Roman Yakubuk);0.8 (2017-11-16)add support forexceptsections with more than one exception
type and arbitrary exception variable name. Thanks to @devanlai;dict keys conversion fixes;enable--inline-mapwhen translating a string with-s;0.7 (2017-09-08)translate dicts unambiguously, using “computed member name form” for
keys that aren’t strings;usemacropypackage to deal with some of the translation
details;translateint()andfloat();fix a bug that prevented BabelJS translation when keyword arguments;
are present;0.6 (2017-05-09)allow to define template literals and tagged templates;define package scopes in imports prepending names with__;translateissubclass();translate lambdas as arrow functions;translate Python 3.6+ f-strings to ES6 template literals;Add translation for__instancecheck__to[Symbol.hasInstance];Sort imports alphabetically;0.5 (2016-11-23)translatetmpl("Astring with js${interpolation}")to ES6 template
literals;preliminary support to translate names liked_fooanddd_barto$fooand$$bar;addded translation of theassertstatement;fixed a bug intry...except...finallystatement when there’s noexceptsection;added translation forfoo is not barthat seems to have dedicated ast
node;if the function is defined in a method but starts withfn_do not convert
it to an arrow function. Useful tonotmaintainthis;added translation forcallableandhasattr/getattr/setattr;updated for loops to support more than one target, so now its possible to
write loops likefor k, v in iterable(a_map):;updated documentation;added a new cli option-sto translate source from the command line or
the standard input;fixed a pair of bugs on sourcemaps;added a new cli option--evalto also evaluate the produced JavaScript
using the embedded interpreter;added a new cli option--dump-astto print out the ast tree of the
passed in string;added sorting to the rendered snippets/decorators/assignments so that their
order does not change at every ricompilation;do not re-declare variables declare in outer scopes;0.4 (2016-11-15)updated BabelJS to version 6.18.1;allow to import modules with dashes inside by using dunder-inside-words
notation (foo__barbecomesfoo-bar);reuse JavaScript interpreter context to speedup translation;updateinoperator to support ES6 collections;added support for method and class decorators;added support for class properties and descriptors;addforloop over JS iterables;allow to loop over inherited properties;fix a bug ontype()translation;support forrange()steps;add support for generator functions andyieldandyield fromexpressions;optionally load babel-polyfill before evaluating code;fix a bug on sourcemaps having wrong references when there are documentation
elements;translate__get__()and__set__()to to JS equivalents;implementdict(foo).update(bar)anddict(foo).copy;documentation improvements;0.3 (2016-04-08)updates to the documentation ( with some fixes made by Hugo Herter,
Daniel Kopitchinski and ironmaniiith)Translatestr(x)intox.toString()Add support for properties and classmethodsTranslate__len__and__str__methods toget length()andtoString()Add support for slices syntax to.slice()Fixed two bugs in sourcemaps generationFixed a bug in theinport ... fromtranslationCorrectly include BabelJS minimized codeFix transpiling of stage3 features0.2 (2016-03-29)use arrow functions to retainthiswere possibletranslateasync/awaitrefactoring of theforloopsadd ability to subtranslate pieces of Python code or objects. Used
to template the creation ofExceptionsublassesadd support for param defaults and keyword argumentsupdated documentation0.1 (2016-03-21)First cut of the features