How to use the conda MatchSpec?
How to list package versions available with conda has useful answers, one of which is at https://stackoverflow.com/a/47795843/257924 which uses two equal signs. conda search -h
doesn't state fully what MatchSpec syntax allows, and only gives a spartan number of examples.
For example, I wanted to see what packages under the latest version of python exist, for a package called jedi
. I had to resort to experimentation and guessing to find the right syntax, because of the above lack in detailed documentation of the MatchSpec syntax. I ended up with:
$ condaw search 'jedi[build=py37*]' --json | grep '"build"'
"build": "py37_1",
"build": "py37_0",
"build": "py37_0",
"build": "py37_0",
"build": "py37_0",
$
The above --json
option was used just so that I could find out what keywords such as build
might be a part of the syntax.
So, where is the MatchSpec syntax officially and fully documented so that I don't have to guess? I'm concluding for now that -h
output is the only one.
Solution 1:
There is some (possibly outdated) documentation in the conda-build docs. However, I still regard the documentation in their code as clearer. It can be read from an activated base env using
python -c "from conda.models.match_spec import MatchSpec; help(MatchSpec)"
or on the GitHub repo.
Technically, the code documentation is more about serializing the MatchSpec
object to the string representation, rather than the other direction of parsing the string, but it covers all the possibilities.
MatchSpec String
Part of the docs describe the class itself, but here are the relevant parts on the string literal representation of the class:
The canonical string representation can generically be represented by
(channel(/subdir):(namespace):)name(version(build))[key1=value1,key2=value2]
where
()
indicate optional fields. The rules for constructing a canonical string representation are:
name
(i.e. "package name") is required, but its value can be '*'. Its position is always outside the key-value brackets.- If
version
is an exact version, it goes outside the key-value brackets and is prepended by==
. Ifversion
is a "fuzzy" value (e.g.1.11.*
), it goes outside the key-value brackets with the.*
left off and is prepended by=
. Otherwiseversion
is included inside key-value brackets.- If
version
is an exact version, andbuild
is an exact value,build
goes outside key-value brackets prepended by a=
. Otherwise,build
goes inside key-value brackets.build_string
is an alias forbuild
.- The
namespace
position is being held for a future conda feature.- If
channel
is included and is an exact value, a::
separator is ued betweenchannel
andname
.channel
can either be a canonical channel name or a channel url. In the canonical string representation, the canonical channel name will always be used.- If
channel
is an exact value andsubdir
is an exact value,subdir
is appended tochannel
with a/
separator. Otherwise,subdir
is included in the key-value brackets.- Key-value brackets can be delimited by comma, space, or comma+space. Value can optionally be wrapped in single or double quotes, but must be wrapped if
value
contains a comma, space, or equal sign. The canonical format uses comma delimiters and single quotes.- When constructing a :class:
MatchSpec
instance from a string, any key-value pair given inside the key-value brackets overrides any matching parameter given outside the brackets.
Supported Keys
In addition to the fields that are explicitly represented in the string, the following keys are supported:
build_number
track_features
features
url
md5
license
license_family
fn
Note: fn
stands for filename.
Examples
The documentation continues on to give examples, showing how one can use this MatchSpec
class to generate these canonical strings:
>>> str(MatchSpec(name='foo', build='py2*', channel='conda-forge'))
'conda-forge::foo[build=py2*]'
>>> str(MatchSpec('foo 1.0 py27_0'))
'foo==1.0=py27_0'
>>> str(MatchSpec('foo=1.0=py27_0'))
'foo==1.0=py27_0'
>>> str(MatchSpec('conda-forge::foo[version=1.0.*]'))
'conda-forge::foo=1.0'
>>> str(MatchSpec('conda-forge/linux-64::foo>=1.0'))
"conda-forge/linux-64::foo[version='>=1.0']"
>>> str(MatchSpec('*/linux-64::foo>=1.0'))
"foo[subdir=linux-64,version='>=1.0']"