uvent: a gevent core implemented using libuv

After working on it on-and-off for a few weeks today I’m open sourcing uvent. uvent is a gevent core implementation using libuv.

I’ve written about libuv earlier in this blog, but to put it shortly: libuv is the new black. Specially when we are talking about asynchronous IO.

uvent is still experimental, but results are encouraging, not all tests are failing! :–) I think libuv is the perfect match for a library such as gevent, we’ll see where this goes.

The code can be checked out here and for those who want to know the scary details I wrote a short document with some notes here

Hope you like it!

:wq

Interactive Python interpreter over TCP for Tornado applications

The Python standard library never ceases to surprise me. I knew about Twisted’s manhole but yesterday I ran across the code module, which is in the Python standard library.

The code module allows you to create a fully fledged Python REPL. So, in order to try it out I decided to implement a “backdoor” server for Tornado applications.

The idea is pretty simple, use Tornado’s TCPServer to serve a Python interpreter. Of course you should only do this in localhost! The can come really useful for debugging, as it doesn’t take any resources from the application, and allows for live inspection.

The result is here on GitHub.

Here is an example, hope you like it!

[gist]https://gist.github.com/3739834[/gist]

:wq

Trying out concurrent.futures

A while back I learned about concurrent.futures, a new module included in Python 3.2. It allows you to create a pool of processes or threads to which you can distribute work and then wait for it to finish. The API is dead simple and there is a backport of the module for Python 2 here.

Today I was working with a small tool we have at work to help us build Debian packages for a number of distributions, which basically calls debuild a number of times and I’m very happy with the result after using this module. Since the tool is just a helper it used to just build all packages one after another, but as the number of packages grows, doing the operations in a serialized way just takes too long. Since the tasks are CPU bound, threads are of no use here, because of the GIL, so going multi-process can help here.

The idea is simple: create a process pool as big as the number of cores we have available, send the hard work to them and wait until they are all done. Here is an example of such use case:

[gist]https://gist.github.com/3660656[/gist]

As it can be seen, the API is really a pleasure to use and it did solve the problem effectively. :–)

:wq

pycares: Python bindings for c-ares, released!

Hi! As you all probably know DNS lookups can get tricky at times, since they block. c-ares is a completely asynchronous DNS resolver written in C, and pycares exports its functionality to Python.

After giving the idea some thought I decided to remove the c-ares based resolver which I had implemented in pyuv and created a standalone package instead.

This way, the implementation is completely independent and it can be used with any asynchronous library like Eventlet, Gevent, pyev, …

Since the c-ares build process can be a bit tricy and uses autotools I decided to use a modified version of the build system used in libuv which is based in plain Makefiles.

You can get the source code on the GitHub repository and checkout the documentation here.

Hope you like it!

:wq

pyuv 0.8.0 released!

Yesterday NodeJS 0.8.0 was released, and libuv got its dedicated branch for maintenance of the 0.8.X version cycle. Since pyuv now implements all the features offered by libuv I chose to follow the same path and branch out pyuv 0.8.0.

From now on pyuv’s v0.8 branch will only get bugfixes from the corresponding libuv branch. pyuv’s master branch will use libuv master and have version number 0.9.0-dev, there will not be a release of that branch soon, I guess.

So, what’s new on pyuv 0.8.0 then?

  • FSPoll handle, for polling for file changes using the stat syscall
  • Several fixes in the fs module for Windows
  • Bugfixes that came with libuv

For version 0.9, apart from following libuv’s development I have plans to make the following changes:

  • Move the getaddrinfo function to the util module
  • Overhaul the dns module, provide a raw wrapper on top of c-ares
    instead of exposing a complete DNS resolver (I’ll cover this in a
    future blog post, when I approach the implementation)

Last but not least, I’d like to thank again the NodeJS and libuv developers, they are really doing a great job!

:wq

Integrating Twisted and Tornado with pyuv

With yesterday’s pyuv release the door was open for integrating pyuv with other event loops or applications. Thanks to the Poll handle we can now create a regular socket in Python and put it in pyuv’s event loop, so we can also use pyuv to replace other event loops ;–)

I created a couple of projects for toying around with this feature. The first project implements a Tornado IOLoop which runs on top of pyuv, and the second one implements a Twisted reactor on top of pyuv.

They are not feature complete yet, but basics are working and I’ll be adding more features as time allows.

Go check them out on GitHub!

:wq

pyuv 0.7.0 released!

It’s been a while since I haven’t mentioned pyuv, let me show you what the new version has to offer.

But first, I’d like to thank Ben Noordhuis, Bert Belder and all contributors to the libuv project for such a great job, the library is pleasure to work with and it gets better every week!

Having that said, pyuv 0.7.0 is out and full of nice features, check them out here. To highlight some:

  • Ability to poll arbitrary file descriptors
  • Overhauled reference counting scheme
  • Python 3 support (was added in a previous release)
  • Windows support (was added in a previous release)
  • And more!

You can download pyuv from the GitHub repository or just install it with pip:

pip install pyuv

Documentation is available here as always.

As of right now pyuv implements all features available on libuv, which took a while to accomplish, but we are finally there :–)

I’ll be publishing a couple of projects built with pyuv shortly, so stay tuned!

:wq

PyStructSequence: creating named tuples in C

I’m not a big fan of namedtuples in Python, but sometimes they are useful.

For example, sys.version_info returns a named tuple (starting with Python 2.7):

sys.version_info(major=2, minor=7, micro=2, releaselevel='final', serial=0)

This means that in order to check the major number you may do sys.version_info[0] or sys.version_info.major. Of course, the latter is more readable.

You can use collections.namedtuple in order to create a named tuple in Python, but what if you want to create such an object in a C extension module?

I found myself diving the CPython source looking for this, and I found it: PyStructSequence. There is not documentation for it at the moment, but there is an issue open for it here. It’s not very complex to use, but I created a very simple example:

[gist]https://gist.github.com/2473614[/gist]

The example shows how a PyStructSequence is created and exposed in a module. Operations with this types of objects are very similar to those with regular tuples (in C), so in order to set an item you’d do the following:

PyStructSequence_SET_ITEM(my_named_tuple, 0, PyString_FromString("content for field 0"));
PyStructSequence_SET_ITEM(my_named_tuple, 1, PyString_FromString("content for field 1"));
...

That’s about it, in case you want to dive deeper I recommend having a look at Modules/posixmodule.c in the CPython source code and checking how stat_result is defined.

:wq

Python data structures

Last night I was browsing pyvideo and found some really interesting videos on Python built-in data structures and their advanced usage.

Here are the three particular videos I liked:

  • “The Mighty Dictionary” by Brandon Rhodes: link
  • “Mastering Team Play: Four powerful examples of composing Python tools” by Raymond Hettinger: link
  • “The Data Structures of Python” by Alex Gaynor: link

If you haven’t watched them yet, do it.

 

pythonz: a Python installation manager

It’s been a while since I haven’t posted anything around here, so it’s about time :–)

Today I’m releaseing pythonz a Python installation manager, which works for CPython, Stackless and PyPy.

It’s a fork of pythonbrew, with some features removed, some bugfixes and also some new features. The main goal of this project is to provide the a way for installing different Python interpreters. Just that. How to pick one and use it afterwards is out of the scope of the project, for that I recommend virtualenvvirtualenvwrapper.

Lets see it in action!

First lets install pythonz:

curl -kL https://raw.github.com/saghul/pythonz/master/pythonz-install | bash

Once pythonz is installed add the following line to your .bashrc:

[[ -s $HOME/.pythonz/etc/bashrc ]] && source $HOME/.pythonz/etc/bashrc

Also lets source it now in order to start using it:

source ~/.pythonz/etc/bashrc

Lets install some pythons!

pythonz install --type cpython --no-test 2.7.2
pythonz install --type stackless --no-test  2.7.2
pythonz install --type pypy --url https://bitbucket.org/pypy/pypy/downloads/pypy-1.8-osx64.tar.bz2 1.8

With the above commands you’ll get CPython 2.7.2, Stackless 2.7.2 and PyPy 1.8 installed on your system.

Note that PyPy is installed in binary form, so you’ll need to indicate the correct URL, matching the appropriate version for your architecture.

Now lets create some virtualenvs with these Python versions we just installed:

mkvirtualenv -p ~/.pythonz/pythons/CPython-2.7.2/bin/python cpython272
deactivate
mkvirtualenv -p ~/.pythonz/pythons/Stackless-2.7.2/bin/python stackless272
deactivate
mkvirtualenv -p ~/.pythonz/pythons/PyPy-1.8/bin/python pypy18
deactivate

In order to use one of our newly created virtualenvs we can now use workon and deactivate as usual:

saghul@hal:~$ workon pypy18
(pypy18)saghul@hal:~$ python
Python 2.7.2 (0e28b379d8b3, Feb 09 2012, 18:31:14)
[PyPy 1.8.0 with GCC 4.2.1] on darwin
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``Therefore, specific information,
I was in an ideal context, I had to realize the faith''
>>>>
(pypy18)saghul@hal:~$ deactivate
saghul@hal:~$

Hope you enjoy using it as much as I do :–)

Get the source on GitHUb!

:wq