By Ingeniweb. A Django site.
Mai 3, 2009
» Gsoc : Keyring library work started !


I am very proud to be a Gsoc mentor this year on a very interesting topic : an universal keyring library for Python.

About the topic

In Distutils, if you want to interact with PyPI, you have to register in the website and you get a login/password so you can register and/or upload your packages.

Before Python 2.6, the only way you could interact with PyPI was by storing these info into your .pypirc file in clear text. This was not the best solution. For example we have in my company some staging servers we share, and from whom we upload packages to various PyPI-like servers. So we have to store PyPI login/password info in them. This means that if Bob wants to push his package from that server, he has to put his password into a clear text file which is most of the time readable by everyone. It’s not such a big deal in our company since we can trust each other, but it’s a very bad practice.

So I ended up changing this in Python 2.6 so people could type their password in a prompt when working with packages, using getpass.getpass. So they wouldn’t have to store them anymore.

But this is not enough : we need to provide something better. We need getpass.getpass to be able to interact with keyring libraries like KeyChain, Gnome Keyring, etc. So the login/password info are safely stored and can be reused.

This service will be useful for Distutils, but also for any Python application.

The idea of the GSOC task is to provide an unified keyring library for Python, and it’s harder that it sounds. For instance, we need to find a way to provide something that works under Windows. So the whole work is quite challenging and interesting, and the goal is to end up with a keyring library we can use into Distutils and propose for inclusion in getpass.

About Kang

Kang Zhang is the student that was selected for this work. Congrats ! He has started to work on it. You can follow his work in his blog. I have a strong feeling that he will succeed in this work and come up with something good.

Take a look at the Python Soc planet too, where all students involved in Python GSOC are blogging about their ongoing work.

Mai 2, 2009
» Basic plugin system using ABCs and the “extensions” package


I need a very simple plugin system for one of my projects. The project is a small WSGI application called mysysadmin that allows you to launch some commands on your system to manage some applications. It also allows you to view log files in your web browser.

It’s similar in some ways to WebMin,

So in my application, every tab is a plugin that manages one application. I have a plugin for Apache, another one for MySQL, and so one.

Back to my plugin system. So every plugin that is registered becomes a tab in the WSGI application, as long as it provides all the methods my web application needs to interact with it. So I want to check that each plugin strictly provides the API needed by the main program.

The first tools that came in mind were :

But I find both projects a bit complex to implement such a simple plugin system.I could use the standalone Plugins package Phillip provides instead of setuptools, but it still does too much things imho. That’s someting I am currently learning by working on packaging matters : one library should not provide too many features.

Extensions : a simple plugin system

So I have started to implement a light-weight plugin system called extensions, which reuses setuptools entry points principles but is more simple to use. The goal of this project is to provide very simple APIs to handle plugins, and to make it work without introducing a new argument into the setup.py setup method, like setuptools does.

For instance, if you want to define an apache function in your modules module, in your myapp package, you just call the register function :

from extensions import register

register('mysysadmin.modules', 'apache', 'myapp.modules:apache')

That’s it !

And to use it, the mysysadmin application can use a simple API called get, that iterates over all plugins defined for “mysysadmin.modules” :

from extensions import get

for plugin in get(group='mysysadmin.modules'):
    # do something with the plugin

The magic is done by writing in the .egg-info directory installed for the package that contains each plugin, a PLUGIN file that contains the list of registered elements. It’s an idea borrowed from setuptoools entry points. So get iterates over all .egg-info directories in your path and load the PLUGIN files it finds.  Nothing new here. That’s how setuptools does, and that’s perfect.

If you have any feedback on extensions, let me know !

Strict plugins

The other need is to strictly check that every plugin provides the API needed, e.g. fulfill the requirements. This is what we could call Design by contract .

You can provide a base class for this, and ask the plugins to inherit from it. Or you can ask the Plugin to provide a marker to specify it implements a given behavior. zope.interface can do a nice job for the latter,and let you check that a given object implements an interface.

But I wanted to give a shot to the brand new Python ABCs and make sure anyone can write a plugin in plain Python, without having to rely on any kind of marker system. ABCs will let you check that a class implements some methods without requiring it to inherit from a specific class, to implement a specific interface or provide a custom marker. Pure duck typing !

So let’s define for our application a Plugin class, that gives the signature every plugin will need to provide. It uses ABCMeta as its meta class, and the abstractmethod for every method that should be implemented by every plugin.

Here’s an extract :

from abc import ABCMeta, abstractmethod

class Plugin(object):
    __metaclass__ = ABCMeta
    @abstractmethod
    def get_command_list(self):
        return []

    @abstractmethod
    def run_command(self, name):
        pass

    @classmethod
    def __subclasshook__(cls, klass):
        if cls is Plugin:
            for method in cls.__abstractmethods__:
                if any(method in base.__dict__ for base in klass.__mro__):
                    continue
                return NotImplemented
            return True
        return NotImplemented

The __subclasshook__ method is a class method that will be called everytime a class is tested using issubclass(klass, Plugin). In that case, it will check that every method marked with the abstractmethod decorator is provided by the class.

So basically, the application can discover and use the plugins, with:

from extensions import get

for plugin in get(group='mysysadmin.modules'):
    klass = plugin.load()
    if not issubclass(klass, Plugin):
        logging.info('sorry, not a suitable plugin')
        continue
    # do something with the plugin
    xxx

Abstract Base Classes are one honking great idea — let’s do more of those!

Avril 15, 2009
» new blog location, new design, update your bookmarks


I was thinking about doing this change for a while, and I took the time to do it last week-end:

My personal website at http://ziade.org is now powered by Pylons and Atomisator. It’s both in French and English (the urls are translated too).

It contains:

  • a home page with my latest twitter entries
  • a blog (this one)
  • some other pages like a résumé, a list of the books I wrote, a projects page, etc.

I am still using WordPress to write my blog entries but they are now processed with Atomisator and displayed at http://ziade.org/blog. The feed is now located at http://ziade.org/blog/xml and I will make sure all Planets use this URL for now on.

Next I’ll probably :

  • move to another blogging tool, and my readers will not suffer from the change as long as they use the ziade.org feed url.
  • add some portlets into the new site, like the ones I have on WordPress.

How do you like this new look ? Any comment / advice ? :)

Avril 10, 2009
» Distutils: introducing the check command (reStructuredText control)


I am introducing the check command in Distutils. This command will check your package metadata, like the sdist and the register command already do (they display warnings).

But the new thing is that it will also allow you to check if long_description is reStructuredText compliant.

Its usage will be:

$ python setup.py check --restructuredtext
running check
warning: check: Title underline too short. (line 32)
warning: check: Title underline too short. (line 32)
warning: check: Could finish the parsing. (line None)

And there’s also a strict mode, that raises an error in case something is wrong

$ python setup.py check --restructuredtext --strict
running check
warning: check: Title underline too short. (line 32)
warning: check: Title underline too short. (line 32)
warning: check: Could finish the parsing. (line None)
error: Please correct your package.

Last, this command will be used by register, and sdist, so you can stop the process in case the metadata are not correct. This is useful to make sure your PyPI home page is not broken for example, since it parses long_description to build it. So a good practice will be to use strict when registering a package:

$ python setup.py register --strict
running register
running check
warning: check: Title underline too short. (line 32)
warning: check: Title underline too short. (line 32)
warning: check: Could finish the parsing. (line None)
error: Please correct your package.

This feature will land in Python 2.7 (I am working on it and it should be commited this week end). Of course, it will not introduce a hard dependency on docutils in Python, neither it will change the current default behavior.

Until then, you can use collective.dist 0.2.3, that provides this feature for Python 2.4 to 2.6

Mars 30, 2009
» Pycon hallway session #2: thoughts for multiple versions in Python


We had an excellent brainstorming session today in the hall, with Toshio, Georg, Martin, Thomas, etc.. (sorry we were so many I don’t have the full list) with some insights from Guido and Brett. We tried to think about a way to handle multiple versions of a same package.

Here’s the two most important concepts :

  • Unicity: There should be one and only one instance of a Python package at a given version on a system
  • Combination: One Python application combines several packages to run

About unicity

A Python package is a component that can be installed on a system. If you use the standard Distutils approach, it will end up in the Python site-packages directory and be importable by the interpreter. This package comes with a version number and is unique.

This unicity is important for security and maintainability. For instance, if there’s a security hole in a package, the fix is applied in one place and the system maintainer knows it can’t be present elsewhere on the system.

This is the system administrator point of view

About Combination

What defines a Python application is the fact that is selects a list of packages it needs to run. And this varies for every application. So two Python applications might need a different version of a given package and that is normal.

What’s important is to have the right list of packages when an application loads. Tools like zc.buildout or virtualenv are perfect for this need : they create an isolated environment for your application to run with the right set of packages.

So the simplest way to release an application is to ship it with everything required, regardless the unicity.

This is the application developer point of view

The idea

zc.buildout and virtualenv are a blast for developers, and another thing system packagers might dislike. This is because they break the unicity by allowing developers to ship their applications as black boxes. Of course one may say that this is perfectly fine since what’s inside an application is not the problem of the system packager. But since this application is made of packages that may be shared on the system by other applications, that is redondant.

Forget site-packages for a moment. And let’s think about a new loading system for packages. This approach is similar in some ways to setuptools’ multiple version system.

Storing multiple versions

First of all, let’s store the packages in a directory, and for each version of the package, under a sub-directory which name is the version.

For example:

  • SQLAlchemy
    • 0.4
      • package code is here
      • package egg-info here
    • 0.5
      • package code is here
      • package egg-info here
  • jsonlib
    • 1.2.6
      • package code is here
      • package egg-info here
    • 1.3.10
      • package code is here
      • package egg-info here

Given this structure, some mechanism can provide to the interpreter the latest available version of a package, as long as Distutils knows how to handle version comparisons correctly (which will be the case in a near future)

Choosing specific versions

Back to our application. Let’s call it MyApp, version 1.0.

It needs specific versions for some packages. Forget zc.buildout and pip for a moment. And let’s think about a different way to express the packages (and versions) its needs.

Let’s make a Python package for this application and let’s make a few assumptions on some features in Distutils:

  • setuptools’ install_requires has made it into Distutils, as part of metadata.
  • metadata are defined statically in a package, apart from setup.py.

So basically, the application is mainly a static list of dependencies defined into install_requires. For example:

  • SQLAlchemy > 0.4
  • jsonlib == 1.2.6

When MyApp will get installed by Distutils, it will be added in the packages tree.

When it is used, it will need to load the versions of SQLAlchemy and jsonlib it needs. The ones that are inside its metadata.

To make it possible, the script that launches the application calls a built-in function called read_deps, that takes the metadata and reads them to know which versions fit:

# the script
read_deps('PKG-INFO')

import SQLAlchemy
import jsonlib
...

This call will load the right versions in the packages tree:

  • SQLAlchemy
    • 0.4
    • 0.5
  • jsonlib
    • 1.2.6
    • 1.3.10
  • MyApp
    • 1.0

What’s next

I just dropped here the rough idea, and a lot of details are missing. But I think it’s a good thing to share this idea here in its early stage.

We have decided we would try to write a prototype using importlib and sys.meta_path. Maybe Georg will start it during the Pycon sprint, and start to digg into the details. He was working on this when I left the open session at Pycon.

Stay tuned

Mars 27, 2009
» Pycon hallway session #1: a keyring library for Python


Before I sit down and clean up my summit notes to send them to python-dev, I wanted to post an entry about a small project which I think could be a great task for a student at the Summer of Code (I doubt it can fill 4 months of work but it could be done amongst other tasks).

Yesterday, we did a late session with Martin von Loewis, Jim Fulton and Georg Brandl about PyPI and the fact that it needed a better way to handle passwords on client side. That is, the fact that you have to store your password in the .pypirc file if you want to upload your package to PyPI.

This is unsafe and unwanted. A few months ago, I have made a small change in Distutils so it would prompt for the password using the getpass module if it doesn’t find it in the .pypirc file. (This was a contrbution of Nathan Van Gheem).

Anyways, this is not enough. Jim suggested to set up a SSH server on PyPI using Paramiko, so we could use a standard ssh connection and benefit from ssh-agent. But this is unfortunately not universal.

So let me get back to the idea I sent some time ago : http://mail.python.org/pipermail/python-ideas/2009-January/002465.html

What about having an option in getpass to store and reuse passwords in
system keyrings ?

    getpass(prompt[, stream])

would become:

    getpass(prompt[, stream, keyring])

where keyring would be a callable that can be use to retrieve the
password from a keyring system
and store it the first time.

The getpass module could provide some keyring support for:

- ssh-agent under Linux
- keychain under Mac OS X
- ...
ss

And let the developers use their own keyring system by providing a callable.

As Greg Smith said in the thread, the first task is to create a library that supports all standard keyring systems out there, including things like KWallet, Internet Explorer, Fireforx and so on…

I’ll mentor this project if any student would like to do it.

Mars 26, 2009
» Pycon Language Summit is tomorrow


Tomorrow is the Language Summit, yeepee. :)

The package and distribution part of the Summit is going to be great since we have key people coming up.

zc.buildout and pip leaders (Jim Fulton and Ian Bicking) will be present, and many others. I’ll be representing Distutils, since I am its current maintainer. Unfortunately Philip Eby (setuptools) can’t make it, but he should be reachable via IRC (I am trying to set something up for tomorrow).

Anyway, one of the goal of the Summit is to validate the new features and enhancements we want to introduce in Distutils and PyPI. It’s important to make sure they play well with third-party tools like zc.buildout, setuptools and pip. We also need to make sure these tools will evolve in the same direction in the future.

We have reached a point in Python where we need to concentrate all the packaging effort to build a common standard in the standard library, because it is badly needed.

Here’s a draft of the slides I will present tomorrow, during the first 5/10 minutes, as a session leader:

  • Packaging Survey results overview
  • Topics to discuss
    • setting up an organized network of mirrors (see PEP 381)
    • discuss about other PyPI enhancements
    • improve the package installation / uninstallation  (see PEP 376)
    • discuss the package dependencies problem and see if we can come up with a PEP
    • discuss the multiple version problem and see if we can come up with a PEP
    • discuss the isolated environment vs the OS vendor approach and see what can be done to improve their coexistence.

Summit schedule:

  • 13:20 -> 13:30 : presentation
  • 13:30 -> 14:30 : discussions/work in small groups
  • 14:30 -> 14:50 : “tour de table”
  • 14:50 -> 15:10 : break
  • 15:10 -> onwards: sprint !

I am not sure about the ‘work in small group’ part yet, because I don’t know how many people will show up, and what people will want to focus on.

» Packaging Survey first results


Around 570 people answered the survey, which is a great number I didn’t expect. Thanks again to Massimo for his help on this.

I have a lot of work to read all the open question answers, and all the comments that goes with the “other” answer, but I wanted to publish the results of the closed questions before the summit.

I don’t want to comment the results yet. I will after I have studied all answers, so it’ll be a little while ;)

Who are you ?

Professional developer using Python exclusively.
283
Professional developer using Python unable to use Python “at work”.
34
Professional developer using Python sometimes.
196
Hobbyist using Python.
116

Where are you located ?

USA
212
Western Europe
268
Eastern Europe
42
Asia
18
Africa
9
Other
70

If you are a web programmer, what is the framework you use the most ?

Pylons
55
TG 2
14
TG 1
15
Django
184
Zope (including Plone)
137
Other
207

How do you organize your application code most of the time ?

I put everything in one package
171
I create several packages and use a tool like zc.buildout or Paver to distribute the whole application
137
I create several packages and use a main package or script to launch the application
198
I use my own mechanism for aggregating packages into a single install.
67

For libraries you don’t distribute publicly, do you you create a setup.py script ?

Yes
321
No
249

What is the main tool or combination of tools you are using to package and distribute your Python application ?

None
80
setuptools
150
distutils
127
zc.buildout and distutils
10
zc.buildout and setuptools
107
Paver and setuptools
9
Paver and Distutils
3
Other
64

How do you install a package that does not provide a standalone installer (but provides a standard setup.py script) most of the time ?

I use easy_install
241
I download it and manually run the python setup.py install command
139
I use pip
34
I move files around and create symlinks manually.
7
I use the packaging tool provided in my system (apt, yum, etc)
81
Other
33

How do you remove a package ?

manually, by removing the directory and fixing the .pth files
275
I use one virtualenv per application, so the main python is never polluted, and only remove entire environments.
154
using the packaging tool (apt, yum, etc)
178
I don’t know / I fail at uninstallation
79
I change PYTHONPATH to include a directory of the packages used by my application, then remove just that directory
31
Other
10

How do you manage using more than one version of a library on a system ?

I don’t use multiple versions of a library
217
I use virtualenv
203
I use Setuptools’ multi-version features
46
I build fresh Python interpreter from source for each project
16
I use zc.buildout
109
I set sys.path in my scripts
48
I set PYTHONPATH to select particular libraries
49
Other
23

Do you work with setuptools’ namespace packages ?

Yes
178
No
344

Has PyPI become mandatory in your everyday work (if you use zc.buildout for example) ?

Yes
228
No
294

If you previously answered Yes, did you set up an alternative solution (mirror, cache..) in case PyPI is down ?

Yes
77
N/A
277
No
166

Do you register your packages on PyPI ?

Yes
239
No
281

Do you upload your package on PyPI ?

Yes
205
No
314

If you previously answered No, how do you distribute your packages ?

One my own website, using simple links
139
One my own website, using a PyPI-like server
50
On a forge, like sourceforge
N/A
251
Other
56

Mars 16, 2009
» How to extend you Plone 3.2 buildout


Plone 3.2 and next comes with a hardcoded versions.cfg for each Plone release. For the current release:
http://dist.plone.org/release/3.2.2/versions.cfg

The Plone Upgrade Guide will show you how to transform a basic buildout created with paster:
http://plone.org/documentation/manual/upgrade-guide/version/upgrading-from-3-x-to-3.2

This solution will work until you already defined a ‘[versions]‘ section in your main buildout file. What we need is to merge the two ‘[versions]‘ sections.

For example, you current ‘buildout.cfg‘ looks like this:

[buildout]
...
eggs =
	archetypes.schematuning
	Products.CacheSetup
	Products.errornumber
	collective.recipe.omelette
	collective.workflowed
	Products.DCWorkflowGraph
	Products.PrintingMailHost
	plone.reload
	Products.PDBDebugMode
	Products.DocFinderTab

versions = versions

[versions]
zope.testing=3.5.1
zope.interface=3.4.1
Products.errornumber=1.2
archetypes.schematuning=1.1
Products.CacheSetup=1.2

If you add extends = http://dist.plone.org/release/3.2.2/versions.cfg it will be overloaded by the local section displayed above and will be simply ignored by ‘bin/buildout‘. If you run an update now all plone bundle eggs will be updated to the last published eggs (Plone 3.3b1, etc).
The solution consist to use the ‘extends’ directive to merge sections. For that we need to put your local ‘[versions]‘ section in a separate file.
dev-versions.cfg‘ will contain:

[versions]
zope.testing=3.5.1
zope.interface=3.4.1
Products.errornumber=1.2
archetypes.schematuning=1.1
Products.CacheSetup=1.2

The ‘buildout.cfg‘ will contain:

[buildout]
...
eggs =
	archetypes.schematuning
	Products.CacheSetup
	Products.errornumber
	collective.recipe.omelette
	collective.workflowed
	Products.DCWorkflowGraph
	Products.PrintingMailHost
	plone.reload
	Products.PDBDebugMode
	Products.DocFinderTab

extends = dev-versions.cfg http://dist.plone.org/release/3.2.2/versions.cfg

versions = versions

We can update now and verify our eggs versions:

  • Plone 3.2.2
  • plone.app.locales 3.2.0
  • Products.CMFPlacefulWorkflow 1.4.0
  • Products.CacheSetup 1.2

It is a certified Plone 3.2.2 installation with our specifics packages.

Mars 15, 2009
» How to upload your package to Plone.org


We have been working hard in the past few months with my Plone friends to make it happen.

It’s now available : Plone.org is acting like PyPI in its Products section, which means that you can use Distutils to register and upload your packages in both places now.

I have written a small tutorial on plone.org to explain how to use it: http://plone.org/documentation/tutorial/how-to-upload-your-package-to-plone.org

I will also explain during my Pycon presentation (http://us.pycon.org/2009/conference/schedule/event/44) how this new feature at Plone.org will help people that are working with Plone and Python packages.

Mars 9, 2009
» Take the Python Packaging Survey


The Python Langage Summit is coming up. To prepare this event, I have put online a survey you can take to tell us a bit more about you and how you package your Python applications.

Thanks to all the people that helped building the survey, and a special thanks to Massimo Di Pierro who created the application that runs the Survey and helped me set up the survey. It runs under web2py.

Mars 5, 2009
» ‘Practical Plone 3′ review


I finished to read the long waited (read updates here :) ) ‘Practical Plone 3′ book. It reprensents a big amount of very good work.

If you want to begin in Plone or if you want a webmaster guide for your brand new Plone site the two first parts are designed for you. Each step of your needs are describe in a very good teaching way.

Parts are growing in difficulties. The first will show you how to install and what in installed in a default Plone site. The second part will learn you how to become the owner of your site by creating content and configuring it. The third part is for those who wanted to learn how to use addon products for Plone or want to customize Plone site: zc.buildout, PloneFormGen and ArchGenXML are presented here. The last part will show you some general needs around Plone: put Plone in production behind Apache or IIS with speed optimizations, and LDAP/Active Directory integration.

Even if the target of this book is beginners it was a very interresting reading for an old developper like me. If you don’t use it for yourself, you will use it to give answers to your end-users. I can only recommand everyone to buy it. Nice work guys.

Février 23, 2009
» Raising Distutils test coverage : half-way


After the next commit I will make in Distutils (that adds tests for bdist_rpm), the test coverage of this Python standard library  package will be at 41%. This means that I have doubled the test coverage over the past few months, from 18% to 41%.

My goal is to double it again, and reach 80% in the next 6 months.

This also means I am just half an idiot now ! (since people who don’t have 100% code coverage are idiots ;) ).

So does it make Distutils more robust ?

It would have probably made the latest Python 3 release looks better for this package, since we had a uncovered cmp() call left in Distutils by the time the release was made. In the meantime, as I said before, the “real” Distutils regression test suite is held by all the packages out there in the community, that are built and installed everyday.

Python trunk Distutils test coverage : 41%

Name               Stmts   Exec  Cover
--------------------------------------
__init__               3      0     0%
archive_util          77     61    79%
bcppcompiler         185      0     0%
ccompiler            453    211    46%
cmd                  180    134    74%
config                73     59    80%
core                  93     50    53%
cygwinccompiler      161      0     0%
debug                  3      3   100%
dep_util              43     11    25%
dir_util             109     76    69%
dist                 581    386    66%
emxccompiler         118      0     0%
errors                49      0     0%
extension             97     28    28%
fancy_getopt         233    126    54%
file_util            124     77    62%
filelist             161    102    63%
log                   46     21    45%
msvc9compiler        408      0     0%
msvccompiler         370      0     0%
spawn                 93     28    30%
sysconfig            323     51    15%
text_file            112     61    54%
unixccompiler        160     64    40%
util                 255    157    61%
version               68     62    91%
versionpredicate      61     51    83%
__init__               3      3   100%
bdist                 61     35    57%
bdist_dumb            57     47    82%
bdist_msi            322      0     0%
bdist_rpm            252    198    78%
bdist_wininst        170      0     0%
build                 60     54    90%
build_clib            90      0     0%
build_ext            334    160    47%
build_py             213    178    83%
build_scripts         78     65    83%
clean                 35      0     0%
config               185      0     0%
install              251    156    62%
install_data          44      0     0%
install_egg_info      40     32    80%
install_headers       25      0     0%
install_lib           97     50    51%
install_scripts       33     29    87%
register             173     82    47%
sdist                228    180    78%
upload               112     38    33%
--------------------------------------
TOTAL               7502   3126    41%


Python 2.5.4 Distutils test coverage : 18%

Name               Stmts   Exec  Cover
--------------------------------------
__init__               3      0     0%
archive_util          78     11    14%
bcppcompiler         185      0     0%
ccompiler            453      0     0%
cmd                  180     79    43%
core                  93     15    16%
cygwinccompiler      160      0     0%
debug                  3      3   100%
dep_util              43      4     9%
dir_util             106     50    47%
dist                 578    342    59%
emxccompiler         118      0     0%
errors                49      0     0%
extension             97      9     9%
fancy_getopt         233    121    51%
file_util            121     50    41%
filelist             162      0     0%
log                   46     15    32%
msvccompiler         365      0     0%
mwerkscompiler       140      0     0%
spawn                 93      0     0%
sysconfig            296     10     3%
text_file            146      0     0%
unixccompiler        159      0     0%
util                 235     69    29%
version               68     48    70%
versionpredicate      61     51    83%
__init__               3      3   100%
bdist                 59      0     0%
bdist_dumb            57      0     0%
bdist_msi            320      0     0%
bdist_rpm            248      0     0%
bdist_wininst        159      0     0%
build                 52     47    90%
build_clib            90      0     0%
build_ext            304      0     0%
build_py             213    143    67%
build_scripts         78     64    82%
clean                 35      0     0%
config               185      0     0%
install              220    120    54%
install_data          44      0     0%
install_egg_info      40      0     0%
install_headers       26      0     0%
install_lib           96      0     0%
install_scripts       33     29    87%
register             171      0     0%
sdist                204      0     0%
upload               118      0     0%
--------------------------------------
TOTAL               7026   1283    18%

Février 20, 2009
» Proposing Python trainings

After years of Plone training, I have been working on a Python course offering. That evolution makes sense since a wider group of people come to Python via Plone, and now I want to bring to the table the other interesting and useful bits of Python… Things like SQLAlchemy, web frameworks, system administration or data crunching techniques and tools, or simply exploiting the Python Standard Library.

There is probably a bunch of people interested by using Python for their daily work, and who need some training to get there.

If you are in that situation, feel free to contact me and let me know which type of course you would like and if I can help organize it for you. For maximum flexibility, you could choose among several options: a public class with several participants, a customized class for a group within your organization, or one or several coaching days to help approach problems within a project. I have already experienced any of these formats and they all work well.

If you are based in France, you might want to join the first public Python class we will be organizing in June for the french public.


Février 19, 2009
» Fix PIL 1.1.6 installation from sources under debian


Today I found a bug in kupu integration in Plone. I prepared a patch and I tried to reinstall plonenext environment. But this time it fails to install on the PIL egg.

The PIL egg is very dependant to your architecure. It depends of libjpeg, tkinter (tcl/tk), and some other libraries. I’m working with a Debian unstable with 3 versions of tcl/tk for various programs: 8.3, 8.4 and 8.5.

The errors was the following:

getting distribution for ‘PIL’.
libImaging/Effects.c:210: warning: ‘perlin_init’ defined but not used
libImaging/Geometry.c:236: warning: ‘quadratic_transform’ defined but not used
libImaging/Quant.c:311: warning: ‘test_sorted’ defined but not used
libImaging/Quant.c:676: warning: ‘checkContained’ defined but not used
libImaging/QuantHash.c:136: warning: ‘_hashtable_test’ defined but not used
_imagingtk.c:20:16: error: tk.h: Aucun fichier ou répertoire de ce type
_imagingtk.c:23: error: expected ‘)’ before ‘*’ token
_imagingtk.c:31: error: expected specifier-qualifier-list before ‘Tcl_Interp’
_imagingtk.c: In function ‘_tkinit’:
_imagingtk.c:37: error: ‘Tcl_Interp’ undeclared (first use in this function)
_imagingtk.c:37: error: (Each undeclared identifier is reported only once
_imagingtk.c:37: error: for each function it appears in.)
_imagingtk.c:37: error: ‘interp’ undeclared (first use in this function)
_imagingtk.c:45: error: expected expression before ‘)’ token
_imagingtk.c:51: error: ‘TkappObject’ has no member named ‘interp’
_imagingtk.c:55: warning: implicit declaration of function ‘TkImaging_Init’
error: Setup script exited with error: command ‘gcc’ failed with exit status 1

All development libraries was installed, but the installer cannot find /usr/include/tk.h. There are /usr/include/tcl8.3/tk.h, /usr/include/tcl8.4/tk.h, /usr/include/tcl8.5/tk.h. Then I wrote the little patch below for the setup.py file:

Index: setup.py
===================================================================
— setup.py    (révision 460)
+++ setup.py    (copie de travail)
@@ -199,6 +199,9 @@
add_directory(library_dirs, “/usr/lib”)
add_directory(include_dirs, “/usr/include”)

+        if os.path.isfile(os.path.join(’/usr/include’, ‘tcl’+TCL_VERSION,’tk.h’)):
+            add_directory(include_dirs, os.path.join(’/usr/include’, ‘tcl’+TCL_VERSION))
+
#
# insert new dirs *before* default libs, to avoid conflicts
# between Python PYD stub libs and real libraries

I hope this patch is generic enough to be merged in the next Imaging release. Waiting this next release, I’m searching for a method to patch an egg before it is compiled by zc.buildout.

Février 15, 2009
» What’s new in Distutils ?


Since Python 3.0.1 was released this week, here’s a quick wrapup of what is going on in Distutils.

Code work (since one month)

New features

  • Issue 2563 : now the manifest is embed in windows extensions
  • Issue 4394 : the storage of the password in .pypirc file is optional now

Fixed bugs

  • Issue 4524: distutils was failing to build scripts with the ‘–with-suffix=3′
  • Issue 5132 : build_ext command was failing under Solaris with ‘–enabled-shared’
  • Issue 5075 : bdist_wininst was depending on the vc runtime

Refactoring

  • Issue 2461 : added test coverage for util.py
  • Issue 3986 : removed  string and type usage from distutils.cmd
  • Issue 3987 : removed type usage from distutils.core

Documentation

  • Issue 5158 : added documentation for depends option for extensions
  • Issue 4987: updated README info
  • Issue 4137 : SIG web pages were updated

Design work

The main topics that are being discussed are:

  • Improving the console script story. thread starts here.
  • Publishing a Survey on Distutils before the Language Summit. thread starts here.
  • Adding an uninstall command to unistall packages in the sdtlib : thread starts here
  • Adding a get_metadata API in pkgutil to get the metadata of an arbritary package The same code can also be used for various lookups (uninstall, console script) : thread starts here
  • Having a new PEP to make egg.info a directory and clearly define PKG-INFO and its match with metdata. thread starts here

Février 8, 2009
» A Distutils Regression Test System ?


I am making some progress in Distutils. I closed something like 10 bugs last week, and I am reaching issues that were added 8 months ago. Not that everything is entirely cleaned up in the newest issues, but they’re almost all being processed. Every commit comes with at least a test, to get the code base back into a state were it is easier to make things evolve without the risk of breaking it up.

It comes through tiny little changes, with tests and an eye on the coverage.

Now I am facing an unpleasant situation : since the test coverage is still low, I am always scared of breaking something in Distutils when I am fixing a bug or making a change.Buildbots are watching, and I run some of my own packaging work with the current trunk.

But still, this is an unpleasant situation, and I don’t want to cause the package to be broken in the next Python version…

But the regression tests exists ! They are there, hidden, in the community. It’s everyone package.

  1. Joe adds an issue in the Python bug tracker, because Distutils didn’t work as expected on his package because of a bug
  2. At some point the bug is (was) fixed.
  3. The test to make sure the bug is fixed is “Joe is running Distutils over his package again, and makes sure it is properly installed, compiled, etc”.
  4. The bug is closed.

So how can I get back this test to make sure Joe’s package is still working properly, so he doesn’t hate us at the next major Python release ?

A Distutils Regression Test Server

If Joe’s package is on PyPI, we can set something up. A dedicated server that watches the PyPI changelog and triggers a buildbot when:

  • a new release of Joe’s Package comes out
  • we change something in Distutils code

The precise test to be run is still unclear to me but, I am thinking about some generic strategies and I think it’s possible. Let’s call this test a distutils regression test. (If you have a better name, I’ll buy it)

Of course it doesn’t have to be on all the packages that are uploaded out there at PyPI. Just Joe’s one, because he came up with a problem we fixed. And we would be ashamed if the bug comes back on Joe’s package.

This requires of course a server, and probably a vmware-like system if Joe runs Windows or Solaris, to make buildbot slaves etc. It also requires that Joe uses the right metadata in his package so we know if it works under Python 2, Python 3, etc. MvL added enough classifiers lately for this.

A Distributed Distutils Regression Test

But some package are not on PyPI, for privacy or conveniency in the packaging process of the person in charge. So, what if the distutils regression test is provided in a Distutils command ? It can run the same test the server runs, and come up with a report that is sendable or sent by mail to a special mailing list or so.

This supposes that the developer is cooperative. So maybe it can even be automatically triggered in case of any failure on any Distutils command, and ask the user if he would like to send a report ?

The good thing here is that it doesn’t require CPU power on the test server, and that anyone can run that test.

So what ?

Well I am just throwing an idea here, because I am really concerned about the potential regression problems. Even if Distutils is 100% covered with tests, it’s not possible to test all combinations. The real world environment is the only test that can be trusted at the end in the packaging area.

I’ll throw this idea at the Language Summit in March, and if it catches people interest, maybe a Google Summer of Code task could be done for that topic ?  Can’t implement it myself, I am overwhelmed already in Distutils maintenance :D

Just out of curiosity, how do *you* test your packages to make sure they get installed correctly ?


Février 1, 2009
» install pymssql and how to deal with DB-Lib error message 20009, severity 9

Hello,

In a recent zope project I’m obliged to use an mssql database. So I test first an installation with a windows server os. Everything is ok when I configure the good port (1433) and open tcpip connection in sql management and stop firewall.

But when I try to connect with pymssql in unix I have some problem.
When I launch a connection to mssql I have this error:

>>> _mssql.connect("host","user", "password")
Traceback (most recent call last):
File "<console>", line 1, in ?
MssqlDatabaseException: DB-Lib error message 20009, severity 9:
Unable to connect: Adaptive Server is unavailable or does not exist
Net-Lib error during Operation now in progress Error 36 - Operation now in progress

Yahoo , I’m very happy.

In google , no good post about this problem, so I’m very desappointed. I know that pymssql on unix work with freedts which is an implementation of the protocol which use mssql.
When you install freedts you install also some utility. It’s located in bin. Some of it  named tsql. You can use it to test your connection. As pymssql is an wrapper to freedts (in unix) and if tsql don’t work I suppose pymssql also. So I try with this command and I have exactly the same results :

mac:bin yboussard$ ./tsql -H myip -p 1433 -U myuser
locale is "fr_FR.UTF-8"
locale charset is "UTF-8"
Password:
Msg 20017, Level 9, State -1, Server OpenClient, Line -1
Unexpected EOF from the server
Msg 20002, Level 9, State -1, Server OpenClient, Line -1
Adaptive Server connection failed
There was a problem connecting to the server

So I’m very again very happy and reassure that I’m in the good way.
In read documentation about freedts and we can debug connection in setting environment variable TDSDUMP=/tmp/freetds.log. So now when I launch an connection I log in freetds.log. I see in this file the tds version used by the connection and I see it was incorrect (tds version is 5) in accordance with that documentation.
So I use an another environnement variable to fix that :

export TDSVER=7.0

And miracle , everything work with tsql. So I force version of tds in my ~/.freetds.conf in global section as this

[global]
tds version = 7.0

And after that everything is ok in python. Yahoo!!. I hope that ticket will be useful for you.

Regards Youenn.


Janvier 28, 2009
» Building a survey for Distutils (Pycon’s Python Language Summit)


I have the opportunity to lead a session at the Python Language Summit at Pycon.

In order to prepare this event, I am currently building a survey because we need to know how people use Distutils, what is wrong with it, and so on…

The draft is here : http://wiki.python.org/moin/Packaging%20Survey

When it’s ready (hopefully soon), I’ll post it in a SurveyMonkey-like system online for people to take it, and synthetize the results, so what I am saying at the summit reflects hopefully the reality.

If you are a Python developer, an OS packager, come to the Distutils-SIG mailing list and help us build the best survey possible !

(while the draft is in a wiki, it’s better to discuss the changes in the mailing list before it is applied)

Janvier 23, 2009
» Singletons (and Borg) are unpythonic (well.. imvho)


Alex Martelli wrote a review about my latest book (can’t find a permanent link on this, just look at Amazon.com you’ll find it).

Amongst the negative parts there’s one noticeable part I’d like to discuss in my blog, because I disagree with Alex’s analysis.

Alex says:

This also holds for the chapter on design patterns, with such egregious claims as “Singletons should not have several levels of inheritance” — they should have as few as practical and feasible, *exactly like any other class*; the desire to limit the number of distinct instances (which is mostly about STATE) is quite orthogonal to the issues with subclassing (which is mostly about BEHAVIOR). From this original “totally missing the point” follows a classic howler (which I’ve seen repeated in a review above): “why not use a module?”. I have news for you, Tarek: a module supports *ZERO* inheritance — which is quite a bit stricter than even the unjustified “should not have several level” claim above. Having to completely give up the usefulness of inheritance just because you want to limit instantiation would be a very limiting engineering tradeoff! If there’s no need for inheritance then *of course* you want to use a module - DOH! - but if there IS (or if special methods can really help you) then it’s not an option.

I think that the Singleton (and Borg) pattern is totally useless in fact. That’s not the philosophy of Python in my humble opinion. And I think my book is right to advise people not to use this pattern.

I don’t see the point of bending down a class so it only has one instance, where you can simply create an instance of that class in a module, add a “_” prefix to that class, and tell the world that this instance is your singleton. I don’t see why a class should deal with that kind of STATE.

Frankly, I doubt that this singleton/borg pattern is really used in the community.

The only place where I really had to use singleton classes was in Zope. But that was more like a marker than anything else, and the class was registered under a “single” name in a global mapping (eg. its id in its container, in the ZODB tree). And in that case, we were creating one mixin class that used a singleton class, and we called it a “tool”, with all the desired BEHAVIOR inside of it.

And well, if we would had several instance of it, for sure nothing bad could really happen, because the real unicity was provided by the id of the object. And nowadays those “tools” are going away and they are now called “utilities”, and I don’t think any singleton class is still really present or used. Just simply because a class is not the right place to enforce this.

I’d also say that there’s an architectural problem when you enforce things like this in Python. If a programmer tells me that he wants to use a Singleton on his class because it holds a DB connector he wants to be instanciated once in his application, I am asking him right away to review the way the program is structured.

So what is the closest element in Python that will let you mark an object as unique ? what is the most convenient way to mark an object with an id in a container ?

A simple variable in a module. (or a simple declaration in a zcml file if you are a zopish guy)

I love Python for this because it’s multiparadigm unlike Java : you don’t have to set up over-engineered OOP stuff for this kind of needs (and it is surely not a tradeoff to use well engineered OOP besides).

Last, when I am claiming in Frenglish, that “Singletons should not have several levels of inheritance”. This is just to warn people that, since these patterns are trying to break the way classes work, you might get screwed at some point when singletons are subclassed. A descriptor or a metaclass or whatever can just break your singleton stuff because Python was not meant to be used like that. It’s not robust.