From 0392d4b9697255176073faceb2299dbe92d7b1d3 Mon Sep 17 00:00:00 2001 From: Andrew Nesbitt Date: Thu, 24 Sep 2026 16:36:17 +0100 Subject: [PATCH] Use resolved scheme for emptiness check in ToVersString ToVersString resolved its scheme argument but then called r.IsEmpty(), which re-read r.Scheme. A schemeless Range from NewRange with PyPI intervals was judged empty under the generic comparator and serialised as vers:pypi/. Fixes #52. --- parser.go | 2 +- parser_test.go | 18 ++++++++++++++++++ range.go | 6 +++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/parser.go b/parser.go index af0ecf1..ca9e2d4 100644 --- a/parser.go +++ b/parser.go @@ -182,7 +182,7 @@ func (p *Parser) ToVersString(r *Range, scheme string) string { return fmt.Sprintf("vers:%s/*", scheme) } // Check if empty but has raw constraints (preserve them for output) - if r.IsEmpty() && len(r.RawConstraints) == 0 { + if r.isEmptyFor(scheme) && len(r.RawConstraints) == 0 { return fmt.Sprintf("vers:%s/", scheme) } diff --git a/parser_test.go b/parser_test.go index 3923688..53b280c 100644 --- a/parser_test.go +++ b/parser_test.go @@ -536,6 +536,24 @@ func TestToVersString(t *testing.T) { "npm", "vers:npm/>=1.0.0|<2.0.0", }, + { + "schemeless pypi calver range", + NewRange([]Interval{NewInterval("2016.11.0", "3003rc1", true, false)}), + "pypi", + "vers:pypi/>=2016.11.0|<3003rc1", + }, + { + "schemeless pypi dev range", + NewRange([]Interval{NewInterval("0.5.0b3.dev13", "0.5.0b3.dev97", true, false)}), + "pypi", + "vers:pypi/>=0.5.0b3.dev13|<0.5.0b3.dev97", + }, + { + "schemeless empty interval", + NewRange([]Interval{NewInterval("2.0", "1.0", true, false)}), + "pypi", + "vers:pypi/", + }, } for _, tt := range tests { diff --git a/range.go b/range.go index 841509b..a48127e 100644 --- a/range.go +++ b/range.go @@ -180,10 +180,14 @@ func samePEP440Release(left, right pep440Version) bool { // IsEmpty returns true if this range matches no versions. func (r *Range) IsEmpty() bool { + return r.isEmptyFor(r.Scheme) +} + +func (r *Range) isEmptyFor(scheme string) bool { if len(r.Intervals) == 0 { return true } - cmp := compareFuncFor(r.Scheme) + cmp := compareFuncFor(scheme) for _, interval := range r.Intervals { if !interval.isEmptyCmp(cmp) { return false