It’s been awhile since my last post, but there were so much happening in my personal life that I simple couldn’t find enough time to write a single post here. Nonetheless, I’ve finished reading the Bible of Python and have a lot of  thoughts from there. And I haven’t let go my idea to create a cross-platform CD/DVD burner in Python.

In this post I’d like to share my happiness around what I consider a significant event in the world of Python – the first public release of LGPL bindings for the perfect Nokia Qt frameworkPySide. At this moment the project is still in the process of development and stays in beta, but the plans are ambitious – to create an LGPL alternative for the PyQt.

So, what’s the PySide and why would world need another Python bindings for Qt. Let me cite the FAQ:

What about PyQt?

Nokia’s initial research into Python bindings for Qt involved speaking with Riverbank Computing, the makers of PyQt. We had several discussions with them to see if it was possible to use PyQt to achieve our goals. Unfortunately, a common agreement could not be found , so in the end we decided to proceed with PySide.

We will however maintain API compatibility with PyQt (you can use the same method names but can’t inter-operate with PyQt), at least for the initial release. To import PySide you have to use “import PySide” instead of “import PyQt4″.

One of the most important things about PySide is that it will maintain the API compatibility with PyQt! It means that you can just replace imports of PyQt with PySide and, viola!, everything works fine and you no more required to distribute under GPL terms.

I encourage everyone to give it a try, though at the moment only Unix version is available. If you interested in how it will go in future, you can read the PySide Roadmap.

I’m now busy reading the great book Learning Python by Mark Lutz. I must say it reminds the C++ bible: The C++ Programming Language by Bjarne Stroustrup. The thing I like about this book – a very thorough content, covering each and every major part of Python programming language. Being a C++ developer, I like to know what happens behind the scence when you write code. And this “Learning Python”, though being much more steadier than, for example, another great book Dive Into Python, covers language in much more detail, leaving behind domain specific information like Web-services, XML handling, etc.. That’s very nice 🙂

While reading a chapter on functions basics, it came to my mind, that Python polymorphism reminds the so-called “static polymorphism” found in C++ templates. The idioms behind both are very much the same. In both cases you define a function that accepts arguments, regardless of their type until they follow some predefined protocol. This way of programming OOP is different from common polymorphism found in static-typed languages.

Usually if you want to make use of polymorphism in C++, you write something like this:

struct IBase
{
    virtual void func() = 0;
    virtual ~IBase() = 0 {}
}
struct SomeClass : public IBase
{
    virtual void func() { std::cout << "Hello there!\n"}
}
[...] //Skip
void someFancyFunction(IBase* arg)
{
    arg->func();
}
[...] //Skip
int main()
{
    IBase* pBase = new SomeClass;
    someFancyFunction(pBase);
    [...] //Skip
}

Here, the function someFancyFunction can only accept arguments that undoubtedly follow the IBase interface. If you try to pass some param unrelated to IBase, the compiler will report an error. This kind of polymorphism is powerful and widely-used, but it encourages a lot of boilerplate code and the code-base tends to extend hugely. It also puts a set of constraints on a developer, preventing from code from flexibility.

On other hand, there is what’s called “static polymorphism” in C++, and it’s the main tool of OOP in Python. Here’s the code example in C++:

template<typename Type>
void fancyFunction(Type& t)
{
    t.func();
    t++;
}

Now, the fancyFunction will happily accept any argument as long as its underlying type has the func method and also provides the post-increment operator. This construction, though less readable, gives much more flexibility to the developer. To use the function, one doesn’t need to derive a new type from some basic interface and implement all of its abstract methods. The only obligation is to define methods used inside fancyFunction. That’s a great leap forward and generally a superb feature of C++.

As, for Python, here polymorphism follows the C++ “static polymorphism” idiom, but it allows to achieve the same goals with less effort. Naturally, functions in Python don’t allow to declare types for arguments, so there’s no need to use cumbersome template<> constructions. In fact, all functions and operations in Python follow static polymorphism – actual receiver of a function call or operand is detected at the point of use in runtime.

To sum up, here’s the list of differences and likenesses of static polymorphism in Python and C++:

  • Both are very similar in behaviour – concrete data types are not specified in function definition, and any type can be accepted until it follows the protocol used inside the function
  • Both are very powerful indeed: C++ templates can be applied for such great things as Curiously Recurring Pattern. On other hand Python classes be defined dynamically in runtime and can be compound in metaclasses.
  • Python and C++ handle dynamic polymorphism differently – in C++ each use of a template with different kind of type actually generates a parallel family of functions and correctness of its use is checked at compile time, saving cost of dispatching via virtual table, but increasing amount of code. In Python actual types are resolved in runtime much like what is done when virtual functions are used in usual polymorphism in C++ – interpreter checks whether the typed passed to function contains needed method or data member, influencing the execution time, but leaving the code size as is.

These parallels between languages  helped me to understand clearly what is polymorphism in Python and how it should be used. As a general rule, you don’t check types in Python methods – testing input arguments is considered lame and redundant here.

P.S. Here’s a little code-snippet that I consider particularly exciting:

def func(x):
   class D(x):
      def foo(self):
         print "Oy!"

class C(object):
    def foo(self):
       print "Hello!"

z = func(C)
z.foo() # prints "Oy!"

GPL PyQt with LGPL Qt

July 4, 2009

UPD: Actually, it turned out that if you don’t want to mess with manual installation of PyQt from sources, and also don’t wish to make fixes in its code, there are easy to use Windows installers on official PyQt page (GPL only). For Python 2.6 it can be downloaded here. Installation process is smooth and runs without any problems. And it DOES work from the scratch with LGPL version of Qt, remaining GPL itself though.

While configuring environment for developing my CD/DVD burner I ran into an issue with PyQt licensing. From my experience and what I heard previously and read in Internet, I was sure that “free” version of PyQt can be used with the “free” version of Qt library. But despite the fact I have LGPL Qt 4.5.2 installed on my Windows machine, the PyQt configure.py script kept telling me that those two libraries have inconsistent licenses. The error message lacks details:

Error: This version of PyQt and the Desktop edition of Qt have incompatible licenses.

That seemed kind of strange to me, so I started a little investigation. I found the initial (I suppose so) request for LGPL version of PyQt: [PyQt] LGPL license. There’s a rather long discussion, even with participation of PyQt author – Phil Thompson, which resulted in nothing. The main thought is that Phill was going to consider – should or not there be PyQt under LGPL.

Since that post was a somewhat outdated, headed back to PyQt site to check current situation and read the following:

PyQt, unlike Qt, is not available under the LGPL.

That stroke me, since I’m not sure if Qt is distributed under GPL at all nowadays. The thoughts started crowding in my head – how to overcome this obstacle (in a good sence). But then finally I’ve read the section named “Compatibility with Qt licenses”:

The GPL version of PyQt can be used with both the LGPL and GPL versions of Qt.

So there should be no problem develop in GPL PyQt with LGPL Qt library. But the configure.py script was resilient – “licenses are different!”. And I decided to dig into installation script with IDLE debugger. It turned out that during initial configuration, PyQt detects my LGPL QT as “Desktop” version and its own – as “GPL”, consequently the comparison of these two fails.

At that moment I decided try to just comment out the fancy function checkLicenses() – and it worked out! Now, after 1,5 hours of investigation, I have a working version of GPL PyQt with LGPL Qt!

P.S. Perhaps, there’s some additional info about how to make GPL PyQt work with LGPL Qt – I don’t know, as I wasn’t able to find any. So I made a fix that I think is a problem with PyQt installation script relying on information found at official site. It’s perhaps an inappropriate method, and I discourage you from using it 😉

And, as it is stated in PyQt’s FAQ:

Riverbank is a product based software development company that depends on sales to fund PyQt’s continued development. […] An LGPL version of PyQt, while probably increasing the number of users, would result in a reduction in income and therefore our ability to fund future development.

So, no luck for us who wish to use PyQt under LGPL license.

In this post I’ll describe my experience during installation of PyQt on Windows platform. And I’ll post the mock-up which was promised in previous post in one of the following posts – I wasn’t yet able to find a decent and free tool for mock-ups creation.

So, to start you have to download and configure SIP -a  tool for creation of C++ to Python bindings. This is essential to start work with PyQt.

  1. Unpack contents of SIP archive to some folder – preferably on the system disk (i.e. C:\)
  2. From the Start menu select the “Microsoft Visual Studio” -> “Visual Studio Tools” sub-item. Here run the  “Visual Studio Command Prompt” with Administrator privileges (via right-click) – on Vista and Windows 7 SIP configuration script won’t be able to access system disk if it is not run with admin rights. If you use MinGW tools you can just start cmd.exe as Admin.
  3. In the opened command prompt go to SIP folder (in my case – C:\sip-4.8.1) and run the following command:
    python configure.py -p [your_platform]
    Replace the your_platform placeholder with real specification of the platform and compiler you use. For me it is: win32-msvc2005. The full list of supported platforms and compilers can be found at “\specs” folder.
  4. Now just run “nmake” and, after SIP is built, “nmake install” (“make” – for MinGW).

At this moment SIP is installed as a package into your Python.

Before building and installing PyQt you have to ensure that you have the following prerequisites:

  1. Installed Python and Qt. Please note that if you use commercial version of Qt, you’ll have to buy commercial PyQt also.
  2. Qt environment is set correctly: QTDIR environment variable points to to folder with Qt, and PATH includes the folder containing qmake.exe.

Now you are ready to build PyQt:

  1. Open cmd.exe in the same way as for the SIP.
  2. run
    python configure.py
    nmake ("make" for MinGW)
    nmake install ("make install" for MinGW)

At this moment we are ready to start development with PyQt!

To start with, I’ll describe the development environment I’ll use to create my CD/DVD burner. Work progress will commence on Windows platform, since that OS is the most familiar for me.

The tools I’ll use:

  • ActiveState Active Python 2.6. That package is de-facto a standard for Windows.
  • ActiveState Komodo Edit. This editor is nice choice for developing in Python on Windows, though not ideal. I like, that Komode Edit is able to compose sources into workspaces, just like Visual Studio does 🙂
  • Qt framework by Nokia for GUI. I’m in love with this library, and since it’s now redistributed under LGPL, my love have increased noticeably 🙂 I will use Qt 4.5.2.
  • PyQt – Python bindings for Qt. I’m not yet familiar with PyQt and hope to get into it during the development process.

When Windows version will be ready I’ll  move on other platforms, and the toolset will surely be changed. But the set of software I specified should be sufficient for the initial release.

In the next post I’ll post the rough mock-up of my CD/DVD burner.

Hi,

Here I’d like to share my goal for the next several weeks.

First of all, the main goal is to develop my skills in Python and to extend them as far as possible. To achieve this I decided, apart from reading books, to create a real application. So, the question was – what kind of software would be both interesting and challenging enough? Having though for a little time, I came with an idea: I’ll write a cross-platform CD/DVD burning application. And that’s why: I don’t like paying for software and I hate what Nero has turned into (a 700Mb monster), and none of free burning apps are good enough for me.

So, here are the main requirements for my future CD/DVD burner:

  1. Developed in Python. That’s point of the whole blog 🙂
  2. The code has to be perfect, written in Python style (not C++) and be reusable (useful for others).
  3. Cross-platform. Yes, Python runs on many OS itself, but the domain-logic is hardly portable. Main targets are Windows, Linux and Mac OS.
  4. User-friendly UI – it should be better than average open-source one (you know, those ugly designs you cannot look at without tears in your eyes). In my opinion, it has to be fun to work with software. Since, I’m not a designer at all and the budget is $0, it’s gonna be somewhat difficult to achieve 🙂
  5. It should be functional – be able to burn CDs/DVDs/Blu-Rays/Audio/Video/ISO and so on. In general, it should be able to work with any kind of media.
  6. The installation process has to be smooth and without a mess – in contradict to usual open-source software (./configure && make things)

So, the goal is set, the work is waiting. Hopefully this tale will be fun and educational. 🙂

Introductory post

June 30, 2009

Hello everyone. Just a few words about myself and what’s this blog about.

I’m a software developer with deep knowledge in C++, and it happens that I’m highly interested in Python programming language, the idiom behind it, the ease of use, etc.

So, lately my interest in Python overcame my native laziness and I finally decided to dive into it. And I’m going to post here my tale of mind-switching from C++ to Python.

Hopefully, someone will find the info here useful.

So, let’s start 🙂