Fix docstrings for core Spack libraries, fixes #1612

This commit is contained in:
Adam J. Stewart 2016-08-24 13:46:29 -05:00
parent 02239c094e
commit 69e50595bf
20 changed files with 199 additions and 195 deletions

View File

@ -476,14 +476,12 @@ def setup_package(pkg, dirty=False):
def fork(pkg, function, dirty=False): def fork(pkg, function, dirty=False):
"""Fork a child process to do part of a spack build. """Fork a child process to do part of a spack build.
Arguments: :param pkg: pkg whose environemnt we should set up the forked process for.
:param function: arg-less function to run in the child process.
:param dirty: If True, do NOT clean the environment before building.
pkg -- pkg whose environemnt we should set up the Usage::
forked process for.
function -- arg-less function to run in the child process.
dirty -- If True, do NOT clean the environment before building.
Usage:
def child_fun(): def child_fun():
# do stuff # do stuff
build_env.fork(pkg, child_fun) build_env.fork(pkg, child_fun)
@ -496,8 +494,8 @@ def child_fun():
If something goes wrong, the child process is expected to print If something goes wrong, the child process is expected to print
the error and the parent process will exit with error as the error and the parent process will exit with error as
well. If things go well, the child exits and the parent well. If things go well, the child exits and the parent
carries on. carries on."""
"""
try: try:
pid = os.fork() pid = os.fork()
except OSError as e: except OSError as e:

View File

@ -83,12 +83,11 @@ def default_version(cls, comp):
Target: x86_64-unknown-linux-gnu Target: x86_64-unknown-linux-gnu
Thread model: posix Thread model: posix
On Mac OS X, it looks like this: On Mac OS X, it looks like this::
Apple LLVM version 7.0.2 (clang-700.1.81) Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.2.0 Target: x86_64-apple-darwin15.2.0
Thread model: posix Thread model: posix
""" """
if comp not in cpr._version_cache: if comp not in cpr._version_cache:
compiler = Executable(comp) compiler = Executable(comp)

View File

@ -24,8 +24,9 @@
############################################################################## ##############################################################################
"""This module implements Spack's configuration file handling. """This module implements Spack's configuration file handling.
=========================
Configuration file scopes Configuration file scopes
=============================== =========================
When Spack runs, it pulls configuration data from several config When Spack runs, it pulls configuration data from several config
directories, each of which contains configuration files. In Spack, directories, each of which contains configuration files. In Spack,
@ -35,15 +36,16 @@
``$(prefix)/etc/spack/``. ``$(prefix)/etc/spack/``.
2. ``user``: Spack next loads per-user configuration options from 2. ``user``: Spack next loads per-user configuration options from
~/.spack/. ``~/.spack/``.
Spack may read configuration files from both of these locations. When Spack may read configuration files from both of these locations. When
configurations conflict, the user config options take precedence over configurations conflict, the user config options take precedence over
the site configurations. Each configuration directory may contain the site configurations. Each configuration directory may contain
several configuration files, such as compilers.yaml or mirrors.yaml. several configuration files, such as compilers.yaml or mirrors.yaml.
=========================
Configuration file format Configuration file format
=============================== =========================
Configuration files are formatted using YAML syntax. This format is Configuration files are formatted using YAML syntax. This format is
implemented by libyaml (included with Spack as an external module), implemented by libyaml (included with Spack as an external module),
@ -63,13 +65,13 @@
cc: /usr/local/bin/mpixlc cc: /usr/local/bin/mpixlc
... ...
In this example, entries like ''compilers'' and ''xlc@12.1'' are used to In this example, entries like "compilers" and "xlc@12.1" are used to
categorize entries beneath them in the tree. At the root of the tree, categorize entries beneath them in the tree. At the root of the tree,
entries like ''cc'' and ''cxx'' are specified as name/value pairs. entries like "cc" and "cxx" are specified as name/value pairs.
``config.get_config()`` returns these trees as nested dicts, but it ``config.get_config()`` returns these trees as nested dicts, but it
strips the first level off. So, ``config.get_config('compilers')`` strips the first level off. So, ``config.get_config('compilers')``
would return something like this for the above example: would return something like this for the above example::
{ 'chaos_5_x86_64_ib' : { 'chaos_5_x86_64_ib' :
{ 'gcc@4.4.7' : { 'gcc@4.4.7' :
@ -84,8 +86,9 @@
Likewise, the ``mirrors.yaml`` file's first line must be ``mirrors:``, Likewise, the ``mirrors.yaml`` file's first line must be ``mirrors:``,
but ``get_config()`` strips that off too. but ``get_config()`` strips that off too.
==========
Precedence Precedence
=============================== ==========
``config.py`` routines attempt to recursively merge configuration ``config.py`` routines attempt to recursively merge configuration
across scopes. So if there are ``compilers.py`` files in both the across scopes. So if there are ``compilers.py`` files in both the
@ -99,7 +102,7 @@
Sometimes, it is useful to *completely* override a site setting with a Sometimes, it is useful to *completely* override a site setting with a
user one. To accomplish this, you can use *two* colons at the end of user one. To accomplish this, you can use *two* colons at the end of
a key in a configuration file. For example, this: a key in a configuration file. For example, this::
compilers:: compilers::
chaos_5_x86_64_ib: chaos_5_x86_64_ib:
@ -114,9 +117,8 @@
... ...
Will make Spack take compilers *only* from the user configuration, and Will make Spack take compilers *only* from the user configuration, and
the site configuration will be ignored. the site configuration will be ignored."""
"""
import copy import copy
import os import os
import re import re

View File

@ -288,8 +288,7 @@ def variant(pkg, name, default=False, description=""):
@directive('resources') @directive('resources')
def resource(pkg, **kwargs): def resource(pkg, **kwargs):
""" """Define an external resource to be fetched and staged when building the
Define an external resource to be fetched and staged when building the
package. Based on the keywords present in the dictionary the appropriate package. Based on the keywords present in the dictionary the appropriate
FetchStrategy will be used for the resource. Resources are fetched and FetchStrategy will be used for the resource. Resources are fetched and
staged in their own folder inside spack stage area, and then moved into staged in their own folder inside spack stage area, and then moved into

View File

@ -261,17 +261,13 @@ def apply_modifications(self):
@staticmethod @staticmethod
def from_sourcing_files(*args, **kwargs): def from_sourcing_files(*args, **kwargs):
""" """Creates an instance of EnvironmentModifications that, if executed,
Creates an instance of EnvironmentModifications that, if executed,
has the same effect on the environment as sourcing the files passed as has the same effect on the environment as sourcing the files passed as
parameters parameters
Args: :param \*args: list of files to be sourced
*args: list of files to be sourced :rtype: instance of EnvironmentModifications"""
Returns:
instance of EnvironmentModifications
"""
env = EnvironmentModifications() env = EnvironmentModifications()
# Check if the files are actually there # Check if the files are actually there
if not all(os.path.isfile(file) for file in args): if not all(os.path.isfile(file) for file in args):

View File

@ -123,25 +123,26 @@ def create(path, specs, **kwargs):
package archives. package archives.
Arguments: Arguments:
path Path to create a mirror directory hierarchy in. path: Path to create a mirror directory hierarchy in.
specs Any package versions matching these specs will be added specs: Any package versions matching these specs will be added \
to the mirror. to the mirror.
Keyword args: Keyword args:
no_checksum: If True, do not checkpoint when fetching (default False) no_checksum: If True, do not checkpoint when fetching (default False)
num_versions: Max number of versions to fetch per spec, num_versions: Max number of versions to fetch per spec, \
if spec is ambiguous (default is 0 for all of them) if spec is ambiguous (default is 0 for all of them)
Return Value: Return Value:
Returns a tuple of lists: (present, mirrored, error) Returns a tuple of lists: (present, mirrored, error)
* present: Package specs that were already present. * present: Package specs that were already present.
* mirrored: Package specs that were successfully mirrored. * mirrored: Package specs that were successfully mirrored.
* error: Package specs that failed to mirror due to some error. * error: Package specs that failed to mirror due to some error.
This routine iterates through all known package versions, and This routine iterates through all known package versions, and
it creates specs for those versions. If the version satisfies any spec it creates specs for those versions. If the version satisfies any spec
in the specs list, it is downloaded and added to the mirror. in the specs list, it is downloaded and added to the mirror."""
"""
# Make sure nothing is in the way. # Make sure nothing is in the way.
if os.path.isfile(path): if os.path.isfile(path):
raise MirrorError("%s already exists and is a file." % path) raise MirrorError("%s already exists and is a file." % path)

View File

@ -84,9 +84,9 @@ class Package(object):
with the package itself. Packages are written in pure python. with the package itself. Packages are written in pure python.
Packages are all submodules of spack.packages. If spack is installed Packages are all submodules of spack.packages. If spack is installed
in $prefix, all of its python files are in $prefix/lib/spack. Most in ``$prefix``, all of its python files are in ``$prefix/lib/spack``.
of them are in the spack module, so all the packages live in Most of them are in the spack module, so all the packages live in
$prefix/lib/spack/spack/packages. ``$prefix/lib/spack/spack/packages``.
All you have to do to create a package is make a new subclass of Package All you have to do to create a package is make a new subclass of Package
in this directory. Spack automatically scans the python files there in this directory. Spack automatically scans the python files there
@ -95,7 +95,7 @@ class Package(object):
**An example package** **An example package**
Let's look at the cmake package to start with. This package lives in Let's look at the cmake package to start with. This package lives in
$prefix/lib/spack/spack/packages/cmake.py: ``$prefix/var/spack/repos/builtin/packages/cmake/package.py``:
.. code-block:: python .. code-block:: python
@ -118,19 +118,21 @@ def install(self, spec, prefix):
1. The module name, ``cmake``. 1. The module name, ``cmake``.
* User will refers to this name, e.g. 'spack install cmake'. * User will refers to this name, e.g. 'spack install cmake'.
* Corresponds to the name of the file, 'cmake.py', and it can * It can include ``_``, ``-``, and numbers (it can even start with a
include ``_``, ``-``, and numbers (it can even start with a
number). number).
2. The class name, "Cmake". This is formed by converting `-` or 2. The class name, "Cmake". This is formed by converting `-` or
``_`` in the module name to camel case. If the name starts with ``_`` in the module name to camel case. If the name starts with
a number, we prefix the class name with ``_``. Examples: a number, we prefix the class name with ``_``. Examples:
=========== ==========
Module Name Class Name Module Name Class Name
=========== ==========
foo_bar FooBar foo_bar FooBar
docbook-xml DocbookXml docbook-xml DocbookXml
FooBar Foobar FooBar Foobar
3proxy _3proxy 3proxy _3proxy
=========== ==========
The class name is what spack looks for when it loads a package module. The class name is what spack looks for when it loads a package module.
@ -139,16 +141,16 @@ def install(self, spec, prefix):
Aside from proper naming, here is the bare minimum set of things you Aside from proper naming, here is the bare minimum set of things you
need when you make a package: need when you make a package:
homepage homepage:
informational URL, so that users know what they're informational URL, so that users know what they're
installing. installing.
url or url_for_version(self, version) url or url_for_version(self, version):
If url, then the URL of the source archive that spack will fetch. If url, then the URL of the source archive that spack will fetch.
If url_for_version(), then a method returning the URL required If url_for_version(), then a method returning the URL required
to fetch a particular version. to fetch a particular version.
install() install():
This function tells spack how to build and install the This function tells spack how to build and install the
software it downloaded. software it downloaded.
@ -156,13 +158,13 @@ def install(self, spec, prefix):
You can also optionally add these attributes, if needed: You can also optionally add these attributes, if needed:
list_url list_url:
Webpage to scrape for available version strings. Default is the Webpage to scrape for available version strings. Default is the
directory containing the tarball; use this if the default isn't directory containing the tarball; use this if the default isn't
correct so that invoking 'spack versions' will work for this correct so that invoking 'spack versions' will work for this
package. package.
url_version(self, version) url_version(self, version):
When spack downloads packages at particular versions, it just When spack downloads packages at particular versions, it just
converts version to string with str(version). Override this if converts version to string with str(version). Override this if
your package needs special version formatting in its URL. boost your package needs special version formatting in its URL. boost
@ -179,12 +181,15 @@ def install(self, spec, prefix):
**spack create** **spack create**
Most software comes in nicely packaged tarballs, like this one: Most software comes in nicely packaged tarballs, like this one
http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz
Taking a page from homebrew, spack deduces pretty much everything it Taking a page from homebrew, spack deduces pretty much everything it
needs to know from the URL above. If you simply type this: needs to know from the URL above. If you simply type this::
spack create http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz spack create http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz
Spack will download the tarball, generate an md5 hash, figure out the Spack will download the tarball, generate an md5 hash, figure out the
version and the name of the package from the URL, and create a new version and the name of the package from the URL, and create a new
package file for you with all the names and attributes set correctly. package file for you with all the names and attributes set correctly.
@ -216,7 +221,6 @@ class Stackwalker(Package):
you can just run configure or cmake without any additional arguments and you can just run configure or cmake without any additional arguments and
it will find the dependencies automatically. it will find the dependencies automatically.
**The Install Function** **The Install Function**
The install function is designed so that someone not too terribly familiar The install function is designed so that someone not too terribly familiar
@ -241,13 +245,12 @@ class Stackwalker(Package):
add_commands_to_module() function in this class. This is where most of add_commands_to_module() function in this class. This is where most of
them are created and set on the module. them are created and set on the module.
**Parallel Builds** **Parallel Builds**
By default, Spack will run make in parallel when you run make() in your By default, Spack will run make in parallel when you run make() in your
install function. Spack figures out how many cores are available on install function. Spack figures out how many cores are available on
your system and runs make with -j<cores>. If you do not want this behavior, your system and runs make with -j<cores>. If you do not want this
you can explicitly mark a package not to use parallel make: behavior, you can explicitly mark a package not to use parallel make:
.. code-block:: python .. code-block:: python
@ -257,14 +260,15 @@ class SomePackage(Package):
... ...
This changes thd default behavior so that make is sequential. If you still This changes thd default behavior so that make is sequential. If you still
want to build some parts in parallel, you can do this in your install function: want to build some parts in parallel, you can do this in your install
function:
.. code-block:: python .. code-block:: python
make(parallel=True) make(parallel=True)
Likewise, if you do not supply parallel = True in your Package, you can keep Likewise, if you do not supply parallel = True in your Package, you can
the default parallel behavior and run make like this when you want a keep the default parallel behavior and run make like this when you want a
sequential build: sequential build:
.. code-block:: python .. code-block:: python
@ -295,14 +299,13 @@ class SomePackage(Package):
p.do_restage() # removes the build directory and p.do_restage() # removes the build directory and
# re-expands the archive. # re-expands the archive.
The convention used here is that a do_* function is intended to be called The convention used here is that a ``do_*`` function is intended to be
internally by Spack commands (in spack.cmd). These aren't for package called internally by Spack commands (in spack.cmd). These aren't for
writers to override, and doing so may break the functionality of the Package package writers to override, and doing so may break the functionality
class. of the Package class.
Package creators override functions like install() (all of them do this), Package creators override functions like install() (all of them do this),
clean() (some of them do this), and others to provide custom behavior. clean() (some of them do this), and others to provide custom behavior.
""" """
# #
# These are default values for instance variables. # These are default values for instance variables.
@ -862,19 +865,21 @@ def do_install(self,
Package implementations should override install() to describe Package implementations should override install() to describe
their build process. their build process.
Args: :param keep_prefix: Keep install prefix on failure. By default, \
keep_prefix -- Keep install prefix on failure. By default, destroys it. destroys it.
keep_stage -- By default, stage is destroyed only if there are no :param keep_stage: By default, stage is destroyed only if there are \
exceptions during build. Set to True to keep the stage no exceptions during build. Set to True to keep the stage
even with exceptions. even with exceptions.
ignore_deps -- Don't install dependencies before installing this :param ignore_deps: Don't install dependencies before installing this \
package package
fake -- Don't really build -- install fake stub files instead. :param fake: Don't really build; install fake stub files instead.
skip_patch -- Skip patch stage of build if True. :param skip_patch: Skip patch stage of build if True.
verbose -- Display verbose build output (by default, suppresses it) :param verbose: Display verbose build output (by default, suppresses \
dirty -- Don't clean the build environment before installing. it)
make_jobs -- Number of make jobs to use for install. Default is ncpus :param dirty: Don't clean the build environment before installing.
run_tests -- Runn tests within the package's install() :param make_jobs: Number of make jobs to use for install. Default is \
ncpus
:param run_tests: Run tests within the package's install()
""" """
if not self.spec.concrete: if not self.spec.concrete:
raise ValueError("Can only install concrete packages: %s." raise ValueError("Can only install concrete packages: %s."
@ -1110,13 +1115,13 @@ def setup_environment(self, spack_env, run_env):
def setup_dependent_environment(self, spack_env, run_env, dependent_spec): def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
"""Set up the environment of packages that depend on this one. """Set up the environment of packages that depend on this one.
This is similar to `setup_environment`, but it is used to This is similar to ``setup_environment``, but it is used to
modify the compile and runtime environments of packages that modify the compile and runtime environments of packages that
*depend* on this one. This gives packages like Python and *depend* on this one. This gives packages like Python and
others that follow the extension model a way to implement others that follow the extension model a way to implement
common environment or compile-time settings for dependencies. common environment or compile-time settings for dependencies.
By default, this delegates to self.setup_environment() By default, this delegates to ``self.setup_environment()``
Example: Example:
@ -1142,7 +1147,6 @@ def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
This is useful if there are some common steps to installing This is useful if there are some common steps to installing
all extensions for a certain package. all extensions for a certain package.
""" """
self.setup_environment(spack_env, run_env) self.setup_environment(spack_env, run_env)

View File

@ -198,13 +198,17 @@ def remove(self, repo):
def get_repo(self, namespace, default=NOT_PROVIDED): def get_repo(self, namespace, default=NOT_PROVIDED):
"""Get a repository by namespace. """Get a repository by namespace.
Arguments
namespace
Look up this namespace in the RepoPath, and return
it if found.
Optional Arguments Arguments:
default
namespace:
Look up this namespace in the RepoPath, and return it if found.
Optional Arguments:
default:
If default is provided, return it when the namespace If default is provided, return it when the namespace
isn't found. If not, raise an UnknownNamespaceError. isn't found. If not, raise an UnknownNamespaceError.
""" """

View File

@ -2085,7 +2085,7 @@ def format(self, format_string='$_$@$%@+$+$=', **kwargs):
$# 7-char prefix of DAG hash with '-' prefix $# 7-char prefix of DAG hash with '-' prefix
$$ $ $$ $
You can also use full-string versions, which elide the prefixes: You can also use full-string versions, which elide the prefixes::
${PACKAGE} Package name ${PACKAGE} Package name
${VERSION} Version ${VERSION} Version
@ -2101,9 +2101,9 @@ def format(self, format_string='$_$@$%@+$+$=', **kwargs):
${SPACK_INSTALL} The default spack install directory, ${SPACK_INSTALL} The default spack install directory,
${SPACK_PREFIX}/opt ${SPACK_PREFIX}/opt
Optionally you can provide a width, e.g. $20_ for a 20-wide name. Optionally you can provide a width, e.g. ``$20_`` for a 20-wide name.
Like printf, you can provide '-' for left justification, e.g. Like printf, you can provide '-' for left justification, e.g.
$-20_ for a left-justified name. ``$-20_`` for a left-justified name.
Anything else is copied verbatim into the output stream. Anything else is copied verbatim into the output stream.

View File

@ -49,16 +49,14 @@ class Stage(object):
some source code is downloaded and built before being installed. some source code is downloaded and built before being installed.
It handles fetching the source code, either as an archive to be It handles fetching the source code, either as an archive to be
expanded or by checking it out of a repository. A stage's expanded or by checking it out of a repository. A stage's
lifecycle looks like this: lifecycle looks like this::
```
with Stage() as stage: # Context manager creates and destroys the with Stage() as stage: # Context manager creates and destroys the
# stage directory # stage directory
stage.fetch() # Fetch a source archive into the stage. stage.fetch() # Fetch a source archive into the stage.
stage.expand_archive() # Expand the source archive. stage.expand_archive() # Expand the source archive.
<install> # Build and install the archive. (handled by <install> # Build and install the archive.
# user of Stage) # (handled by user of Stage)
```
When used as a context manager, the stage is automatically When used as a context manager, the stage is automatically
destroyed if no exception is raised by the context. If an destroyed if no exception is raised by the context. If an
@ -66,19 +64,17 @@ class Stage(object):
destroyed, for potential reuse later. destroyed, for potential reuse later.
You can also use the stage's create/destroy functions manually, You can also use the stage's create/destroy functions manually,
like this: like this::
```
stage = Stage() stage = Stage()
try: try:
stage.create() # Explicitly create the stage directory. stage.create() # Explicitly create the stage directory.
stage.fetch() # Fetch a source archive into the stage. stage.fetch() # Fetch a source archive into the stage.
stage.expand_archive() # Expand the source archive. stage.expand_archive() # Expand the source archive.
<install> # Build and install the archive. (handled by <install> # Build and install the archive.
# user of Stage) # (handled by user of Stage)
finally: finally:
stage.destroy() # Explicitly destroy the stage directory. stage.destroy() # Explicitly destroy the stage directory.
```
If spack.use_tmp_stage is True, spack will attempt to create If spack.use_tmp_stage is True, spack will attempt to create
stages in a tmp directory. Otherwise, stages are created directly stages in a tmp directory. Otherwise, stages are created directly

View File

@ -56,6 +56,7 @@ def assert_rev(self, rev):
def try_fetch(self, rev, test_file, args): def try_fetch(self, rev, test_file, args):
"""Tries to: """Tries to:
1. Fetch the repo using a fetch strategy constructed with 1. Fetch the repo using a fetch strategy constructed with
supplied args. supplied args.
2. Check if the test_file is in the checked out repository. 2. Check if the test_file is in the checked out repository.

View File

@ -52,6 +52,7 @@ def tearDown(self):
def try_fetch(self, rev, test_file, args): def try_fetch(self, rev, test_file, args):
"""Tries to: """Tries to:
1. Fetch the repo using a fetch strategy constructed with 1. Fetch the repo using a fetch strategy constructed with
supplied args. supplied args.
2. Check if the test_file is in the checked out repository. 2. Check if the test_file is in the checked out repository.

View File

@ -53,6 +53,7 @@ def tearDown(self):
def set_up_package(self, name, MockRepoClass, url_attr): def set_up_package(self, name, MockRepoClass, url_attr):
"""Set up a mock package to be mirrored. """Set up a mock package to be mirrored.
Each package needs us to: Each package needs us to:
1. Set up a mock repo/archive to fetch from. 1. Set up a mock repo/archive to fetch from.
2. Point the package's version args at that repo. 2. Point the package's version args at that repo.
""" """

View File

@ -24,7 +24,7 @@
############################################################################## ##############################################################################
"""Tests for provider index cache files. """Tests for provider index cache files.
Tests assume that mock packages provide this: Tests assume that mock packages provide this::
{'blas': { {'blas': {
blas: set([netlib-blas, openblas, openblas-with-lapack])}, blas: set([netlib-blas, openblas, openblas-with-lapack])},

View File

@ -63,6 +63,7 @@ def get_rev():
def try_fetch(self, rev, test_file, args): def try_fetch(self, rev, test_file, args):
"""Tries to: """Tries to:
1. Fetch the repo using a fetch strategy constructed with 1. Fetch the repo using a fetch strategy constructed with
supplied args. supplied args.
2. Check if the test_file is in the checked out repository. 2. Check if the test_file is in the checked out repository.

View File

@ -31,15 +31,15 @@ def composite(interface=None, method_list=None, container=list):
"""Returns a class decorator that patches a class adding all the methods """Returns a class decorator that patches a class adding all the methods
it needs to be a composite for a given interface. it needs to be a composite for a given interface.
:param interface: class exposing the interface to which the composite :param interface: class exposing the interface to which the composite \
object must conform. Only non-private and non-special methods will be object must conform. Only non-private and non-special methods will \
taken into account be taken into account
:param method_list: names of methods that should be part of the composite :param method_list: names of methods that should be part of the composite
:param container: container for the composite object (default = list). :param container: container for the composite object (default = list). \
Must fulfill the MutableSequence contract. The composite class will expose Must fulfill the MutableSequence contract. The composite class will \
the container API to manage object composition expose the container API to manage object composition
:return: class decorator :return: class decorator
""" """

View File

@ -155,11 +155,11 @@ def highest(self):
@coerced @coerced
def satisfies(self, other): def satisfies(self, other):
"""A Version 'satisfies' another if it is at least as specific and has a """A Version 'satisfies' another if it is at least as specific and has
common prefix. e.g., we want gcc@4.7.3 to satisfy a request for a common prefix. e.g., we want gcc@4.7.3 to satisfy a request for
gcc@4.7 so that when a user asks to build with gcc@4.7, we can find gcc@4.7 so that when a user asks to build with gcc@4.7, we can find
a suitable compiler. a suitable compiler."""
"""
nself = len(self.version) nself = len(self.version)
nother = len(other.version) nother = len(other.version)
return nother <= nself and self.version[:nother] == other.version return nother <= nself and self.version[:nother] == other.version
@ -388,10 +388,10 @@ def __contains__(self, other):
@coerced @coerced
def satisfies(self, other): def satisfies(self, other):
""" """A VersionRange satisfies another if some version in this range
A VersionRange satisfies another if some version in this range
would satisfy some version in the other range. To do this it must would satisfy some version in the other range. To do this it must
either: either:
a) Overlap with the other range a) Overlap with the other range
b) The start of this range satisfies the end of the other range. b) The start of this range satisfies the end of the other range.
@ -401,6 +401,7 @@ def satisfies(self, other):
by 4.7.3.5, etc. by 4.7.3.5, etc.
Rationale: Rationale:
If a user asks for gcc@4.5:4.7, and a package is only compatible with If a user asks for gcc@4.5:4.7, and a package is only compatible with
gcc@4.7.3:4.8, then that package should be able to build under the gcc@4.7.3:4.8, then that package should be able to build under the
constraints. Just using overlaps() would not work here. constraints. Just using overlaps() would not work here.