SharpDevelop Community

Get your problems solved!
Welcome to SharpDevelop Community Sign in | Join | Help
in Search

Matt Ward

May 2009 - Posts

  • Debugging IronPython Code in SharpDevelop

    With SharpDevelop 3.1 you can now debug IronPython code with the IronPython Interpreter (ipy.exe).

    Before you start make sure the debugger is set to use the Just My Code feature. From the Tools menu select Options and then click the Debugging category.

    Debugger options for debugging IronPython code

    Ensure that the Just My Code feature is checked and that the Step over code without symbols is not checked. If the Step over code without symbols option is selected then stepping will not work properly and lines of code will be skipped over.

    There are two ways to debug your code. You can use the Python menu or modify the project options. We will look at both of these alternatives. First open your IronPython project into SharpDevelop. Open your main file and make sure it is the active text editor window. Set a breakpoint somewhere in your code. Then from the Python menu select Run.

    Python menu option to run with debugger

    This will start ipy.exe which will run your code and the debugger should stop the execution at the breakpoint.

    Debugging IronPython code

    From this point you can do the usual debugging activities such as stepping through your code, viewing the callstack, adding items to the watch window, etc.

    If you want to use a different ipy.exe then this can be specified in the Python Options dialog (Tools menu | Options).

    Python options dialog

    To enable debugging when you press F5 or select the Debug Run menu option you can modify the project options. From the Projects menu select Project Options and then open the Debug tab. Here you should change the Start Action to Start external program and use the browse button to locate ipy.exe. In the Start Options add the following command line arguments, changing the name of your main file as required.

    -D ${ProjectDir}\Program.py

    Once these changes are saved you can then press F5 and ipy.exe will be run under the debugger instead of running the compiled executable.3

    Issues

    • No support for debugging the executable produced by the IronPython compiler since it does not produce debug symbols (i.e. .pdb files).
    • When using ipy.exe you need to add references to .NET assemblies explicitly in your code except for System which is included by default. For example:
      import clr 
      clr.AddReference("System.Windows.Forms")

    Thanks

    Thanks to David Srbecky, SharpDevelop's debugger expert and maintainer, for reviewing the code changes I wanted to make to the debugger and making sure nothing was broken. Adding support for debugging IronPython was straightforward and required 10-15 lines of new code thanks to the code already written by David.

    Thanks also to Harry Pierson (IronPython Program Manager at Microsoft) who has written a great set of blog posts on creating an IronPython debugger in IronPython which gave me the reason why SharpDevelop's debugger was not working when debugging IronPython code.

  • IronPython 2.0 Forms Designer

    Support for designing Windows Forms in IronPython is now available in SharpDevelop 3.1. The original IronPython forms designer was removed when SharpDevelop 3.0 began supporting IronPython 2.0 which had removed support for generating IronPython code from Microsoft's CodeDOM. The forms designer has now been re-implemented to use the IronPython abstract syntax tree (AST) and no longer relies on the CodeDOM.

    Creating a Windows Application

    To create a Windows Application open up the new project dialog by selecting New then Solution from the File menu. Select the Python category to show the available project templates. Select the Windows Application project template, enter a name and location and click the Create button.

    New Python Project Dialog

    Designing Windows Forms

    The Windows Forms designer is not yet complete so be warned that it could generate form code that will no longer compile.

    The designer can be opened by opening a form in the text editor and selecting the Design tab at the bottom of the editor.

    Python main form before opening the designer

    Once open in the designer you can add controls to the form by dragging the controls from the Tools window. In the screenshot below a label, text box and a button have been added.

    Main form designed in designer

    Click the Source tab at the bottom of the editor to view the generated code in the InitializeComponents method.

    Generated form code

    Limitations

    The IronPython forms designer is not yet complete and the following are some of the known limitations.

    1. No support for project or local form resources.
    2. No support for icons.
    3. Incomplete support for ToolStripItems and menu strips.
    4. Incomplete support for ListViewItems.
    5. No support for TreeViewItems.
    6. Incomplete support for non-visual components (e.g. Timers).
    7. Controls needed to be fully namespace qualified.

    Forms Designer Internals

    For those interested in how the forms designer actually works at a high level we will now look at what the IronPython forms designer does when loading and then generating code for a form.

    To show the form in the designer the following steps are executed.

    1. The form's code is parsed and an IronPython AST (PythonAst object) is created.
    2. The AST is then visited and each control is added to the forms designer and the control's properties are set.
    3. The form's properties are set in the designer and the form is displayed.

    To generate the code after the form has been designed the following steps are executed.

    1. The form is obtained from the forms designer.
    2. Each of the child components of the form have their properties checked to see if they need to be serialized. This can be done by getting all the property descriptors and then checking the ShouldSerializeValue method. If they do need to be serialized then code is generated for them and added to a StringBuilder.
    3. After all the child components are added the code for the form is generated.
    4. Finally the generated code is inserted into the text editor inside the InitializeComponent method, replacing any existing code.
  • Converting C# and VB.NET Code to IronPython

    SharpDevelop 3.1 now supports converting C# and VB.NET code to IronPython. It can convert a single file or an entire project. The code to convert between these languages is still under development and has some limitations.

    Converting an Individual File

    To convert a C# or VB.NET file, open it in SharpDevelop's text editor, then from Tools menu select Convert code to Python.

    Convert code to Python menu option.

    The code conversion is limited to converting classes so it will not convert an arbitary piece of code that is not inside a class.

    C# code before conversion.

    C# code after conversion to Python

    Converting a Project

    To convert a C# or VB.NET project, open it in SharpDevelop, then from the Project menu select Convert From C# to Python.

    Convert from C# project to Python project menu option.

    Once converted the project will most likely not compile straight away due to limitations in the implementation. At the time of writing converting a project has the following limitations:

    • Project's Main File is not set.
    • No code generated to call the project's Main entry method.
    • Namespace imports do include all the used classes.

    Code Conversion Internals

    Converting code to IronPython was originally supported in SharpDevelop 2.2 and was based on converting code to a Microsoft CodeDOM and then getting IronPython 1.0 to generate the Python code. In IronPython 2.0 this CodeDOM support was removed so the code conversion feature was removed from SharpDevelop 3.0 since that was using IronPython 2.0. In SharpDevelop 3.1 the code conversion has been rewritten to no longer use the CodeDOM support. It now works by executing the following simple steps:

    1. The C# or VB.NET code is parsed using SharpDevelop's parsing library NRefactory and an abstract syntax tree (AST) is generated.
    2. A visitor class then walks this AST and generates Python code which is added to a StringBuilder.
    3. Once the visit is complete the generated Python code is then displayed or saved to disk.
  • NUnit 2.5 Support

    SharpDevelop 3.1 now supports NUnit 2.5.

    A summary of which NUnit version is supported by SharpDevelop is shown in the table below.

    SharpDevelop 3.1 NUnit 2.5
    SharpDevelop 3.0 NUnit 2.4.8
    SharpDevelop 2.2.1 NUnit 2.4.7
    SharpDevelop 1.1 NUnit 2.2

    NUnit 2.5 Changes

    NUnit 2.5 has changed quite substantially compared with the previous 2.4.8 release, as outlined in the NUnit 2.5 release notes. The problems that we had when migrating SharpDevelop's unit tests to NUnit 2.5 were as follows.

    1. Assert.IsInstanceOfType has been replaced by Assert.IsInstanceOf.

      Your code will still compile and work if Assert.IsInstanceOfType is used but you will get compiler warnings.

    2. NUnit.Framework.SyntaxHelpers namespace no longer exists.

      All classes that were in this namespace have been moved to the NUnit.Framework namespace.

    3. The Has.Count constraint no longer takes an integer parameter.

      To fix this problem replace code such as:

      Assert.That(classesCollection, Has.Count(1));

      With the following:

      Assert.That(classesCollection.Has.Count.EqualTo(1));
    4. Overriding a [TestFixtureSetUp] method in a derived class using the new keyword no longer works.

      Some of the SharpDevelop unit tests were overriding an abstract base test class [TestFixtureSetUp] method in a derived class by using the new keyword, as shown below.

      Base class:

      [TestFixtureSetUp] 
      public void SetUpFixture()
      {
      // Setup code.
      }

      Derived class:

      [TestFixtureSetUp] 
      public new void SetUpFixture()
      {
      // Extra setup code.
      base.SetUpFixture();
      }

      In NUnit 2.4.8 the SetUpFixture method in the derived class would be called when running the tests allowing it to execute some extra setup steps. In NUnit 2.5 the base class SetUpFixture method is called instead and the derived class method is never called. To resolve the problem we changed the base class so it used a virtual method and allowed the derived class to override this to execute its extra setup steps.

      Base class:

      [TestFixtureSetUp] 
      public void SetUpFixture()
      {
      BeforeSetUpFixture();
      // Setup code.
      }

      public virtual void BeforeSetUpFixture()
      {
      }

      Derived class:

      public override void BeforeSetUpFixture() 
      {
      // Extra setup code.
      }
Powered by Community Server (Commercial Edition), by Telligent Systems
Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.