python-semanticversion icon indicating copy to clipboard operation
python-semanticversion copied to clipboard

feat: SimpleSpec support set operations

Open yxliang01 opened this issue 5 years ago • 5 comments

SimpleSpec essentially is a semver set expression to specify a set of version numbers. So, it is natural to support set operations to the class, e.g. intersection and union. Such operations can be useful, e.g. to check whether two SimpleSpecs are compatible and what are the versions fulfilling both.

yxliang01 avatar Aug 25 '20 09:08 yxliang01

Indeed, under the hood a SimpleSpec is just a thin wrapper around a Clause (an internal class), which supports set operations.

Thus, one could do (SimpleSpec('>=1.1').clause & SimpleSpec('<2.0').clause).match(Version('1.3.4'))

However, before adding that feature, I'll have to think how it should be documented and supported in the long term. Could you help me by providing snippets for how you would expect this new feature to be used in practice? It would help in desiging a reasonable, easy-to-use API ;)

NB: Since it's a feature of the BaseSpec, it is actually available for all variants: SimpleSpec, NPMSpec, and future variants.

rbarrois avatar Aug 25 '20 13:08 rbarrois

E.g. the environment supports >0.5.0 while the codebase might support >0.6.0, then we can try to see whether environment is compatible with the codebase by creating two SimpleSpecs and check if their intersection set is empty.

yxliang01 avatar Aug 25 '20 17:08 yxliang01

@yxliang01 yes, I do see the use case :) My question is, how would you write some code using it :)

Some options:

# Use boolean operations to combine specs
>>> Version('0.7.0') in (Spec('>0.5.0') & Sepc('>0.6.0'))
True

# Use set operations on lists of versions
>>> Spec('>0.5.0') & [Version('0.4.0'), Version('0.5.0'), Version('0.6.0')]
[Version('0.6.0')]

# Can we combine specs from different "worlds"?
>>> SimpleSpec('>0.5.0') & NpmSpec('<0.6.0')
<CombinedSpec>

rbarrois avatar Aug 26 '20 11:08 rbarrois

I think the three use cases are great and not conflicting :) Meanwhile, I believe my use case is also common, it will fit the most for my case to add a compatibleWith(BaseSpec) method to the Spec classes and return bool indicating whether the intersection contains any element.

yxliang01 avatar Aug 26 '20 14:08 yxliang01

I'm facing the same need as @yxliang01 -- I need to know if the intersection is empty. Is there a straightforward way to do it?

Combining clauses produces an AllOf object, and I initially hoped that it will be clear whether or not it represents an empty set by calling .simplify(), but unfortunately that didn't work out.

supersergiy avatar Jul 15 '22 19:07 supersergiy