mamba-org / rattler

Rust crates to work with the Conda ecosystem.
BSD 3-Clause "New" or "Revised" License
226 stars 42 forks source link

NamelessMatchSpec::from_str more strict than MatchSpec::from_str #736

Closed AaronOpfer closed 4 weeks ago

AaronOpfer commented 4 weeks ago

It seems like NamelessMatchSpec is more particular than MatchSpec when parsing.

My test:

   let ms1 =
       MatchSpec::from_str("python ==2.7.*.*|>=3.6", ParseStrictness::Lenient).expect("nameful");
   let ms2 =
       NamelessMatchSpec::from_str("==2.7.*.*|>=3.6", ParseStrictness::Lenient).expect("nameless")

My output:

thread 'main' panicked at src/main.rs:64:82:
nameless: InvalidVersionSpec(InvalidConstraint(RegexConstraintsNotSupported))          
baszalmstra commented 4 weeks ago

Thanks for this report, it triggered a deeper investigation. I fixed this in #738 .

So basically what happened is that actually ==2.7.*.* is an unsupported version because it basically says: I want exactly 2.7.*.*. Because of the exact equality rattler will deduce that 2.7.*.* must be a regular expression which is not supported by rattler. Thats why you get the RegexConstraintsNotSupported error.

However, through some historic conda magic that rattler also implements (when parsing in lenient mode), in some cases (if there is no build string) the == part of the version in matchspec is removed. That turns ==2.7.*.* into 2.7.*.* which is still not actually a valid version because that still looks like a regex, but rattler just interprets this as 2.7.* (in lenient mode again).

Anyway, with #738 both matchspec and the nameless variant implement this behavior. However, in strict mode the removal of a == is not performed anymore so in strict mode this specific matchspec will give a parser error.

AaronOpfer commented 4 weeks ago

Thanks! Looking forward to the next rattler_conda_types build to give it another go.