philipcristiano's posterous

 
Filed under

Python

 

5 tips for packaging your Python projects « Fetchez le Python

Next week I am keynoting at Pycon Japan, and one thing I will talk about is packaging of course. And in particular: what advice can I give my audience on how to package Python projects today ?

This is a hard task, because we are in some kind of transitional state.

Anyways, I wrote down a list of advices and removed everything that was dependent on the tools we did not release yet — that’s another part in my keynote.

Here’s a list. Most of them are not controversial. If you see something missing or want to rant about one, please comment.

Tip # 1 — Use a PEP 386 compatible scheme for your versions

Having several version scheme in our eco-system is pure madness. It breaks interoperability, and makes it impossible to write tools that handle versions properly. By using a PEP 386-friendly scheme now, you are making your project future-proof !

PyPI already rejects any Metadata 1.2 project that does not comply to this policy. You probably don’t know this because no tools produces Metadata 1.2 packages yet. But that’s going to be the default in Python 3.3 and distutils2.

So long “devdevdev123″ and “3765-2011-test” versions !

Tip #2 — try to make setup.py as dumb and simple as possible

setup.py is not your personal build system. I have seen crazy things in some projects. Remember that setup.py is used by installers for a lot of different tasks. Like getting the metadata fields of the project.

Here’s a simple test: make sure “python setup.py –name” returns the name field without any external dependency, and without calling any function or method.

Remember that setup.py is going away in Python 3.3 and distutils2, replaced by simple options in setup.cfg. Don’t be scared, you will still able to do complex tasks.

My advice: don’t do anything else that feeding setup() with options in there. Put all your build things in another place, and if they need to be called by setup.py, make sure they are called only when needed.

Tip #3 — Do not make any assumption about which installer will be used

Make sure your setup.py can be run by a vanilla Python (==distutils). Even if you use setuptools or distribute, in most case you can manage to have it working in both tools. You can always tell the user to do extra steps manually if he needs to.

Forcing the installation of an installer, by using the ez_setup script for instance, without asking, is a bit rude to the end-user. It’s basically forcing the end user to use a new installer. If you do this in your setup.py, ask first !

Or simply tell the user “This project only works with the XXX installer — install it if you want. Aborting.”

Tip #4 — Do not release unstable releases at pypi

Our installers are not –yet– smart enough to prefer stable releases when they are asked to get a project at PyPI. That’s how PyPI is built: every project has a directory with all releases and it’s up to the installer to decide which one is the “latest”. The only tool out there that’s smart about it is zc.buildout.

So when you push an alpha release or a rc release at PyPI, it’s going to land in people environments unless they have mature processes to update their stuff — or simply because they make the assumption that PyPI is where stable release go. So do not make assumptions about how your users are updating your project.

Prefer another explicit channel for your beta testers. All installers know how to install from any url or directory.

Tip #5 — Be cautious about your data files

Distutils or Distribute or Python itself have no way to explicitly make a difference between a doc file or a media file or a configuration file. They are all data files. Worse, since they are no universal place for data files on the various OSes, people tend to treat their data files like Python modules so they are able to find them back on the target system without trouble.

Yeah that’s broken, and we’ve fixed it in 3.3. But until then, that’s unfortunately the most protable way to do this. So what you can do is document clearly how you handle your data files and create a single function or module that reads them. That’ll help the downstream maintainers to handle your project.

Like this:

Be the first to like this post.

Filed under: mozilla, python

Filed under  //   Packaging   Python  

Comments [0]

Plug v0.1.3 Released

Plug is a tool to automate packaging and installation of Python daemons including Python dependencies in the package. It grew out of my use of Supervisor and the problems of managing large numbers of processes.

Version 0.1.3

I've removed all the extra --command options, you can now just `plug install package.plug`. There is still the --number option for setup though.

There was a bug where runit wasn't properly shutting down the process when it thought it was. The issue occured because I didn't exec properly when calling the plug's command so runit was sending a SIGTERM to the script, not the process. Once the process was zombified runit had no hope of getting it.

Installs will also remove an existing plug of the same name should one exist. This is to force a reinstall in case you have two packages with the same plug name. 

You can get Plug on PyPi.

Filed under  //   Plug   Project   Python   Release  

Comments [0]

PMS v0.1.1

I've uploaded v0.1.1 of PMS to PyPi. This adds an endpoint that returns the next event from Mongo. This endpoint can be used with the pms_watch command in your shell to get events from PMS easily.

I still have no docs or tests so we'll see this week when I try using it with another project if it winds up being useful.

The pms_watch command should probably be moved to a pms_utils package.

Filed under  //   Project   Python   pms  

Comments [0]

Python Monitoring Service

I've started a new project called the Python Monitoring Service with a goal to provide a service for application monitoring.

The intended use case will eventually be for internal applications to push events to the service to be easily aggregated for DevOps. It currently uses JSON over HTTP for messaging and stores events in MongoDB.

This week I hope to integrate it with a project at work and get some idea of how I want to use it. It's on PyPi as well although there is not documentation, tests, or reason to use it yet.

 

Filed under  //   Project   Python   monitoring  

Comments [0]

Screencast: Custom Vim Refactorings — Extra Cheese

Filed under  //   Gary Bernhardt   Python   Refactoring   Screencast   VIM  

Comments [0]