Visitar URL original
Feature request: concise "compatibility" matching · Issue #284 · python-semver/python-semver · GitHub
Skip to content

Feature request: concise "compatibility" matching #284

Closed

Description

@sbrudenell

I'd really like a concise expression for "is version x compatible with version y?"

Specifically, suppose I write code against one version of an API, and the API exposes a semver-compliant version. Is v_caller compatible with v_api?

The most concise expression I can come up with is something like v_caller <= v_api and v_caller.major == v_api.major, but I really wish this was simpler and more readable. Maybe v_caller.compatible(v_api); or maybe v_caller.can_call(v_api) better illustrates which operand is which.

I know this would be covered by #241, but its scope is quite broad. I wanted to specifically call out this feature.

Activity

  1. added
    EnhancementNot a bug, but increases or improves in value, quality, desirability, or attractiveness
    Release_3.x.yOnly for the major release 3
    on Oct 21, 2020
  2. tomschr commented on Oct 21, 2020

    @tomschr
    Member

    @sbrudenell Thanks for your report.

    I'd really like a concise expression for "is version x compatible with version y?"

    Yes, but what you mean by "compatible with"? I have a vague idea, but "In the face of ambiguity, refuse the temptation to guess." 😉

    Could you help me to understand what you mean by giving a more verbose example? Thanks! 👍

  3. sbrudenell commented on Oct 26, 2020

    @sbrudenell
    ContributorAuthor

    Maybe a clearer way to say what I mean is: x -> y is not a breaking change.

    Another way: x matches "^y" according to npm version matching idioms. (or probably a subset of the idiom, not treating version 0 as special)

    Does that make sense?

  4. Lexicality commented on Jun 8, 2021

    @Lexicality
    Contributor

    Yes, but what you mean by "compatible with"? I have a vague idea, but "In the face of ambiguity, refuse the temptation to guess." 😉

    For my use case I'd most like to be able to use the PEP 440 version of "compatible": https://www.python.org/dev/peps/pep-0440/#compatible-release

    I would also greatly appreciate being able to use the operators from that pep in the code, for example

    >>> semver.match("1.2.3", "==1.*")
    True
    
  5. rafalkrupinski commented on Nov 14, 2022

    @rafalkrupinski
    Contributor

    Isn't the specification enough?
    SemVer is all about compatibility...

  6. Lexicality commented on Nov 14, 2022

    @Lexicality
    Contributor

    Isn't the specification enough?
    SemVer is all about compatibility...

    The spec is about API compatibility, but doesn't have any info about version compatibility, eg ~=1.2

  7. rafalkrupinski commented on Nov 14, 2022

    @rafalkrupinski
    Contributor

    The spec is about API compatibility, but doesn't have any info about version compatibility, eg ~=1.2

    Did you mean version matching?

    OP asked for a method to check if a caller implementing version X is compatible with a callee implementing version Y, using somthing like X.compatible_with(Y).

    I'd really like a concise expression for "is version x compatible with version y?"

    That's exactly what SemVer is about.
    In order to do that, compatible_with function should simply apply the rules described in the spec, in reverse.

    Yes, but what you mean by "compatible with"?

    This is where I'm lost, SemVer describes exactly the rules to answer that.

  8. added 2 commits that reference this issue on Nov 15, 2022
    6205142
    507b641
  9. tomschr commented on Nov 15, 2022

    @tomschr
    Member

    Funny coincidence, I've played around with these extended matching parts in PR #367. 😄 It may or may not be integrated into the main branch, depending on the outcome of your comments. If you want to give it a try, please comment on the respective PR.

    It goes in the direction to #241.

    @sbrudenell, @Lexicality and @rafalkrupinski would that help? Any comments are greatly appreciated.

  10. rafalkrupinski commented on Nov 15, 2022

    @rafalkrupinski
    Contributor

    I'm looking for trivial matching according to semver rules

    • if major is different, it's incompatible
    • if major is equal but minor is lower, it's incompatible
    • if Prerelease is present and different, it's incompatible
    • otherwise it's compatible
  11. tomschr commented on Nov 15, 2022

    @tomschr
    Member

    Would something like this be useful?

    def iscompatible(v1: Version, v2: Version):
         if v1.major != v2.major:
             return False
         if v1.minor < v2.minor:
             return False
         if v1.prerelease != v2.prerelease:
             return False
         return True
    
    >>> v1 = Version(1, 2, 3)
    >>> v2 = Version(1, 1, 4)
    >>> v3 = Version(1, 3, 5)
    
    >>> iscompatible(v1, v2)
    True
    >>> iscompatible(v1, v3)
    False

    The code is derived from your description. Certainly we could optimize it.

  12. rafalkrupinski commented on Nov 15, 2022

    @rafalkrupinski
    Contributor

    @tomschr
    Yes, that's roughly what I was looking for.
    It should follow the specification rather than my brief summary, but I think the only thing I've missed is that versions starting with 0 are incompatible with each other unless identical.

    Also, I'd rather have a method instead of a function, so there is a clear this and that, since compatibility is directed, i.e.

    • caller 1.1 is compatible with callee 1.2, but
    • caller 1.2 is not compatible with callee 1.1.

    I'd like to put a version in my model classes and yaml files, so the program can verify if it can handle the files, similar to Kubernetes.

    Cheers

  13. tlaferriere commented on Nov 15, 2022

    @tlaferriere
    Contributor

    Handling the semantics of the distinction between caller and callee is going to be a bit of a job. The most obvious but implicit way I can think of is encoding this information in the order of the arguments to the function, like so:

    def iscompatible(caller: Version, callee: Version):
        ...

    In a more explicit way, but still mostly implicit, there is the option of creating a method on Version where self is considered the caller and the other version the callee:

    def iscompatible(self, callee: Version):
        ...

    As I write it down, I realise that having these arg names actually makes them very explicit, so they may not be that bad choices in the end.

  14. 47 remaining items

  15. added 3 commits that reference this issue on Mar 7, 2023
    467ea0c
    239f517
    948539f
  16. unpinned this issue on Mar 7, 2023
  17. added 2 commits that reference this issue on Jul 2, 2023
    0c08f75
    d7b12ad
  18. added 2 commits that reference this issue on Jul 24, 2023
    745d1bf
    ecd2949
  19. added 2 commits that reference this issue on Sep 16, 2023
    f5907a9
    da04d19
  20. added 2 commits that reference this issue on Oct 5, 2023
    c30a9bf
    b8ae6fa
  21. added a commit that references this issue on Nov 1, 2023
    74b0b2e
  22. added a commit that references this issue on Aug 13, 2024
    5d6137e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    EnhancementNot a bug, but increases or improves in value, quality, desirability, or attractivenessRelease_3.x.yOnly for the major release 3

    Type

    No type

    Fields

    SIze

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions