Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Rethinking __init__ of VersionInfo class? #303

Copy link
Copy link
Open
@tomschr

Description

@tomschr
Issue body actions

Situation

Originally posted by @tomschr in #258 (comment)

From the above discussion, I thought it would be worth to decouple the compare discussion from the initializer discussion. Both are somewhat related, but can live independently.

With a more "advanced" initializer/constructor we get the following benefits:

  • more "pythonic": it's one, obvious way to get an instance.
  • avoids the longer function call Version.parse(...).
  • more readable

With such an (overloaded?) initializer, we could cover the following use cases:

>>> from semver import Version
>>> Version(1)
Version(major=1, minor=0, patch=0, prerelease=None, build=None)
>>> Version(1, "4", b"5")
Version(major=1, minor=4, patch=5, prerelease=None, build=None)
>>> Version(1, patch=2)
Version(major=1, minor=0, patch=2, prerelease=None, build=None)
>>> Version("1.2.3")
Version(major=1, minor=2, patch=3, prerelease=None, build=None)
>>> Version(b"1.2.3")
Version(major=1, minor=2, patch=3, prerelease=None, build=None)
>>> v = Version(b"2.3.4")
>>> Version(v)
Version(major=2, minor=3, patch=4, prerelease=None, build=None)
>>> t = (1, 2, 3)
>>> Version(*t)                                             
Version(major=1, minor=2, patch=3, prerelease=None, build=None)
>>> d = {'major': 3, 'minor': 4, 'patch': 5,  'prerelease': 'pre.2', 'build': 'build.4'}
>>> Version(**d)
Version(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')

Discussions and Possible Solutions

To implement a somewhat more advanced constructor/initializer, we have these options:

  1. Program it manually with isinstance and if...else constructs
  2. Use the typing.overload function (suggested by @tlaferriere)
  3. Use functools.singledispatch

However, all three comes at a cost or an issue:

  1. Maybe not impossible, but the code would look probably ugly.
  2. "The @overload decorator is purely for type hints, you can only specify one function body and it has to distinguish the different types using isinstance.` (Originally posted by @tlaferriere in Consider keeping compare module level function #258 (comment))
  3. Is not possible with an __init__ method. The singledispatch works only for functions(!), not methods. For methods we would need functools.singledispatchmethod which is only available from Python >= 3.8.

Another idea goes into a completely different direction. Maybe we shouldn't change the Version class much, but offer a much shorter variant: semver.v.

from functools import singledispatch

# ...
@singledispatch
def ver(major, minor=0, patch=0, prerelease=None, build=None) -> "Version":
    return Version(major, minor, patch, prerelease, build)
    
@ver.register(bytes)
@ver.register(str)
def _(ver: str) -> "Version":
    if isinstance(ver, bytes):
       ver = str(ver, "utf-8")
    if "." in ver:
        return Version.parse(ver)
    return Version(int(ver))

@ver.register(Version)
def _(ver: "Version") -> "Version":
    return ver

Which means, we could just use semver.v as a much shorter variant:

>>> import semver
>>> semver.v("1.2.3")
Version(major=1, minor=2, patch=3, prerelease=None, build=None)

One drawback could be that v is quite short. Maybe too short? Especially if you import it with from semver import v it could be easily overwritten by other, local variables.
That could be a bit avoided to use capital V or ver. Or we use the much longer name semver.version.

Thoughts? Any other ideas? Would that be worth the effort?

@tlaferriere @gsakkis @ppkt

Metadata

Metadata

Assignees

No one assigned

    Labels

    DesignIdeas, suggestions, musings about design questionsIdeas, suggestions, musings about design questionsEnhancementNot a bug, but increases or improves in value, quality, desirability, or attractivenessNot a bug, but increases or improves in value, quality, desirability, or attractivenessQuestionUnclear or open issue subject for debateUnclear or open issue subject for debateRelease_3.x.yOnly for the major release 3Only for the major release 3

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.