Canonical Voices

Posts tagged with 'development'

Daniel Holbach

The times for Ubuntu have never been more exciting. Cloud, server, desktop, laptop, TV, tablet, phone – everything runs Ubuntu or is soon going to. This makes developing Ubuntu very special, because fixes which go into Ubuntu in one place will benefit all form factors and all circumstances where it’s used. By improving Ubuntu you make millions of people around the globe happy.

During every 6 month release cycle we run Ubuntu Developer Week. It’s back and we’re going to have it from 29th January to 31st January. During the event we will have online sessions where seasoned Ubuntu developers introduce you to their respective area of expertise or to Ubuntu Development in general.

We will have many great sessions, from hands-on introduction to packaging and Ubuntu development to talks about how to quickly get involved in certain teams and interact with other projects. We will talk about tools and infrastructure, fixing bugs, finding memleaks, working with apps, create Ubuntu images and much much much more. This is the best opportunity to get a feel for how Ubuntu development works, get to know people and ask all the questions you might have.

I talked to a few session hosts, read below what they had to say.

Martin Pitt

Martin Pitt

Martin Pitt, who will talk about Automated Testing, says: “We have been, and are changing the Ubuntu development process to employ automated testing and avoid introducing regressions, and to improve confidence, focus, and development speed. In the first talk I will give an overview about the various kinds of tests that we do, so that you know where to watch out for failures and get debugging information. The second talk focuses on how to write tests, i.e. which technologies are available for e.g. hardware and GUI related behaviour or system-wide integration checks.”


Stefano Rivera

Stefano Rivera

Stefano Rivera, who will talk about Upstreams and Debian in particular, said: “So, working effectively in Ubuntu means also working with the teams and people upstream who wrote the software we distribute. I’ll talk about why this is important, when it’s necessary, and how to go about it. In particular, our most important upstream is Debian. Debian has a rather unusual (though powerful) bug-tracker. We’ll cover finding, submitting, and modifying bugs on it.

Chris Wilson

Chris Wilson

Chris Wilson, project leader of the Hundred Papercuts Team, says: “Unity may be the shiny new thing that everyone loves, but style without substance is only so much fluff, and the substance of Ubuntu is still its GTK-based apps. Once Hundred Paper Cuts focuses it’s attention on that substance, rubbing out the little annoyances that get under our skin every day we’re using Ubuntu. This session will introduce you to the project, how it works, and how to get involved. If you want to contribute to Ubuntu in a way that has the biggest impact on the quality of experience for the end user, then don’t miss this.


Bhavani Shankar

Bhavani Shankar

Bhavani Shankar, said about his talk about patch systems: “Many a time we wonder how to integrate a particular fix a particular part of the code in a program and upload into repositories without having to change code each time by hand and making it clumsy. In this session I’m going to show how to use different patch management systems that are in practice now.

About his talk about the app review process in Ubuntu he says: “In this session I’m going to explain the present workflow of reviewing apps and give an introduction into the new app dev upload process to automate reviews.

The forum we use for this is IRC, as it makes it easy to interact for many people without losing track, you can easily copy/paste and we can save the logs as searchable docs afterwards. You join in by simply connecting to #ubuntu-classroom on

Check out the schedule and find more info on the Ubuntu wiki. We hope to see you all there, please let you friends know too. :-)

Read more
Jussi Pakkanen

We have all ran into software inconveniences. These are things that you can basically do but for some reason or another are unintuitive, hard or needlessly complex. When you air your concerns on these issues, sometimes they get fixed. At other times you get back a reply starting with “Well in general you may have a point, but …”.

The rest of the sentence is something along the lines of these examples:

“… you only have to do it once so it’s no big deal.”
“… there are cases where [e.g. autodetection] would not work so having the user [manually do task X] is the only way to be reliable.”
“… I don’t see any problem, in fact I like it the way it is.”
“… replacing [the horrible thing in question] with something better is too much work.”
“… fixing that would change things and change is bad.”
“… that is the established standard way of doing things.”
“… having a human being write that in is good, it means that the input is inspected.”

These are all fine and acceptable reasonings under certain circumstances. In fact, they are great! Let’s see what life would be like in a parallel universe where people had followed them slavishly.

Booting Linux: an adventure for the brave

You arrive to your work computer and turn it on. The LILO boot prompt comes up as usually. You type in the partition you want to boot from. This you must do every time because you might have changed partition settings and thus make LILO go out of sync. You type in your boot stanza sure in the knowledge that you get 100% rock solid boot every time.

Except when you have a typo in your boot command but a computer can’t work around that. And that happens only rarely anyways and why would you boot your computer more than once per month?

Once the kernel has loaded, you type in the kernel modules you need to use the machine. You also type in all extra parameters those modules require because some chipsets may work incorrectly sometimes (or so you have been told). So you type in some dozen strings of hexadecimal numbers and really enjoy it in a stockholmesque way.

Finally all the data is put in and the system will boot itself. Then it is time to type in your network settings. In this universe there is no Protocol to Configure network Host settings Dynamically. And why would there be? Any bug in such a system would render the entire network unusable. No, the only way to ensure that things work is to configure network settings by hand every time. Errors in settings cause only one machine to break, not the entire network. Unless you mix gateway/netmask/IP addresses but surely no-one is that stupid? And if they are, it’s their own damn fault! Having things fail spectacularly is GOOD because it shames people into doing the right thing.

After this and a couple of other simple things (each of which you only need to do once, remember) you finally have a working machine. You log on.

Into a text console, naturally. Not all people need X so it should not be started by default. Resources must be used judiciously after all.

But you only need to start X once per session so no biggie. Just like you only need to write in your monitor modeline once per X startup because autodetection might fail and cause HW failure. The modeline can not be stored in a file and used automatically because you might have plugged in a different monitor. Typing it in every time is the only way to be sure. Or would you rather die horribly in a fire caused by incorrect monitor parameters?

After all that is done you can finally fire up an XTerm to start working. But today you feel like increasing the font size a bit. This is about as simple as can get. XTerm stores a list of font sizes it will display in XResources. All you have to do is to edit them, shut down X and start it up again.

Easy as pie. And the best part: you only have to do this once.

Well, once every time you want to add new font sizes. But how often is that, really?


The examples listed above are but a small fraction of reality. If computer users had to do all “one time only” things, they would easily take the entire eight hour work day. The reason they don’t is that some developer Out There has followed this simple rule:

Almost every task that needs to be done “one time only” should, in fact, be done exactly zero times.


Read more

I just released a new PyGObject, for GNOME 3.7.4 which is due on Wednesday.

This release saw a lot of bug and memory leak fixes again, as well as enabling some more data types such as GParamSpec, boxed list properties, or directly setting string members in structs.

Thanks to all contributors!

Summary of changes (see change log for complete details):

  • Allow setting values through GtkTreeModelFilter (Simonas Kazlauskas) (#689624)
  • Support GParamSpec signal arguments from Python (Martin Pitt) (#683099)
  • pygobject_emit(): Fix cleanup on error (Martin Pitt)
  • Add signal emission methods to TreeModel which coerce the path argument (Simon Feltman) (#682933)
  • Add override for GValue (Bastian Winkler) (#677473)
  • Mark caller-allocated boxed structures as having a slice allocated (Mike Gorse) (#699501)
  • pygi-property: Support boxed GSList/GList types (Olivier Crête) (#684059)
  • tests: Add missing backwards compat methods for Python 2.6 (Martin Pitt) (#691646)
  • Allow setting TreeModel values to None (Simon Feltman) (#684094)
  • Set clean-up handler for marshalled arrays (Mike Gorse) (#691509)
  • Support setting string fields in structs (Vadim Rutkovsky) (#678401)
  • Permit plain integers for “gchar” values (Martin Pitt)
  • Allow single byte values for int8 types (Martin Pitt) (#691524)
  • Fix invalid memory access handling errors when registering an enum type (Mike Gorse)
  • Fix (out) arguments in callbacks (Martin Pitt)
  • Fix C to Python marshalling of struct pointer arrays (Martin Pitt)
  • Don’t let Property.setter() method names define property names (Martin Pitt) (#688971)
  • Use g-i stack allocation API (Martin Pitt) (#615982)
  • pyg_value_from_pyobject: support GArray (Ray Strode) (#690514)
  • Fix obsolete automake macros (Marko Lindqvist) (#691101)
  • Change dynamic enum and flag gtype creation to use namespaced naming (Simon Feltman) (#690455)
  • Fix Gtk.UIManager.add_ui_from_string() override for non-ASCII chars (Jonathan Ballet) (#690329)
  • Don’t dup strings before passing them to type registration functions (Mike Gorse) (#690532)
  • Fix marshalling of arrays of boxed struct values (Carlos Garnacho) (#656312)
  • testhelpermodule.c: Do not unref called method (Martin Pitt)

Read more
Jussi Pakkanen

Using libraries in C++ is simple. You just do #include<libname> and all necessary definitions appear in your source file.

But what is the cost of this single line of code?

Quite a lot, it turns out. Measuring the effect is straightforward. Gcc has a compiler flag -E, which only runs the preprocessor on the given source file. The cost of an include can be measured by writing a source file that has only one command: #include<filename>. The amount of lines in the resulting file tells how much code the compiler needs to parse in order to use the library.

Here is a table with measurements. They were run on a regular desktop PC with 4 GB of RAM and an SSD disk. The tests were run several times to insure that everything was in cache. The machine was running Ubuntu 12/10 64 bit and the compiler was gcc.

Header                     LOC    Time

map                       8751    0.02
unordered_map             9728    0.03
vector                    9964    0.02
Python.h                 11577    0.05
string                   15791    0.07
memory                   17339    0.04
sigc++/sigc++.h          21900    0.05
boost/regex.h            22285    0.06
iostream                 23496    0.06
unity/unity.h            28254    0.14
xapian.h                 36023    0.08
algorithm                40628    0.12
gtk/gtk.h                52379    0.26
gtest/gtest.h            53588    0.12
boost/proto/proto.hpp    78000    0.63
gmock/gmock.h            82021    0.18
QtCore/QtCore            82090    0.22
QtWebKit/QtWebKit        95498    0.23
QtGui/QtGui             116006    0.29
boost/python.hpp        132158    3.41
Nux/Nux.h               158429    0.71

It should be noted that the elapsed time is only the amount it takes to run the code through the preprocessor. This is relatively simple compared to parsing the code and generating the corresponding machine instructions. I ran the test with Clang as well and the times were roughly similar.

Even the most common headers such as vector add almost 10k lines of code whenever they are included. This is quite a lot more than most source files that use them. On the other end of the spectrum is stuff like Boost.Python, which takes over three seconds to include. An interesting question is why it is so much slower than Nux, even though it has less code.

This is the main reason why spurious includes need to be eliminated. Simply having include directives causes massive loss of time, even if the features in question are never used. Placing a slow include in a much used header file can cause massive slowdowns. So if you could go ahead and not do that, that would be great.

Read more
Jussi Pakkanen

A long time ago in the dawn of the new millennium lived a man. He was working as a software developer in a medium sized company. His life was pretty good all things considered. For the purposes of this narrative, let us call him Junior Developer.

At his workplace CVS was used for revision control. This was okay, but every now and then problems arose. Because it could not do atomic commits, sometimes two people would check in things at the same time, which broke everything. Sometimes this was immediately apparent and caused people to scramble around to quickly fix the code. At other times the bugs would lay dormant and break things at the worst possible times.

This irritated everyone but since the system mostly worked, this was seen as an unfortunate fact of life. Then Junior Developer found out about a brand new thing called Subversion. It seeemed to be just the thing they needed. It was used in almost exactly the same way, but it was so much better. All commits were atomic, which made mixing commits impossible. One could even rename files, a feature thus far unheard of.

This filled the heart of Junior Developer with joy. With one stroke they could eliminate most of their tooling problems and therefore improve their product’s quality. Overjoyed he waited for the next team meeting where they discussed internal processes.

Once the meeting started, the Junior Developer briefly reminded people of the problems and then explained how Subversion would fix most of the problems that CVS was causing.

At the other end of the table sat a different kind of man, who we shall call the Senior Developer. He was a man of extraordinary skill. He had personally designed and coded many of the systems that the company’s products relied on. Whenever anyone had a difficult technical issue, he would go ask the Senior Developer. His knowledge on his trade had extensive depth and breadth.

Before anyone else had time to comment on the Junior Developer’s suggestion, he grabbed the stage and let out a reply in a stern voice.

- This is not the sort of discussion we should be getting into. CVS is good and we’ll keep using it. Next issue.

The Junior Developer was shocked. He tried to form some sort of a reply but words just refused to come out of his mouth. Why was his suggestion for improvement shot down so fast? Had someone already done a Subversion test he had not heard about? Had he presented his suggestion too brazenly and offended the Senior Developer? What was going on?

These and other questions raced around in his head for the next few days. Eventually he gathered enough willpower and approached the Senior Developer during a coffee break.

- Hey, remember that discussion on Subversion and CVS we had a few days ago? Why did you declare it useless so quickly? Have you maybe tried it and found it lacking?

- I figured you might mention this. Look, I’m sure you are doing your best but the fact of the matter is that CVS is a good tool and it does everything we want it to do.

- But that’s just the thing. It does not do what we want. For example it does not have atomic commits. It would prevent check-in conflicts.

The Senior Programmer lifted his coffee cup to his lips and took a swig. Not to play for time, but simply to give emphasis to his message.

- CVS is a great tool. You just have to be careful when using it and problems like this don’t happen.

The Junior Programmer then tried to explain that even though they were being careful, breakages still happened and they had been for as long as anyone could remember. He tried explaining that in Subversion one could rename files and retain their version control history. He tried to explain how these and other features would be good, how they would allow for developers to spend more of their time on actual code and less on working around features of their tools.

The Senior Developer countered each of these issues with one of two points. Number one was the fact that you could achieve roughly the same with CVS if that is really what was wanted (with an unspoken but very clear implication that it was not). Number two was that functionality such as renames could be achieved by manually editing the repository files. This was considered a major plus, since one would not be able to do this kind of maintenance work on Subversion repositories because they were not plain text files. Any database runs the risk of corruption, which was unacceptable for something as important as source code.

The discussion went on but eventually the Senior Developer had finished his coffee and walked over to the dishwasher to put his cup away.

- Look, I appreciate the thinking you have obviously put into this but let me tell you a little something.

He put his cup away and turned to face the Junior Developer who at this point was majorly frustrated.

- I have used CVS for over 10 years. It is the best system there is. In this time there have been dozens of revision control systems that claim to have provided the same benefits that this Subversion of yours does. I have tried many of them and none have delivered. Some have been worse than the systems CVS replaced if you can believe that. The same will happen with Subversion. The advantages it claims to provide simply are not there, and that’s the sad truth.

The Junior Developer felt like shouting but controlled himself realizing that no good thing could come out of losing his temper. He slouched in his chair. The Senior Developer looked at the clearly disillusioned Junior Developer and realized the argument had ended in his favor. He left back to his office.

At the coffee room door he turned around and said his final words to the Junior Developer.

- Besides, even if the atomic commits you seem to hold so dear would work, the improvements they provide would be minimal. They are a nice-to-have toy and will never account for anything more than that.


This story is not true. But it could be.

Variants of this discussion are being held every single day in software development companies and communities around the world.

Read more

I just released a new PyGObject, for GNOME 3.7.3 which is due on Wednesday.

This is mostly a bug fix release. There is one API addition, it brings back official support for calling GLib.io_add_watch() with a Python file object or fd as first argument, in addition to the official API which expects a GLib.IOChannel object. These modes were marked as deprecated in 3.7.2 (only).

Thanks to all contributors!

Summary of changes (see change log for complete details):

  • Add support for caller-allocated GArray out arguments (Martin Pitt) (#690041)
  • Re-support calling GLib.io_add_watch with an fd or Python file (Martin Pitt)
  • pygtkcompat: Work around IndexError on large flags (Martin Pitt)
  • Fix pyg_value_from_pyobject() range check for uint (Martin Pitt)
  • Fix tests to work with g-i 1.34.2 (Martin Pitt)
  • Fix wrong refcount for GVariant property defaults (Martin Pitt) (#689267)
  • Fix array arguments on 32 bit (Martin Pitt)
  • Add backwards compatible API for GLib.unix_signal_add_full() (Martin Pitt)
  • Drop MININT64/MAXUINT64 workaround, current g-i gets this right now (Martin Pitt)
  • Fix maximum and minimum ranges of TYPE_(U)INT64 properties (Simonas Kazlauskas) (#688949)
  • Ship in tarballs (Martin Pitt) (#688697)
  • Various added and improved tests (Martin Pitt)

Read more

When writing system integration tests it often happens that I want to mount some tmpfses over directories like /etc/postgresql/ or /home, and run the whole script with an unshared mount namespace so that (1) it does not interfere with the real system, and (2) is guaranteed to clean up after itself (unmounting etc.) after it ends in any possible way (including SIGKILL, which breaks usual cleanup methods like “trap”, “finally”, “def tearDown()”, “atexit()” and so on).

In gvfs’ and postgresql-common’s tests, which both have been around for a while, I prepare a set of shell commands in a variable and pipe that into unshare -m sh, but that has some major problems: It doesn’t scale well to large programs, looks rather ugly, breaks syntax highlighting in editors, and it destroys the real stdin, so you cannot e. g. call a “bash -i” in your test for interactively debugging a failed test.

I just changed postgresql-common’s test runner to use unshare/tmpfses as well, and needed a better approach. What I eventually figured out preserves stdin, $0, and $@, and still looks like a normal script (i. e. not just a single big string). It still looks a bit hackish, but I can live with that:

set -e
# call ourselves through unshare in a way that keeps normal stdin, $0, and CLI args
unshare -uim sh -- -c "`tail -n +7 $0`" "$0" "$@"
exit $?

# unshared program starts here
set -e
echo "args: $@"
echo "mounting tmpfs"
mount -n -t tmpfs tmpfs /etc
grep /etc /proc/mounts
echo "done"

As Unix/Linux’ shebang parsing is rather limited, I didn’t find a way to do something like

#!/usr/bin/env unshare -m sh

If anyone knows a trick which avoids the “tail -n +7″ hack and having to pay attention to passing around “$@”, I’d appreciate a comment how to simplify this.

Read more
Jussi Pakkanen

Software quality has received a lot of attention recently. There have been tons of books, blog posts, conferences and the like on improving quality. Tools and practices such as TDD, automatic builds, agile methods, pair programming and static code analysers are praised for improving code quality.

And, indeed, that is what they have done.

But one should never mix the tool with the person using it. All these wonderful tools are just that: tools. They are not the source of quality, only facilitators of it. The true essence of quality does not flow from them. It comes from somewhere else entirely. When distilled down to its core, there is only one source of true quality.


The only way to get consistently high quality code is that the people who generate it care about it. This means that they have a personal interest in their code tree. They want it to succeed and flourish. In the best case they are even proud of it. This is the foundation all quality tools lie on.

If caring does not exist, even the best of tools can not help. This is due to the fact that human beings are very, very good at avoiding work they don’t want to do. As an example, let’s look at code review. A caring person will review code to the best of their abilities because he wants the end result be the best it can be. A non-caring one will shrug, think “yeah, sure, fine, whatever” and push the accept button, because it’s less work for him and he knows that his merge requests will go in easier if there is a general (though unspoken) consensus of doing things half-assed.

Unfortunately caring is not something you can buy, it is something you must birth. Free food and other services provided by companies such as Valve and Google can be seen as one way of achieving quality. If a company sincerely cares about its employees, they will in return care about the quality of their work.

All that said, here is my proposal for a coder’s mascot:

Read more

I just released Apport 2.7.

The main new feature is supporting foreign architectures in apport-retrace. If apport-retrace works in sandbox mode and works on a crash that was not produced on the same architecture as apport-retrace is running on, it will now build a sandbox for the report’s architecture and invoke gdb with the necessary magic options to produce a proper stack trace (and the other gdb information).
Right now this works for i386, x86_64, and ARMv7, but if someone is interested in making this work for other architectures, please ping me.

This is rolled out to the Launchpad retracers, see for example Bug #1088428. So from now on you can report your armhf crashes to Launchpad and they ought to be processed. Note that I did a mass-cleanup of old armhf crash bugs this morning, as the existing ones were way too old to be retraced.

For those who are running their own retracers for their project: You need to add an armhf specific apt sources list your per-release configuration directory, e. g. Ubuntu 12.04/armhf/sources.list as armhf is on instead of Also, you need to add an armhf crash database to your crashdb.conf and add a cron job for the new architecture. You can see how all this looks like in the configuration files for the Launchpad retracers.

The other improvement concerns package hooks. So far, when a package hook crashed the exception was only printed to stderr, where most people would never see them when using the GTK or KDE frontend. With 2.7 these exceptions are also added to the report itself (HookError_filename), so that they appear in the bug reports.

The release also fixes a couple of bugs, see the release notes for details.

Read more
Daniel Holbach

We have achieved a huge milestone in the development community. For years we wanted translatable packaging and development documentation. It’s there. If you head to you can see the following:

The Ubuntu Packaging Guide (Spanish) – would you like to learn how to package or become an Ubuntu Developer? Here’s a comprehensive, topic-base guide that explores and describes the main concepts of packaging. It is available as

This is absolutely awesome. From now on we will be able to add languages and have up-to-date Packaging and Development docs available whenever they are complete enough.

This work was brought to you by many people who worked very hard to get all the bits right, both on the packaging, integration, beautification and translations sides. You all know who you are. Be proud of your work. This will ease the steps of many people into helping out with Ubuntu!

As always this is ongoing work and the great thing is, you can help out:

This makes me a very happy man and it’s great we finally got there. Now let’s get all the other translations up to scratch! :-D

Read more
Jussi Pakkanen

Every day computer users do a variation of a simple task: selecting an element from a list of choices. Examples include installing packages with ‘apt-get install packagename’, launching an application from the Dash with its name, selecting your country from a list on web pages and so on.

The common thing in all these use cases is intolerance for errors. If you have just one typo in your text, the correct choice will not be found. The only way around is to erase the query and type it again from scratch. This is something that people have learned to do without thinking.

It’s not very good usability, though. If the user searches for, say, Firefox by typing “friefox” by accident, surely the computer should be able to detect what the user meant and offer that as an alternative.

The first user-facing program in Ubuntu to offer this kind of error tolerance was the HUD. It used the Levenshtein distance as a way of determining user intent. In computer science terminology this is called approximate string matching or, informally, fuzzy matching.

Once the HUD was deployed, the need to have this kind of error correction everywhere became apparent. Thus we sent out to create a library to make error tolerant matching easy to embed. This library is called libcolumbus.

Technical info

Libcolumbus has been designed with the following goals in mind:

  • it must be small
  • it must be fast
  • it must be easy to embed
  • it is optimized for online typing

The last of these means that you can do queries at any time, even if the user is still typing.

At the core of libcolumbus is the Levenshtein distance algorithm. It is a well known and established way of doing fuzzy matching. Implementations are used in lots of different places, ranging from heavy duty document retrieval engines such as Lucene and
Xapian all the way down to Bash command completion. There is even a library that does fuzzy regexp matching.

What sets Columbus apart from these are two things, both of which are well known and documented but less often used: a fast search implementation and custom errors.

The first feature is about performance. The fast Levenshtein implementation in libcolumbus is taken almost verbatim from this public domain implementation. The main speedup comes from using a trie to store the words instead of iterating over all items on every query. As a rough estimate, a brute force implementation can do 50-100 queries a second with a data set of 3000 words. The trie version can do 600 queries/second on a data set of 50000 words.

The second feature is about quality of results. It is best illustrated with an example. Suppose there are two items to choose from, “abc” and “abp”. If the user types “abo”, which one of these should be chosen? In the classical Levenshtein sense both of the choices are identical: they are one replace operation away from the query string.

However from a usability point of view “abp” is the correct answer, because the letter p is right next to the letter o and very far from the letter c. The user probably meant to hit the key o but just missed it slightly. Libcolumbus allows you to set custom errors for these
kinds of substitutions. If the standard substitution error is 100, one could set the error for substitution error for adjacent keys to a smaller value, say 20. This causes words with “simple typos” to be ranked higher automatically.

There are several other uses for custom errors:

  • diacritical characters such as ê, é and è can be mapped to have very small errors to each other
  • fuzzy number pad typing can be enabled by assigning mapping errors from the number to corresponding letters (e.g. ’3′ to ‘d’, ‘e’ and ‘f’) as well as adjacent letters (i.e. those on number keys ’2′ and ’6′)
  • spam can be detected by assigning low errors for letters and numbers that look similar, such as ’1′ -> ‘i’ and ’4′ -> ‘a’ to match ‘v14gr4′ to ‘viagra’

Libcolumbus contains sample implementations for all these except for the last one. It also allows setting insert and delete errors at the beginning and end of the match. When set to low values this makes the algorithm do a fuzzy substring search. The online matching discussed above is implemented with this. It allows the library to match the query term “fier” to “firefox” very fast.

Get the code

Our goal for the coming cycle is to enable error tolerant matching in as many locations as possible. Those developers who wish to try it on their application can get the source code here.

The library is implemented in C++0x. The recommended API to use is the C++ one. However since many applications can not link in C++ libraries, we also provide a plain C API. It is not as extensive as the C++ one, but we hope to provide full coverage there too.

The main thing to understand is the data model. Libcolumbus deals in terms of documents. A document consists of a (user provided) document ID and a named collection of texts. The ID field is guaranteed to be large enough to hold a pointer. Here’s an example of what a document could look like:

id: 42
  name: packagename
  description: This package does something.

Each line is a single word field name followed by the text it contains. A document can contain an arbitrary number of fields.  This is roughly analogous to what MongoDB uses. It should be noted that libcolumbus does not read any data files. The user needs to create document objects programmatically. The example above is just a visualisation.

When the documents are created and passed to the main matcher object for processing, the system is ready to be queried. The result of queries is a list of document IDs and corresponding relevancies. Relevancy is just a number whose meaning is roughly “bigger relevancy means better”. The exact values are arbitrary and may change even between queries. End-user applications usually don’t need to bother with them.

There is one thing to be mindful, though. The current implementation has a memory backend only. Its memory usage is moderate but it has not yet been thoroughly optimized. If your data set size is a few hundred unique words, you probably don’t have to care. A few thousand takes around 5 MB which may be a problem in low memory
devices. Tens of thousands of words take tens of megabytes which may be too much for many use cases. Both memory optimizations and a disk backend are planned but for now you might want to stick to smallish data sets.

Read more
Daniel Holbach

Our Ubuntu Development Hangouts have had guests every now and then, but we wanted to get more people on board to talk about what’s going on in Ubuntu development. Many of our viewers asked for more detailed information about specific topics.

So here’s what we’re up to in the next weeks (we’ll add more dates and more sessions):

  • 4th Dec 2012, 15:00 UTC: Rick Spencer, Vice President of Ubuntu Engineering at Canonical will talk to us about 13.04 and the great things which are coming.
  • 11 Dec 2012, 16:00 UTC: Iain Lane, Ubuntu and Debian Developer will chat with us about desktop stuff, motu stuff, release team, backports and all that jazz.
  • 13 Dec 2012, 9:00 UTC: Didier Roche, Unity+Desktop hacker, Unity progress in 13.04, daily builds, automated tests.
  • 18 Dec 2012, 16:00 UTC: Chris Wilson, One Hundred Paper Cuts Team Lead will talk about the One Hundred Paper Cuts project, what the project does and how to get involved.
Your host

This guy will be part of the fun as well. :)

Read more

just released a new PyGObject, for GNOME 3.7.2 which is due on Wednesday.

In this version PyGObject went through some major refactoring: Some 5.000 lines of static bindings were removed and replaced with proper introspection and some overrides for backwards compatibility, and the static/GI/overrides code structure was simplified. For the developer this means that you can now use the full GLib API, a lot of which was previously hidden by old and incomplete static bindings; also you can and should now use the officially documented GLib API instead of PyGObject’s static one, which has been marked as deprecated. For PyGObject itself this change means that the code structure is now a lot simpler to understand, all the bugs in the static GLib bindings are gone, and the GLib bindings will not go out of sync any more.

Lots of new tests were written to ensure that the API is backwards compatible, but experience teaches that ther is always the odd corner case which we did not cover. So if your code does not work any more with 3.7.2, please do report bugs.

Another important change is that if you build pygobject from source, it now defaults to using Python 3 if installed. As before, you can build for Python 2 with PYTHON=python2.7 or the new --with-python=python2.7 configure option.

This release also brings several marshalling fixes, docstring improvements, support for code coverage, and other bug fixes.

Thanks to all contributors!

Summary of changes (see changelog for complete details):

  • [API change] Drop almost all static GLib bindings and replace them with proper introspection. This gets rid of several cases where the PyGObject API was not matching the real GLib API, makes the full GLib API available through introspection, and makes the code smaller, easier to maintain. For backwards compatibility, overrides are provided to emulate the old static binding API, but this will throw a PyGIDeprecationWarning for the cases that diverge from the official API (in particular, GLib.io_add_watch() and GLib.child_watch_add() being called without a priority argument). (Martin Pitt, Simon Feltman)
  • [API change] Deprecate calling GLib API through the GObject namespace. This has always been a misnomer with introspection, and will be removed in a later version; for now this throws a PyGIDeprecationWarning.
  • [API change] Do not bind gobject_get_data() and gobject_set_data(). These have been deprecated for a cycle, now dropped entirely. (Steve Frécinaux) (#641944)
  • [API change] Deprecate void pointer fields as general PyObject storage. (Simon Feltman) (#683599)
  • Add support for GVariant properties (Martin Pitt)
  • Add type checking to GVariant argument assignment (Martin Pitt)
  • Fix marshalling of arrays of struct pointers to Python (Carlos Garnacho) (#678620)
  • Fix Gdk.Atom to have a proper str() and repr() (Martin Pitt) (#678620)
  • Make sure g_value_set_boxed does not cause a buffer overrun with GStrvs (Simon Feltman) (#688232)
  • Fix leaks with GValues holding boxed and object types (Simon Feltman) (#688137)
  • Add doc strings showing method signatures for gi methods (Simon Feltman) (#681967)
  • Set Property instance doc string and blurb to getter doc string (Simon Feltman) (#688025)
  • Add GObject.G_MINSSIZE (Martin Pitt)
  • Fix marshalling of GByteArrays (Martin Pitt)
  • Fix marshalling of ssize_t to smaller ints (Martin Pitt)
  • Add support for lcov code coverage, and add a lot of missing GIMarshallingTests and g-i Regress tests. (Martin Pitt)
  • pygi-convert: remove deprecated GLib ? GObject conversions (Jose Rostagno)
  • Add support for overriding GObject.Object (Simon Feltman) (#672727)
  • Add –with-python configure option (Martin Pitt)
  • Do not prefer unversioned “python” when configuring, as some distros have “python” as Python 3. Use Python 3 by default if available. Add –with-python configure option as an alternative to setting $PYTHON, whic is more discoverable. (Martin Pitt)
  • Fix property lookup in class hierarchy (Daniel Drake) (#686942)
  • Move property and signal creation into _class_init() (Martin Pitt) (#686149)
  • Fix duplicate symbols error on OSX (John Ralls)
  • [API add] Add get_introspection_module for getting un-overridden modules (Simon Feltman) (#686828)
  • Work around wrong 64 bit constants in GLib Gir (Martin Pitt) (#685022)
  • Mark GLib.Source.get_current_time() as deprecated (Martin Pitt)
  • Fix OverflowError in source_remove() (Martin Pitt) (#684526)

Read more

With python-dbusmock you can provide mocks for arbitrary D-BUS services for your test suites or if you want to reproduce a bug.

However, when writing actual tests for gnome-settings-daemon etc. I noticed that it is rather cumbersome to always have to set up the “skeleton” of common services such as UPower. python-dbusmock 0.2 now introduces the concept of “templates” which provide those skeletons for common standard services so that your code only needs to set up the particular properties and specific D-BUS objects that you need. These templates can be parameterized for common customizations, and they can provide additional convenience methods on the org.freedesktop.DBus.Mock interface to provide more abstract functionality like “add a battery”.

So if you want to pretend you have one AC and a half-charged battery, you can now simply do

  def setUp(self):
     (self.p_mock, self.obj_upower) = self.spawn_server_template('upower', {})

  def test_ac_bat(self):
     self.obj_upower.AddAC('mock_AC', 'Mock AC')
     self.obj_upower.AddChargingBattery('mock_BAT', 'Mock Battery', 50.0, 1200)

Or, if your code is not in Python, use the CLI/D-BUS interface, like in shell:

  # start a fake system bus
  eval `dbus-launch`

  # start mock upower on the fake bus
  python3 -m dbusmock --template upower &

  # add devices
  gdbus call --system -d org.freedesktop.UPower -o /org/freedesktop/UPower \
      -m org.freedesktop.DBus.Mock.AddAC mock_ac 'Mock AC'
  gdbus call --system -d org.freedesktop.UPower -o /org/freedesktop/UPower \
      -m org.freedesktop.DBus.Mock.AddChargingBattery mock_bat 'Mock Bat' 50.0 1200

In both cases upower --dump or gnome-power-statistics will show you the expected devices (of course you need to run that within the environment of the fake $DBUS_SYSTEM_BUS_ADDRESS, or run the mock on the real system bus as root).

Iftikhar Ahmad contributed a template for NetworkManager, which allows you to easily set up ethernet and wifi devices and wifi access points. See pydoc3 dbusmock.templates.networkmanager for details and the test cases for how this looks like in practice.

I just released python-dbusmock 0.2.1 and uploaded the new version to Debian experimental. I will sync it into Ubuntu Raring in a few hours.

Read more

I just released PyGObject 3.4.2, a bug fix release for GNOME 3.6.2.

Thanks to all contributors!

  • Fix marshalling of GByteArrays (Martin Pitt)
  • Fix marshalling of ssize_t to smaller ints (Martin Pitt)
  • Fix crash with GLib.child_watch_add (Daniel Narvaez) (#688067)
  • Fix various bugs in GLib.IOChannel (Martin Pitt)
  • Work around wrong 64 bit constants in GLib Gir (Martin Pitt) (#685022)
  • Fix OverflowError in source_remove() (Martin Pitt) (#684526)
  • Fix Signal decorator to not use base class gsignals dict (Simon Feltman) (#686496)

Read more
Daniel Holbach

It’s time for some Ubuntu Development Events for those of you who are raring to go get started for 13.04 development.

We will be starting the fun today at 13:00 UTC with Ubuntu Open Week. Luckily I still managed to book a double session, so we’ll have plenty of time to get you started and introduced to Development team and what we do.

The Ubuntu Developer Summit (UDS) will be happening form 29th October to 1st November in Copenhagen and we will have some workshops there as well. If you’re in town, make sure you drop by. Watch the Packaging Guide User Testing and the Get Started with Ubuntu Development workshops. For us it will be great to see how people use the Packaging Guide and what we need to fix. For you it will be great to have people around who are going to help you if you should get stuck. Also it will be a great time to catch up and get to know each other. Thanks a lot to Benjamin Drung (and others) who are going to help with these events.

There will be plenty more activity at UDS which I’ll blog about soon too. :-)

Read more

For writing tests for GVFS (current tests, proposed improvements) I want to run Samba as normal user, so that we can test gvfs’ smb backend without root privileges and thus can run them safely and conveniently in a “make check” environment for developers and in JHBuild for continuous integration testing. Before these tests could only run under gvfs-testbed, which needs root.

Unlike other servers such as ssh or ftp, this turned out surprisingly non-obvious and hard, so I want to document it in this blog post for posterity’s benefit.

Running the server

Running smbd itself is mainly an exercise of figuring out all the options that you need to set; Alex Larsson and I had some fun figuring out all the quirks and hiccups that happen between Ubuntu’s and Fedora’s packaging and 3.6 vs. 4.0, but finally arrived at something working.

First, you need to create an empty directory where smbd can put all its databases and state files in. For tests you would use mkdtemp(), but for easier reading I just assume mkdir /tmp/samba here.

The main knowledge is in the Samba configuration file, let’s call it /tmp/smb.conf:

workgroup = TESTGROUP
interfaces = lo
smb ports = 1445
log level = 2
map to guest = Bad User
passdb backend = smbpasswd
smb passwd file = /tmp/smbpasswd
lock directory = /tmp/samba
state directory = /tmp/samba
cache directory = /tmp/samba
pid directory = /tmp/samba
private dir = /tmp/samba
ncalrpc dir = /tmp/samba

path = /tmp/public
guest ok = yes

path = /tmp/private
read only = no

For running this as a normal user you need to set a port > 1024, so this uses 1445 to resemble the original (privileged) port 445. The map to guest line makes anonymous logins work on Fedora/Samba 4.0 (I’m not sure whether it’s a distribution or a version issue). Don’t ask about “dir” vs. “directory”, that’s an inconsistency in Samba; with above names it works on both 3.6 and 4.0.

We use the old “smbpasswd” backend as shipping large tdb files is usually too inconvenient and brittle for test suites. I created an smbpasswd file by running smbpasswd on a “real” Samba installation, and then using pdbedit to convert it to a smbpasswd file:

sudo smbpasswd -a martin
sudo pdbedit -i tdbsam:/var/lib/samba/passdb.tdb -e smbpasswd:/tmp/smbpasswd

The result for password “foo” is


which you are welcome to copy&paste (you can replace “myuser” with any valid user name, of course).

This also defines two shares, one public, one authenticated. You need to create the directories and populate them a bit:

mkdir /tmp/public /tmp/private
echo hello > /tmp/public/hello.txt
echo secret > /tmp/private/myfile.txt

Now you can run the server with

smbd -iFS -s /tmp/smb.conf

The main problem with this approach is that smbd exits (“Server exit (failed to receive smb request)”) after a client terminates, so you need to write your tests in a way to only run one connection/request per test, or to start smbd in a loop.

Running the client

If you merely use the smbclient command line tool, this is rather simple: It has a -p option for specifying the port:

$ smbclient -p 1445 //localhost/private
Enter martin's password: [enter "foo" here]
Domain=[TESTGROUP] OS=[Unix] Server=[Samba 3.6.6]
smb: \> dir
  .                                   D        0  Wed Oct 17 08:28:23 2012
  ..                                  D        0  Wed Oct 17 08:31:24 2012
  myfile.txt                                   7  Wed Oct 17 08:28:23 2012

In the case of gvfs it wasn’t so simple, however. Surprisingly, libsmbclient does not have an API to set the port, it always assumes 445. smbclient itself uses some internal “libcli” API which does have a way to change the port, but it’s not exposed through libsmbclient. However, Alex and I found some mailing list posts ([1], [2]) that mention $LIBSMB_PROG, and it’s also mentioned in smbclient’s manpage. It doesn’t quite work as advertised in the second ML post (you can’t set it to smbd, smbd apparently doesn’t speak the socket protocol over stdin/stdout), and it’s not being used anywhere in the current Samba sources, but what does work is to use good old netcat:

export LIBSMB_PROG="nc localhost 1445"

with that, you can use smbclient or any program using libsmbclient to talk to our test smb server running as user.

Read more

I just released PyGObject 3.4.1, in time for the GNOME 3.6.1 release on Wednesday.

This version provides a nice set of bug fixes. no API changes.

Thanks to all contributors!

Complete list of changes:

  • Skip Regress tests with –disable-cairo (Martin Pitt) (#685094)
  • _pygi_marshal_from_py_uint64: Re-fix check of negative values (Martin Pitt) (#685000)
  • Fix leak with python callables as closure argument. (Simon Feltman) (#685598)
  • Gio overrides: Handle setting GSettings enum keys (Martin Pitt) (#685947)
  • tests: Check reading GSettings enums in Gio overrides (Martin Pitt)
  • Fix unsigned values in GArray/GList/GSList/GHash (Martin Pitt) (#685860)
  • build: Fix srcdir != builddir (Colin Walters)
  • _pygi_marshal_from_py_uint64(): Use correct data type in py2.7 check (Alban Browaeys) (#685000)
  • Install an .egg-info file (Johan Dahlin) (#680138)
  • PyGProps_getattro(): Fix GObjectClass leak (Johan Dahlin) (#685218)
  • pygobject.c: Don’t leak GObjectClass reference (Olivier Crête) (#684062)
  • Fix memory leak in _pygi_argument_to_array() (Alban Browaeys) (#685082)
  • Fix error messages for out of range numbers (Martin Pitt) (#684314)
  • Kill dbus-daemon after running tests (Martin Pitt) (#685009)
  • GVariant overrides: Support empty tuple arrays (Martin Pitt) (#684928)
  • TestGVariant: Split creation test case into several smaller ones (Martin Pitt)
  • Fix unused variables and results (Martin Pitt)
  • tests: Fix wrong return type in test_int64_callback() (Martin Pitt) (#684700)
  • Fix GValue marshalling of long and unsigned long (Giovanni Campagna) (#684331)
  • Clean up deprecation message for assigning gpointers to objects. (Simon Feltman) (#683599)
  • pygi-property: Lookup property in base classes of non-introspected types (Olivier Crête) (#684058)

Read more
Jussi Pakkanen

There have been several posts in this blog about compile speed. However most have been about theory. This time it’s all about measurements.

I took the source code of Scribus, which is a largeish C++ application and looked at how much faster I could make it compile. There are three different configurations to test. The first one is building with default settings out of the box. The second one is about changes that can be done without changing any source code, meaning building with the Ninja backend instead of Make and using Gold instead of ld. The third configuration adds precompiled headers to the second configuration.

The measurements turned out to have lots of variance, which I could not really nail down. However it seemed to affect all configurations in the same way at the same time so the results should be comparable. All tests were run on a 4 core laptop with 4 GB of ram. Make was run with ‘-j 6′ as that is the default value of Ninja.

Default:    11-12 minutes
Ninja+Gold: ~9 minutes
PCH:        7 minutes

We can see that a bit of work the compile time can be cut almost in half. Enabling PCH does not require changing any existing source files (though you’ll get slightly better performance if you do). All in all it takes less than 100 lines of CMake code to enable precompiled headers, and half of that is duplicating some functionality that CMake should be exposing already. For further info, see this bug.

Is it upstream? Can I try it? Will it work on my project?

The patch is not upstreamed, because it is not yet clean enough. However you can check out most of it in this merge request to Unity. In Unity’s case the speedup was roughly 40%, though only one library build time was measured. The total build time impact is probably less.

Note that if you can’t just grab the code and expect magic speedups. You have to select which headers to precompile and so on.

Finally, for a well tuned code base, precompiled headers should only give around 10-20% speed boost. If you get more, it probably means that you have an #include maze in your header files. You should probably get that fixed sooner rather than later.

Read more

I found it surprisingly hard to determine in tearDown() whether or not the test that currently ran succeeded or not. I am writing some tests for gnome-settings-daemon and want to show the log output of the daemon if a test failed.

I now cobbled together the following hack, but I wonder if there’s a more elegant way? The interwebs don’t seem to have a good solution for this either.

    def tearDown(self):
        # collect log, run() shows it on failures
        with open( as f:
            self.log_output =

    def run(self, result=None):
        '''Show log output on failed tests'''

        if result:
            orig_err_fail = result.errors + result.failures
        if result and result.errors + result.failures > orig_err_fail:
            print('\n----- daemon log -----\n%s\n------\n' % self.log_output)

Read more