-
Notifications
You must be signed in to change notification settings - Fork 376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for full regex queries in libmamba's MatchSpec implementation #1853
Comments
The packages not found error does look like it comes from libsolv, no? Because you mentioned yesterday that the error already happens when parsing MatchSpecs themselves. libsolv has this code to strip away everything that comes before the last colon here: https://github.com/openSUSE/libsolv/blob/e13455d011710a99ef1dfb33432044cc7eae0efb/src/conda.c#L576-L578 If we change that to consider only colons that come before the first space, that would probably help to make this work! E.g. we could change the code to read:
|
Oh, yes, you are right! Where are the spaces coming from? An alternative would be to check whether the spec contains a square bracket. My C is terrible, so this would be in C-ish Python: spec = "conda-forge::numpy[build='^(?:py39.*)$']"
bracket = spec.find("[")
if bracket >= 0:
name = spec[:bracket]
colon = name.find(":")
if colon >= 0:
name = name[colon+1:]
fields = spec[bracket:]
spec = name + fields
else:
colon = spec.find(":")
if colon >= 0:
spec = spec[colon+1:] |
So TLDR:
Ok, I had time to look into this a bit more. I applied this patch to libsolv's diff --git a/src/conda.c b/src/conda.c
index 6f6a65a6..dd9b5948 100644
--- a/src/conda.c
+++ b/src/conda.c
@@ -574,7 +574,7 @@ pool_conda_matchspec(Pool *pool, const char *name)
int haveglob = 0;
/* ignore channel and namespace for now */
- if ((p2 = strrchr(name, ':')))
+ if ((p2 = strrchr(name, ':')) && (p2 < strchr(name, ' ')))
name = p2 + 1;
name2 = solv_strdup(name);
/* find end of name */
@@ -619,10 +619,10 @@ pool_conda_matchspec(Pool *pool, const char *name)
if (p <= version + 1 || (p[-1] != ' ' && p[-1] != '='))
break; /* no build */
/* check char before delimiter */
- if (p[-2] == '=' || p[-2] == '!' || p[-2] == '|' || p[-2] == ',' || p[-2] == '<' || p[-2] == '>' || p[-2] == '~')
+ if (p[-2] == '=' || p[-2] == '!' || p[-2] == '|' || p[-2] == ',' || p[-2] == '<' || p[-2] == '>' || p[-2] == '~' || p[-2] == '?')
{
/* illegal combination */
- if (p[-1] == ' ')
+ if (p[-1] == ' ' || (p[-1] == '=' && p[-2] == '?'))
{
p--;
continue; /* special case space: it may be in the build */
With this patch the parsing does not choke, so we can get to a different error now :) Let's assume we want to install
I want to test advanced regexes, so I'll use the string Vanilla conda:
Cool that worked. Now let's make it break. I'll query for an non-existing artifact:
As expected, it fails. Now with
Oh wow it worked! Well, it always works :D The regex is not really respected:
And it's not about the regex. This should fail too and it doesn't:
It looks like it's dropped:
Ok, so let's add the version then? If I specify a version (even with just
^ These two should have worked!! See logs:
Also for completeness, this also fails, of course:
|
PR submitted upstream openSUSE/libsolv#506 |
libsolv patch for the feedstock: conda-forge/libsolv-feedstock#60 |
Closing in favor of #3169 which is a bit more recent. |
Hello!
Apparently,
conda
'sMatchSpec
class supports full regex syntax for queries as long as the string is wrapped with^$
. Otherwise it's handled as a glob (which internally gets converted to a full regex anyway).So all of these are equivalent and return the same results:
However
libmamba
'sMatchSpec
(re)implementation seems to choke on the:
character of the(?:)
non-capturing group.I understand this is very niche, but the suggested solution for an upcoming PR in conda, which deals with the very old problem of glob strings deemed as not compatible (when indeed they are), might end up producing a regex build string. See conda/conda#11612 for details.
The solution works well for
conda
but when I tried to see what happens withlibmamba
throughconda-libmamba-solver
, it cannot parse the resulting match spec string:That weird package not found is the byproduct of misparsing this spec:
numpy[build='^(?=.*py39.*)(?:py39.*)$']
. I guess the parser is splitting by colon to find the channel spec, if any.If I try to create an environment with less weird regex builds, it does work, btw:
So hopefully it's just a parsing issue :D
The text was updated successfully, but these errors were encountered: