Editor integration

30 views
Skip to first unread message

Paul Hildebrandt

unread,
Nov 29, 2008, 3:14:14 PM11/29/08
to Pythoscope
I was thinking about editor integration today. One thing that make
products really click is when they are so easy to use they can't be
ignored. Editor integration helps with this goal. I've used pydev
with Eclipse but I am not using it currently. Currently, I just use
Emacs and have been thinking about something for it. Does anyone have
a favorite editor that they think would be worth trying pythoscope
integration? The first step would just be the static analysis. A
users would just hit a button and their source code in their editor
could have test code generated for them. Thoughts?

Paul

Andre Roberge

unread,
Nov 29, 2008, 4:41:59 PM11/29/08
to pytho...@googlegroups.com
I've been using Komodo IDE ($$) after using the free Komodo Edit
(and/or Open Komodo now?). I believe it already has a pyunit and nose
plugin.

http://www.activestate.com/Products/komodo_ide/feature_showcase.mhtml

I think it would be cool to have it integrated in it.

André

>
> Paul
>
> >
>

Kent Tenney

unread,
Nov 30, 2008, 10:54:49 AM11/30/08
to pytho...@googlegroups.com, leo-e...@googlegroups.com
I also like this kind of stuff, my efforts are directed at Leo
http://webpages.charter.net/edreamleo/front.html
https://launchpad.net/leo-editor

$ bzr branch lp:leo-editor

Leo is a powerful easy to use outline-based editor.
Written in pure Python, it is so extensible it can be considered
a development framework for information management.

The user community is very active, and the BD:
https://launchpad.net/~edreamleo
is very B, responsive and helpful. He works nearly full time on Leo

IPython has incorporated Leo as the 'workbook' provider. The IPython guy was
very impressed with the ease of integrating with Leo.

The use case you have could be tested with the following pseudocode:

@button pythoscope
\
import pythoscope
this_file = p.getExternalFile
pythoscope.gentests(this_file)

@button => Leo creates a clickable icon in the toolbar to run the code
in the body
of the node

p => the node currently focused

getExternalFile => Leo has many tools to manage files on the
filesystem. It's great
for organizing not only data, but files. (and data therein ...)

given this node, you click on the toolbar icon named 'script-button', and the
'pythoscope' button is added to the toolbar.

Now, while editing a Python source file in Leo, a click on the
'pythoscope' button
will run gentests.

@buttons offers instant gratification, there is also a powerful plugin
framework.

If this intrigues, I suggest posting an inquiry to the Leo list.
http://groups.google.com/group/leo-editor

Thanks,
Kent

>
> Paul
>
> >
>

Paul Hildebrandt

unread,
Nov 30, 2008, 2:31:02 PM11/30/08
to pytho...@googlegroups.com, leo-e...@googlegroups.com
That does look interesting. Leo looks like a cool editor. I think what
you propose looks like painless integration assuming pythoscope provides
the correct hooks. I will have to dig into it a little more but it
looks as if Leo already provides automatic static unit test generation.

@test nodes create unit tests automatically
http://sourceforge.net/project/screenshots.php?group_id=3458&ssid=5350

As to not just add redundant features we would need to make sure that
pythoscope would be adding something. If it does indeed add something
maybe the integration point should (also?) be the @test node.

Paul

>
>> Paul
>>
>>
>
> >
>

Paul Hildebrandt

unread,
Nov 30, 2008, 6:27:45 PM11/30/08
to Pythoscope
I like the idea of integration into Komodo. I downloaded that free
version (Komodo Edit) and tried the plug-in kNose. It gives red/greed
bar interface to Komodo using nose under the covers. I wrote the
author of kNose, Brandon Corfman, to discuss possible integration with
Pythoscope as well.

Paul

On Nov 29, 1:41 pm, "Andre Roberge" <andre.robe...@gmail.com> wrote:
> On Sat, Nov 29, 2008 at 4:14 PM, Paul Hildebrandt
>

Kent Tenney

unread,
Dec 1, 2008, 12:33:41 PM12/1/08
to pytho...@googlegroups.com
I've never used @test nodes.

I think pythoscope offers a lot more than @test nodes.
I'll have a go at integration.

>
> Paul
>
>>
>>> Paul
>>>
>>>
>>
>> >
>>
>
>
> >
>

Paul Hildebrandt

unread,
Dec 1, 2008, 1:10:41 PM12/1/08
to pytho...@googlegroups.com
Cool!   Keep us updated.

Paul

--

Michał Kwiatkowski

unread,
Dec 1, 2008, 3:41:47 PM12/1/08
to pytho...@googlegroups.com
Hi,

It's cool you got those things started on editor's integration.

From my part, I hacked some Elisp code today, so if anyone uses Emacs
please give it a try. Simply put the following into your .emacs, open
a file from pythoscope-initialized project and run with "M-x
pythoscope-run-on-current-file". This isn't bullet-proof yet, just
wanting to see if that's the right way to go. Let me know what you
think.

Oh, and I'm using Emacs 23.0.60.1 from Ubuntu, hope it works on older versions.

Cheers,
mk

===== emacs integration code start =====

(defun pluralize (word count)
"Return word with a counter in singular or plural form, depending on count."
(if (= count 1)
(format "one %s" word)
(format "%d %ss" count word)))

(defvar *pythoscope-process-output* "")

(defun pythoscope-generated-tests ()
"Based on output collected in *pythoscope-process-output* return hash
mapping modules to number of tests that where added to them."
(let ((tests (make-hash-table :test #'equal)))
(loop for start = 0 then (match-end 0)
while (string-match "Adding generated \\w+ to \\(.*?\\)\\.$"
*pythoscope-process-output* start)
do
(let ((modname (match-string 1 *pythoscope-process-output*)))
(puthash modname (1+ (gethash modname tests 0)) tests)))
tests))

(defun pythoscope-tests-hash-to-descriptions (tests)
(loop for modname being the hash-keys in tests
using (hash-value test-count)
collect (format "%s for %s" (pluralize "test" test-count) modname)))

(defun pythoscope-generated-tests-summary ()
(let ((tests (pythoscope-generated-tests)))
(if (zerop (hash-table-count tests))
"No tests were generated."
(concat "Generated "
(string-join ", " (pythoscope-tests-hash-to-descriptions tests))
"."))))

(defun pythoscope-process-sentinel (process event)
(when (memq (process-status process) '(signal exit))
(let ((exit-status (process-exit-status process)))
(if (zerop exit-status)
(message (pythoscope-generated-tests-summary))
(message "pythoscope[%d] exited with code %d"
(process-id process) exit-status)))))

(defun pythoscope-process-filter (process output)
"Save all pythoscope output to *pythoscope-process-output* for later
inspection."
(setq *pythoscope-process-output*
(concat *pythoscope-process-output* output)))

(defun pythoscope-run-on-file (filename)
"Generate tests for given file using pythoscope."
(interactive "f")
(setq *pythoscope-process-output* "")
(let ((process (start-process "pythoscope-process"
(current-buffer)
"pythoscope"
filename)))
(set-process-sentinel process 'pythoscope-process-sentinel)
(set-process-filter process 'pythoscope-process-filter))
(message "Generating tests..."))

(defun pythoscope-run-on-current-file ()
"Generate tests for file open in the current buffer."
(interactive)
(let ((filename (buffer-file-name)))
(when filename
(pythoscope-run-on-file filename))))

===== emacs integration code end =====

Edward K. Ream

unread,
Dec 2, 2008, 11:22:15 AM12/2/08
to Pythoscope


On Nov 30, 1:31 pm, Paul Hildebrandt
<Paul.Hildebra...@disneyanimation.com> wrote:

> That does look interesting.  Leo looks like a cool editor.  I think what
> you propose looks like painless integration assuming pythoscope provides
> the correct hooks.  I will have to dig into it a little more but it
> looks as if Leo already provides automatic static unit test generation.

Hi Paul,

I'm the author of Leo. Kent is the best kind of "troublemaker": he
looks around for new ways to use Leo, and in the process upsets our
comfortable routines :-)

When I read Kent's first post I had two thoughts. First, pythoscope
could solve some big unit test problems for Leo. Second, that it
would be cool to have pythoscope/Leo generate @test nodes, just as you
say.

I've just returned from vacation, so it may be a day or two before I
can dive into pythoscope, but I suspect pythoscope will benefit Leo
greatly. Thanks for your great work. I look forward to fruitful
cooperation between our projects.

Edward

Michał Kwiatkowski

unread,
Dec 2, 2008, 2:21:39 PM12/2/08
to pytho...@googlegroups.com
On Tue, Dec 2, 2008 at 5:22 PM, Edward K. Ream <edre...@gmail.com> wrote:
> I'm the author of Leo. Kent is the best kind of "troublemaker": he
> looks around for new ways to use Leo, and in the process upsets our
> comfortable routines :-)
>
> When I read Kent's first post I had two thoughts. First, pythoscope
> could solve some big unit test problems for Leo. Second, that it
> would be cool to have pythoscope/Leo generate @test nodes, just as you
> say.
>
> I've just returned from vacation, so it may be a day or two before I
> can dive into pythoscope, but I suspect pythoscope will benefit Leo
> greatly. Thanks for your great work. I look forward to fruitful
> cooperation between our projects.

Same here, Edward. I'm excited people want to integrate Pythoscope
with different editors. It's a sign that it *is* useful after all. :-)

Pythoscope is still pretty experimental and its internal structure
tend to change from time to time, so let me know if you have any
questions about how to interface with it.

Cheers,
mk

Edward K. Ream

unread,
Dec 2, 2008, 2:54:10 PM12/2/08
to pytho...@googlegroups.com
On Tue, Dec 2, 2008 at 1:21 PM, Michał Kwiatkowski
<consta...@gmail.com> wrote:

> Same here, Edward. I'm excited people want to integrate Pythoscope
> with different editors. It's a sign that it *is* useful after all. :-)

Excellent.

> Pythoscope is still pretty experimental and its internal structure
> tend to change from time to time, so let me know if you have any
> questions about how to interface with it.

It all seems like magic at present. I've downloaded Pythoscope from
lp:pythoscope and installed it with python setup.py install.

Here are some newbie confusions. Newbies always find the bugs :-)

1. I wasn't sure which directory should be used when using pythoscope
--init. I guessed it should be Leo's trunk directory so I could do
'pythoscope leo'. That is, I thought it would be useful to do the
entire leo package. And yes, the leo directory *is* a package.

2. However, 'pythoscope leo' started analyzing lots of files, so I hit
ctrl-c and got a traceback saying to report a bug. I'm pretty sure
that's not necessary :-)

3. In an effort to reduce the amount of work that pythoscope was doing
(I was in a hurry just to see what kind of output pythoscope was going
to create), I specified the leo/core package. But still, pythoscope
started analyzing packages outside the leo/core package, so again I
hit ctrl-c.

4. The tutorial said I could point pythoscope at a single file, so I did::

pythoscope leo/core/leoNodes.py

This still analyzes a lot, but ok, I let it run. Now I got a real bug:

QQQQQQ
pythoscope leo/core/leoNodes.py
INFO: Inspecting module launchLeo.py.
INFO: Inspecting module leo\core\komodo-test-data.py.
INFO: Inspecting module leo\core\komodo-test.py.
INFO: Inspecting module leo\core\leoApp.py.
INFO: Inspecting module leo\core\leoAtFile.py.
INFO: Inspecting module leo\core\leoBridge.py.
INFO: Inspecting module leo\core\leoBridgeTest.py.
INFO: Inspecting module leo\core\leoChapters.py.
INFO: Inspecting module leo\core\leoColor.py.
INFO: Inspecting module leo\core\leoCommands.py.
INFO: Inspecting module leo\core\leoCompare.py.
INFO: Inspecting module leo\core\leoConfig.py.
INFO: Inspecting module leo\core\leoDebugger.py.
INFO: Inspecting module leo\core\leoDynamicTest.py.
INFO: Inspecting module leo\core\leoEditCommands.py.
INFO: Inspecting module leo\core\leoFileCommands.py.
INFO: Inspecting module leo\core\leoFind.py.
INFO: Inspecting module leo\core\leoFrame.py.
INFO: Inspecting module leo\core\leoGlobals.py.
INFO: Inspecting module leo\core\leoGui.py.
INFO: Inspecting module leo\core\leoImport.py.
INFO: Inspecting module leo\core\leoKeys.py.
INFO: Inspecting module leo\core\leoMenu.py.
INFO: Inspecting module leo\core\leoNodes.py.
INFO: Inspecting module leo\core\leoPlugins.py.
INFO: Inspecting module leo\core\leoPymacs.py.
INFO: Inspecting module leo\core\leoShadow.py.
INFO: Inspecting module leo\core\leoTangle.py.
INFO: Inspecting module leo\core\leoTest.py.
INFO: Inspecting module leo\core\leoUndo.py.
INFO: Inspecting module leo\core\leo_Debugger.py.
INFO: Inspecting module leo\core\leo_FileList.py.
INFO: Inspecting module leo\core\leo_RemoteDebugger.py.
INFO: Inspecting module leo\core\leo_run.py.
INFO: Inspecting module leo\core\leo_Shell.py.
INFO: Inspecting module leo\core\runLeo.py.
INFO: Inspecting module leo\core\scriptFile.py.
INFO: Inspecting module leo\core\__init__.py.
INFO: Inspecting module leo\dist\leo-post-install-script.py.
INFO: Inspecting module leo\extensions\asciidoc.py.
INFO: Inspecting module leo\extensions\colors.py.
INFO: Inspecting module leo\extensions\Gato\AnimatedAlgorithms.py.
INFO: Inspecting module leo\extensions\Gato\AnimatedDataStructures.py.
INFO: Inspecting module leo\extensions\Gato\AnimationHistory.py.
INFO: Inspecting module leo\extensions\Gato\DataStructures.py.
INFO: Inspecting module leo\extensions\Gato\EditObjectAttributesDialog.py.
INFO: Inspecting module leo\extensions\Gato\Embedder.py.
INFO: Inspecting module leo\extensions\Gato\Gato.py.
INFO: Inspecting module leo\extensions\Gato\GatoConfiguration.py.
INFO: Inspecting module leo\extensions\Gato\GatoDialogs.py.
INFO: Inspecting module leo\extensions\Gato\GatoFile.py.
INFO: Inspecting module leo\extensions\Gato\GatoGlobals.py.
INFO: Inspecting module leo\extensions\Gato\GatoIcons.py.
INFO: Inspecting module leo\extensions\Gato\GatoSystemConfiguration.py.
INFO: Inspecting module leo\extensions\Gato\GatoTest.py.
INFO: Inspecting module leo\extensions\Gato\GatoUtil.py.
INFO: Inspecting module leo\extensions\Gato\Graph.py.
INFO: Inspecting module leo\extensions\Gato\GraphCreator.py.
INFO: Inspecting module leo\extensions\Gato\GraphDisplay.py.
INFO: Inspecting module leo\extensions\Gato\GraphEditor.py.
INFO: Inspecting module leo\extensions\Gato\GraphUtil.py.
INFO: Inspecting module leo\extensions\Gato\Gred.py.
INFO: Inspecting module leo\extensions\Gato\logging.py.
INFO: Inspecting module leo\extensions\Gato\PlanarEmbedding.py.
INFO: Inspecting module leo\extensions\Gato\PlanarityTest.py.
INFO: Inspecting module leo\extensions\Gato\TextTreeWidget.py.
INFO: Inspecting module leo\extensions\Gato\TreeWidget.py.
INFO: Inspecting module leo\extensions\Gato\__init__.py.
INFO: Inspecting module leo\extensions\optparse.py.
INFO: Inspecting module leo\extensions\path.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\bin\bundlepmw.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\contrib\DirBrowser.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\contrib\MCListbox.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\contrib\PmwFileDialog.py.
INFO: Inspecting module
leo\extensions\Pmw\Pmw_1_3\contrib\PmwFullTimeCounter.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\contrib\PmwVerticalGauge.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\contrib\TreeBrowser.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\AboutDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\All.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\Args.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\Balloon.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\BltGraph.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\BltTabset.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ButtonBox.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\Colors.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ComboBox.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ComboBoxDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ConfigClass.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\Counter.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\CounterDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\DemoVersion.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\Dialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\EntryField.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ErrorHandling.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ExampleDemo.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\Grid.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\Group.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\HistoryText.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\LabeledWidget.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\LogicalFont.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\MainMenuBar.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\MenuBar.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\MessageBar.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\MessageDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\MessageInfo.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\MultiLineLabel.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\NestedDialogs.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\NoteBook.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\NoteBook_2.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\NoteBook_3.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\OptionMenu.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\PanedWidget.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\PanedWidget_2.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\PromptDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\RadioSelect.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\Resources.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\Resources_Pmw.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ScrolledCanvas.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ScrolledField.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ScrolledFrame.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ScrolledListBox.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ScrolledText.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ScrolledText_2.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\SelectionDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\ShowBusy.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\SpecialCounter.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\SpecialEntry.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\Spectrum.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\SpeedTest.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\SubClassing.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\TextDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\TextDisplay.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\TimeCounter.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\demos\WidgetDestroy.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\doc\example.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\doc\ExampleDemo.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\doc\exercises.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\doc\ScrolledText_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwAboutDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwBalloon.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwBase.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwBlt.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwButtonBox.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwColor.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwComboBox.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwComboBoxDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwCounter.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwCounterDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwEntryField.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwGroup.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwHistoryText.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwLabeledWidget.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwLoader.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwLogicalFont.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwMainMenuBar.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwMenuBar.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwMessageBar.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwMessageDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwNoteBook.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwOptionMenu.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwPanedWidget.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwPromptDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwRadioSelect.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwScrolledCanvas.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwScrolledField.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwScrolledFrame.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwScrolledListBox.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwScrolledText.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwSelectionDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwTextDialog.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwTimeCounter.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\PmwTimeFuncs.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\lib\__init__.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\AboutDialog_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\All.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\Blt_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\ButtonBox_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\Colors_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\ComboBox_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\CounterDialog_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\Counter_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\Dialog_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\EntryField_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\LabeledWidget_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\ManualTests.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\MegaWidget_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\MessageDialog_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\NoteBook_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\OptionMenu_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\Options_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\PanedWidget_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\PmwBase_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\PromptDialog_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\RadioSelect_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\ScrolledCanvas_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\ScrolledField_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\ScrolledFrame_test.py.
INFO: Inspecting module
leo\extensions\Pmw\Pmw_1_3\tests\ScrolledListBox_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\ScrolledText_test.py.
INFO: Inspecting module
leo\extensions\Pmw\Pmw_1_3\tests\SelectionDialog_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\Test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\TestVersion.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\TextDialog_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\tests\Tkinter_test.py.
INFO: Inspecting module leo\extensions\Pmw\Pmw_1_3\__init__.py.
INFO: Inspecting module leo\extensions\Pmw\__init__.py.
INFO: Inspecting module leo\extensions\sets.py.
INFO: Inspecting module leo\extensions\subprocess.py.
INFO: Inspecting module leo\extensions\testExtension.py.
INFO: Inspecting module leo\modes\actionscript.py.
INFO: Inspecting module leo\modes\ada95.py.
INFO: Inspecting module leo\modes\ahk.py.
INFO: Inspecting module leo\modes\antlr.py.
INFO: Inspecting module leo\modes\apacheconf.py.
INFO: Inspecting module leo\modes\apdl.py.
INFO: Inspecting module leo\modes\applescript.py.
INFO: Inspecting module leo\modes\asp.py.
INFO: Inspecting module leo\modes\aspect_j.py.
INFO: Inspecting module leo\modes\assembly_macro32.py.
INFO: Inspecting module leo\modes\assembly_mcs51.py.
INFO: Inspecting module leo\modes\assembly_parrot.py.
INFO: Inspecting module leo\modes\assembly_r2000.py.
INFO: Inspecting module leo\modes\assembly_x86.py.
INFO: Inspecting module leo\modes\awk.py.
INFO: Inspecting module leo\modes\b.py.
INFO: Inspecting module leo\modes\batch.py.
INFO: Inspecting module leo\modes\bbj.py.
INFO: Inspecting module leo\modes\bcel.py.
INFO: Inspecting module leo\modes\bibtex.py.
INFO: Inspecting module leo\modes\c.py.
INFO: Inspecting module leo\modes\chill.py.
INFO: Inspecting module leo\modes\cobol.py.
INFO: Inspecting module leo\modes\coldfusion.py.
INFO: Inspecting module leo\modes\cplusplus.py.
INFO: Inspecting module leo\modes\csharp.py.
INFO: Inspecting module leo\modes\css.py.
INFO: Inspecting module leo\modes\cvs_commit.py.
INFO: Inspecting module leo\modes\d.py.
INFO: Inspecting module leo\modes\doxygen.py.
INFO: Inspecting module leo\modes\dsssl.py.
INFO: Inspecting module leo\modes\eiffel.py.
INFO: Inspecting module leo\modes\embperl.py.
INFO: Inspecting module leo\modes\erlang.py.
INFO: Inspecting module leo\modes\factor.py.
INFO: Inspecting module leo\modes\forth.py.
INFO: Inspecting module leo\modes\fortran.py.
INFO: Inspecting module leo\modes\foxpro.py.
INFO: Inspecting module leo\modes\freemarker.py.
INFO: Inspecting module leo\modes\gettext.py.
INFO: Inspecting module leo\modes\groovy.py.
INFO: Inspecting module leo\modes\haskell.py.
INFO: Inspecting module leo\modes\hex.py.
INFO: Inspecting module leo\modes\html.py.
INFO: Inspecting module leo\modes\i4gl.py.
INFO: Inspecting module leo\modes\icon.py.
INFO: Inspecting module leo\modes\idl.py.
INFO: Inspecting module leo\modes\inform.py.
INFO: Inspecting module leo\modes\ini.py.
INFO: Inspecting module leo\modes\inno_setup.py.
INFO: Inspecting module leo\modes\interlis.py.
INFO: Inspecting module leo\modes\io.py.
INFO: Inspecting module leo\modes\java.py.
INFO: Inspecting module leo\modes\javascript.py.
INFO: Inspecting module leo\modes\jcl.py.
INFO: Inspecting module leo\modes\jhtml.py.
INFO: Inspecting module leo\modes\jmk.py.
INFO: Inspecting module leo\modes\jsp.py.
INFO: Inspecting module leo\modes\latex.py.
ERROR: Oops, it seems internal Pythoscope error occured. Please file a
bug report at https://bugs.launchpad.net/pythoscope

Traceback (most recent call last):
File "c:\Python25\Scripts\pythoscope-script.py", line 8, in <module>
load_entry_point('pythoscope==0.3.2', 'console_scripts', 'pythoscope')()
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\pythoscope\__init__.py",
line 176, in main
generate_tests(args, force, template)
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\pythoscope\__init__.py",
line 104, in generate_tests
inspect_project(project)
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\pythoscope\inspector\__init__.py",
line 11, in inspect_project
updates = add_and_update_modules(project) +
add_and_update_points_of_entry(project)
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\pythoscope\inspector\__init__.py",
line 36, in add_and_update_modules
static.inspect_module(project, modpath)
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\pythoscope\inspector\static.py",
line 119, in inspect_module
return inspect_code(project, path, read_file_contents(path))
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\pythoscope\inspector\static.py",
line 126, in inspect_code
visitor = descend(tree, ModuleVisitor)
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\pythoscope\astvisitor.py",
line 58, in descend
visitor.visit(tree)
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\pythoscope\astvisitor.py",
line 234, in visit
self.visit_node(tree)
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\pythoscope\astvisitor.py",
line 247, in visit_node
if pattern.match(node, results):
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\lib2to3\pytree.py",
line 428, in match
if not self._submatch(node, r):
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\lib2to3\pytree.py",
line 542, in _submatch
for c, r in generate_matches(self.content, node.children):
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\lib2to3\pytree.py",
line 744, in generate_matches
for c0, r0 in p.generate_matches(nodes):
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\lib2to3\pytree.py",
line 658, in generate_matches
for count, r in self._recursive_matches(nodes, 0):

[big snip]

File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\lib2to3\pytree.py",
line 686, in _recursive_matches
for c0, r0 in generate_matches(alt, nodes):
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\lib2to3\pytree.py",
line 744, in generate_matches
for c0, r0 in p.generate_matches(nodes):
File "c:\python25\lib\site-packages\pythoscope-0.3.2-py2.5.egg\lib2to3\pytree.py",
line 451, in generate_matches
if nodes and self.match(nodes[0], r):
RuntimeError: maximum recursion depth exceeded

C:\leo.repo\trunk>
QQQQQQ

So I'm stuck. What should I do next?

Edward
--------------------------------------------------------------------
Edward K. Ream email: edre...@gmail.com
Leo: http://webpages.charter.net/edreamleo/front.html
--------------------------------------------------------------------

Edward K. Ream

unread,
Dec 2, 2008, 3:35:58 PM12/2/08
to Pythoscope


On Dec 2, 1:54 pm, "Edward K. Ream" <edream...@gmail.com> wrote:

>
> read more »

Edward K. Ream

unread,
Dec 2, 2008, 3:46:48 PM12/2/08
to Pythoscope
On Dec 2, 1:54 pm, "Edward K. Ream" <edream...@gmail.com> wrote:

> So I'm stuck.

While waiting for help, I created @@auto nodes (disabled @auto nodes)
for all of pythoscope's source files. They are in test.leo in rev
1278 of Leo's trunk at lp:leo-editor The pythoscope sources are
"clean": @auto imported these files without any problems.

I created these nodes so I can study the sources with Leo. As usual,
I disabled the @auto nodes so there is no chance of anyone changing
the actual pythoscope sources inadvertently.

Edward

Michał Kwiatkowski

unread,
Dec 2, 2008, 3:47:25 PM12/2/08
to pytho...@googlegroups.com
2008/12/2 Edward K. Ream <edre...@gmail.com>:

> 1. I wasn't sure which directory should be used when using pythoscope
> --init. I guessed it should be Leo's trunk directory so I could do
> 'pythoscope leo'. That is, I thought it would be useful to do the
> entire leo package. And yes, the leo directory *is* a package.

Yes, your project top directory is the right one to use.

> 2. However, 'pythoscope leo' started analyzing lots of files, so I hit
> ctrl-c and got a traceback saying to report a bug. I'm pretty sure
> that's not necessary :-)
>
> 3. In an effort to reduce the amount of work that pythoscope was doing
> (I was in a hurry just to see what kind of output pythoscope was going
> to create), I specified the leo/core package. But still, pythoscope
> started analyzing packages outside the leo/core package, so again I
> hit ctrl-c.

Analyze step is implicit in Pythoscope. What you specify as arguments
to pythoscope command is modules you want to generate tests for.

Still, if all you want is to generate test stubs, I admit, there is no
good reason for Pythoscope to analyze everything. Since this is a real
pain for bigger projects and I've heard this complain before, I will
probably fix this sooner than later.

Having said that, dynamic analysis puts more requirements on what we
have to analyze statically. The reason why Pythoscope currently
inspects everything can be summarized in the following two points:

* you can't run any dynamic analysis without prior static knowledge
about the system, like location and contents of modules
* understanding dependencies between modules is a hard problem, one
which we currently avoid by analyzing everything

There is a plan to make Pythoscope faster, see
http://pythoscope.org/improving-performance for some rough overview. I
think some of those optimizations may actually be fun to implement, so
if anyone has some free time on their hands, I'll be happy to accept
patches. ;-)

> 4. The tutorial said I could point pythoscope at a single file, so I did::
>
> pythoscope leo/core/leoNodes.py
>
> This still analyzes a lot, but ok, I let it run.

Yeah, see above. And thanks for patience. :-)

> Now I got a real bug:
>
> QQQQQQ
> pythoscope leo/core/leoNodes.py
> INFO: Inspecting module launchLeo.py.
> INFO: Inspecting module leo\core\komodo-test-data.py.

[cut lots of inspects]

That seems like a bug. Let's track that here:

https://bugs.launchpad.net/pythoscope/+bug/304541

In the meantime, if you just want to play with Pythoscope to see what
it can do, you may choose a smaller project for testing. Even a simple
script will do. You can also read the tutorial:
http://pythoscope.org/documentation , but you have probably done that
already.

Cheers,
mk

Kent Tenney

unread,
Dec 2, 2008, 4:42:26 PM12/2/08
to pytho...@googlegroups.com, leo-e...@googlegroups.com
a tip I've found useful;
the default is stubs which fail, but the
'nose' type stubs succeed by default.

$ pythoscope -t nose leo/core/leoGlobals.py

will result in the file
tests/test_leo_core_leoGlobals.py

which, when run
$ python tests/test_leo_core_leoGlobals.py

will be silent.

If the `-t nose` option is not used, every test
issues a failure notice.

Paul Hildebrandt

unread,
Dec 2, 2008, 4:48:32 PM12/2/08
to pytho...@googlegroups.com, leo-e...@googlegroups.com
Michal and I've talked several times about wanting to implement a nose type skip test helper for unittest.  It's even been brought up on this list.  I made a blue print for it here. 
https://blueprints.launchpad.net/pythoscope/+spec/provide-skip-test-function
We agree it should be done.  :)

Kent Tenney wrote:
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Pythoscope" group.
To post to this group, send email to pytho...@googlegroups.com
To unsubscribe from this group, send email to pythoscope+...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/pythoscope?hl=en
-~----------~----~----~----~------~----~------~--~---

  


--

Edward K. Ream

unread,
Dec 3, 2008, 9:44:37 AM12/3/08
to pytho...@googlegroups.com
On Tue, Dec 2, 2008 at 2:47 PM, Michał Kwiatkowski
<consta...@gmail.com> wrote:

> Analyze step is implicit in Pythoscope. What you specify as arguments
> to pythoscope command is modules you want to generate tests for.
>
> Still, if all you want is to generate test stubs, I admit, there is no
> good reason for Pythoscope to analyze everything. Since this is a real
> pain for bigger projects and I've heard this complain before, I will
> probably fix this sooner than later.

Iirc, the reason why I mentioned this was simply to give you the
context of what I was doing, and to indicate that the docs weren't
clear that it would happen. At present, at least, I don't consider it
a bug.

> Having said that, dynamic analysis puts more requirements on what we
> have to analyze statically. The reason why Pythoscope currently
> inspects everything can be summarized in the following two points:
>
> * you can't run any dynamic analysis without prior static knowledge
> about the system, like location and contents of modules
> * understanding dependencies between modules is a hard problem, one
> which we currently avoid by analyzing everything

Thanks for this explanation.

> There is a plan to make Pythoscope faster, see
> http://pythoscope.org/improving-performance for some rough overview. I
> think some of those optimizations may actually be fun to implement, so
> if anyone has some free time on their hands, I'll be happy to accept
> patches. ;-)

:-)

>> 4. The tutorial said I could point pythoscope at a single file, so I did::
>>
>> pythoscope leo/core/leoNodes.py
>>
>> This still analyzes a lot, but ok, I let it run.
>
> Yeah, see above. And thanks for patience. :-)
>
>> Now I got a real bug:

> That seems like a bug. Let's track that here:
>
> https://bugs.launchpad.net/pythoscope/+bug/304541

Thanks for creating this page.

> In the meantime, if you just want to play with Pythoscope to see what
> it can do, you may choose a smaller project for testing. Even a simple
> script will do.

Good idea. Thanks.

Edward

Michał Kwiatkowski

unread,
Dec 3, 2008, 4:23:32 PM12/3/08
to pytho...@googlegroups.com
Hi,

It looks like Leo is pushing Pythoscope to its limits. Raising max
recursion limit to around 2500 makes the original problem disappear,
but shows another one - memory consumption. Leo has more than 500
Python files. After Pythoscope analyzed around 270 and allocated
around 1.2 Gb of memory I was forced to kill the process. We either
have a memory leak, or we simply use really lousy data structures. I
will investigate that more later.

BTW, any recommendations for Python memory profilers?

Cheers,
mk

Edward K. Ream

unread,
Dec 3, 2008, 4:33:43 PM12/3/08
to pytho...@googlegroups.com
On Wed, Dec 3, 2008 at 3:23 PM, Michał Kwiatkowski
<consta...@gmail.com> wrote:

> It looks like Leo is pushing Pythoscope to its limits.

Glad to be of help :-)

> We either have a memory leak, or we simply use really lousy data structures. I will investigate that more later.

I'm sure you will fix the proximate cause of the problem.

However, many of Leo's "500 files" are in the extensions folder, and I
don't see how they should need to be analyzed in order to generate
test cases for Leo's two dozen or so core files. Would it be feasible
to use an "ignore list"?

Edward

Michał Kwiatkowski

unread,
Dec 3, 2008, 5:11:25 PM12/3/08
to pytho...@googlegroups.com
2008/12/3 Edward K. Ream <edre...@gmail.com>:

>> We either have a memory leak, or we simply use really lousy data structures. I will investigate that more later.
>
> I'm sure you will fix the proximate cause of the problem.
>
> However, many of Leo's "500 files" are in the extensions folder, and I
> don't see how they should need to be analyzed in order to generate
> test cases for Leo's two dozen or so core files. Would it be feasible
> to use an "ignore list"?

Yeah, another item on a looong TODO list. ;-)

Cheers,
mk

Kent Tenney

unread,
Feb 4, 2009, 10:26:48 AM2/4/09
to pytho...@googlegroups.com
Howdy,

I have been looking at the pythoscope code and have a few questions
regarding integration with the Leo editor.

The capability I want is:

Clicking a button in Leo while editing code will run tests and report results,
creating the tests if they don't exist.

While editing a method or function in Leo, clicking a button will take
me to the corresponding test, visa versa.

For synching the code and test, what is the proper way to fetch the munged
test file path and method/function name?

ie: I'm editing the Tool.run(self) method in ~/work/mytools/tool.py
what do I call to get "~/work/tests/test_mytool_tool.py"
and "def test_run(self)"

and visa versa.

I cobbled together string mungage to do it, but would prefer
using Pythoscope.

Thanks,
Kent

On Tue, Dec 2, 2008 at 12:10 PM, Paul Hildebrandt

Michał Kwiatkowski

unread,
Feb 5, 2009, 4:06:55 PM2/5/09
to pytho...@googlegroups.com
On Wed, Feb 4, 2009 at 4:26 PM, Kent Tenney <kte...@gmail.com> wrote:
> I have been looking at the pythoscope code and have a few questions
> regarding integration with the Leo editor.
>
> The capability I want is:
>
> Clicking a button in Leo while editing code will run tests and report results,
> creating the tests if they don't exist.

Probably the easiest way to do this is to call "pythoscope <name of
the module>" first, followed by invocation of your test runner of
choice. Since pythoscope won't overwrite any existing tests, running
it like that shouldn't do any harm. Note that it will (unless no
changes were made to the project) re-run the dynamic inspection
though. We could provide a --skip-dynamic-inspection option if that is
what you need.

> While editing a method or function in Leo, clicking a button will take
> me to the corresponding test, visa versa.
>
> For synching the code and test, what is the proper way to fetch the munged
> test file path and method/function name?
>
> ie: I'm editing the Tool.run(self) method in ~/work/mytools/tool.py
> what do I call to get "~/work/tests/test_mytool_tool.py"
> and "def test_run(self)"
>
> and visa versa.

Currently Pythoscope only has functions which help it to match
application modules with test modules. No matching is done on the
method/function level. The reason for this is that, although during
run Pythoscope knows exactly which functions/methods it generates
tests for, it doesn't save that information anywhere. While this data
is not needed by Pythoscope itself right now I see its usefulness in
editor integration and would very much like to see this functionality
included. So, if you like to modify Pythoscope to keep all this
additional information, I will happily accept a patch. :-)

I don't want to leave you empty-handed, so here's a piece of code that
matches application modules with test modules. It works for many
different test location conventions, not only the default one used by
Pythoscope.

----- code start -----
from pythoscope.store import Project
from pythoscope.generator.adder import find_associate_test_module_by_name

PROJECT_DIR = "/tmp/foo" # must be already inspected by pythoscope
CURRENT_MODULE = "bar.py" # relative to PROJECT_DIR

project = Project.from_directory(PROJECT_DIR)
module = project[CURRENT_MODULE]

test_module = find_associate_test_module_by_name(project, module)
if test_module:
# test_module.get_path() will return an absolute path
else:
# no test file for given module exist
----- code end -----

Hope that helps.

Cheers,
mk

Reply all
Reply to author
Forward
0 new messages