monodevelop-python revisited

Development on my python addin for monodevelop has gone so quickly that I've gotten pretty excited about working on it. It has come from realization to working code in just a few short days. So I thought I'd put together a little overview of what I have added this week and where I'd like to go.

As an aside, I've noticed frequently that people do not understand that monodevelop can be used for more than writing .NET. Like many other IDE shells, it is a framework that facilitates development tools. It happens to be written and deployed on Mono. I think because of this, we may want to alter naming of addins in a way that make it less confusing. Michael Hutchinson suggested PyDevelop/RubyDevelop. Of course, RubyDevelop doesn't exist yet. IronRuby's AST should make that doable in a relatively short time period if someone is interested.

Its worthwhile to note that I only have support for python2.5. However, the core is built already to support more versions of the python runtime. I just need to do it.

Compiling of Code

Often times I forget that python code is compiled because it works so well. You can pre-compile your code to save a marginal amount of time during startup. It also lets you be sure that your code is syntactically correct. Debug mode will generate .pyc's by default and Release mode will generate .pyo's.

Parsing of Python

The parsing of python happens in a python subprocess. I originally did the interaction with the host process over stdin/stdout. I moved away from this as it became a source of contention as there is inherently no concurrency. Both python and .NET happen to come with HTTP utilities and I get concurrency for free! Therefore, the python process sets up an embedded HTTP server and the .NET code POST's to it. The result of the parsing comes back as an XML representation of the python AST along with some extra sauce. For example, I also analyze the code with pyflakes if it is available, allowing for warnings to be displayed inline with errors. You can see this in the image below. Currently, these are highlighted in red as well with errors, but I believe this will be changed in monodevelop before too long. Any of yellow, green, or blue would be a good choice in my opinion.

Python Source Regions

Now that we have an AST representation of the python source code we can start to do fancy things with it. We know how big blocks of code are, where they are located, and what modules they interact with. Using this knowledge, we build DomRegions to be used by the editor. This gives us code folding as you can see below.

You will notice throughout the rest of this overview, how this AST is fundamental to providing language support.

From the AST, I currently have information about:

  • imports
  • classes
  • functions (and their arguments)
  • attributes
  • locals
  • pydoc's
  • comments (well, not done through the AST, yet)

Code Completion

With both regional and contextual information available, we can take the current editor cursor position to know where we currently are within the AST. This allows us to provide code completion for locals, attributes, functions, modules and whatnot. Note that I just have basic functionality here, and I intend to really beef this up in the short term. The proof that it works is there, so thats a decent start.

Smart Indentation

Its important for your text editor to not slow you down from your current thought process. One of the easiest ways to keep your flow moving is to always have your cursor in the right position. The editor will flow with your movements for blocks. This is really quite simple in python, as blocks are prefixed with a line ending in a colon “class Hi:”. My implementation of this may not be the correct way to go, but “it works”. Also note, until per project code formatting arrives in monodevelop, you should set your tab vs. spaces mode to 4 spaces.

Class Browser

Monodevelop includes an extensible class browser pad. The implementation really is a piece of art. I've been fortunate enough to write code for it a few times in the past. Anyhow, we use the AST objects directly within this tree to render a hierarchy of the modules within your project. I'd like to include imported modules outside your project as well.

Document Outline

In similar spirit to the class browser, the document outline pad provides a module hierarchy for the currently open source file. The implementation here is currently hack'ish do to the interfaces being very .NET specific. It sounds like this may change before monodevelop 2.0 is released.

Editor ComboBox JumpTo

Many developers have come to love the combobox at the top of the editor to jump to regions within their source file. I personally like to keep my individual sources as succinct as possible, but I understand why its useful. Therefore, I support that as well. Again, this is sort of hack'ish do the the current interfaces.

Where would I like to go?

I have lots of ideas and diminishing time to implement them. So if anyone feels like helping, its time to speak up.

The debugger interfaces appear to be stabilizing, so this sounds like a feature worth implementing. The bundled python debugger should help us a lot here. We can again work as a subprocess to perform the necessary hooks for step/locals/watches and whatnot. While we are at it, how about remote debugging over ssh.

I'm also excited to start on a profiler. The interfaces for the profiling API are thankfully generic enough to support this relatively easy. We again simply need a subprocess that writes out the profile snapshot to a file. Using the output from the profiler, I will build a view that includes (Module/Function, N Calls, Avg per call, Total time, and Total % of time). I haven't used profilers too much, so if you have suggestions on what you want to see, please don't hesitate to chime in.

An interactive python shell is a must. Will most likely defer to Vte and python/ipython for this.

UML generation is really quite easy when you have the AST already available. I would love to see someone make a gtk canvas that can read graphviz dot files. Making it look sexier than graphviz is a must. I remember using omnigraffle years ago and it looked incredible.

Templates. We need a bunch, simple as that. I'm thinking gtk examples, unit tests, twisted plugins, qt demos, clutter, GNOME, and more.

Code coverage is also useful and simple enough to record during runtime. We can use the output of this to render over the icons on the class pad. Essentially light up code paths that are never executed.

Setuptools integration could be worthy as lots of good projects in python are available from the python cheese shop. (“easy_install processing”).

Refactoring seems doable as the python language makes that fairly easy. I haven't looked at the refactoring API's within monodevelop yet, so its hard to say. At the minimum, I'd think renaming of methods, classes, and modules should be doable.

This is the end of me wasting your time, continue with your hacking and thanks for reading this far.

Update

git://git.dronelabs.com/git/users/chris/monodevelop-pybinding.git

If you have monodevelop from trunk, you can install from the Addin Manager using http://audidude.com/python-addin/

Update

This has been merged into monodevelop trunk. It is in extras/PyBinding/.

Comments (36)

  1. Sandy wrote:

    This is seriously cool. Don’t forget to link to your git repo, add-in repo, etc!

    Friday, October 3, 2008 at 11:29 pm #
  2. Tinh Xuan Truong wrote:

    MonoDevelop should concentrate on stability before adding new features.
    I just want to use MonoDevelop for .NET development, nothing else!
    Do I need JavaBinding, BooBinding, ValaBinding, BlahblahblahBinding? No, I don’t.
    And I think a lot of people out there think the same as I do.

    Saturday, October 4, 2008 at 3:27 am #
  3. chergert wrote:

    Perhaps MonoDevelop should. I don’t hack on it, so I wouldn’t know! I however have written an addin that I myself can use, and on top of that, I’m letting people download it! Shut your mouth and contribute some code.

    Saturday, October 4, 2008 at 3:45 am #
  4. This looks really cool, and I’m impressed with how quickly you’ve got it going. Congratulations!

    Saturday, October 4, 2008 at 5:53 am #
  5. Christian: apologies for posting this on your blog, but I felt it needed saying.

    Tinh: While I’m sorry that you are having problems with Monodevelop, I’m disappointed that you are complaining on the blog of an independent contributor. What Christian chooses to write in his own time is his own choice; I for one am glad that he has chosen to enrich MonoDevelop.

    If you have problems, please file bugs so that we on the MonoDevelop team can fix them. I have very few stability problems, so I suspect it’s related to other aspects of your distro’s configuration. If we believed MD was unstable, we wouldn’t have shipped 1.0. The “core” MonoDevelop team does indeed work on core features and fixes bugs, particularly those related to stability, but if bugs only show up on certain configurations we often won’t see them, and hence we rely on users to report them. Complaining to other people doesn’t help; if I hadn’t been re-reading this post, I wouldn’t even have seen your comment.

    Saturday, October 4, 2008 at 6:02 am #
  6. Kudos chergert, this looks really cool and I appreciate your work as an independent contributor :)

    Saturday, October 4, 2008 at 9:32 pm #
  7. Ignacius wrote:

    Why have you choose the http server method for comunicate two processes and don’t you use what has been designed for interprocess comunication which is for example dbus?

    Saturday, October 4, 2008 at 11:36 pm #
  8. Miguel de Icaza wrote:

    This is great!

    When is this code going mainstream? ;-)

    Sunday, October 5, 2008 at 12:56 am #
  9. chergert wrote:

    Ignacius: MonoDevelop is striving to run on windows and I have friends who run it on OS X. So at the current state of dbus, that is out of the question.

    Most importantly, I just wanted to get it done quick, and HTTP was the quickest solution.

    Miguel: Sometime this week?

    Sunday, October 5, 2008 at 5:59 am #
  10. d-_-b wrote:

    Nice,

    Would it be possible(In the future) to use the GUI designer as well?

    Because IMHO Python needs a nice IDE with a GUI designer.

    Regards,

    Thursday, October 9, 2008 at 7:43 am #
  11. Hi – what are you using to provide code completion?

    I’ve developed PySmell, a code completion provider for various IDEs – I only have Vim support right now, since it’s what I’m using, but it would be nice to integrate this with your project!

    http://github.com/orestis/pysmell

    Thursday, October 9, 2008 at 1:12 pm #
  12. chergert: it’s just my idea about MD, and it seems that I expressed at the wrong place, I’m terribly sorry for that.
    Michael Hutchinson: I’m an active bug report of MD ;) . Maybe the poort stability of MD in case come from “bleeding edge” (I alway compile MD from the source to use)

    Thursday, October 9, 2008 at 3:44 pm #
  13. Mark Ferrer wrote:

    Wow. That is awesome. I’ve used MonoDevelop a few times since I program .net at work and program with OpenSource stuff on my free time. Given that, I haven’t spent much time using MonoDevelop due to the fact that I use Python (w/ Django) most of my free time, but this capability with MonoDevelop would be really good to have. This would definitely get me to use MonoDevelop a lot more. Awesome job on it.

    Thursday, October 9, 2008 at 4:16 pm #
  14. I’m .Net ignorant, so I may be WAY off base, but: instead of doing another process for the Python compiler, isn’t IronPython’s parser/compiler available as an assembly you can link to? Thus, call the parser directly in-process?

    Thursday, October 9, 2008 at 7:43 pm #
  15. David wrote:

    Awesome! I’m going to be emailing you often when I attempt to do this for Haskell.

    Thursday, October 9, 2008 at 11:03 pm #
  16. chergert wrote:

    @David sure thing

    @Joshua, Perhaps it is, but I want to support multiple versions of python, including things like decorators. I’m not sure IronPython supports that nor is a license that permits me to link against it. (Is it MS-PL? If so its fine). Most people only have ironpython 1 on Linux which doesn’t support decorators I don’t think. Also, I had a desire for pyflakes, which isn’t supported on IronPython.

    Anyhow, Yes, its probably possible. However, I think it would limit us in its current shape.

    Friday, October 10, 2008 at 5:45 am #
  17. mike wrote:

    As it is not yet released separately, will you continue to update your repo until 2.0 is final?

    Thursday, February 19, 2009 at 5:53 pm #
  18. chergert wrote:

    Michael Hutchinson had been making packages for the openSUSE Build Service.

    The source itself is maintained within the official monodevelop subversion repository here.

    I’ll be hosting a package for Ubuntu eventually. Waiting on the 2.0 betas to be packaged.

    Thursday, February 19, 2009 at 9:34 pm #
  19. mike wrote:

    Ohh, I was talking about the Python-AddIn only.

    Ok, so I will build that from SVN for the time being. (already using MD2beta1)

    Thursday, February 19, 2009 at 9:59 pm #
  20. chergert wrote:

    If you use –select to enable addins, you will see it at the bottom.

    Thursday, February 19, 2009 at 10:49 pm #
  21. Looks siiiick! Great work.

    Friday, February 20, 2009 at 2:19 am #
  22. mike wrote:

    Maybe I should rather create a real bug report, but maybe I just overlooked something.

    Whenever I want to edit any python file (installed py-addin from svn) it tells my “… executable not found”

    Do I have to set anything before using the plugin?

    Just want to open a single file.

    Friday, February 20, 2009 at 3:51 pm #
  23. chergert wrote:

    Make sure python2.5 is in your path. I haven’t added support for other versions of python yet.

    Perhaps next week I can look at adding support for that.

    I also noticed after taking a quick look, that some of the completion stuff seems to be less than spectacular due to some changes in MD core.

    If MD has support for me to do proper indexing on system modules, I can add that as well.

    Saturday, February 21, 2009 at 8:22 am #
  24. tretle wrote:

    This rocks, great work :D

    Sunday, February 22, 2009 at 4:26 pm #
  25. popi wrote:

    Will it be updated for be integrated in the final release? there are dependency problems to instal it in last beta of mono develop…

    Tuesday, March 17, 2009 at 11:28 am #
  26. chergert wrote:

    @popi

    It is maintained in the monodevelop source tree now. When compiling, use –select with configure to enable the python binding.

    For example,

    ./configure –select –prefix=/usr

    Cheers

    Tuesday, March 17, 2009 at 10:08 pm #
  27. This is great! I plan on learning PyQT this summer and MonoDevelop + Python + QtDesigner will hopefully provide a good cross-platform environment to do that. And it seems like the final puzzle is in place :)

    Thanks for developing this!

    Sunday, March 22, 2009 at 5:22 pm #
  28. Help a Noob wrote:

    I am just starting to use monodevelop, and this python addin would be the *perfect* glue for a project I have in mind. I added your Addin Repo to MD and it sees your Pthon Language Binding. But when I tell MD to install it, it fails with warnings about missing deps: Core 1.9, Project 1.9, SourceEditor2 1.9 etc. What’s that all about? I’m eager to start hacking!

    Thanks!
    -cmundi

    Sunday, April 12, 2009 at 5:21 am #
  29. sebasmagri wrote:

    Please update the plugin for 2.0!!! :D

    Tuesday, April 21, 2009 at 4:48 am #
  30. Zanko wrote:

    Great ! I was searching this feature for a long time (and was not commited to use eclipse, which has it but is, according to me, a bloatware).

    Monday, May 25, 2009 at 10:24 pm #
  31. bpedman wrote:

    I get the same error as help a noob…it would be great to try this out in 2.0!

    and does the debugger work?

    Tuesday, June 9, 2009 at 4:09 pm #
  32. droetker wrote:

    I’d also like to try this in 2.0…

    Wednesday, June 24, 2009 at 6:56 pm #
  33. Matthew wrote:

    When I do make it outputs:
    error CS0006: cannot find metadata file `/usr/lib/monodevelop/AddIns/VersionControl/MonoDevelop.VersionControl.dll’
    error CS0006: cannot find metadata file `/usr/lib/monodevelop/AddIns/NUnit/MonoDevelop.NUnit.dll’

    Wednesday, July 1, 2009 at 10:08 am #
  34. Matthew wrote:

    And when installed with the add-in manager there is package conficts

    Wednesday, July 1, 2009 at 10:12 am #
  35. chergert wrote:

    This is all maintained by the MD team now. I’m not up to date on its status in the tree.

    Wednesday, July 1, 2009 at 10:21 am #
  36. jack mullen wrote:

    Is there any documentation on using this template ?

    Tuesday, November 17, 2009 at 10:20 pm #