Pip requirements

You should be used to installing new modules using pip. You have probably used a requirements.txt file to install multiple modules together with the command.

pip install -r requirements.txt

But what about if you need more flexibility. Why would you ever need more flexibility? If you look at my introduction to YAML post, the code supports either the yaml or ruamel.yaml module. There is no way to add conditional logic to a requirements.txt file so a different strategy is needed.

pip is just a module so it can be imported like any other module. This not only gives you access to the main method, which takes an argument list just as if you were calling pip from the command line, but also to its various methods and classes. One of these is the WorkingSet class which creates a collection of the installed modules (or active distributions as the documentation calls them). Using this we can create the conditional logic needed to ensure one of the yaml modules is installed as below.

import pip
package_names = [ ws.project_name for ws in pip._vendor.pkg_resources.WorkingSet() ]
if ('yaml' not in package_names) and ('ruamel.yaml' not in package_names):

WorkingSet returns a few other useful properties and methods apart from the package_name. The location property returns the path to where the module is installed and the version property naturally returns the version installed. The requires method returns a list of dependencies.

As with most modules, if you’re interested in finding out more dig around in the source code.


I have been looking into Ansible for automation which has meant looking at YAML files again. I’ve looked at YAML before which in theory offers benefits over ini, JSON and XML based files but the lack of built in module has resulted in me using choosing ini or JSON formats. I have recently been favouring JSON in projects and as this is a subset of YAML it is time to take another look at format.

For a long time the defacto standard library has been PyYAML. There are a bunch of Windows installers on the page which can be used to get up and running. However this module has received few updates in recent years and doesn’t appear to support the later YAML 1.2 standard. Up has stepped Anthon van der Neut who has used this as the basis for his own ruamel.yaml module. This can be installed using pip in the usual way.

Whichever one you choose, you can use safe_load to load a YAML file (or convert a string) and dump to create a YAML string

    import ruamel.yaml as yaml
except ImportError:
    import yaml

pydic = yaml.safe_load("""
# example yaml (this is a comment)
name: test
version: 1.0
inlinelist: [ "tinker", "tailor", "soldier", "spy" ]
- first item
- second item
    name: subdictionary
    usage: anything
with open('test.yml','w') as ymlfile:

There is a limit on what how readable the output from the dump method is as you will see from the above example. If you are using YAML files for configuration you can be much more verbose and use whitespace. There is a full reference card of the YAML 1.1 spec in a single page on the yaml.org website.

Finally, if you need to pass information to a JavaScript program (either in a browser or to node – which would usually force going with JSON) there is even a port of PyYAML to JavaScript.