Pyzo as a live Leo explorer

124 views
Skip to first unread message

Matt Wilkie

unread,
Apr 6, 2020, 7:29:57 PM4/6/20
to leo-editor
Happy Monday discovery:

Pyzo's workspace feature can be used to interactively explore Leo's modules, functions, classes, methods and defined variables in real time. This is so cool.
  1. Create a new shell that uses the same env (python.exe) that you use with Leo.
  2. Open that shell.
  3. Open launchLeo.py
  4. Run it (F5)
  5. Open the Workspace tool and explore!
It doesn't give you the Global, Commander, Position, Headline and Body  (g,c,p,h,v,...) variables which you have within Leo. Though you can reconstruct those inside Pyzo if you wish by extracting the relevant snippets from Leo's code and running them in the interactive shell window.





-matt

Thomas Passin

unread,
Apr 6, 2020, 8:48:13 PM4/6/20
to leo-editor


On Monday, April 6, 2020 at 7:29:57 PM UTC-4, Matt Wilkie wrote:
Happy Monday discovery:

Pyzo's workspace feature can be used to interactively explore Leo's modules, functions, classes, methods and defined variables in real time. This is so cool

It is very cool, and your steps didn't quite work for me.  I'm using pyzo 4.10.2 on Windows.  For one thing, I don't even have an F5 command.  Here is what I did:

1. Use the Shell/ Edit Shell Configurations menu item to open the configuration dialog;
2. Click Add Config in the upper right corner.
3. Give this config a name, and select a python exe from the dropdown box - or just type in the path to your own python.exe (I've got one for Jython, which Pyzo didn't know about by default);
4. In the Startup Script edit box, put in the path to launchLeo.py (if you have one; I don't) or runLeo.py.  My entry:

C:\Users\tom\AppData\Local\Programs\Python\Python38\Lib\site-packages\leo\core\runLeo.py

5. In the argv edit box at the bottom, type in your arguments, like --use-docks.
6. Save everything by clicking the Done button.

Then, launch your new configuration using the new menu item at the bottom of the Shell menu.  If everything goes well, Leo will open and you will see all those interesting items in the Workspace panel.

Beyond this, I don't know much about what you can do with them so far. but it's very cool ...

Matt Wilkie

unread,
Apr 7, 2020, 11:17:50 AM4/7/20
to leo-editor
It is very cool, and your steps didn't quite work for me.  I'm using pyzo 4.10.2 on Windows.  For one thing, I don't even have an F5 command. Here is what I did:

Oh! F5 is menu "Run >> Execute file" which might also be bound to Ctrl-E. It's the conceptual equivalent to Leo's "Run current node tree as script", Ctrl-B.

Thanks for adding another working recipe.

Beyond this, I don't know much about what you can do with them so far. but it's very cool ...

Anything you do in the interactive shell becomes part of the Workspace. I use it most to look at what my variables etc. actually turn into (which can be quite different from what I think they are!). So if I have this function in a script (that I have opened and run in Pyzo):

def get_leo_libpath():
 
import leo
 
return leo.__path__[0]


and assign it, either in the script or in the interactive shell:


x = get_leo_libpath()

This variable and it's value are now visible in the Workspace immediately. This means I don't need to sprinkle print(x) when I'm trying to understand what's happening.




This is probably a narrow use of it's actual feature set.

Using it this way for all of Leo as a running app might not be that practical, for instance whatever you do in the running Leo GUI won't show up in Pyzo's workspace (I don't think anyway, I might be wrong about that). I'm finding it useful right at the moment because it shows me all the Leo parts that loaded and available, and inside what modules. (Which is a different picture than just scanning 'leo/core/...' for .py files, that may or not have been called yet.)

-matt

Thomas Passin

unread,
Apr 7, 2020, 6:19:36 PM4/7/20
to leo-editor
The steps I posted earlier give you a running copy of Leo, and access to some to Leo's objects in Pyzo's Workspace pane, but the interactive shell pane doesn't accept input.  I suppose it's waiting for Leo to terminate.  I have found a simpler set of steps that launch Leo, let you see many more Leo objects in the Workspace, and also interact with the running Leo in Pyzo's interactive pane.  This is probably exactly what Matt was explaining, but somehow I didn't quite understand something about it.  So I'd like to write it down here.

1.  First of all, create a shell configuration in Pyzo, but don't have it run Leo as I described earlier.  Instead, pick or type in the path to the Python interpreter you want to use, and don't give it an argument or initial script. Give the configuration a name and save it.  I called mine "Bare Python".

2.  Next, in the editor pane (usually on the left), type these two lines:

import leo
leo.run()

3.  Start the shell you created using Pyzo's Shell menu.

4. Now press <CTRL>-<ENTER>.  Or you can use the Run/Execute Cell menu item.  This will launch Leo (though without docks) and you will be able to interact with it in Pyzo's interactive shell pane (normally in the upper right).  Every Leo object and attribute you could want will be available in the Workspace pane. 

For example, in the workspace, double click on leo, then scroll down and double click on plugins.  You will see all the plugins Leo is using.  Double click on one of them and you will see its objects and attributes.

In the interactive pane, just by way of example, type leo.  On my computer, I got this:

<module 'leo' from 'c:\\users\\tom\\appdata\\local\\programs\\python\\python38\\lib\\site-packages\\leo\\__init__.py'>

In other words, just what you would expect from a Python interactive session.

This is really nice.

Matt Wilkie

unread,
Apr 8, 2020, 11:37:18 AM4/8/20
to leo-editor
Thanks for the extra detail Thomas.

Something like this function in runLeo.py to add command line argument might be used to invoke no-docks:

def run_console(*args, **keywords):
   
"""Initialize and run Leo in console mode gui"""
   
import sys
   sys
.argv.append('--gui=console')
   run
(*args, **keywords)


It is called like this:


import leo.core.runLeo
leo
.core.runLeo.run_console()


I tried simply changing it to `leo.core.runLeo.run_console('--no-dock')` instead but that failed, so more would be needed. A path perhaps though.


Leo 6.3-devel, devel branch, build 8051ecd172
2020-04-05 05:55:36 -0500

trace
: createMenuFromConfigList NO PARENT Edit Settings doHandlersForTag,callTagHandler,onCreate,build_menu

Redirection is not supported.

The kernel process exited. (1)


-matt



Thomas Passin

unread,
Apr 8, 2020, 12:25:56 PM4/8/20
to leo-editor

On Wednesday, April 8, 2020 at 11:37:18 AM UTC-4, Matt Wilkie wrote:
Thanks for the extra detail Thomas.

Something like this function in runLeo.py to add command line argument might be used to invoke no-docks:

def run_console(*args, **keywords):
   
"""Initialize and run Leo in console mode gui"""
   
import sys
   sys
.argv.append('--gui=console')
   run
(*args, **keywords)

I wouldn't be using --gui=console to use docks, but this worked like a charm (no def: needed) -

import leo

import sys

sys.argv.append('--use-docks')

leo.run()


Then CTRL-ENTER in Pyzo.


Thanks for the idea!

Matt Wilkie

unread,
Apr 12, 2020, 6:51:53 PM4/12/20
to leo-editor
Oh good, such a short and sweet recipe!

-matt

Offray Vladimir Luna Cárdenas

unread,
Apr 13, 2020, 2:22:10 PM4/13/20
to leo-e...@googlegroups.com

This looks pretty cool Matt! Kind of reminds me about the Pharo inspector[1][2], with its faceted navigation.

I don't think this will be integrated in Leo in someway (I don't know about its live introspection capabilities), but is nice to see such experiments.

[1] https://www.youtube.com/watch?v=_kd4FDKLVFg
[2] http://rmod-pharo-mooc.lille.inria.fr/MOOC/Videos/W2/C019-Videos-GTInspector1-Introduction-V2-HD_720p_4Mbs.m4v

Cheers,

Offray

--
You received this message because you are subscribed to the Google Groups "leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email to leo-editor+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/leo-editor/f375b799-22a0-4176-9577-34a43601d2bd%40googlegroups.com.

tfer

unread,
Apr 18, 2020, 4:58:58 PM4/18/20
to leo-editor
Okay, I'm playing with this, getting interesting results.
  • Working on Windows 10
  • Using Miniconda
  • Using powershell instance(s) in Conemu
    1. setup posh-git to integrate git into powershell
      • easiest installed with scoop from the extras bucket
    2. setup conda to integrate it into powershell
      • involves running: conda init
  • Making a conda env and then customizing:
    1. conda create --name lpik_3.7 python=3.7 ipykernel
      1. initials indicating:
        1. l - leo
        2. p - pyzo
        3. i - IPython
        4. k - kernel, (an ipykernel, registered to run Juypter Notebooks)
    2. pip install -e .
      1. run inside the repository directory, this set up the env so Leo will have the packages it needs
      2. Note: in setup.py, I've commented out the 'nbformat' and replaced it with 'notebook'
        1. This gives the env the packages to run IPython, and Jupyter Notebooks
    3. pip install pyzo
    4. Now when you follow Matt's instructions, and open the shell, it will have IPython interpreter running in it
    5. Pressing F5, Leo will start
      1. Once you close any blocking dialog boxes, (like Tips, or This file may already Open ...), you'll get the IPython prompt back in the pyzo shell.
    • back there, you can use the magic command - 'notebook' to start a Juypter Notebook
      • even though I've registered this env with step 1. above, it is not showing in the kernel options, so the notebook is not what we want yet
Note: I get this warning in the shell when starting Leo:

>>> (executing file "launchLeo.py")

Qt WebEngine seems to be initialized from a plugin. Please set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute before constructing QGuiApplication.


Not sure how to do what it is asking.


Tom

Thomas Passin

unread,
Apr 18, 2020, 6:38:11 PM4/18/20
to leo-editor
I have found that it's better to configure the Pyzo shell for "none- No Gui Support" if you want to launch Leo in the way I illustrated above.  Otherwise I have had circumstances in which Pyzo's handling of PyQt5 seems to interfered with Leo's.

I don't know how this would play with Ipython/Jupiter.

Thomas Passin

unread,
Apr 18, 2020, 6:41:37 PM4/18/20
to leo-editor


On Saturday, April 18, 2020 at 4:58:58 PM UTC-4, tfer wrote:
Okay, I'm playing with this, getting interesting results:
 [snip]
pip install pyzo

I installed Pyzo using the standalone installer.  I don't know if that would make any difference in what you are doing or not.  But at least it doesn't depend  directly on Conda.

tfer

unread,
Apr 18, 2020, 7:56:22 PM4/18/20
to leo-editor
Though I'm using a conda env, pip is not conda related.  From what I've seen, they must not have a complete requirement clause in their setup.py as the pip install, if done before the pip install -e . for leo, doesn't load in any pytq stuff so it won't run until leo does that for you.

I'm curious, is your shell in IPython instance, (try? to see if it has magics)?  I did not get that until I change Leo's requirement to "notebook".

Having Ipython running adds a lot of inspection stuff.

tfer

unread,
Apr 18, 2020, 10:29:02 PM4/18/20
to leo-editor
Got another warning after Leo starts:

Leo 6.3-devel, devel branch, build cbb73524c3

2020-04-15 04:24:37 -0500

Note on using QApplication.exec_():

The GUI event loop is already running in the pyzo kernel, and exec_()

does not block. In most cases your app should run fine without the need

for modifications. For clarity, this is what the pyzo kernel does:

- Prevent deletion of objects in the local scope of functions leading to exec_()

- Prevent system exit right after the exec_() call


Tom 

tfer

unread,
Apr 19, 2020, 4:11:41 PM4/19/20
to leo-editor
Okay, I've made some progress.  Turns out, I was erroneously assumed I was in an IPython shell because it had 'magics', but it was just the idle interpreter, (never spent much time in Idle).  All it took was creating a new shell config, and ticking the IPython box.

I'm going paste in some of the shell interaction with comments interspersed and a question.

Python 3.7.7 (default, Apr 15 2020, 05:09:04) on Windows (64 bits).


This is the Pyzo interpreter with integrated event loop for PYQT5.




Using IPython 7.13.0 -- An enhanced Interactive Python.


?         -> Introduction and overview of IPython's features.


%quickref -> Quick reference.


help      -> Python's own help system.


object?   -> Details about 'object', use 'object??' for extra details.




In [1]: whos  #this is before I started "launchLeo.py" with F5


Interactive namespace is empty.




In [2]: (executing file "launchLeo.py")


Qt WebEngine seems to be initialized from a plugin. Please set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute before constructing QGuiApplication.




In [3]: whos #note our workspace is now populated with stuff from Leo!

Variable             Type      Data/Info

----------------------------------------

leo                  module    <module 'leo' from 'c:\\v<...>ditor\\leo\\__init__.py'>

load_locals          dict      n=6

runMainLoop_locals   dict      n=1

run_locals           dict      n=4


In [4]: g.commander_command('new') # naive attempt open a new file in Leo

---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-4-c784551296f6> in <module>

----> 1 g.commander_command('new')


NameError: name 'g' is not defined


/*
Hmm, 'g' is not availible, let's try a fully qualified name, reaching down
from the 'leo' we saw from
In [3]: whos :
*/


In [5]: leo.commands.commanderFileCommands.new() # so here is my question,what should I use for my argument?

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-5-0f3e5c284e86> in <module>

----> 1 leo.commands.commanderFileCommands.new()


TypeError: new() missing 1 required positional argument: 'self'


In [6]:


The question is at In [5] above, I guess it would be 'g.app', but 'g' isn't available, any suggestions?

Doing things like this is the reason I first started looking at IPython, to provide a way to explore Leo code.

Tom


Thomas Passin

unread,
Apr 19, 2020, 6:16:54 PM4/19/20
to leo-editor
No, not IPython.

Thomas Passin

unread,
Apr 19, 2020, 6:24:28 PM4/19/20
to leo-editor


On Sunday, April 19, 2020 at 4:11:41 PM UTC-4, tfer wrote:
Okay, I've made some progress.  Turns out, I was erroneously assumed I was in an IPython shell because it had 'magics', but it was just the idle interpreter, (never spent much time in Idle).  All it took was creating a new shell config, and ticking the IPython box.

I'm going paste in some of the shell interaction with comments interspersed and a question.
[snip]

In [4]: g.commander_command('new') # naive attempt open a new file in Leo

---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-4-c784551296f6> in <module>

----> 1 g.commander_command('new')


NameError: name 'g' is not defined


/*
Hmm, 'g' is not availible, let's try a fully qualified name, reaching down
from the 'leo' we saw from
In [3]: whos :
*/


In [5]: leo.commands.commanderFileCommands.new() # so here is my question,what should I use for my argument?

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-5-0f3e5c284e86> in <module>

----> 1 leo.commands.commanderFileCommands.new()


TypeError: new() missing 1 required positional argument: 'self'


In [6]:


The question is at In [5] above, I guess it would be 'g.app', but 'g' isn't available, any suggestions?

Doing things like this is the reason I first started looking at IPython, to provide a way to explore Leo code.

When I run command [4] in the Python console tab inside Leo (not the Pyzo shell), I get this:

>>> g.commander_command('new')

<leo.core.leoGlobals.CommanderCommand object at 0x000001FDACBE36D0>


And also in the console tab:


>>> import leo

>>> help(leo.commands.commanderFileCommands.new)

Help on function new in module leo.commands.commanderFileCommands:


new(self, event=None, gui=None)

Create a new Leo window.


I'm not sure what object is needed for self...



tfer

unread,
Apr 19, 2020, 7:59:58 PM4/19/20
to leo-editor


On Sunday, April 19, 2020 at 6:16:54 PM UTC-4, Thomas Passin wrote:
No, not IPython.

As text has no vocal inflection, I don't now what you mean by this, do you mean:
    No, not IPython! --> as in "I don't like/use it", or something else?

Tom 

Thomas Passin

unread,
Apr 19, 2020, 9:35:18 PM4/19/20
to leo-editor
Well, literally I meant only that I didn't set up the Pyzo shell to use it. A little deeper, and I haven't fired up an IPython shell for years, and I wouldn't know how to take advantage of it in our current context.  So I didn't go futzing around with it before posting my response, since I couldn't have added anything useful.

tfer

unread,
Apr 19, 2020, 11:39:56 PM4/19/20
to leo-editor


On Sunday, April 19, 2020 at 6:24:28 PM UTC-4, Thomas Passin wrote:

When I run command [4] in the Python console tab inside Leo (not the Pyzo shell), I get this:
Not sure how to get, where is a 'consoletab', It must only appear with some start up option.  Nothing in the doc, though I have seen once.

tfer

unread,
Apr 19, 2020, 11:44:00 PM4/19/20
to leo-editor
Yeah, It been a few years since I've played with it too, but it should be useful for exploring the running instance of Leo, and put it though its paces.
Reply all
Reply to author
Forward
0 new messages