Global variables and namespace

605 views
Skip to first unread message

Kiko

unread,
Dec 16, 2013, 7:00:13 AM12/16/13
to bry...@googlegroups.com
Hi all,

I am playing with Brython and the IPython notebook (http://www.ipython.org). The IPython notebook uses a lot of javascript libraries (jquery, codemirror, bootstrap, mathjax, require, internal ipython javascript,...).

When I load brython into the notebook I can execute some code but then the notebook functionality is 'broken'.

I saw that brython populates the namespace with a lot of global variables that could have a collision with other global names from other libraries.

I have been seeing that other libraries use a global namespace and then all the functionality is attached to this global name (e.g., d3, THREE,...).

I wonder if it would be a good idea to use this philosophy for Brython in order to prevent possible collisions with other third party libraries and in order to have a better namespace related with the brython functionality.

Now my stupid question of a js noob. Is it possible to load a library with a local alias? For example, to have something like mybrython.__BRYTHON__ instead of __BRYTHON__

What do you think, guys?

Kiko

unread,
Dec 18, 2013, 2:08:42 AM12/18/13
to bry...@googlegroups.com
No thoughts about this?

Brython is overwritting things like SyntaxError, TypeError,... Brython is changing properties or moving properties to use their own. It populates the global namespace with popular names like object, type, bool, abs, id, None,... Brython populates the namespace with hundreds of names that are used only internally by the translator.

My js knowledge is very low and maybe I don't understand why things are like this but I think this behaviour is error prone and can drive to conflicts with other js libraries.

On the other hand, why there are __BRYTHON__.date or __BRYTHON__.re? I think they are not used in the code.

Thanks.


2013/12/16 Kiko <kikoco...@gmail.com>

Pierre Quentel

unread,
Dec 18, 2013, 5:19:53 AM12/18/13
to bry...@googlegroups.com
Kiko,

You are right, of course. I have been thinking of this issue for some time, this is why I introduced the object __BRYTHON__, but its use is very limited so far. The only drawback is that functions defined in the Brython code will no longer be available directly from Javascript, for instance the first example on the home page with the tag

<button onclick="echo()">

will have to be written something like

 <button onclick="__BRYTHON__.echo()">

but it's a minor drawback compared to the present situation

I am going to concentrate on this after publishing the next version

Thanks,
Pierre



2013/12/18 Kiko <kikoco...@gmail.com>

--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/brython/CAB-sx62-JRR_LKOSfNiSEYi3zFOVVsfFgeDfyCGtvjh1f%2B2sLg%40mail.gmail.com.

For more options, visit https://groups.google.com/groups/opt_out.

Kiko

unread,
Dec 18, 2013, 5:31:52 AM12/18/13
to bry...@googlegroups.com



2013/12/18 Pierre Quentel <pierre....@gmail.com>

Kiko,

You are right, of course. I have been thinking of this issue for some time, this is why I introduced the object __BRYTHON__, but its use is very limited so far. The only drawback is that functions defined in the Brython code will no longer be available directly from Javascript, for instance the first example on the home page with the tag

<button onclick="echo()">

will have to be written something like

 <button onclick="__BRYTHON__.echo()">

but it's a minor drawback compared to the present situation

I am going to concentrate on this after publishing the next version

Thanks,
Pierre



Thanks for the answer, Pierre. I think it is better to solve this issue now and not in the future when Brython will be so massively used :-)

Maybe something less verbose than __BRYTHON__ would also be better.

Kind regards.

Kiko

unread,
Dec 18, 2013, 6:04:56 AM12/18/13
to bry...@googlegroups.com
BTW, I am thinking in the possibility to use Brython inside the IPython notebook so you could have:

-Syntax highlight
-Autocompletion
-Possibility to use Python and Brython in the same environment and pass info from the Python runtime to the Brython runtime and viceversa
-An environment for rapid testing as all happens in a Browser.

The idea would be to have a 'Brython magic' (examples, http://nbviewer.ipython.org/github/ipython/ipython/blob/master/examples/notebooks/Cell%20Magics.ipynb).

More or less I know where I have to go in the IPython code but js functionality is broken when I include Brython in the equation and the new version of IPython (2.0) maybe will change some stuff.

Let's see if the idea is possible before PyConUS :-P (see my PyConES slides and the possibility to run a HTML5 slideshow with 'native' live code).


2013/12/18 Kiko <kikoco...@gmail.com>

sepe...@gmail.com

unread,
Dec 22, 2013, 1:50:22 AM12/22/13
to bry...@googlegroups.com
+1 idea

On 12/18/2013 05:19 AM, Pierre Quentel wrote:
> Kiko,
>
> You are right, of course. I have been thinking of this issue for some time, this
> is why I introduced the object __BRYTHON__, but its use is very limited so far.
> The only drawback is that functions defined in the Brython code will no longer
> be available directly from Javascript, for instance the first example on the
> home page with the tag
>
> <button onclick="echo()">
>
> will have to be written something like
>
> <button onclick="__BRYTHON__.echo()">
>
> but it's a minor drawback compared to the present situation
>
> I am going to concentrate on this after publishing the next version
>
> Thanks,
> Pierre
>
>
>
> 2013/12/18 Kiko <kikoco...@gmail.com <mailto:kikoco...@gmail.com>>
>
> No thoughts about this?
>
> Brython is overwritting things like SyntaxError, TypeError,... Brython is
> changing properties or moving properties to use their own. It populates the
> global namespace with popular names like object, type, bool, abs, id,
> None,... Brython populates the namespace with hundreds of names that are
> used only internally by the translator.
>
> My js knowledge is very low and maybe I don't understand why things are like
> this but I think this behaviour is error prone and can drive to conflicts
> with other js libraries.
>
> On the other hand, why there are __BRYTHON__.date or __BRYTHON__.re? I think
> they are not used in the code.
>
> Thanks.
>
>
> 2013/12/16 Kiko <kikoco...@gmail.com <mailto:kikoco...@gmail.com>>
> <mailto:brython%2Bunsu...@googlegroups.com>.
> To post to this group, send email to bry...@googlegroups.com
> <mailto:bry...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/brython/CAB-sx62-JRR_LKOSfNiSEYi3zFOVVsfFgeDfyCGtvjh1f%2B2sLg%40mail.gmail.com.
>
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "brython" group.
> To unsubscribe from this group and stop receiving emails from it, send an email
> to brython+u...@googlegroups.com.
> To post to this group, send email to bry...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/brython/CA%2BgUBLRuKy35GF1h4XRkWwmNC%3DqZJitFH68i5nSZkP6tT3YKYQ%40mail.gmail.com.

Billy Earney

unread,
Dec 23, 2013, 2:37:24 PM12/23/13
to bry...@googlegroups.com
Pierre,

Could we take approach jquery and other javascript libraries use?

Instead of typing jQuery("blah"), they do $("blah").  

So for the above, couldn't we write a wrapper  $("echo()") that would would be translated to something like __BRYTHON__.echo()?   This shortcut seems to have gained acceptance in the javascript community for many popular javascript libraries.

Billy


Olemis Lang

unread,
Dec 23, 2013, 3:09:07 PM12/23/13
to brython
On Mon, Dec 23, 2013 at 2:37 PM, Billy Earney <billy....@gmail.com> wrote:
Pierre,

Could we take approach jquery and other javascript libraries use?

Instead of typing jQuery("blah"), they do $("blah").  

 
So for the above, couldn't we write a wrapper  $("echo()") that would would be translated to something like __BRYTHON__.echo()?   This shortcut seems to have gained acceptance in the javascript community for many popular javascript libraries.

that will be a problem when trying to integrate brython with other libs already defining $ . So (IMO) should be combined with adoption and support of AMD 


[...]

--
Regards,

Olemis - @olemislc

Apache™ Bloodhound contributor
http://issues.apache.org/bloodhound
http://blood-hound.net

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:


Christophe Gragnic

unread,
Dec 23, 2013, 3:29:12 PM12/23/13
to bry...@googlegroups.com
On Mon, Dec 23, 2013 at 9:09 PM, Olemis Lang <ole...@gmail.com> wrote:
>
> that will be a problem when trying to integrate brython with other libs
> already defining $ . So (IMO) should be combined with adoption and support
> of AMD

Hi,
Knowing that Brython code is contained in text/python3 and compiled before
exposing things, would this really be a problem?

--

http://profgra.org/lycee/ (site pro)
http://delicious.com/profgraorg (liens, favoris)
https://twitter.com/profgraorg

Olemis Lang

unread,
Dec 23, 2013, 3:52:36 PM12/23/13
to brython
On Mon, Dec 23, 2013 at 3:29 PM, Christophe Gragnic <christop...@gmail.com> wrote:
On Mon, Dec 23, 2013 at 9:09 PM, Olemis Lang <ole...@gmail.com> wrote:
>
> that will be a problem when trying to integrate brython with other libs
> already defining $ . So (IMO) should be combined with adoption and support
> of AMD

Hi,
Knowing that Brython code is contained in text/python3 and compiled before
exposing things, would this really be a problem?

IMO the next step for brython (to succeed and be even more useful) is to be integrated with popular js frameworks. From a practical perspective it's almost impossible *in a relative short time* to rewrite (and test, and ...) in python all use cases and diversity covered by current js frameworks to work in the browser, and thereby if you want to load e.g. dojo objects and made them available in brython code then the import *should* be integrated (somehow) with amd, and provide support for such use cases in brython import machinery . 

I do not see why <script text/python3 /> has any influence considering that loading , parsing, etc ... happens under the hood and python code is only executed until after brython core is loaded .

My point is , if e.g. jquery defines $ and brython does the same thing then both definitions will collide .

Pierre Quentel

unread,
Dec 23, 2013, 3:55:09 PM12/23/13
to bry...@googlegroups.com


Le lundi 23 décembre 2013 21:29:12 UTC+1, Grahack a écrit :
On Mon, Dec 23, 2013 at 9:09 PM, Olemis Lang <ole...@gmail.com> wrote:
>
> that will be a problem when trying to integrate brython with other libs
> already defining $ . So (IMO) should be combined with adoption and support
> of AMD

Hi,
Knowing that Brython code is contained in text/python3 and compiled before
exposing things, would this really be a problem?

Hi,

I'm not 100% sure if it's possible, but here is what I would prefer :

- put all Python built-in names as attributes of a single Javascript object __builtins__ (hopefully no Javascript library uses this name) : names such as object, str, list etc. are not defined in the global Javascript namespace, so don't conflict with other libraries

- similarly, put Brython-specific objects (such as DOMNode, JSObject etc.) as attributes of the object __BRYTHON__

- each Brython script is run inside an anonymous function ; at the beginning of the function, all the attributes of __builtins__ are introduced in the function namespace by something like

for(var $pyattr in __builtins__){eval("var "+$pyattr+"=__buiiltins__[$pyattr]")


so that the Javascript code generated by Brython can use str, list, object etc., but these names still remain out of the global Javascript namespace

For the names defined inside the Brython script, things could simply remain as they are today : set them as attributes of window, so that they are available from Javascript. A function defined by

def echo():
    print('hello')


could still be called natively from the HTML tag

<button onclick="echo()">

With this option, it is the responsability of the developer not to define names that conflict with the Javascript libraries or Python module he uses ; for instance, avoid defining THREE if he uses the three.js library - this is what he would also have to do if he developed in Javascript

What do you think of that ?

- Pierre

Kiko

unread,
Dec 23, 2013, 4:48:00 PM12/23/13
to bry...@googlegroups.com
I'm not 100% sure if it's possible, but here is what I would prefer :

- put all Python built-in names as attributes of a single Javascript object __builtins__ (hopefully no Javascript library uses this name) : names such as object, str, list etc. are not defined in the global Javascript namespace, so don't conflict with other libraries

- similarly, put Brython-specific objects (such as DOMNode, JSObject etc.) as attributes of the object __BRYTHON__

- each Brython script is run inside an anonymous function ; at the beginning of the function, all the attributes of __builtins__ are introduced in the function namespace by something like

for(var $pyattr in __builtins__){eval("var "+$pyattr+"=__buiiltins__[$pyattr]")


so that the Javascript code generated by Brython can use str, list, object etc., but these names still remain out of the global Javascript namespace

For the names defined inside the Brython script, things could simply remain as they are today : set them as attributes of window, so that they are available from Javascript. A function defined by

def echo():
    print('hello')


could still be called natively from the HTML tag

<button onclick="echo()">

With this option, it is the responsability of the developer not to define names that conflict with the Javascript libraries or Python module he uses ; for instance, avoid defining THREE if he uses the three.js library - this is what he would also have to do if he developed in Javascript

What do you think of that ?

- Pierre

Nowadays, Brython rewrites objects in the namespace and, for instance, if you use jQuery, its functions are modified with some attributes written by brython.js (__class__,...). So, Pierre, your approach is ok for me if Brython doesn't affect the general behaviour of other objects not provided/created by brython itself and if the global namespace is not 'polluted' with all the brython names and all of them are kept in an easy, intuitive and independent namespace.

Thanks.

Olemis Lang

unread,
Dec 23, 2013, 4:59:28 PM12/23/13
to brython

On Mon, Dec 23, 2013 at 3:55 PM, Pierre Quentel <pierre....@gmail.com> wrote:
[...] 
Hi,



:)
 
- each Brython script is run inside an anonymous function ; at the beginning of the function, all the attributes of __builtins__ are introduced in the function namespace by something like

for(var $pyattr in __builtins__){eval("var "+$pyattr+"=__buiiltins__[$pyattr]")


so that the Javascript code generated by Brython can use str, list, object etc., but these names still remain out of the global Javascript namespace

That's usually the role of $ variable in amd signatures (i.e. anonymous functions) , to encapsulate a bunch of built-in attributes and pass a single arg in to the anonymous function .
  
For the names defined inside the Brython script, things could simply remain as they are today : set them as attributes of window, so that they are available from Javascript. A function defined by

def echo():
    print('hello')


could still be called natively from the HTML tag

<button onclick="echo()">

it'd be nice to be able to do something like <button onclick="brython:echo()" /> 

btw , Joyeux Noël !
 

sepe...@gmail.com

unread,
Dec 24, 2013, 6:28:23 AM12/24/13
to bry...@googlegroups.com
On 12/23/2013 04:59 PM, Olemis Lang wrote:
>
> it'd be nice to be able to do something like <button onclick="brython:echo()" />

Yes, I think Olemis has a good idea. Perhaps a little more like this-
<button onclick="__BRYTHONENV__:echo()" />

And to add Consistency, replacing __builtins__ with __BUILTINS__ (or
__BBUILTINS__ for brython builtins)

Sepero

Olemis Lang

unread,
Dec 24, 2013, 12:59:58 PM12/24/13
to bry...@googlegroups.com
FWIW , I consider __*__ variants a bit unreadable , and that's an
aspect of code I value a lot : readability .

I am not really sure this will work either . The brython: (...
whatever ...) prefix will be interpreted as a label [1]_ in on*
attribute declarations whereas it will be parsed as a URI scheme [2]_
in href definitions . I do not think it will possible (to hook into
any API) to detect / intercept both cases and perform special handling
(if needed).

Another (more realistic ?) approach may be related to hijacking data
URI scheme [3]_ but the whole idea is still WiP

.. [1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label

.. [2] http://stackoverflow.com/questions/11823290/what-is-the-difference-in-call-of-javascript-function-onclick-javascript-funct

.. [3] http://en.wikipedia.org/wiki/Data_URI_scheme

Billy Earney

unread,
Dec 24, 2013, 2:51:27 PM12/24/13
to bry...@googlegroups.com
instead of $("echo()") or __BRYTHON__.echo() what about using a keyword such as PYTHON("echo()") or py("echo()")?


Or would it be possible, for each event to create a wrapper that would check for a instance of the function in brython first, then revert to the global scope if a brython version wasn't found?  This would require overriding each event, and could be somewhat inefficient.


Billy
 


--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Olemis Lang

unread,
Dec 25, 2013, 10:11:08 AM12/25/13
to bry...@googlegroups.com
On 12/24/13, Billy Earney <billy....@gmail.com> wrote:
> instead of $("echo()") or __BRYTHON__.echo() what about using a keyword
> such as PYTHON("echo()") or py("echo()")?

hmmm ... I guess you'll always have python functions eval and exec ,
which btw might clash with JS builtin names .

>
> Or would it be possible, for each event to create a wrapper that would
> check for a instance of the function in brython first, then revert to the
> global scope if a brython version wasn't found? This would require
> overriding each event, and could be somewhat inefficient.

That's something I though of once I suggested brython: i.e. let's
parse all onclick declarations starting with ... and do ... but it's
worthless ; IMO this approach would be quite inefficient in practice .

Pierre Quentel

unread,
Dec 25, 2013, 3:30:23 PM12/25/13
to bry...@googlegroups.com


Le mardi 24 décembre 2013 12:28:23 UTC+1, Sepero a écrit :
On 12/23/2013 04:59 PM, Olemis Lang wrote:
>
> it'd be nice to be able to do something like <button onclick="brython:echo()" />

Yes, I think Olemis has a good idea. Perhaps a little more like this-
<button onclick="__BRYTHONENV__:echo()" />


I don't think it's possible to do anything inside a script with this syntax, I suppose the part before the colon can only be handled by the browser itself

What do you think is wrong with simply using onclick="echo()" ?
 
And to add Consistency, replacing __builtins__ with __BUILTINS__ (or
__BBUILTINS__ for brython builtins)


I chose __builtins__ for compliance with Python : this name is defined by the Python interpreter for all scripts, it holds all the built-in Python names as attributes, exactly what I propose to do with this variable for Brython

Sepero

Olemis Lang

unread,
Dec 25, 2013, 8:16:48 PM12/25/13
to bry...@googlegroups.com
On 12/25/13, Pierre Quentel <pierre....@gmail.com> wrote:
> Le mardi 24 décembre 2013 12:28:23 UTC+1, Sepero a écrit :
>>
>> On 12/23/2013 04:59 PM, Olemis Lang wrote:
>> >
>> > it'd be nice to be able to do something like <button
>> onclick="brython:echo()" />
>>
>> Yes, I think Olemis has a good idea. Perhaps a little more like this-
>> <button onclick="__BRYTHONENV__:echo()" />
>>
>>
> I don't think it's possible to do anything inside a script with this
> syntax, I suppose the part before the colon can only be handled by the
> browser itself
>
> What do you think is wrong with simply using onclick="echo()" ?
>

If I may ... the first thing I consider that may be (improved |
changed) regarding that syntax is that

1. it is still javascript, and thereby it's not possible to insert
python syntax e.g. onclick="print(x for x in some_list)" <= nor even
anything close to that . It's not actually something *wrong* , it's
nice to have .
2. brython names might clash with other js names which have to be
global in order to be referenced inline; therefore it'd be nice to
separate both js & brython vars namespaces

>
>> And to add Consistency, replacing __builtins__ with __BUILTINS__ (or
>> __BBUILTINS__ for brython builtins)
>>
>>
> I chose __builtins__ for compliance with Python

imo +1 ... good choice !
;)

v+python

unread,
Dec 26, 2013, 5:05:42 AM12/26/13
to bry...@googlegroups.com


On Wednesday, December 25, 2013 5:16:48 PM UTC-8, Olemis Lang wrote:

If I may ... the first thing I consider that may be (improved |
changed) regarding that syntax is that

  1. it is still javascript, and thereby it's not possible to insert
python syntax e.g. onclick="print(x for x in some_list)" <= nor even
anything close to that . It's not actually something *wrong* , it's
nice to have .

In fact, due to the need to have an onload handler in the body, as part of the implementation of a load-and-go language translator, the "not possible" Olemis refers to is by design: http://www.w3.org/TR/html401/interact/scripts.html. The only ways to use python syntax for intrinsic event handlers would be to translate python to javascript on the server side, or to have the translator resident in the browser.
 
  2. brython names might clash with other js names which have to be
global in order to be referenced inline; therefore it'd be nice to
separate both js & brython vars namespaces

__builtins__ is a nice name for python __builtins__ as defined by the python language specification and CPython reference implementation. This would not be a good place to put user-defined names, when seen from brython code. __builtins__ has special semantics.

If a separation between js and brython namespaces is desired, it should be done with the language names, so that javascript would reference python names in the python namespace (I'm no javascript expert; hopefully it supports nested namespaces, python does), and python would reference javascript in the javascript namespace. What the names of those namespaces should be depends on the conventions in javascript, when seen in javascript code, and should be one of   js. __js__. or the fully spelled out varieties.  From javascript, I would recommend   py or __py__, or the fully spellled out varieties, unless there is specifically a naming convention reserved for implementations that is spelled differently. Maybe $py ?

Olemis Lang

unread,
Dec 26, 2013, 9:58:22 AM12/26/13
to bry...@googlegroups.com
On 12/26/13, v+python <v+py...@g.nevcal.com> wrote:
> On Wednesday, December 25, 2013 5:16:48 PM UTC-8, Olemis Lang wrote:
>>
>>
>> If I may ... the first thing I consider that may be (improved |
>> changed) regarding that syntax is that
>>
>> 1. it is still javascript, and thereby it's not possible to insert
>> python syntax e.g. onclick="print(x for x in some_list)" <= nor even
>> anything close to that . It's not actually something *wrong* , it's
>> nice to have .
>>
>
> In fact, due to the need to have an onload handler in the body, as part of
> the implementation of a load-and-go language translator, the "not possible"
> Olemis refers to is by design:
> http://www.w3.org/TR/html401/interact/scripts.html.

thanks for sharing ...

> The only ways to use
> python syntax for intrinsic event handlers would be to translate python to
> javascript on the server side, or to have the translator resident in the
> browser.
>

hmmm ... by playing the rules that example will not wok , yes ...

jftr , that's why I said *nor even close to that* because I was
expecting to focus on something *like* that but not exactly the same
as I wrote it because obviously might not be feasible due to (current)
browser design .

<joke> Nevertheless we can be rude ! I'm hoping we can rewrite all
those standards by gathering a few signatures ... :P </joke>

Billy Earney

unread,
Dec 26, 2013, 10:04:43 AM12/26/13
to bry...@googlegroups.com
I like $py or py.   What is neat about this is that we could put 'real' python code between parenthesis..   ie, py("print(','.join([_f for _f in [a,b,c]]))")  which could be pretty cool, but not useful for anything complex.  :)


--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Pierre Quentel

unread,
Dec 27, 2013, 1:50:01 AM12/27/13
to bry...@googlegroups.com
The more I think of it, the more I am convinced that the solution is not to expose Brython namespace to Javascript programs at all, except for Brython functions defined at module level in the __main__ program, so that they can react to calls in event attributes (onclick="foo()")

The reason is that in most cases, it is not possible to create Javascript objects that can be used to interact with the matching Brython variable (at least with a simple syntax). For instance, suppose you have defined a dictionary in Brython with

br_dict = {'a':1}

and you want to add another item from a Javascript program. For this, in the Javascript program, you would like something like

js_dict = $py(br_dict) // or $py.br_dict, or $py("br_dict")...
js_dict['b']=2


Well, there is no such object, because in order to set an item to br_dict, the Javascript code is (once the builtin name __builtins__ will be introduced)

__builtins__.getattr(br_dict,'__setitem__')('b',2)

Providing a conversion function would work in some limited cases, but fail in most cases without any useful error message, or require a very complicated syntax. It's better to give a simple message : Brython variables must be dealt with only in Brython programs

If the only remaining use case is function calls inside event attributes, then since Brython functions are Javascript functions, they can be exposed in the global Javascript namespace. The risk of conflict with Javascript names exists and must be documented, but is not high enough to introduce a specific syntax

- Pierre


sepe...@gmail.com

unread,
Dec 27, 2013, 5:08:22 AM12/27/13
to bry...@googlegroups.com
A lot of what's being discussed looks good to me from many perspectives. I'm far
more experienced with Python than Javascript, so a little bit of the discussion
is beyond my understanding. The only point that I'd really like to stress is
consistency. I touched on this previously. Use underscores on everything or
nothing, AND use all Uppercase or all lowercase for naming.
__BUILTINS__ vs __builtins__ vs BUILTINS vs builtins
__BRYTHON__ vs __brython__ vs BRYTHON vs brython
__PY__ vs .......

I feel the names themselves are less important than the consistency of the
names. Not only what will work best now, but also what will work best going into
the future. This alone may take some time and thought to conclude upon.

Billy Earney

unread,
Dec 27, 2013, 10:07:22 AM12/27/13
to bry...@googlegroups.com
Pierre,

I think you are making a good call here.

Could we expose certain functions to a javascript global by creating a special decorator?

For example:

@expose
def echo(event):
     ## do neat stuff here..
    
where expose is defined in javascript as something like

function expose(f) {
    eval(f.__name__ + "= f")
}

// the expose function above probably isn't correct, but what it should do is take a function defined in brython and make it a global in javascript.  

What do others think?

Billy





--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Christophe Gragnic

unread,
Dec 27, 2013, 11:45:49 AM12/27/13
to bry...@googlegroups.com

Le 27 déc. 2013 16:07, "Billy Earney" <billy....@gmail.com> wrote:
> ...
> @expose
> ...
> What do others think?

That this thread contains a whole bunch of brilliant ideas (including this one), and that this is great team work.

chri

Olemis Lang

unread,
Dec 27, 2013, 1:41:18 PM12/27/13
to bry...@googlegroups.com



On Dec 27, 2013 11:45 AM, "Christophe Gragnic" <christop...@gmail.com> wrote:
>
> Le 27 déc. 2013 16:07, "Billy Earney" <billy....@gmail.com> wrote:
> > ...
> > @expose
> > ...
> > What do others think?

Cool,  that's part of the solution, where (module) would it be defined ?

>
> That this thread contains a whole bunch of brilliant ideas (including this one), and that this is great team work.
>

<joke> It's the side effects of the wine we drink on Christmas </joke>

Sent from Android

--
Regards

Olemis - @olemislc
Blog-ES : http://simelo-es.blogspot.com
Blog-EN : http://simelo-en.blogspot.com
Projects : http://blood-hound.net

Billy Earney

unread,
Dec 27, 2013, 1:54:59 PM12/27/13
to bry...@googlegroups.com
I think it should be part of the browser package (ie, in file _browser.js).

Someone could call it like so:

from browser import expose

I'm not sure that the name 'expose' is the most descriptive, so maybe one someone can think of a better name.



--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Olemis Lang

unread,
Dec 28, 2013, 1:40:33 AM12/28/13
to bry...@googlegroups.com
On 12/27/13, Billy Earney <billy....@gmail.com> wrote:
> I think it should be part of the browser package (ie, in file _browser.js).
>
> Someone could call it like so:
>
> from browser import expose
>
> I'm not sure that the name 'expose' is the most descriptive, so maybe one
> someone can think of a better name.
>

hmmm ... -1 , IMO this belongs in the module we have for js/py
integration . This is a generic js feature not just limited to a given
browser capability (like e.g. html5 , local storage , ...)

[...]

p.s. btw , I've started to sketch handling of data:text/python, URIs .
The goal is to intercept all click events bubbling up to document body
root element , detect the presence of href attribute and , if there's
a match , execute python code (working up to this point ;) and prevent
browser from performing default action (i.e. launch download box) .

This approach will lead to the effective execution of inline python
code simulating on click handling . It will not be an intrinsic event
definition , though , but I'm hoping we can

1. work it out any time soon
2. find a feasible alternative approach

for the moment , please see

https://bitbucket.org/olemis/brython/issue/181/simulate-intrinsic-events-powered-by
https://bitbucket.org/olemis/brython-mq/src/t181_py_events/t181/t181_r6ea26044ddae_uri_data.diff?at=t181_py_events

Pierre Quentel

unread,
Dec 28, 2013, 2:26:14 AM12/28/13
to bry...@googlegroups.com
This is not far from the definition of public vs private names in a module, and for this Python has a convention : the public names are those declared in __all__, or if __all__ is not defined, those that don't start with an underscore

Instead of a decorator, I suggest to adopt this convention for the functions that should be included in the Javascript global namespace



2013/12/27 Billy Earney <billy....@gmail.com>

Glenn Linderman

unread,
Dec 28, 2013, 2:42:14 AM12/28/13
to bry...@googlegroups.com
So when reusing __all__ for this purpose, when a brython script imports a module, will __all__ of that module's public names be exposed to javascript?

But that potential interaction, points out an insufficiency in the decorator idea too... you wouldn't want to edit module sources to add the decorator to those module methods that you want to expose to javascript, especially if it is a standard module. And different applications using the module might have different needs, and hence want to expose different names to javascript. Or must all of an imported modules names that want to be exposed to javascript also be imported into main, where they will (automatically or via __all__) be further exposed javascript?

So a list like __all__, with a default of those names not starting with an underscore, is probably good... together with a mechanism that can be used after importing a module, to specify which of its names should be exposed to javascript as well.

Pierre Quentel

unread,
Dec 28, 2013, 2:54:48 AM12/28/13
to bry...@googlegroups.com


Le samedi 28 décembre 2013 08:42:14 UTC+1, v+python a écrit :
So when reusing __all__ for this purpose, when a brython script imports a module, will __all__ of that module's public names be exposed to javascript?


No, the only names that would be exposed (ie added as attributes of the Javascript object "window") are the functions defined in the main module. The other types (strings, dictionaries, user-defined classes etc.) in the main module would not be exposed because there's not much you can do with them in Javascript, and none of the names in imported modules would be exposed either

Olemis Lang

unread,
Dec 28, 2013, 3:25:15 AM12/28/13
to bry...@googlegroups.com
On 12/28/13, Olemis Lang <ole...@gmail.com> wrote:
> On 12/27/13, Billy Earney <billy....@gmail.com> wrote:
[...]
>
> p.s. btw , I've started to sketch handling of data:text/python, URIs .
> The goal is to intercept all click events bubbling up to document body
> root element , detect the presence of href attribute and , if there's
> a match , execute python code (working up to this point ;) and prevent
> browser from performing default action (i.e. launch download box) .
>
> This approach will lead to the effective execution of inline python
> code simulating on click handling .

Few minutes after baking it's still warm !
:)

The patch seems to be ready now . For the technical details and
overview please see latest comments in issue #181 .

I've added test code in /site/gallery/ which basicly consists in a
clone of hello.html with minor modifications . The resulting web page
is small and therefore shown below

{{{#!html

<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Let Brython intercept intrinsic
events and data: URI with MIME type='text/python3'">
<meta name="keywords" content="Python,Brython">
<meta name="author" content="Olemis Lang">
<meta charset="iso-8859-1">
<script src="../../src/brython.js" type="text/javascript"></script>
</head>
<body onLoad="brython()">
<img src="../brython.png">
<script type="text/python">
from browser import doc
</script>
<p>Your name is : <input id="zone" type="text">
<a href="data:text/python,doc['message'].text = 'Hello %s !' %
doc['zone'].value">clic !</a>
<p id="message"></p>
</body>
</html>

}}}

Those interested in knowing a bit more please review the patch(es) in
MQ branch t181_py_events [2]_ . Nonetheless there's something weird .
It won't yield expected results if I remove inline script element
inserted in <body /> and also modify the anchor as follows

{{{#!html

<a href="data:text/python,from browser import doc;
doc['message'].text = 'Hello %s !' % doc['zone'].value">clic !</a>
}}}

Should I gather positive feedback on this solution I'll commit it
myself into the repository .

.. [1] https://bitbucket.org/olemis/brython/issue/181/simulate-intrinsic-events-powered-by

.. [2] https://bitbucket.org/olemis/brython-mq/src/t181_py_events/t181/?at=t181_py_events

Olemis Lang

unread,
Dec 28, 2013, 3:51:30 AM12/28/13
to bry...@googlegroups.com
On 12/28/13, Pierre Quentel <pierre....@gmail.com> wrote:
>
>
> Le samedi 28 décembre 2013 08:42:14 UTC+1, v+python a écrit :
>>
>> So when reusing __all__ for this purpose, when a brython script imports
>> a module, will __all__ of that module's public names be exposed to
>> javascript?
>>
>>
> No, the only names that would be exposed (ie added as attributes of the
> Javascript object "window") are the functions defined in the main module.
> The other types (strings, dictionaries, user-defined classes etc.) in the
> main module would not be exposed because there's not much you can do with
> them in Javascript, and none of the names in imported modules would be
> exposed either
>

I'm not really sure about this ... __all__ is not about public vs
private . It's more like a tricky aspect of import statements and the
underlying machinery .

Let's say users have three <script type="text/python" /> embedded in
my web page , each having __all__ bound to a list of var names . What
shall be done in that case ?

I think the decorator idea is very nice indeed because :

1. Libs have the chance to automatically expose python objects (e.g.
functions) after imports
* ... which should otherwise be exposed by hand ... in every page ... :-/
2. the same works in "__main__" module

>> But that potential interaction, points out an insufficiency in the
>> decorator idea too... you wouldn't want to edit module sources to add the
>> decorator to those module methods that you want to expose to javascript,

I do not get it . The very same nature of decorators implies that they
are functions so may be called anywhere with any number of arguments .
What stops users from executing in __main__ (i.e. inline <script />
code in target web page ;) `expose(mypackage.mymodule.myfunc)` ?

>> especially if it is a standard module.

provided that my previous comment is accurate , I can not see any difference .

[...]
>> . Or must all of an imported modules names that want to be
>> exposed to javascript also be imported into main, where they will
>> (automatically or via __all__) be further exposed javascript?

Obviously they have to be imported (module1 =imports=> module2
=imports=> ...) ... now ... into __main__ ... hmmm ... I do not think
I'd like doing so . This would be §3 in my list above ;)

>>
>> So a list like __all__, with a default of those names not starting with an
>>
>> underscore, is probably good...

I honestly do not like __main__.__all__ . It has tricky semantics and
might lead to embarrassing scenarios that might be even hard to debug
I'm thinking of e.g. server-side generation of web page contents for
modular web apps (e.g. containing reusable UI snipets like Bloodhound
widgets or Allura widgets or ... ) . It'd be complicated to deal with
__main__.__all__

>> together with a mechanism that can be used
>> after importing a module, to specify which of its names should be exposed
>> to javascript as well.
>>

afaics the decorator proposal satisfies this requirement , cmiiw

Glenn Linderman

unread,
Dec 28, 2013, 4:07:03 AM12/28/13
to bry...@googlegroups.com
On 12/28/2013 12:51 AM, Olemis Lang wrote:
But that potential interaction, points out an insufficiency in the
>> decorator idea too... you wouldn't want to edit module sources to add the
>> decorator to those module methods that you want to expose to javascript,
I do not get it . The very same nature of decorators implies that they
are functions so may be called anywhere with any number of arguments .
What stops users from executing in __main__ (i.e. inline <script />
code in target web page ;) `expose(mypackage.mymodule.myfunc)` ?


Apologies. I forgot decorators could be invoked that way.

Billy Earney

unread,
Dec 28, 2013, 9:29:18 AM12/28/13
to bry...@googlegroups.com
Thanks for all the comments/suggestions.  IMO, decorators is still the best way to implement this.   This is similar to how cherrypy exposes elements:  http://cherrypy.readthedocs.org/en/latest/tutorial/exposing.html   This seems to work well.

Billy



--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Pinault Nicolas

unread,
Dec 28, 2013, 10:01:34 AM12/28/13
to bry...@googlegroups.com
Le 28/12/2013 15:29, Billy Earney a écrit :
Thanks for all the comments/suggestions.  IMO, decorators is still the best way to implement this.   This is similar to how cherrypy exposes elements:  http://cherrypy.readthedocs.org/en/latest/tutorial/exposing.html   This seems to work well.

I think using decorators is a clever idea.

Nicolas
Billy



On Sat, Dec 28, 2013 at 3:07 AM, Glenn Linderman <v+py...@g.nevcal.com> wrote:
On 12/28/2013 12:51 AM, Olemis Lang wrote:
But that potential interaction, points out an insufficiency in the
>> decorator idea too... you wouldn't want to edit module sources to add the
>> decorator to those module methods that you want to expose to javascript,
I do not get it . The very same nature of decorators implies that they
are functions so may be called anywhere with any number of arguments .
What stops users from executing in __main__ (i.e. inline <script />
code in target web page ;) `expose(mypackage.mymodule.myfunc)` ?


Apologies. I forgot decorators could be invoked that way.
--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/brython/52BE94B7.6030705%40g.nevcal.com.

For more options, visit https://groups.google.com/groups/opt_out.

--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Olemis Lang

unread,
Dec 28, 2013, 10:25:43 AM12/28/13
to bry...@googlegroups.com
jftr , wrapping up ...

On 12/28/13, Olemis Lang <ole...@gmail.com> wrote:
> On 12/28/13, Pierre Quentel <pierre....@gmail.com> wrote:
>> Le samedi 28 décembre 2013 08:42:14 UTC+1, v+python a écrit :
>
[...]
>
> I think the decorator idea is very nice indeed because :
>
> 1. Libs have the chance to automatically expose python objects (e.g.
> functions) after imports
> * ... which should otherwise be exposed by hand ... in every page ...
> :-/
> 2. the same works in "__main__" module
>
>>> But that potential interaction, points out an insufficiency in the
>>> decorator idea too... you wouldn't want to edit module sources to add
>>> the
>>> decorator to those module methods that you want to expose to javascript,
>
[...]
> What stops users from executing in __main__ (i.e. inline <script />
> code in target web page ;) `expose(mypackage.mymodule.myfunc)` ?
>

... no matter how deep the import chain ...

3. they support exposing any python objects defined in any module ,

>>> . Or must all of an imported modules names that want to be
>>> exposed to javascript also be imported into main, where they will
>>> (automatically or via __all__) be further exposed javascript?
>
> Obviously they have to be imported (module1 =imports=> module2
> =imports=> ...) ... now ... into __main__ ... hmmm ... I do not think
> I'd like doing so . This would be §3 in my list above ;)
>

4. exporting decision can be explicitly made anywhere in code
deep inside the import chain
5. it is possible to export anonymous objects from nested contexts
e.g. closures
6. it is possible to dynamically export objects created anytime
after bryhon is loaded
* as opposite to __all__ which requires all names to be available
beforehand when executing python code in scripts embedded
in the web page .

>>>
>>> So a list like __all__, with a default of those names not starting with
>>> an
>>>
>>> underscore, is probably good...
>
> I honestly do not like __main__.__all__ . It has tricky semantics and
> might lead to embarrassing scenarios that might be even hard to debug
[...]

7. ... and all this implies that it fits seamlessly into server-side apps
based upon modular architectures e.g. defining stand-alone
isolated and independent server-side components rendering UI snippets
that might be reused all over across a web site or even embedded
elsewhere .

... considering this then I'm so inclined to vote in favor of decorators (fwiw)

Pierre Quentel

unread,
Dec 28, 2013, 3:29:42 PM12/28/13
to bry...@googlegroups.com

I am still not convinced by decorators

I don't understand the scenario where an imported module would expose a function. Suppose the decorator "expose" is implemented, and there is a module foo with this function (remember that all there is to expose is a callback function for a DOM event) :

@expose
def bar():
    print('ok')


with this Brython script

<script type="text/python3">
bar = 0
import foo
</script>

With the standard Python process, import foo executes the module foo. The decorator will expose the name "bar" to the global Javascript namespace, with the side effect that it will also be available in the Python script, overriding the value of bar in this script. Very confusing, isn't it ? and it's even worse if foo1 imports foo2 that imports foo3 where a name "bar" is exposed...

__all__ or the underscore convention actually deal with private vs public names. Quote from the Python Language Reference, 7.11 :

The public names defined by a module are determined by checking the module’s namespace for a variable named __all__; if defined, it must be a sequence of strings which are names defined or imported by that module. The names given in __all__ are all considered public and are required to exist. If __all__ is not defined, the set of public names includes all names found in the module’s namespace which do not begin with an underscore character ('_'). __all__ should contain the entire public API. It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module).

If we use __all__ or the underscore, it will only apply to the main module (the one that is inside a <script type="text/python3"> tag), not to the imported modules. If there are several main modules in a page, then all the names in __all__, or those that don't start with an underscore, will be exposed, I don't see a problem here

 

sepe...@gmail.com

unread,
Dec 28, 2013, 4:13:05 PM12/28/13
to bry...@googlegroups.com
To help others understand better, could you please give some example code showing how each part would be accessed in js-
1. python builtins
2. brython modules
3. brython environment

Like I said previously, I think the most important thing is naming consistency. An example of consistent naming-
__builtins__
__brython__
__brythonenv__

Also, on the topic of export decorator, I think it may be a good idea, but it seems not very relevant at this time. What I mean is, export doesn't seem to be a solution to the problem, but rather, a possible compliment to the solution.

The solution is to figure out the best way to clean global namespace, and after that problem is solved we can possibly use "export" to bring stuff back in.


--- Original Message ---

--
Regards,

Olemis - @olemislc

Featured article:

with this Brython script

 

-- You received this message because you are subscribed to the Google Groups "brython" group.To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.To post to this group, send email to bry...@googlegroups.com.To view this discussion on the web visit https://groups.google.com/d/msgid/brython/8278b79f-2f47-4a22-ae61-0b0e8c7c2b4f%40googlegroups.com.For more options, visit https://groups.google.com/groups/opt_out.

Olemis Lang

unread,
Dec 28, 2013, 11:57:37 PM12/28/13
to bry...@googlegroups.com
On 12/28/13, sepe...@gmail.com <sepe...@gmail.com> wrote:

Is this an option ? Let $brython be *like* the js mapping
corresponding to the global namespace of __main__ module then ...

> To help others understand better, could you please give some example code
> showing how each part would be accessed in js-
> 1. python builtins

$brython.__builtins__

> 2. brython modules

Provided that `import module` has been executed in inline <script
type="text/python" /> then

$brython.module

> 3. brython environment
>

# I'm guessing that by environment you mean global namespace , cmiiw
$brython.__dict__

[...]

Olemis Lang

unread,
Dec 29, 2013, 3:50:13 AM12/29/13
to bry...@googlegroups.com
On 12/28/13, Pierre Quentel <pierre....@gmail.com> wrote:
> Le samedi 28 décembre 2013 16:25:43 UTC+1, Olemis Lang a écrit :
>>
>> jftr , wrapping up ...
>>
>> On 12/28/13, Olemis Lang <ole...@gmail.com <javascript:>> wrote:
>> > On 12/28/13, Pierre Quentel <pierre....@gmail.com <javascript:>> wrote:
>> >
>> >> Le samedi 28 décembre 2013 08:42:14 UTC+1, v+python a écrit :
>> >
>> [...]
>> >
>> > I think the decorator idea is very nice indeed because :
>> >
[...]
>
> I am still not convinced by decorators
>
> I don't understand the scenario where an imported module would expose a
> function. Suppose the decorator "expose" is implemented, and there is a
> module foo with this function (remember that all there is to expose is a
> callback function for a DOM event) :
>
> @expose
> def bar():
> print('ok')
>
> with this Brython script
>
> <script type="text/python3">
> bar = 0
> import foo
> </script>
>
> With the standard Python process, import foo executes the module foo. The
> decorator will expose the name "bar" to the global Javascript namespace,
> with the side effect that it will also be available in the Python script,
> overriding the value of *bar* in this script. Very confusing, isn't it ?

Well , if we stick to the semantics , expose(bar) will be operating
upon the js namespace whereas bar = 0 is recorded in the global python
namespace . If they are meant to be different (... which is what this
thread is about ;) then it makes sense .

> and it's even worse if foo1 imports foo2 that imports foo3 where a name
> "bar" is exposed...
>

I see your point . So, you mean that things could become a bit messy
and out of control once a single name is overridden .

[...]

Olemis Lang

unread,
Dec 29, 2013, 3:53:42 AM12/29/13
to bry...@googlegroups.com
On 12/28/13, Pierre Quentel <pierre....@gmail.com> wrote:
> Le samedi 28 décembre 2013 16:25:43 UTC+1, Olemis Lang a écrit :
[...]
>> On 12/28/13, Olemis Lang <ole...@gmail.com <javascript:>> wrote:
>> > On 12/28/13, Pierre Quentel <pierre....@gmail.com <javascript:>> wrote:
>> >> Le samedi 28 décembre 2013 08:42:14 UTC+1, v+python a écrit :
>
[...]
>
> __all__ or the underscore convention actually deal with private vs public
> names. Quote from the Python Language Reference, 7.11 :
>
> *The public names defined by a module are determined by checking the
> module’s namespace for a variable named __all__;

IMO it's a tricky (interpretation | usage) of the English language .
The docs say «public names» . Considering this ...

{{{#!py module1.py

__all__ = ['a', 'b']

a,b,c = 1,2,3
}}}

What are a,b exactly ?

== 1. Attributes exported by module ? ==
No

{{{#!py

>>> import module1
>>> module1.c
3
}}}

== 2. The only module members that may be imported from elsewhere ? ==
No

{{{#!py

>>> from module1 import c
>>> c
3
}}}

== 3. Is the public API really 'defined' ?
No

{{{
>>> from module1 import *
>>> a
1
>>> b
2
>>> c
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'c' is not defined
>>> del a, b
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
>>> c
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'c' is not defined
>>> import sys
>>> sys.modules['module1'].__all__.append('c')
>>> from module1 import *
>>> a
1
>>> b
2
>>> c
3
}}}

<jftr>
So, what does «public» exactly mean ? Those are the names that will be
added in the current (global / local) namespace as a side effect of
executing the statement `from module1 import *` . Interpretation of
natural language is ambiguous sometimes. Nonetheless it is a fact that
the word «public» creates some confusion because

- in programming languages and modularization vocabularies
«public» is used as an (attribute, namespace, ...) access control
and visibility concept
* e.g. compare vs OSGi or other similar modularization technologies
- __all__ has no influence on module attribute access (see §1)
- __all__ does not prevent other names to be imported into
an external namespace (see §2)
- the «public» API is not closed (see §3) , it may be modified at run-time
but such modifications are *ONLY* expressed as a consequence of
an *EXTERNAL* module executing an import statement
(or equivalent e.g. __import__ ) .
- therefore __all__ is not even related to modularization but rather coupled
to the mechanics of the import statement and the fact that it will
override previous assignments and
* IOW , __all__ makes no sense at all if just a single variant of import
is removed from the language .
</jftr>

[...]
>
> If we use __all__ or the underscore, it will only apply to the main module
> (the one that is inside a <script type="text/python3"> tag), not to the
> imported modules. If there are several main modules in a page, then all the
>
> names in __all__, or those that don't start with an underscore, will be
> exposed, I don't see a problem here
>

In any case , let's formalize this approach a bit . Let's say that
there are (at least) two built-in components in brython :

1. the brython «kernel» (brython.js & co.)
2. __main__ module(s) for each inline <script type="text/python"/> tag

... and let's assume that brython bootstrap process on page load
consists in the kernel executing the equivalent of `from __main__
import *` statement, hence values defined in __main__.__all__ will
override definitions in the kernel's namespace which we can claim to
be the external javascript namespace .

That being said , yes , this is sound and makes sense .

Nonetheless , what about if an app (say SPA [1]_ ) while entering
different states dynamically generates in the client-side new py
objects that have to be exposed in js namespace afterwards for further
processing (e.g. inside event handlers) ? By *ONLY* relying upon
__all__ there's no hope because it *ONLY* plays a role at import time
. So, we need a mechanism so that the Brython code will be able to
modify the javascript namespace.

In order to be consistent with the previous (formal) interpretation of
the bootstrap process , and considering all other comments above, in
order to expose the new values .

Wrapping up , your proposal (the way I see it) may be formalized by
introducing a virtual module (that I'll call __kernel__ below but of
course you might find a better name for it (__noyau__ ? :P) with the
following characteristics :

- Brython Axiom #1 : __kernel__ module is assumed to always be there
- Brython Axiom #2 : it's code is assumed to be `from __main__ import *`
(... this will never be actual code so this is a real "Brythonic Axiom")
- Brython Axiom #3 : the namespace of __kernel__ module consists in
the external namespace of the environment hosting brython e.g. the
browser's javascript namespace .
- Brython Axiom #4 : the bootstrap process semantically consists in
importing the __kernel__ module . This is the source of all the subsequent
brython bigban-ish experience :)
- Brython Axiom #5 : importing __main__ module consists in finding all
<script type="text/python[3]" /> elements defined in a web page; for each
such instance parse its code, and execute the resulting js code by
applying the corresponding side effects upon a regular dictionary
(i.e. __main__.__dict__)


Corolaries :

- Pierre's theorem : All the names declared in __all__ variable defined in
inline <script type="text/brython" /> tags will overwrite variables in
javascript namespace (Axiom #3 + from ... import * semantics )
- Olemis' theorem : Native js values assigned to js variables will be
accessible (and transformed into valid Python objects when necessary)
by reading __kernel__'s attributes
e.g. py_var_name = __builtins__.__kernel__.js_var_name ; otoh it will
be possible to assign values to js variables in a similar way
__builtins__.__kernel__.js_var_name = py_var_name
- Billy's conjecture : It'd be possible to implement `expose` decorator e.g.
the (javascript function) equivalent to

{{{#!py

def expose(f):
# TODO: Deal with other sophistcated cases , etc ...
# FIXME: `__builtins__.__kernel__` vs `import __kernel__` vs `__kernel__`
setattr(__builtins__.__kernel__, f.func_name, f)
return f
}}}

- <add your own> ;)

.. [1] http://en.wikipedia.org/wiki/Single_page_application

[...]

Pinault Nicolas

unread,
Dec 29, 2013, 5:43:03 AM12/29/13
to bry...@googlegroups.com
...
If we use __all__ or the underscore, it will only apply to the main module (the one that is inside a <script type="text/python3"> tag), not to the imported modules. If there are several main modules in a page, then all the names in __all__, or those that don't start with an underscore, will be exposed, I don't see a problem here

�
I'm currently translating a js library to Brython.
There is an object which adds elements to the DOM an binds events to these elements.
The "raw" translation (which is working) of the function to bind events is the following :

��� def addEvent(self, eventName, callback):
������� """ Adds a listener callback to a DOM element which is fired on a specified
����������� event.� Callback is sent the event object and the element that triggered the event
������� """
������� def listener(event) :
����������� event = event or window.event
����������� target = event.target or event.srcElement
����������� block = callback(event, target) #callback.apply(elem, [event, target]);
����������� if block == False :
��������������� if event.preventDefault :
������������������� event.preventDefault()
��������������� else :
������������������� event.returnValue = false;
������������������� event.cancelBubble = true;
����������� return block;

������� self.container.bind(eventName, listener)
������� return listener

Each time addEvent() is called, a new listener() function is created.
With a decorator, I can easily expose the listener() function to js.
How do I do this with __all__ ?

Nicolas
--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Billy Earney

unread,
Dec 29, 2013, 8:40:36 AM12/29/13
to bry...@googlegroups.com





With the standard Python process, import foo executes the module foo. The decorator will expose the name "bar" to the global Javascript namespace, with the side effect that it will also be available in the Python script, overriding the value of bar in this script. Very confusing, isn't it ? and it's even worse if foo1 imports foo2 that imports foo3 where a name "bar" is exposed...

Why should exposing the name "bar" to the global javascript namespace, override the value of bar in the python script?   I see them as two different variables/functions in different namespaces.

Billy

sepe...@gmail.com

unread,
Dec 29, 2013, 4:29:26 PM12/29/13
to bry...@googlegroups.com
I can see Billy's point here, but from my perspective, this dialog appears to be going in multiple directions at once.


To be clear about the problem-
We need to clean the global namespace of JS. To do this, we need to put the currently global variables into some global objects.

Does anyone disagree with this??? Reread again. We need to be clear on exactly what the problem is right now.

An "export" decorator may be a great idea, but it can be implemented after JS namespace is cleaned. Talk about "export" decorator at this time seems secondary and possibly distracting from the problem at hand.

I think the thing to discuss is:
1. How many new JS global variables are going to be needed
2. What will each of them contain
3. And what will they be named


If anyone thinks I'm mistaken here, please correct me. Hopefully, this can help the discussion move forward.

Glenn Linderman

unread,
Dec 29, 2013, 5:03:33 PM12/29/13
to bry...@googlegroups.com
On 12/29/2013 1:29 PM, sepe...@gmail.com wrote:
Talk about "export" decorator at this time seems secondary and possibly distracting from the problem at hand.

Let's posit that all the brython symbols are moved to a small collection of global objects (one to three have been mentioned).

Now how do you write HTML event code in js to access those objects?  You can't, easily, you have to mention the object name, which causes clutter in the event code, and breaks all existing event code.

Solving both problems at the same time is therefore appropriate, so that event code doesn't have to be rewritten twice.

Kiko

unread,
Dec 29, 2013, 5:23:33 PM12/29/13
to bry...@googlegroups.com

I can see Billy's point here, but from my perspective, this dialog appears to be going in multiple directions at once.


To be clear about the problem-
We need to clean the global namespace of JS. To do this, we need to put the currently global variables into some global objects.

Does anyone disagree with this??? Reread again. We need to be clear on exactly what the problem is right now.

An "export" decorator may be a great idea, but it can be implemented after JS namespace is cleaned. Talk about "export" decorator at this time seems secondary and possibly distracting from the problem at hand.

I think the thing to discuss is:
1. How many new JS global variables are going to be needed
2. What will each of them contain
3. And what will they be named


If anyone thinks I'm mistaken here, please correct me. Hopefully, this can help the discussion move forward.

+1 to retarget the topic of this thread.

In general I agree with Pierre.

-I would clean the global JS namespace and put all the brython stuff in a global object (if possible).
The python modules and scripts made out of Brython should be responsability of the developer of these modules/scripts.

A global object called $py or something similar would be fine.

sepe...@gmail.com

unread,
Dec 29, 2013, 6:09:20 PM12/29/13
to bry...@googlegroups.com
Ok, the solution to this problem will break existing code. I agree that's an excellent point. The thing is, an "export" decorator doesn't solve the problem of broken code, it simply moves the breakage from the JS code to the PY code.

For example- Without "export", we have to fix things by editing the JS code. With "export", we can fix things by editing the PY code.

So either way, code will be broken. Adding "export" decorator doesn't fix the breakage that will occur. So I still contend that "export" is something to think about after we solve the global namespace problem.

It may be possible to mitigate breakage for a limited time by keeping everything in global namespace, but I would avoid keeping things that way for a prolonged period of time. It could lead to difficult to trace errors.


--- Original Message ---

From: "Glenn Linderman" <v+py...@g.nevcal.com>
Sent: December 29, 2013 5:03 PM
To: bry...@googlegroups.com
Subject: Re: Global variables and namespace

On 12/29/2013 1:29 PM, sepe...@gmail.com wrote:

Talk about "export" decorator at this time seems secondary and possibly distracting from the problem at hand.

Billy Earney

unread,
Dec 29, 2013, 6:09:31 PM12/29/13
to bry...@googlegroups.com
+1 to retarget the topic of this thread.

+1 $py

+ 1 clean global JS namespace.

Billy


--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Glenn Linderman

unread,
Dec 29, 2013, 8:52:16 PM12/29/13
to bry...@googlegroups.com
On 12/29/2013 3:09 PM, sepe...@gmail.com wrote:
Ok, the solution to this problem will break existing code. I agree that's an excellent point. The thing is, an "export" decorator doesn't solve the problem of broken code, it simply moves the breakage from the JS code to the PY code.

For example- Without "export", we have to fix things by editing the JS code. With "export", we can fix things by editing the PY code.

So either way, code will be broken. 

Good point. The JS code, however, is likely to be scattered through the HTML, whereas the PY code is likely to be a nice chunk in one spot. In other words, not all breakage is as severe.

Pierre's proposed inclusion of __all__ symbols, or all non-_ symbols actually does provide a path that avoids breakage, because most function symbols would be non-_ symbols, and until __all__ is introduced to the code to limit the symbols that are placed in the JS global name space, all such symbols would be.


Adding "export" decorator doesn't fix the breakage that will occur. So I still contend that "export" is something to think about after we solve the global namespace problem.

It may be possible to mitigate breakage for a limited time by keeping everything in global namespace, but I would avoid keeping things that way for a prolonged period of time. It could lead to difficult to trace errors.

If there are difficult to trace errors that result from JS global name space pollution (and I agree there could be), then Pierre's solution doesn't fully eliminate that, until and unless code is updated to actually use __all__.

Of course, there could be a transition period, after which __all__ (or @expose, or both) would be required to be used to cause symbols to be placed in the JS global name space.

In other words, to make a solution that effectively cleans the JS global name space will require breakage of something, at some point in time. It would be nice if there were not multiple steps of breakage.

The proposed __all__ doesn't seem to be a complete solution, in terms of solving the problem for dynamically created symbols, or for symbols deep in a library.

The @expose seems to be a complete solution for any symbol.

Have there been other types of solutions proposed? If so, I missed them.

Either solution could be implemented with a migration path... the current symbol behavior can be kept, the new solution implemented (syntax-wise, at least, but perhaps as a noop), and released. Then people can migrate as best they can (but they might miss a symbol they need, but they can do as good a job of preparing as they wish), and then the current symbol behavior can be turned off... it is then that "breakage" will happen... if the migration steps were not completely completed (i.e. some symbols were missed).

Pierre Quentel

unread,
Dec 30, 2013, 3:11:17 AM12/30/13
to bry...@googlegroups.com

After reading all your messages - thanks a lot for that - I finally agree that a function to explicitely expose the functions that can be used from Javascript code is the way to go

I have implemented it as the function "expose" in module javascript (half a line !) and adapted the code of a few pages ; not so many in fact since many demos declare the bindings inside Brython code. The documentation pages have been updated

There is still some work to finish cleaning up the namespace used by Brython but I think most of it is done

Could you do some testing with the latest version on Bitbucket ? if there is no blocking issue I will publish it as version 1.5

- Pierre

Billy Earney

unread,
Dec 30, 2013, 12:31:17 PM12/30/13
to bry...@googlegroups.com
Pierre,

I'll look at the current revision later today (in the next 4 or 5 hours, after I get off work) and I'll let you know if I see any show stoppers.

Great Work!

Billy


--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

sepe...@gmail.com

unread,
Dec 30, 2013, 9:16:39 PM12/30/13
to bry...@googlegroups.com
Pierre, you are ultimately in charge, but it might be best to get a little more democratic input on this? The reason I bring this up is because there are a lot of factors to making a change like this.

Some of the factors that concern me:
1. What are the merits of using an expose decorator vs global variable reference? I do not know if switching to use "expose" is the best solution, but I have no compelling argument either way. How does everyone else feel- Anyone prefer using global js variable reference? If so, why?

2. Perhaps we could imagine a better decorator name than "expose"? Anyone have suggestions?

3. What will we call the new global js variable that encapsulates Brython code ($py, __builtins__)? Any other suggestions?


Obviously, I think a very important factor is naming consistency. What are the names of other global variables that Brython already creates in js?


I'm in ill health right now, so hHopefully that all makes sense,

Billy Earney

unread,
Dec 30, 2013, 10:07:55 PM12/30/13
to bry...@googlegroups.com
Pierre does about 95% of the work, so I'm not sure if a democratic model is the best way to go, but I don't think a dictatorship is healthy either (to be clear, I'm not saying Pierre is a dictator)..  just my 2 cents...

I like expose.  that is what cherrypy uses, its short (only 6 chars), and seems somewhat descriptive to me.   I don't care what the name of the global variable that encapsulates brython code is.  __BRYTHON__ is okay with me.

When I referred to py or $py, I was talking about how to access python code from javascript events if we didn't use decorators, but since we decided on using a decorator to "expose" functions/variables to javascript, using py or $py is irrelevant, IMO.  I wonder if we want to allow more than one way to access a python object from Javascript?  For those not wanting to use decorators, do we want to provide a function named $py that people could call from javascript to access a brython version instead of having to do something like __BRYTHON__.echo()?  so it would be written $py("echo()").

I plan on using decorators to expose functions, but others may not like that style.

Billy
 


--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

sepe...@gmail.com

unread,
Dec 30, 2013, 10:54:10 PM12/30/13
to bry...@googlegroups.com
Hey Billy, please don't think I dislike the name "expose". I just was looking to see perhaps there are other ideas and garner feedback. I personally think "expose" is a good name, and now that I know it shares similar usage in other projects, I think that lends to its credibility.

Also, you mention allowing more than one way to access python attributes from Javascript. It seems impossible (impractical) to prevent accessing the global js object. If the final conclusion is to go with a decorator, then I agree, it would be preferable that the global js object should be- easily accessible (if needed for some reason).

But at the same time, if choosing to use decorator, I will be 100% on board with promoting that preferred way of coding. It is Pythonic for there to be 1 right way to do a thing.


Pierre Quentel

unread,
Dec 31, 2013, 6:04:15 AM12/31/13
to bry...@googlegroups.com
Sepero,

The topic had been discussed long enough (2 weeks, more than 50 posts) and I felt that most arguments had been presented, so I thought it was time to make a decision. The decorator option seemed to be prefered by most contributors, with good reasons that I didn't think useful to rephrase. Maybe this decision is not good ; if we discover unexpected issues, we will have to reconsider it

Thinking of it once again, I realise that another option - exposing a global object to the Javascript namespace - already exists. Let me explain

The objects created in a Brython module are attributes of the objects $globals or $locals, this is necessary to make the built-in globals() and locals() functions work

In the latest revisions, $globals is no more set in the global JS namespace. But for a module X, __BRYTHON__.scope[X].__dict__ is set to $globals. This is necessary for imports : when a module is imported, its code is run in an anonymous function which returns it $globals, and the names defined in it must be accessible from the importing module

This means that from a Javascript program, you can access any object Y in any module X as

__BRYTHON__.scope[X].__dict__[Y]

For instance, if you don't want to use a decorator, you can access the function echo() in the main module by

<button onclick="__BRYTHON__.scope['__main__'].__dict__.echo()">


The syntax is ugly (it was not intended to be used in Javascript programs) but it wouldn't be difficult to set a global variable ($py or any other name) to __BRYTHON__.scope['__main__'].__dict__ so that the tag can be written

<button onclick="$py.echo()">

As for naming consistency :
- __builtins__ for the dictionary holding Python builtins is mandatory because it's how it's called in Python
- Brython also exposes the function brython(), used on page load
- __BRYTHON__ is only used internally and in the standard library, it's not expected to be used in Brython programs ; having a different look (all uppercase) helps to indicates that it has a different use
 

sepe...@gmail.com

unread,
Dec 31, 2013, 8:35:05 AM12/31/13
to bry...@googlegroups.com
Hi Pierre, you've explained a lot in your last message. I can see clearly now with your decision to go with the "expose" decorator. With this new knowledge, I agree with the decision to use decorator. It looks like a good course of action.

If deciding on using "export" decorator, I would say that a $py variable is not necessary. A syntax like __BRYTHON__.scope[X].__dict__[Y] appears sufficient, without needing to create any other variables. It is not brief, but it is easy to understand. It is not complex, and it is also very explicit, both are virtues of Python.

Lastly, I want to try to elaborate on naming, and why I believe it matters a lot. When a 3rd party developer works with software they have to know their naming "safe zone". Different js libraries have different conventions. A developer cannot be bothered to remember every variable name every library uses. If I find out Brython uses both "__builtins__" and "__BRYTHON__", what I see is that they are possibly using everything "__xxxx__" and "__XXXX__", and I am limiting the variable names I create based on that information. Also as a 3rd party dev, if I ever by chance need to use/access these Brython variable names, I'm more inclined to make typo errors. Making then differently up/low-cased causes unnecessary confusion for the 3rd party dev. It does not help. So basically, this is a plea to not cause the 3rd party dev to have to think more than necessary. Choose one single naming convention (whether __xxxx__ or __XXXX__ or $xxxx), and try to stick to using only that convention for everything. It is for similar reasons that Python 3 has changed all stdlibs to lower case. Make things brain dead simple for those who use your code.

You say "__BRYTHON__ is only used internally and in the standard library, it's not expected to be used in Brython programs". I have to say that 3rd party devs will not care about this. If on rare chance they ever need to dig into a Brython global variable, the naming difference of "__builtins__" and "__brython__" will be enough, and less likely to lead to typos.


My apologies for such a long message. :)

Glenn Linderman

unread,
Dec 27, 2013, 2:29:54 PM12/27/13
to bry...@googlegroups.com
I haven't a clue about the appropriate javascript implementation, but I think the ability to expose only particular symbols (maybe restricted to functions, if that is all a reasonable implementation would allow) to the javascript "global" name space is an excellent idea.

I liked Pierre's idea when I read it, but then after reading Billy's idea, I wonder if @expose (however it might eventually get spelled) should be required for exposing a symbol to javascript... in fact, that even Brython functions defined at module level in the __main__ program would not be exposed by default.

Not all existing Python code is particularly well encapsulated and dragging it into the browser, perhaps 10-20 functions when one is needed, and the others are helpers, could inadvertently pollute the namespace.

Requiring @expose for those symbols needed by javascript would minimize the pollution. Of course, some might overuse @expose, but they are polluting their own namespace.

I would spell @expose as @javascript or @js, perhaps.  Or @browser.

Handily, this is a syntax that can be implemented in pure python as a noop to allow sharing of source code between CPython and brython where that might be useful.


On 12/27/2013 7:07 AM, Billy Earney wrote:
Pierre,

I think you are making a good call here.

Could we expose certain functions to a javascript global by creating a special decorator?

For example:

@expose
def echo(event):
     ## do neat stuff here..
    
where expose is defined in javascript as something like

function expose(f) {
    eval(f.__name__ + "= f")
}

// the expose function above probably isn't correct, but what it should do is take a function defined in brython and make it a global in javascript.  

What do others think?

Billy





On Fri, Dec 27, 2013 at 12:50 AM, Pierre Quentel <pierre....@gmail.com> wrote:
The more I think of it, the more I am convinced that the solution is not to expose Brython namespace to Javascript programs at all, except for Brython functions defined at module level in the __main__ program, so that they can react to calls in event attributes (onclick="foo()")

The reason is that in most cases, it is not possible to create Javascript objects that can be used to interact with the matching Brython variable (at least with a simple syntax). For instance, suppose you have defined a dictionary in Brython with

br_dict = {'a':1}

and you want to add another item from a Javascript program. For this, in the Javascript program, you would like something like

js_dict = $py(br_dict) // or $py.br_dict, or $py("br_dict")...
js_dict['b']=2


Well, there is no such object, because in order to set an item to br_dict, the Javascript code is (once the builtin name __builtins__ will be introduced)

__builtins__.getattr(br_dict,'__setitem__')('b',2)

Providing a conversion function would work in some limited cases, but fail in most cases without any useful error message, or require a very complicated syntax. It's better to give a simple message : Brython variables must be dealt with only in Brython programs

If the only remaining use case is function calls inside event attributes, then since Brython functions are Javascript functions, they can be exposed in the global Javascript namespace. The risk of conflict with Javascript names exists and must be documented, but is not high enough to introduce a specific syntax

- Pierre

Glenn Linderman

unread,
Dec 31, 2013, 4:25:05 PM12/31/13
to bry...@googlegroups.com
On 12/31/2013 3:04 AM, Pierre Quentel wrote:
As for naming consistency :
- __builtins__ for the dictionary holding Python builtins is mandatory because it's how it's called in Python

Brython could change references to __builtins__ to __BRYTHON__.__builtins__  to avoid exposing that name, perhaps?  This is not a suggestion, just a question, but if the goal is to absolutely minimize the global names exposed by Brython to Javascript, it might have merit, if possible to do.


- Brython also exposes the function brython(), used on page load

- __BRYTHON__ is only used internally and in the standard library, it's not expected to be used in Brython programs ; having a different look (all uppercase) helps to indicates that it has a different use

[out of order quote]


The syntax is ugly (it was not intended to be used in Javascript programs) but it wouldn't be difficult to set a global variable ($py or any other name) to __BRYTHON__.scope['__main__'].__dict__ so that the tag can be written

<button onclick="$py.echo()">

As written, this would only work for exposing symbols in __main__, not other symbols that are deeper. Of course, symbols to be exposed could be cloned to main using Python syntax. One could speculate that a special module named "__expose__" could be created, and used by @expose or with other python syntax to populate the expose module with names that should be exposed. Then $py could be set to __BRYTHON__.scope[['__expose__'].__dict__

The special module would be created and populated by brython.js, and the first entry in it would be brython(), so that the following would work: <body onload="$py.brython()">

I think this could get things down to  2 symbols:  __BRYTHON__ and $py

either

@expose
def foo():
    pass

or without the decorator, an assignment such as 

__expose__.foo = foo

could be used to add additional names to the list of items readily accessible from javascript, via $py. syntax.

In any case, I think we have the ideas in place, to reduce name pollution of javascript to small number; I'm not particularly interested in how they are spelled, as long as the number is small. I like the idea of using $py (or something) as a short way to access lots of python names without polluting the javascript name space, even with the names needed for invoking various functions as HTML event handlers.

Having a way that names can be put directly in the javascript namespace, for people that really want them there, in spite of the potential for conflict, would also be good, but having a $py prefix seems better for most cases.

Billy Earney

unread,
Dec 31, 2013, 5:45:34 PM12/31/13
to bry...@googlegroups.com
Glenn,

+1   I agree.  I think using $py to access a python function from javascript is a good idea.  That way, there won't be any confusion when there is a javascript function "echo" and a python function called "echo".

<button onclick="echo" />  and <button onclick="$py.echo" />  refer to two different functions.  The first a javascript function, and the second a python function.   When using a decorator alone,  what does <button onclick="echo" />  really mean?

Of course the name could be something different from $py, but I believe it should be short and easy to type :)

Billy
 


--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

sepe...@gmail.com

unread,
Dec 31, 2013, 7:44:36 PM12/31/13
to bry...@googlegroups.com
So Billy are you saying that this would be how it could work?

@expose
def echo():

Gives us this function call $py.echo()

I would give that a +1

If it wasn't to troublesome for Pierre and it doesn't risk internal conflict, then I would also be for putting __builtins__ inside __BRYTHON__. +1


I would also give support to @browser if the Brython import module wasn't already named "browser". For that reason, I have to give @browser a -1

In the end, I still give the name @expose +1

--- Original Message ---

From: "Billy Earney" <billy....@gmail.com>
Sent: December 31, 2013 5:45 PM
To: bry...@googlegroups.com
Subject: Re: Global variables and namespace


Glenn,

Billy
 

-- You received this message because you are subscribed to the Google Groups "brython" group.To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.To post to this group, send email to bry...@googlegroups.com.To view this discussion on the web visit https://groups.google.com/d/msgid/brython/CAB1ii-cLc8PzbsnZP5SCudUH6nnAbb83Ns3jPvtrwK9kcxrfQw%40mail.gmail.com.For more options, visit https://groups.google.com/groups/opt_out.

Billy Earney

unread,
Dec 31, 2013, 8:27:05 PM12/31/13
to bry...@googlegroups.com
+1

>So Billy are you saying that this would be how it could work?
>
>@expose
>def echo():
>
>Gives us this function call $py.echo()


Pierre Quentel

unread,
Jan 1, 2014, 5:19:28 AM1/1/14
to bry...@googlegroups.com


Le mardi 31 décembre 2013 23:45:34 UTC+1, Billy Earney a écrit :
Glenn,

+1   I agree.  I think using $py to access a python function from javascript is a good idea.  That way, there won't be any confusion when there is a javascript function "echo" and a python function called "echo".

<button onclick="echo" />  and <button onclick="$py.echo" />  refer to two different functions.  The first a javascript function, and the second a python function.   When using a decorator alone,  what does <button onclick="echo" />  really mean?

I am not in favour of forcing the use of a prefix for Python functions. Brython is here to show that Python can be an alternative to Javascript for web browser development, and the DOM is language-independant. Having to write "$py.echo" for Python functions (even when no Javascript library is loaded in the page), and just "echo" for Javascript functions, gives the impression that Javascript is the default language
 

Pierre Quentel

unread,
Jan 1, 2014, 5:23:04 AM1/1/14
to bry...@googlegroups.com


Le mercredi 1 janvier 2014 01:44:36 UTC+1, Sepero a écrit :
So Billy are you saying that this would be how it could work?

@expose
def echo():

Gives us this function call $py.echo()

I would give that a +1

If it wasn't to troublesome for Pierre and it doesn't risk internal conflict, then I would also be for putting __builtins__ inside __BRYTHON__. +1

+1 also (I will alias it as __BRYTHON__.b internally, to reduce the additional size of the Brython scripts...)

sepe...@gmail.com

unread,
Jan 1, 2014, 5:30:24 AM1/1/14
to bry...@googlegroups.com
I agree that Pierre makes a good point here. I think the goal is to allow people to write code in python for everything. Making it equivalent to js, and not secondary to js.


--- Original Message ---

From: "Pierre Quentel" <pierre....@gmail.com>
Sent: January 1, 2014 5:19 AM
To: bry...@googlegroups.com
Subject: Re: Global variables and namespace

Le mardi 31 décembre 2013 23:45:34 UTC+1, Billy Earney a écrit :

Glenn,

+1   I agree.  I think using $py to access a python function from javascript is a good idea.  That way, there won't be any confusion when there is a javascript function "echo" and a python function called "echo".


<button onclick="echo" />  and <button onclick="$py.echo" />  refer to two different functions.  The first a javascript function, and the second a python function.   When using a decorator alone,  what does <button onclick="echo" />  really mean?

I am not in favour of forcing the use of a prefix for Python functions. Brython is here to show that Python can be an alternative to Javascript for web browser development, and the DOM is language-independant. Having to write "$py.echo" for Python functions (even when no Javascript library is loaded in the page), and just "echo" for Javascript functions, gives the impression that Javascript is the default language
 

Of course the name could be something different from $py, but I believe it should be short and easy to type :)

Billy
 


-- You received this message because you are subscribed to the Google Groups "brython" group.To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.To post to this group, send email to bry...@googlegroups.com.To view this discussion on the web visit https://groups.google.com/d/msgid/brython/4d755bc1-401f-463e-8566-cf7f56c2a14a%40googlegroups.com.For more options, visit https://groups.google.com/groups/opt_out.

Glenn Linderman

unread,
Jan 1, 2014, 6:00:34 AM1/1/14
to bry...@googlegroups.com
On 1/1/2014 2:19 AM, Pierre Quentel wrote:
<button onclick="echo" />  and <button onclick="$py.echo" />  refer to two different functions.  The first a javascript function, and the second a python function.   When using a decorator alone,  what does <button onclick="echo" />  really mean?

I am not in favour of forcing the use of a prefix for Python functions. Brython is here to show that Python can be an alternative to Javascript for web browser development, and the DOM is language-independant. Having to write "$py.echo" for Python functions (even when no Javascript library is loaded in the page), and just "echo" for Javascript functions, gives the impression that Javascript is the default language

Javascript _is_ the default language, though, because of the following reality:

<meta http-equiv="Content-Script-Type" content="text/python">

doesn't work (or if it does, it isn't standard).


When python can be the default language, just define $py = __main__ and gradually remove the @expose operators, and appropriately qualify other references to their defined scope using the python syntax.

This points out a need to spell $py without using a $ though.  _py ?

And you wouldn't have to force a prefix: @expose could take an optional parameter. The parameter could have 3 values: to place the symbol in __expose__, to place the symbol in the javascript global namespace, to do both. The default could be discussed at length. People that wish to keep the javascript global namespace as clean as possible would use __expose__ and _py.  People that want the convenience of not using _py., are willing to pollute the javascript global namespace and risk possible collisions, would be the other setting. Not sure if both is useful except maybe as a transition between one scheme and the other.

While using python for everything in the script is an ideal that I highly approve of, I can envision the need for using certain javascript libraries, and even javascript code snippets that are borrowed from javascript coding sites, without needing to convert them to python. So I suspect the reality will be a mixture, and the mixture might well benefit from the ability to minimize the python symbols in the javascript namespace.

On the other hand, the number symbols required for use in event handlers is generally small, and users concerned with pollution or naming conflicts could simply prefix all their javascript global names with.... _py_ (or something application specific).

Olemis Lang

unread,
Jan 1, 2014, 11:46:31 AM1/1/14
to bry...@googlegroups.com
On 1/1/14, Glenn Linderman <v+py...@g.nevcal.com> wrote:
> On 1/1/2014 2:19 AM, Pierre Quentel wrote:
>>
>> <button onclick="echo" /> and <button onclick="$py.echo" />
>> refer to two different functions. The first a javascript function,
>> and the second a python function. When using a decorator alone,
>> what does <button onclick="echo" /> really mean?
>>
>>
>> I am not in favour of forcing the use of a prefix for Python
>> functions. Brython is here to show that Python can be an alternative
>> to Javascript for web browser development, and the DOM is
>> language-independant. Having to write "$py.echo" for Python functions
>> (even when no Javascript library is loaded in the page), and just
>> "echo" for Javascript functions, gives the impression that Javascript
>> is the default language
>
> Javascript _is_ the default language, though,

... obviously ... neither vbscript, (... nor tcl [1]_ ? what's the
supporting browser ? or is it just not real at all ? ) is even close
to js , it's a de-facto standard .

> because of the following
> reality:
>
> <meta http-equiv="Content-Script-Type" content="text/python">
>
> doesn't work (or if it does, it isn't standard).
>

This is (one of) the paths I'm following to work around (and obviously
hack) intrinsic events definitions .

>
> When python can be the default language, just define $py = __main__ and
> gradually remove the @expose operators, and appropriately qualify other
> references to their defined scope using the python syntax.
>
> This points out a need to spell $py without using a $ though. _py ?

I think you are making a good point here ...

[...]

.. [1] http://www.w3.org/TR/html401/interact/scripts.html

Billy Earney

unread,
Jan 2, 2014, 10:05:10 PM1/2/14
to bry...@googlegroups.com
Accessing and using javascript functions from Brython is one of Brython's strengths.  Yes, optimally, we would want to only use python for client side scripts, but in the near future, that will not be a reality.  Hopefully, one day, no one will want to use javascript, but will prefer languages such as python.  So until then, the languages will need to live side by side.

Billy 


--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

sepe...@gmail.com

unread,
Jan 3, 2014, 3:27:57 AM1/3/14
to bry...@googlegroups.com
I think I agree with Pierre, that the vision of Brython is to be a 100% alternative to js.

For that reason it makes sense to me to avoid packing everything into a $py variable. To me that would give the appearance of making Brython a second class citizen to js.

With an export decorator, the dev can choose to place 1 or 100 functions into the js namespace. So if js namespace becomes flooded, it is their own fault.

Though, there is still a conflict for me.

I think the export decorator is a good solution for placing functions into js global namespace.
BUT, an export collision can happen if exporting the function "echo()" from 2 separate python namespaces.

# in __main__
from brython import export
import mymodule
@export
def echo():
print("This is __main__")

# in mymodule
from brython import export
@export
def echo():
print("This is mymodule")


A possible solution might be to have the export decorator restricted to only working with functions in __main__ namespace? Or when names collide, report a warning and give precedence to __main__ functions?


Js is a single namespace language, while python is multi-namespace language, and that makes the conversion a bit tricky. For now, I do not know what is the best path. I tend to lean in favor of restricting export decorator to the __main__ namespace. I wonder what everyone else thinks?

Billy Earney

unread,
Jan 3, 2014, 7:44:11 AM1/3/14
to bry...@googlegroups.com
how about functions exposed from __main__ are put in the "global" namespace directly, and the echo from mymodule would be accessed from javascript via  mymodule.echo?

<button click="mymodule.echo"/>

Billy


--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

sepe...@gmail.com

unread,
Jan 3, 2014, 9:57:17 AM1/3/14
to bry...@googlegroups.com
+1

Glenn Linderman

unread,
Jan 3, 2014, 3:50:25 AM1/3/14
to bry...@googlegroups.com
On 1/3/2014 12:27 AM, sepe...@gmail.com wrote:
I think I agree with Pierre, that the vision of Brython is to be a 100% alternative to js.

Yes, I agree that is the best vision. But it is not achievable with current standards unless the browser includes the brython interpreter/translator, so that the <body onload="brython()"> become unnecessary, so the other event handlers can be written in brython, and the brython interpreter/translator notices the default language is set to brython, and translates those event handlers appropriately.


For that reason it makes sense to me to avoid packing everything into a $py variable. To me that would give the appearance of making Brython a second class citizen to js.

While we want to keep the best vision in mind, we also need to deal with realities. The reality is that brython is, and will be, a second class citizen to js, just like every other non-js language in the browser (except for specific browsers and languages, perhaps).


With an export decorator, the dev can choose to place 1 or 100 functions into the js namespace. So if js namespace becomes flooded, it is their own fault.

This is true, but users of a module may not take time to learn what names a module @exposes. Hence, I recommend, that in general, modules not directly use @expose.


Though, there is still a conflict for me.

I think the export decorator is a good solution for placing functions into js global namespace.
BUT, an export collision can happen if exporting the function "echo()" from 2 separate python namespaces.

I would think that the use of the @export decorator should mostly be restricted to __main__, as a convention. In general, modules should be imported to be used by python code in __main__, rather than by js. __main__ should be mainly responsible for choosing what gets exported to js for use in event handler code. There may be a few modules written specifically to assist in writing event handler code, for which it may be convenient to include @expose in the module, but that should be a well-documented exception to the general usage convention.


A possible solution might be to have the export decorator restricted to only working with functions in __main__ namespace? Or when names collide, report a warning and give precedence to __main__ functions?

If modules use @expose, then what if names collide, and neither are from __main__? This starts to get confusing. And depending on interdependencies among modules, the order @expose references actually happen may not be the order that is seen in the import statements in __main__. Hence, my recommended usage convention above helps with this, so neither "first exposed name" nor "last exposed name" taking precedence will lead to an easily understandable rule.



Js is a single namespace language, while python is multi-namespace language, and that makes the conversion a bit tricky. For now, I do not know what is the best path. I tend to lean in favor of restricting export decorator to the __main__ namespace. I wonder what everyone else thinks?

As consenting adults, I think using the @export decorator in __main__ should be preferred, rather than using it in a module. But I see no reason whatsoever to restrict it to being used only with symbols from the __main__ namespace... just that the __main__ code should generally be the decision making module, so that you don't have to look too deep to discover what functions the js event handlers are actually calling.

sepe...@gmail.com

unread,
Jan 3, 2014, 11:33:13 AM1/3/14
to bry...@googlegroups.com
Billy, perhaps that brings us back to the beginning? Putting everything from
__main__ into js namespace. I've thought about this several hours now. Sadly,
the solution seems not very clean, because what happens if define functions
named "length" or "replace" or "search" (also javascript functions)? That's not
good.

But you might argue, the same could apply if trying to decorate python functions
of the same names. And I would say you are right!

So this makes me have to rethink things. While I agree with Pierre for Brython
to be equivalent to js, I can now see how builtin js functions/variables are a
barrier to Brython namespace. The js namespace is already polluted with many
names. For a happy newcomer to Brython (someone unfamiliar with js), this is a
nightmare waiting to happen. They will be confused and upset for why they cannot
decorate/expose their function named "window"...

In the end, the only way to truly have a clean namespace is to use something
like a variable named $py. This is a conclusion that I hate to admit.

I think the possibility of using a $py variable is worth discussing further.
> <mailto:brython%2Bunsu...@googlegroups.com>.
> To post to this group, send email to bry...@googlegroups.com
> <mailto:bry...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/brython/230017670.31215.1388737685265.JavaMail.seven%40ap03.prod.7sys.net.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "brython" group.
> To unsubscribe from this group and stop receiving emails from it, send an email
> to brython+u...@googlegroups.com.
> To post to this group, send email to bry...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/brython/CAB1ii-fR_%2BTuXU-BB4uC7LdPg6nU1Tr0-PCtue4_zKrDwsY72A%40mail.gmail.com.

Pinault Nicolas

unread,
Jan 3, 2014, 1:08:30 PM1/3/14
to bry...@googlegroups.com
Le 03/01/2014 09:27, sepe...@gmail.com a �crit :
Why not use a decorator with an argument giving the js name to expose to ?
def expose(js_name=None):
blabla


class A() :
@expose
def myfunc(self) :
...

class B() :
@expose("objB_myfunc")
def myfunc(self):
...

This will expose A.myfunc() as myfunc and B.myfunc() as objB_myfunc.

Nicolas

Glenn Linderman

unread,
Jan 3, 2014, 1:43:56 PM1/3/14
to bry...@googlegroups.com
On 1/3/2014 4:44 AM, Billy Earney wrote:
how about functions exposed from __main__ are put in the "global" namespace directly, and the echo from mymodule would be accessed from javascript via  mymodule.echo?

<button click="mymodule.echo"/>

Billy

After I shut the computer down last night, I was wondering about the feasibility of doing a hierarchical naming... that _py could be an object, and items that are @expose-d could populate the object with new methods that mirrored the hierarchy of the python names.

echo from __main__ could be   _py.echo  and echo from mymodule could be _py.mymodule.echo

Glenn Linderman

unread,
Jan 3, 2014, 1:54:39 PM1/3/14
to bry...@googlegroups.com
On 1/3/2014 8:33 AM, sepe...@gmail.com wrote:

I think the possibility of using a $py variable is worth discussing further.

Needs to be spelled as a legal python name, in anticipation of the day when brython _can_ be used in event handler code, so that simple event handlers such as

<a onclick="_py.foo()" ...>

are legal syntax in both js and brython, and would not need to be converted on a particular schedule when switching from

<meta http-equiv="Content-Script-Type" content="text/javascript">

to

Glenn Linderman

unread,
Jan 3, 2014, 2:09:21 PM1/3/14
to bry...@googlegroups.com
On 1/3/2014 10:08 AM, Pinault Nicolas wrote:
Why not use a decorator with an argument giving the js name to expose to ?
This is an intriguing option, although it still requires avoiding all the names in the existing js namespace (which I'm told can be quite cluttered), to avoid hard to debug issues.

A prefix such as _py means you only need to pick names that are not in the set of python names that are already exposed, which is a much simpler task.

On the other hand, even that doesn't really address the issue on exposing names from multiple modules, which an argument would allow, but Billy's proposal this morning of keeping the qualification would resolve exposing names from multiple python modules that would conflict if unqualified.

Your example


class B() :
    @expose("objB_myfunc")
    def myfunc(self):

shows a style which would likely be commonly adopted when doing renames, that of including the object, class, or module name in the rename. I tend to think Billy's solution of  B.myfunc(), or my variation  _py.B.myfunc() would be more clearly a hierarchy than is available with renaming to B_myfunc or _py.B_myfunc(), especially if extended to deeper hierarchical names.

On the other hand, if using the hierarchical names is not possible or extremely hard to implement, then this renaming idea would be a good alternative. I'm not a javascript expert, I only dabble in javascript, so don't presently have the knowledge to properly evaluate the alternatives from an implementation standpoint.

sepe...@gmail.com

unread,
Jan 3, 2014, 2:28:00 PM1/3/14
to bry...@googlegroups.com
I agree, good reason to prefer _py over $py
> --
> You received this message because you are subscribed to the Google Groups
> "brython" group.
> To unsubscribe from this group and stop receiving emails from it, send an email
> to brython+u...@googlegroups.com.
> To post to this group, send email to bry...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/brython/52C7076F.9000208%40g.nevcal.com.

Olemis Lang

unread,
Jan 3, 2014, 2:48:23 PM1/3/14
to bry...@googlegroups.com
I've stepped back for a while and see how discussion is running in
circles over and over .

On 1/3/14, Glenn Linderman <v+py...@g.nevcal.com> wrote:
> On 1/3/2014 12:27 AM, sepe...@gmail.com wrote:
>> I think I agree with Pierre, that the vision of Brython is to be a 100%
>> alternative to js.
>
> Yes, I agree that is the best vision. But it is not achievable with
> current standards unless the browser includes the brython
> interpreter/translator, so that the <body onload="brython()"> become
> unnecessary, so the other event handlers can be written in brython, and
> the brython interpreter/translator notices the default language is set
> to brython, and translates those event handlers appropriately.
>

Summarizing I mostly agree with Glenn and Pinault :

- expose decorator should have an optional arg for js ns name
* Zen of Py => better explicit than implicit
* especially for cases where a function in 3rd party lib
(beyond developer control) is meant to be exposed or when
py function name creates conflicts with global js name
* ... defaulting to the name of decorated function
- we really need *now* a variable or a common way to retrieve
brython objects exposed to js, e.g. _py
* Zen of Py => practicality beats purity
* Pierre's vision is correct
* I don't think I'm terribly wrong by saying that we all agree with Pierre
* ... but it's *not feasible* *now*
* I've recently discussed the subject of 'Content-Script-Type' with
some people @ Mozilla and the answer was something like :
"I am not very sure but, if possible, I'm sure it's a non-trivial task"
... further research is needed though .
- better _py than $py
* but considering (standardized but apparently far from
real though possible) forthcoming migration path using
Content-Script-Type maybe better to choose something else ?
* ... but fact is that global namespace after import looks like this

{{{#!py

$ python3
Python 3.1.2 (r312:79147, Dec 9 2011, 20:47:34)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> __main__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '__main__' is not defined
>>> globals()
{'__builtins__': <module 'builtins' (built-in)>, '__name__':
'__main__', '__doc__': None, '__package__': None}
>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError',
'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning',
'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError',
'ImportError', 'ImportWarning', 'IndentationError', 'IndexError',
'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError',
'NameError', 'None', 'NotImplemented', 'NotImplementedError',
'OSError', 'OverflowError', 'PendingDeprecationWarning',
'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StopIteration',
'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit',
'TabError', 'True', 'TypeError', 'UnboundLocalError',
'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError',
'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__',
'__debug__', '__doc__', '__import__', '__name__', '__package__',
'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes',
'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits',
'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec',
'exit', 'filter', 'float', 'format', 'frozenset', 'getattr',
'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int',
'isinstance', 'issubclass', 'iter', 'len', 'license', 'list',
'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct',
'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr',
'reversed', 'round', 'set', 'setattr', 'slice', 'sorted',
'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

}}}

among all these var names the only one I seem to find closer to what
we want is vars , but it's a function . So maybe another option would
be to add a vars function in global js namespace and intrinsic events
will look like this

<button onclick="vars()['echo']()" ></button>

AFAICT this form will be both a valid py and js syntax . What d'u think ?

By doing so it's also transparent whatever decision we might make
about storing internal js variables needed to make brython work (be it
$py , $brython , _py , ... )

>> For that reason it makes sense to me to avoid packing everything into a
>> $py variable. To me that would give the appearance of making Brython a
>> second class citizen to js.
>
> While we want to keep the best vision in mind, we also need to deal with
> realities.
[...]
>
>> With an export decorator, the dev can choose to place 1 or 100 functions
>> into the js namespace. So if js namespace becomes flooded, it is their own
>> fault.
>
[...]
>
>> Though, there is still a conflict for me.
>>
>> I think the export decorator is a good solution for placing functions into
>> js global namespace.
>> BUT, an export collision can happen if exporting the function "echo()"
>> from 2 separate python namespaces.
>
> I would think that the use of the @export decorator should mostly be
> restricted to __main__, as a convention.

... or maybe we do not needed at all should we find a way (e.g.
proposed vars() function ) to retrieve in js code any variable bound
to the namespace of brython's __main__ module

[...]

Glenn Linderman

unread,
Jan 3, 2014, 3:32:16 PM1/3/14
to bry...@googlegroups.com
On 1/3/2014 11:48 AM, Olemis Lang wrote:
... or maybe we do not needed at all should we find a way (e.g.
proposed vars() function ) to retrieve in js code any variable bound
to the namespace of brython's __main__ module

On 12/31/2013 3:04 AM, Pierre Quentel wrote:
This means that from a Javascript program, you can access any object Y in any module X as

__BRYTHON__.scope[X].__dict__[Y]

So maybe  _py.y  should access  __BRYTHON__.scope['__main__'].__dict__['y']

and _py.x.y  should access __BRYTHON__.scope['x'].__dict__['y']

(maybe I got the syntax wrong, but the idea is there). I don't know if such can be implemented in js using that syntax, but probably it could using the js equivalent of python  _py( y, x=='__main__')

It is nice that everyone is contributing interesting points to the discussion!

Olemis Lang

unread,
Jan 3, 2014, 4:42:20 PM1/3/14
to bry...@googlegroups.com
On 1/3/14, Olemis Lang <ole...@gmail.com> wrote:
> I've stepped back for a while and see how discussion is running in
> circles over and over .
>

So for the sake of moving forward with this subject and considering
that we have been throwing many ideas on the table by now , my
suggestion is to call upon a vote

I'll take for granted that brython must not pollute the underlying
global js namespace . The following options have been proposed (pros +
and cons - included inline) :

1. expose decorator
+ single helper function to set global names for any name defined any time
at any level of the package / module hierarchy
+ may (must?) be implemented on top of other suggested solutions
+ ... so it's not an exclusive alternative
- it might lead to confusion and non-trivial debugging sessions to
figure out what package / module / class / function / ... is setting
the definitive binding in js ns for a given var name.
- Glenn : "If modules use @expose, then what if names
collide, and neither are from __main__? This starts to get confusing"
- Glenn : "users of a module may not take time to learn what names a
module @exposes" [1]_
- Glenn : "in general, it might be recommended that modules not directly
use @expose." [1]_
* intrinsic handler example [2]_ : alert('message')
2. $py js variable
+ efficient js access
+ concise name
- not available initially in py ns
- not even valid python syntax so requires definition of expose()
- suggests hard-coded dependency on js
- code has to be modified in case of python been
available via Content-Script-Type (if that ever happens)
* intrinsic event example : $py.echo('message')
3. _py js variable
+ js access not optimized
+ concise name
+ valid python syntax , does not require definition of expose()
+ does not suggest hard-coded dependency on js
+ code does not have to be modified in case of python been
available via Content-Script-Type (if that ever happens)
- not available initially in py ns
* intrinsic event example : _py.echo('message')
4. vars() built-in function
+ js access not optimized
+ valid python syntax , does not require definition of expose()
+ by design provides access to *all* variables in __main__ py
namespace, including __builtins__
+ does not suggest hard-coded dependency on js
+ code does not have to be modified in case of python been
available via Content-Script-Type (if that ever happens)
+ available initially in py ns !
- not so concise in practice
* intrinsic event example : vars()['echo']('message')

After assessing the facts mentioned above , please vote and choose
which one(s) do you prefer .

P.S. : In any case there's no currently feasible approach for defining
intrinsic events using python syntax , but this will be deferred to be
discussed in a separate thread

.. [1] @expose may be seen as a shortcut e.g. in pythonic jargon ,
similar to __import__('__main__').var_name = value

.. [2] js alert function would be overriden

Olemis Lang

unread,
Jan 3, 2014, 4:50:54 PM1/3/14
to bry...@googlegroups.com
... and my vote is as follows ...

On 1/3/14, Olemis Lang <ole...@gmail.com> wrote:
> On 1/3/14, Olemis Lang <ole...@gmail.com> wrote:
[...]
>
> 1. expose decorator
[...]

+1

> 2. $py js variable
[...]

-1

> 3. _py js variable
[...]

-0

> 4. vars() built-in function
[...]

+1

>
> After assessing the facts mentioned above , please vote and choose
> which one(s) do you prefer .
>

... or suggest other options and explain pros vs cons hto establish
how they perform when compared against other alternatives .

[...]

Olemis Lang

unread,
Jan 3, 2014, 5:35:39 PM1/3/14
to bry...@googlegroups.com
On 1/3/14, Glenn Linderman <v+py...@g.nevcal.com> wrote:
> On 1/3/2014 11:48 AM, Olemis Lang wrote:
>> ... or maybe we do not needed at all should we find a way (e.g.
>> proposed vars() function ) to retrieve in js code any variable bound
>> to the namespace of brython's __main__ module
>
> On 12/31/2013 3:04 AM, Pierre Quentel wrote:
>> This means that from a Javascript program, you can access any object Y
>> in any module X as
>>
>> __BRYTHON__.scope[X].__dict__[Y]
>
> So maybe _py.y should access __BRYTHON__.scope['__main__'].__dict__['y']
>
> and _py.x.y should access __BRYTHON__.scope['x'].__dict__['y']
>

beyond the fact that such approach requires recording values and
synchronizing in two places ... afaict , it might become more
complicated than that .

> (maybe I got the syntax wrong, but the idea is there). I don't know if
> such can be implemented in js using that syntax,

In general I guess it's not possible . Python and js have
substantially different semantics . IMHO working towards emulating py
syntax in js will (at least) degrade performance a lot .

[...]

> but probably it could
> using the js equivalent of python _py( y, x=='__main__')

I do not get it ...

Glenn Linderman

unread,
Jan 3, 2014, 6:09:08 PM1/3/14
to bry...@googlegroups.com
On 1/3/2014 1:42 PM, Olemis Lang wrote:
On 1/3/14, Olemis Lang <ole...@gmail.com> wrote:
I've stepped back for a while and see how discussion is running in
circles over and over .

So for the sake of moving forward with this subject and considering
that we have been throwing many ideas on the table by now , my
suggestion is to call upon a vote

Good idea to summarize all the various thoughts.  I'm not sure I understand the reasons behind all your comments. Seems good to me to reach a consensus on what the options mean, and what the pros and cons arguments mean, before voting.

In particular, I don't understand why $py is "efficient js access" and _py is "js access not optimized". Is $ special in js? If it is accurate, http://javascript.about.com/od/hintsandtips/a/dollar-and-underscore.htm debunks any optimization due to a name containing $.  I think $py and _py are the same, regarding js access.

You also state, about _py: "not available initially in py ns" -- while I didn't suggest that, there is nothing to preclude it, other than implementation cost, which seems likely to be minimal. Since _py is spelled to work in either js or python.

Unstated is the mechanism by which 2, 3, 4 obtain and recognize symbols. The expose decorator is well-defined in most proposals... its use causes a particular symbol to be placed in a particularly useful namespace, either the global js namespace, or perhaps the internal namespace of an object named, variously, $py or _py, or available via a function possibly names vars() or possibly named _py().

$py or _py could be an object that is populated by expose, or it could be populated by all named function definitions, or it could be populated by all symbols definitions, or it could be a function that looks up symbols in the existing __BRYTHON__.scope[X].__dict__[Y].

If it is any but the first, the definition and use of expose is probably not needed.

So my vote is that if you (Olemis), or I, have missed something in these summary descriptions, that others pipe up to complete them. And then let the implementors choose what is best, given an understanding of the implementation tradeoffs.

Olemis Lang

unread,
Jan 3, 2014, 8:26:49 PM1/3/14
to bry...@googlegroups.com
On 1/3/14, Glenn Linderman <v+py...@g.nevcal.com> wrote:
> On 1/3/2014 1:42 PM, Olemis Lang wrote:
>> On 1/3/14, Olemis Lang <ole...@gmail.com> wrote:
>>> I've stepped back for a while and see how discussion is running in
>>> circles over and over .
>>>
>> So for the sake of moving forward with this subject and considering
>> that we have been throwing many ideas on the table by now , my
>> suggestion is to call upon a vote
>
> Good idea to summarize all the various thoughts.

;)

> I'm not sure I
> understand the reasons behind all your comments.

well , nothing in particular ; only that we have reached the same
starting point many times in the discussion . We have some candidates
so my call here is : «ok , this is it so far ... what's your opinion


> Seems good to me to
> reach a consensus on what the options mean, and what the pros and cons
> arguments mean, before voting.
>

Of course , that's why I wrote them all side-by-side so that it would
be relatively easy to compare them and gather personal opinions about
each case . Indeed in my initial message I forgot to include the
paragraph (which I included later when I emitted my 'vote' ;) saying

«or suggest other options and explain pros vs cons to establish how
they perform when compared against other alternatives »

So there's a chance for somebody else to suggest something interesting
beyond what's been said . If so , please compare vs what we already
have .

> In particular, I don't understand why $py is "efficient js access" and
> _py is "js access not optimized". Is $ special in js?

I've read in a book that (in practice) there's a chance for these to
be optimized by js engines ... but this may be all wrong ; indeed all
other aspects are more important than this one ;)

> If it is accurate,
> http://javascript.about.com/od/hintsandtips/a/dollar-and-underscore.htm
> debunks any optimization due to a name containing $. I think $py and
> _py are the same, regarding js access.
>

If so , then let's just ignore that point in the comparison .

> You also state, about _py: "not available initially in py ns" -- while I
> didn't suggest that, there is nothing to preclude it, other than
> implementation cost, which seems likely to be minimal. Since _py is
> spelled to work in either js or python.
>

I mean , immediately after launching the CPython interpreter there's
no _py variable defined in the global namespace . OTOH `vars` is a
builtin name . That's what I mean . Considering the previous efforts
towards compatibility and the possible use of Content-Script-Type ...
well ... maybe that matters . I'm just saying , Indeed I'll actually
change my opinion about _py to 0+ , which because I have no arguments
against using it but , should anyone propose a different approach ,
well , I'd like to know ;)

> Unstated is the mechanism by which 2, 3, 4 obtain and recognize symbols.

IMO that's ok . It's an implementation detail and should offer room
for optimizations . The focus should be on what we could refer to as
the «public API»

> The expose decorator is well-defined in most proposals... its use causes
> a particular symbol to be placed in a particularly useful namespace,
> either the global js namespace, or perhaps the internal namespace of an
> object named, variously, $py or _py, or available via a function
> possibly names vars() or possibly named _py().
>

+1

> $py or _py could be an object that is populated by expose,

That's a reasonable option .

> or it could
> be populated by all named function definitions, or it could be populated
> by all symbols definitions,

In advance my opinion is that these approaches are evil in the sense
that performance of js hash key lookup should be degraded as the
number of keys increases and the number of names (function , vars ,
...) involved in loaded py modules is usually high .

Another js performance tips consist in [1]_

= 4. Object properties and array items are slower than variables =

Adapted to this context this means that $py and/or _py might introduce
some overhead , though it should be mitigated by using local vars ,
e.g. var x = $py.var_name

> or it could be a function that looks up
> symbols in the existing __BRYTHON__.scope[X].__dict__[Y].
>

In this case the overhead would be much more noticeable . I try to
reduce function calls when possible because (since they switch to an
inner execution context , add closures , etc ...) they are expensive .
Besides in that statement there are 4 additional attribute lookup

> If it is any but the first, the definition and use of expose is probably
> not needed.
>

I agree ... maybe there is still a case for having expose decorator in
the end , considering performance .

> So my vote is that if you (Olemis), or I, have missed something in these
> summary descriptions, that others pipe up to complete them. And then let
> the implementors choose what is best, given an understanding of the
> implementation tradeoffs.
>
[...]

feel free to express yourself (that's the goal in the end) , but
please , let's move forward ;)

.. [1] http://jonraasch.com/blog/10-javascript-performance-boosting-tips-from-nicholas-zakas

Glenn Linderman

unread,
Jan 3, 2014, 9:11:57 PM1/3/14
to bry...@googlegroups.com
I think we've reached a common understanding of the issues here.

sepe...@gmail.com

unread,
Jan 5, 2014, 11:16:45 AM1/5/14
to bry...@googlegroups.com
Pierre, when I think about this type of change to Brython, I'm trying to juggle
many goals in my mind. I think you have similar goals.

Trying to:
Follow Python principals when designing Python parts.
Follow Javascript principals when designing Javascript parts.
Keep Brython on equivalent status to JS.
Prepare Brython for ultimate longevity.
Simplify the learning curve for newcomers and Python devs.


Because of namespace conflict with JS, I have recently thought the better
direction is to use a javascript namespace(_py) variable.

Olemis has brought up the idea of using the vars() function. While this solution
is very clever, I think all the extra syntax will increase the learning curve
for newcomers, it's annoyingly repetitive, and it is very error prone to typos.

Though we have to admit, the benefit of vars() is that it would result in no
breakage in the future IF Brython became natively supported in the browser. On
the other hand, something like "_py" absolutely would cause breakage in such a
future event. If someone had this in their code onclick="_py._py()" there is
no way to deprecate such usage, because there is no way syntactically separate
these two statememts:
_py._py() # Old code that is a _py function in the _py js variable.
_py._py() # New code that is a _py function in a _py object.

Therefore removing the _py variable would need to be done with a hard break, and
it would make ALL existing code backward INcompatible. That is not what people
will want, and it will prevent Brython from becoming natively supported in the
browser.

Thus I now think that using _py is a terrible idea, but I truthfully do not care
for typing vars()['''] either.

So what was the other option? Put Python functions side by side with JS vars...

@export a function directly to JS namespace.



Given the choice between repetitively using vars() OR directly sharing namespace
with js variables, I would choose sharing space. Of course, the @expose
decorator would accept an argument to modify the name on export.


If people still wants to use vars(), they could export it.

Glenn Linderman

unread,
Jan 5, 2014, 6:46:46 PM1/5/14
to bry...@googlegroups.com
On 1/5/2014 8:16 AM, sepe...@gmail.com wrote:
Though we have to admit, the benefit of vars() is that it would result in no breakage in the future IF Brython became natively supported in the browser. On the other hand, something like "_py" absolutely would cause breakage in such a future event. If someone had this in their code   onclick="_py._py()"   there is no way to deprecate such usage, because there is no way syntactically separate these two statememts:
_py._py() # Old code that is a _py function in the _py js variable.
_py._py() # New code that is a _py function in a _py object.

Therefore removing the _py variable would need to be done with a hard break, and it would make ALL existing code backward INcompatible. That is not what people will want, and it will prevent Brython from becoming natively supported in the browser.

Your example:

onclick="_py._py()"

That looks like valid javascript syntax, invoking a function in the javascript _py namespace called _py().

That looks like valid python syntax, invoking a function in the python _py module called _py().

So I don't understand why you perceive the transition to require a hard break, nor why you perceive that it would make ALL existing code backward INcompatible.  It is just a matter of making sure that the javascript _py namespace is the same as the python _py module. Since python gets compiled to javascript in the brython implementation, this is trivially achieved.  When the event handler syntax is changed from


<meta http-equiv="Content-Script-Type" content="text/javascript">

to

<meta http-equiv="Content-Script-Type" content="text/python">

there would need be no change to the handlers of the sort shown by your example.

sepe...@gmail.com

unread,
Jan 6, 2014, 2:13:26 AM1/6/14
to bry...@googlegroups.com

On 01/05/2014 06:46 PM, Glenn Linderman wrote:
> On 1/5/2014 8:16 AM, sepe...@gmail.com wrote:
>> Though we have to admit, the benefit of vars() is that it would result in no
>> breakage in the future IF Brython became natively supported in the browser. On
>> the other hand, something like "_py" absolutely would cause breakage in such a
>> future event. If someone had this in their code onclick="_py._py()" there
>> is no way to deprecate such usage, because there is no way syntactically
>> separate these two statememts:
>> _py._py() # Old code that is a _py function in the _py js variable.
>> _py._py() # New code that is a _py function in a _py object.
>>
>> Therefore removing the _py variable would need to be done with a hard break,
>> and it would make ALL existing code backward INcompatible. That is not what
>> people will want, and it will prevent Brython from becoming natively supported
>> in the browser.
>
> Your example:
>
> onclick="_py._py()"
>
> That looks like valid javascript syntax, invoking a function in the javascript
> _py namespace called _py().
>
> That looks like valid python syntax, invoking a function in the python _py
> module called _py().
>

That's correct.

We must realize that If Brython became natively supported in the browser, then
use of a _py prefix would become obsolete. We would no longer need the _py
prefix. Something that used to be "_py.echo()" now becomes just "echo()".
This destroys backward compatibility. Can you see why?

I'll try to explain. If we try to keep the prefix _py backward compatible into
a future native Brython, we would need to introduce a _py variable into the
Brython __main__ environment. (So we could still use that old html code
"_py.echo()" )

If the developer is already using a variable named _py ,then we have broken
their code by bring in a new variable of the same name. To use _py prefix in a
backward compatible way, we would need to prohibit use of the var name _py in
Brython code.



To use _py and prohibit its use in Brython code might be the cleanest and
simplest way to proceed, while maintaining backward compatibility. Just perhaps
it might be a worthwhile way to go?

Glenn Linderman

unread,
Jan 6, 2014, 2:48:21 AM1/6/14
to bry...@googlegroups.com
On 1/5/2014 11:13 PM, sepe...@gmail.com wrote:

On 01/05/2014 06:46 PM, Glenn Linderman wrote:
On 1/5/2014 8:16 AM, sepe...@gmail.com wrote:
Though we have to admit, the benefit of vars() is that it would result in no
breakage in the future IF Brython became natively supported in the browser. On
the other hand, something like "_py" absolutely would cause breakage in such a
future event. If someone had this in their code   onclick="_py._py()"   there
is no way to deprecate such usage, because there is no way syntactically
separate these two statememts:
_py._py() # Old code that is a _py function in the _py js variable.
_py._py() # New code that is a _py function in a _py object.

Therefore removing the _py variable would need to be done with a hard break,
and it would make ALL existing code backward INcompatible. That is not what
people will want, and it will prevent Brython from becoming natively supported
in the browser.

Your example:

onclick="_py._py()"

That looks like valid javascript syntax, invoking a function in the javascript
_py namespace called _py().

That looks like valid python syntax, invoking a function in the python _py
module called _py().


That's correct.

We must realize that If Brython became natively supported in the browser, then use of a  _py  prefix would become obsolete. We would no longer need the  _py prefix. Something that used to be  "_py.echo()"  now becomes just  "echo()". This destroys backward compatibility. Can you see why?

No. It provides a migration path. While the _py. may no longer be necessary, it is not harmful.


I'll try to explain. If we try to keep the prefix  _py  backward compatible into a future native Brython, we would need to introduce a  _py  variable into the Brython __main__ environment. (So we could still use that old html code "_py.echo()" )

Ah yes, but who would use _py as a python name when _py as a js name is already defined? It would be confusing to use it for something else on the python side... but I do see your point about the potential for incompatibility, now that you have explained.


If the developer is already using a variable named  _py  ,then we have broken their code by bring in a new variable of the same name. To use  _py  prefix in a backward compatible way, we would need to prohibit use of the var name  _py  in Brython code.

No problem. Prohibit it now, while still in alpha.  Better, define it now, as containing exactly the same stuff as is in the js _py namespace, so that it can be used in both python and js code, either accidentally or intentionally, for consistency.


To use  _py  and prohibit its use in Brython code might be the cleanest and simplest way to proceed, while maintaining backward compatibility. Just perhaps it might be a worthwhile way to go?

I think so.

Pierre Quentel

unread,
Jan 6, 2014, 9:45:03 AM1/6/14
to bry...@googlegroups.com

The main point initially raised by Kiko was that the whole Brython namespace, including the Python built-ins, was defined in the global Javascript namespace, with an important risk of conflicts

Now that this issue is solved, and that the only name exposed by Brython by default is going to be __BRYTHON__ (very unlikely to be used in a JS program), all that is left is, how do we call Brython functions as callbacks from inline Javascript events ?

I think it's a minor problem, since we could simply ignore it by binding functions to events with

    elt.bind('click',echo)

Among the proposed solutions, I may be missing something obvious but I don't get the idea of using _py (or any other name) :
- Javascript programs can set a variable _py to any value, so the name conflict remains
- forbidding a name such as "_py" in Brython programs breaks compatibility with Python

We can't use vars() either, because it is not defined in the Javascript namespace (it would be __BRYTHON__.__builtins__.vars())

I like the solution with "expose" because it gives control to the developer on the names (s)he wants to expose, while preserving the simple syntax "onclick=echo()", which is symmetric to elt.bind('click',echo). By the way, I don't think we need to pass an additional argument if we want an alias, nor need to prepend the module name as suggested by Billy : since "expose" is a function, we can use it as such in the main program

    from javascript import expose
    import X     # X has a function "func" that we want to expose
   
    echo = expose(X.func)


To avoid errors difficult to track, the solution with "expose" can be improved by allowing only functions defined in the module __main__ to be exposed

With this option, yes, there is a risk that another Javascript or Python program in the same page defines another function echo(). But it's also the case if all the code is written in Javascript, or if it's all in Python : using a library requires the effort to learn its API

sepe...@gmail.com

unread,
Jan 6, 2014, 12:08:30 PM1/6/14
to bry...@googlegroups.com
Just to clarify my view on the _py solution. If it is chosen, then I think
@export wouldn't be needed at all. And use of _py should be restricted to only
__main__ namespace.




With that said, I think I agree with Pierre's solution more than anyone else,
and restricting @expose to __main__ is definitely necessary.

Pierre, you make a great point about using event binding, and with that, I'm
again agreeing with you that @export is the best solution.

In fact, I think your point about binding is so good that it should be promoted
with it's own decorator. Like this:
@bind('element_id', 'onclick')
def my_click_function(ev):
...

Binding allows us to keep our code inside Python, and the more things we can
keep inside Python namespace, the better. Developers should be Encouraged to use
binding instead of exporting. An exporting should only ever be used for rare
cases like working with JS.

Olemis Lang

unread,
Jan 6, 2014, 3:30:30 PM1/6/14
to brython

On Mon, Jan 6, 2014 at 9:45 AM, Pierre Quentel <pierre....@gmail.com> wrote:
[...]  
Now that this issue is solved, and that the only name exposed by Brython by default is going to be __BRYTHON__ (very unlikely to be used in a JS program), all that is left is, how do we call Brython functions as callbacks from inline Javascript events ?

Regarding intrinsic events , afaict for the moment there's no much hope with defining intrinsic events using python syntax in on* element's attributes . At least I can not find any APIs .

So there's still a chance to :

  1. intercept data:text/python[3] [6]_ URLs in href definitions 
      * as an equivalent to javascript: URI schema [1]_
  2. support data-click attribute
      * e.g. similar to Kendo UI [2]_
  3. support data-bind attribute
      * e.g. similar to Kendo UI [3]_ , knockout [4]_ et al.

I think it's a minor problem, since we could simply ignore it by binding functions to events with

    elt.bind('click',echo)

  4. and also add 'on' method for direct vs delegated event handler definition [5]_

I could spend some time working on these enhancements 
;)

[...]


We can't use vars() either, because it is not defined in the Javascript namespace (it would be __BRYTHON__.__builtins__.vars())

fwiw the original proposal implied to bind 'vars' name in global js namespace to the value of __BRYTHON__.__builtins__.vars
 

I like the solution with "expose" because it gives control to the developer

... and hides any implementation detail .

[...]

which is symmetric to elt.bind('click',echo). By the way, I don't think we need to pass an additional argument if we want an alias, nor need to prepend the module name as suggested by Billy : since "expose" is a function, we can use it as such in the main program

    from javascript import expose
    import X     # X has a function "func" that we want to expose
   
    echo = expose(X.func)


To avoid errors difficult to track, the solution with "expose" can be improved by allowing only functions defined in the module __main__ to be exposed

I do not get it . In your sample code you have actually exposed a function defined in a module .
 

With this option, yes, there is a risk that another Javascript or Python program in the same page defines another function echo(). But it's also the case if all the code is written in Javascript, or if it's all in Python : using a library requires the effort to learn its API

sepe...@gmail.com

unread,
Jan 6, 2014, 4:30:15 PM1/6/14
to bry...@googlegroups.com


On 01/06/2014 03:30 PM, Olemis Lang wrote:
>
>
> Regarding intrinsic events , afaict for the moment there's no much hope with
> defining intrinsic events using python syntax in on* element's attributes . At
> least I can not find any APIs .
>
> So there's still a chance to :
>
> 1. intercept data:text/python[3] [6]_ URLs in href definitions
> * as an equivalent to javascript: URI schema [1]_
> 2. support data-click attribute
> * e.g. similar to Kendo UI [2]_
> 3. support data-bind attribute
> * e.g. similar to Kendo UI [3]_ , knockout [4]_ et al.
>
I see the links, but perhaps you could elaborate on this more? I assume most of
us are not very familiar with Kendo UI.



> from javascript import expose
> import X # X has a function "func" that we want to expose
>
> echo = expose(X.func)
>
> To avoid errors difficult to track, the solution with "expose" can be
> improved by allowing only functions defined in the module __main__ to be exposed
>
>
> I do not get it . In your sample code you have actually exposed a function
> defined in a module .
>
That was his purpose in the example. He was saying 2 things.
1. @expose is only for __main__
2. If you want to @expose something from a module, it can be done in the
__main__ namespace.



> With this option, yes, there is a risk that another Javascript or Python
> program in the same page defines another function echo(). But it's also the
> case if all the code is written in Javascript, or if it's all in Python :
> using a library requires the effort to learn its API
>
>
> js frameworks have developed solutions to avoid these issues :
>
> - jquery noConflict
> - amd
> - commonjs
>

Perhaps you could elaborate on this further also?

Olemis Lang

unread,
Jan 6, 2014, 5:44:01 PM1/6/14
to brython
On Mon, Jan 6, 2014 at 4:30 PM, sepe...@gmail.com <sepe...@gmail.com> wrote:


On 01/06/2014 03:30 PM, Olemis Lang wrote:


Regarding intrinsic events , afaict for the moment there's no much hope with
defining intrinsic events using python syntax in on* element's attributes . At
least I can not find any APIs .

So there's still a chance to :

   1. intercept data:text/python[3] [6]_ URLs in href definitions
       * as an equivalent to javascript: URI schema [1]_
   2. support data-click attribute
       * e.g. similar to Kendo UI [2]_
   3. support data-bind attribute
       * e.g. similar to Kendo UI [3]_ , knockout [4]_ et al.

I see the links, but perhaps you could elaborate on this more? I assume most of us are not very familiar with Kendo UI.


neither do I  ... only the use of data-click and data-bind attributes with custom python syntax matters to me in the context of this discussion . Everybody else is doing it so why can't we ?
;)
 



         from javascript import expose
         import X     # X has a function "func" that we want to expose

         echo = expose(X.func)

    To avoid errors difficult to track, the solution with "expose" can be
    improved by allowing only functions defined in the module __main__ to be exposed


I do not get it . In your sample code you have actually exposed a function
defined in a module .

That was his purpose in the example. He was saying 2 things.
1. @expose is only for __main__
2. If you want to @expose something from a module, it can be done in the __main__ namespace.


Maybe I did not understand the phrase «allowing only functions *defined* in the module __main__» , which is not actually the case of X.func . You mean the invocation is performed in __main__ .

[...]

Pierre Quentel

unread,
Jan 7, 2014, 4:19:32 AM1/7/14
to bry...@googlegroups.com


Le lundi 6 janvier 2014 21:30:30 UTC+1, Olemis Lang a écrit :

On Mon, Jan 6, 2014 at 9:45 AM, Pierre Quentel <pierre....@gmail.com> wrote:
[...]  
Now that this issue is solved, and that the only name exposed by Brython by default is going to be __BRYTHON__ (very unlikely to be used in a JS program), all that is left is, how do we call Brython functions as callbacks from inline Javascript events ?

Regarding intrinsic events , afaict for the moment there's no much hope with defining intrinsic events using python syntax in on* element's attributes . At least I can not find any APIs .

So there's still a chance to :

  1. intercept data:text/python[3] [6]_ URLs in href definitions 
      * as an equivalent to javascript: URI schema [1]_
  2. support data-click attribute
      * e.g. similar to Kendo UI [2]_
  3. support data-bind attribute
      * e.g. similar to Kendo UI [3]_ , knockout [4]_ et al.

I think it's a minor problem, since we could simply ignore it by binding functions to events with

    elt.bind('click',echo)

  4. and also add 'on' method for direct vs delegated event handler definition [5]_

I could spend some time working on these enhancements 
;)

[...]


We can't use vars() either, because it is not defined in the Javascript namespace (it would be __BRYTHON__.__builtins__.vars())

fwiw the original proposal implied to bind 'vars' name in global js namespace to the value of __BRYTHON__.__builtins__.vars
 
Sorry, I didn't get it. But it means that there is a potential conflict with a name "vars" defined in a Javascript program

I like the solution with "expose" because it gives control to the developer

... and hides any implementation detail .

[...]

which is symmetric to elt.bind('click',echo). By the way, I don't think we need to pass an additional argument if we want an alias, nor need to prepend the module name as suggested by Billy : since "expose" is a function, we can use it as such in the main program

    from javascript import expose
    import X     # X has a function "func" that we want to expose
   
    echo = expose(X.func)


To avoid errors difficult to track, the solution with "expose" can be improved by allowing only functions defined in the module __main__ to be exposed

I do not get it . In your sample code you have actually exposed a function defined in a module .
 

With this option, yes, there is a risk that another Javascript or Python program in the same page defines another function echo(). But it's also the case if all the code is written in Javascript, or if it's all in Python : using a library requires the effort to learn its API

js frameworks have developed solutions to avoid these issues :

  - jquery noConflict
I visited the page on noConflict. The use case is : a jQuery user want to use also the library prototype.js. He knows that prototype.js defines a name $, so he wants to rename the jQuery variable of the same name. All that jQuery noConflict does is provide a way to rename it

The important point is that the jQuery user has studied the API of prototype.js and knows that there is a conflict on this name - it's not jQuery itself that magically avoids any name conflict

It's exactly the same with what is proposed for Brython : very few names are exposed, and it's up to the developer to choose the right ones

Olemis Lang

unread,
Jan 7, 2014, 10:48:04 AM1/7/14
to bry...@googlegroups.com
On 1/7/14, Pierre Quentel <pierre....@gmail.com> wrote:
> Le lundi 6 janvier 2014 21:30:30 UTC+1, Olemis Lang a écrit :
[...]
>>>
>>> We can't use vars() either, because it is not defined in the Javascript
>>> namespace (it would be __BRYTHON__.__builtins__.vars())
>>>
>>
>> fwiw the original proposal implied to bind 'vars' name in global js
>> namespace to the value of __BRYTHON__.__builtins__.vars
>>
>>
> Sorry, I didn't get it. But it means that there is a potential conflict
> with a name "vars" defined in a Javascript program
>

That was the initial proposal , yes . Sepero makes a good point about
the fact that by offering an export decorator then brython's vars
built-in could be @expose-d as well

[...]
>>>
>>> With this option, yes, there is a risk that another Javascript or Python
>>>
>>> program in the same page defines another function echo(). But it's also
>>> the case if all the code is written in Javascript, or if it's all in
>>> Python
>>> : using a library requires the effort to learn its API
>>>
>>
>> js frameworks have developed solutions to avoid these issues :
>>
>> - jquery noConflict
>>
> I visited the page on noConflict. The use case is : a jQuery user want to
> use also the library prototype.js. He knows that prototype.js defines a
> name $, so he wants to rename the jQuery variable of the same name. All
> that jQuery noConflict does is provide a way to rename it
>

yes

> The important point is that the jQuery user has studied the API of
> prototype.js and knows that there is a conflict on this name - it's not
> jQuery itself that magically avoids any name conflict
>

yes , the point is that noConflict is an aspect of the jquery API with
this goal in mind ... but, afaics in the long term , mainly offered
for (backwards) compatibility .

> It's exactly the same with what is proposed for Brython : very few names
> are exposed, and it's up to the developer to choose the right ones
>

except that we do not offer noConflict resolution (up to this point) .
Let's suppose we move forward with _py js var , or whatever . What if
another clinet-side python library (skulpt , ...) does a similar thing
? __BRYTHON__ is quite unlikely to cause any conflicts (... as is
jQuery vs $ ...)

>> - amd

... but this is another story ... By adopting asynchronous module
definition [1]_ style the code could be executed with external deps
isolated in a closure (i.e. no access to global vars) , module names
are not hard coded , etc , etc ... All major libraries , starting with
dojo , jquery , ... offer support for amd loaders .

So this is a completely different (generic) approach to isolate access
to "globals" namely module dependencies . When it comes to intrinsic
event definitions , well that's another subject . I guess globals will
always be needed .

<ot>
There are even standalone js loaders e.g. requirejs with a
considerable number of extensions e.g. i18n , text , css ... therefore
it's a mature technology supported by communities and major industry
players like IBM , Google ...
</ot>

>> - commonjs

... and this one is for the enthusiasts of server-side javascript +
node.js + brython


.. [1] http://en.wikipedia.org/wiki/Asynchronous_module_definition

Pierre Quentel

unread,
Jan 7, 2014, 3:21:14 PM1/7/14
to bry...@googlegroups.com


Le lundi 6 janvier 2014 21:30:30 UTC+1, Olemis Lang a écrit :

You're right, this doesn't make sense. echo must be defined in the body of the __main__ module, with def or lambda

Something like :

@expose
def echo():
    return X.func()

Not very elegant, but what else ?
 

Glenn Linderman

unread,
Jan 7, 2014, 4:13:30 PM1/7/14
to bry...@googlegroups.com
On 1/7/2014 1:19 AM, Pierre Quentel wrote:
It's exactly the same with what is proposed for Brython : very few names are exposed, and it's up to the developer to choose the right ones

Yesterday, I had thought about writing a message yakking about __BRYTHON__ and _py not being all that intrusive to javascript (2 symbols instead of 1, what's the big deal?), and reserving _py in brython/python code not being that big a deal either.... but it seemed contrary to the idea of reducing exposed symbols, and I thought I would contemplate it more before writing it.  I'm glad I did.

Your message today points out the possible need to not even expose the single name __BRYTHON__ on occasion. But then, there really is already more than one symbol defined in the javascript global name space.... __BRYTHON__ and  brython(), the latter being the method invoked by <body onload="brython()">

The comments about changing "$" to something else for jquery got me to thinking the other direction: instead of making 2 exposed symbols for Brython, how about reducing it to one renamable one? Or maybe two, if easily renamable.  But how?

Well,

<script type="text/javascript" src="/brython/brython.js"></script>

works regardless of the path to brython.js, or even the name of brython.js.  One technique would be name the function used in

<body onload="brython(1)">

the same as the root of the file from which it is loaded. So if brython.js were renamed to foo.js, then

<body onload="foo(1)">

would be used.  But if brython.js is loaded by an administrator, that might not give the flexibility needed to individual users of the server.

Another technique would be to add query parameters to the  src URL.  Here is an example showing how one could explicitly specify today's defaults, and another showing changed names.

<script type="text/javascript" src="/brython/brython.js?name=brython&globals=__BRYTHON__"></script>

<script type="text/javascript" src="/brython/brython.js?name=foo&globals="_foo"></script>

I don't know enough javascript to know if a js function can have attributes as well as a call, in a manner similar to python classes having a call as well as attributes, but could

brython() also contain the name space of __BRYTHON__ as attributes? Would that be a way to get things down to one name?  Of course, one can always do:

<body onload="__BRYTHON__.brython()">

And, of course, I don't know how easy or efficient it would be to allow renamable global names for these two items, either... but if jquery can do it... So this is just an idea, tossed out in case it might be useful, but without an underlying implementation.

Some other thoughts...

Regarding the symbol in the python side, should _py be desirable, it could also be imported from the javascript module, and renamed during the import, so its visibility in __main__ would not be a significant source of incompatibility... and similarly on the javascript side, if the other names can be changed, so could _py.  While expose seems to be an acceptable solution for placing symbols directly in the javascript namespace, should it be desirable to create a namespace such as _py, so that a multitude of non-conflicting names could be offered to javascript while only worrying about name conflict with one (more) symbol, it would be possible to use expose to create _py, and then implement symbols within _py using python source. So anyone that prefers a solution like $py or _py or vars() can make it using expose, but the reverse is not true, so expose is a more powerful solution (but also more dangerous to the javascript namespace).


Off topic thoughts...

While thinking about all this naming, isn't there already a javascript module that is an interface from python to javascript? Maybe, maybe not... I went looking for one, and the ones I found now are not called javascript. Of course, even if there were two modules called javascript (by filename) one could be renamed (by filename) or installed as a submodule, to avoid conflict at the global namespace. Finding PyExecJS, though, makes me think that that interface to JS from Python is flexible enough it might be possible to implement that interface as an interface from Brython to the hosting javascript engine!
It is loading more messages.
0 new messages