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 =====
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
> 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
--------------------------------------------------------------------
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
$ 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.
--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
> 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
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
> 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
Yeah, another item on a looong TODO list. ;-)
Cheers,
mk
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
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