Clone this repo:
  1. 27d837f Put cros_venv inside the venv by Allen Li · 3 days ago master
  2. 7d502d6 Clean up and update README by Allen Li · 3 days ago
  3. be79936 Add backports.tempfile and dependency wheels by Prathmesh Prabhu · 3 days ago
  4. 267d89d Add simple/canonical template virtualenv script by Allen Li · 4 days ago
  5. eb04d3c Clear out existing virtualenv when creating by Allen Li · 12 days ago release-R59-9460.B stabilize-9460.4.B

infra_virtualenv README

This repository provides a common Python virtualenv interface that infra code (such as chromite) can depend on.

Usage

Virtualenv users should mimic this repository, which itself uses virtualenv for running unit tests.

  1. Create a venv directory. All packages and modules in this directory will be importable inside the virtualenv.
  2. Create a requirements.txt file inside venv to list external packages to install.
  3. Copy bin/find_virtualenv.sh and bin/turtle which serve as templates.

Adding pre-built packages

To add packages to this repository, run:

$ pip wheel -w path/to/pip_packages -r path/to/requirements.txt

Commit the changes and make a CL.

Low level API

The create_venv script prepares a virtualenv using a requirements.txt file.

$ create_venv requirements.txt

The script will print the path to the virtualenv to stdout. Note that the output ends with a newline; Bash handles this, but Python does not.

To run the virtualenv Python, call bin/python under the virtualenv directory.

Together, this might look up:

$ venv=$(create_venv requirements.txt)
$ ${venv}/bin/python

NOTE: it is not generally safe to run the other scripts in the virtualenv's bin directory due to hard-coded paths. Instead of running bin/pip for example, use bin/python -m pip.

Adding arbitrary directories to import path

NOTE: Do not use this for third party dependencies (stuff not owned by ChromiumOS)! This should only be used to set up imports for stuff we own. For example, importing python-MySQL SHOULD NOT use this, but importing chromite from Autotest MAY use this.

This should be handled by the minimum amount of code in the package's __init__.py file.

Example:

"""Autotest package."""

import sys

# Use the minimum amount of logic to find the path to add
_chromite_parent = 'site-packages'
sys.path.append(_chromite_parent)

A solid understanding of the Python import system is recommended (the link is for Python 3, but it is informative).

In brief, __init__.py is executed whenever a package is imported. A package is imported before any submodule or subpackage is imported. A package is only imported once per Python process; future imports are looked up in sys.modules. Thus, __init__.py will modify sys.path exactly once and is guaranteed to be run before anything in that package is imported.