Skip to content

VersionInfo.parse should be a class method #276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Anvil opened this issue Jul 21, 2020 · 8 comments · Fixed by #277
Closed

VersionInfo.parse should be a class method #276

Anvil opened this issue Jul 21, 2020 · 8 comments · Fixed by #277
Labels
Blocked Issue depends on a different issue or cannot be solved ATM Enhancement Not a bug, but increases or improves in value, quality, desirability, or attractiveness Question Unclear or open issue subject for debate

Comments

@Anvil
Copy link
Contributor

Anvil commented Jul 21, 2020

I wanted to create a subclass of VersionInfo for company reasons (more checkings, more methods, etc) and it turned out the VersionInfo.parse is a staticmethod, always returning VersionInfo instances, no matter what.

By turning the parse static method into a class method and making it return cls(**version_parts) the result of parse will be an instance of the subclass (my class), not the superclass (VersionInfo).

e.g:

class MyBogusVersionInfo(semver.VersionInfo):

    @classmethod
    def parse(cls, version):
        if version.startswith("foobar"):
            version = version[6:]
        return super().parse(version)

print(type(MyBogusVersionInfo.parse("1.2.3")))

Current result is : <class 'semver.VersionInfo'>, while I would have expected <class 'MyBogusVersionInfo'>

@tomschr tomschr added Enhancement Not a bug, but increases or improves in value, quality, desirability, or attractiveness Question Unclear or open issue subject for debate labels Jul 21, 2020
@tomschr
Copy link
Member

tomschr commented Jul 21, 2020

Thanks @Anvil for your issue and the pull request. 👍

That's an interesting approach. I see your point. However, not entirely sure if changing .parse from a staticmethod to a classmethod is completely backward compatible... 🤔

Apart from that, the .parse method could be removed in semver3. We've discussed this in issue #258. For semver3, an idea is to "overload" the initializer to allow more datatypes. Maybe that could solve your use case. If we go this route, that would make the .parse and adapting it kind of obsolete.

Do you need it for Python2 only or do you use it for Python3?

Thanks for your pull request (PR). As the above discussion is not really solved, I would like to wait for this issue until the above issue is remedied.

Just a short comment about your PR: you don't have to change anything right now (due to the open discussion). It's just a reminder for future PRs. We require test cases for each new feature. 😉 If a feature changes the public API, this also needs to be documented. Ideally with some code examples. For further details, refer to our Contributing to semver section.

@tomschr tomschr added the Blocked Issue depends on a different issue or cannot be solved ATM label Jul 21, 2020
@Anvil
Copy link
Contributor Author

Anvil commented Jul 24, 2020

Hello

As far as I can tell, there wont be any breaking by changing static to class. The reference "VersionInfo.parse" makes it automatically bound to the class.

In general, all factory methods (methods that return an instance of the class) should be class methods, not staticmethods.

I dont use python 2 anymore. Do you intent do keep compatibility with python2 ?

@Anvil
Copy link
Contributor Author

Anvil commented Jul 24, 2020

I can provide tests and examples if it's accepted, though. Feel free to ask.

@Anvil
Copy link
Contributor Author

Anvil commented Jul 24, 2020

A basic yet (i think) meaningful test case / example, would be to have a subclass that accepts "v1.2.3" as semver, so that you can directly feed git tag ot the parse method. The subclass would have a parse such as:

class GitTagSemVer(VersionInfo):
    @classmethod
    def parse(cls, version: str):
        if not version.startswith('v'):
            raise ValueError(f"{version}: not a valid semantic version tag") 
        return super().parse(version[1:])

    def __str__(self):
        # Reconstruct the tag.
        return "v" + super().__str__()

import git
import logging

def semver_tags(path):
    repo = git.Repo(path)
    for tag in repo.tags:
        try:
            yield GitTagSemVer.parse(tag)
        except ValueError:
            logging.error(f"{tag}: bad semver tag")

@tomschr
Copy link
Member

tomschr commented Oct 12, 2020

Thank you @Anvil for all the ideas. Sorry for not responding to it earlier. I hope I can work on that soon.

Your ideas and arguments make sense to me. 👍

Do you intent do keep compatibility with python2 ?

That's a good question. If possible, I would love to have at least this issue compatible between the two versions. It doesn't look like a big problem. But let me think of it again, once I'm coming back to this issue.

@Anvil
Copy link
Contributor Author

Anvil commented Oct 16, 2020

I'm glade it makes sense. On my part, there is no requirement nor need for a python2 compatibility. My team and I are working with python >= 3.6. Thank you for your work !

@tomschr
Copy link
Member

tomschr commented Oct 16, 2020

I'm glade it makes sense.

Absolutely! 👍 I'm glad you've reached out to us and contributed.

On my part, there is no requirement nor need for a python2 compatibility. My team and I are working with python >= 3.6. Thank you for your work !

That's great! I've added a small test case; there I had to adapt the super() method a bit. I almost forgot how that worked as I'm using Python 3 most of the day.

Plan is to release 2.11.0 soon and start working on Python 3. Otherwise these compatibility things will always bite me. 😆

@tomschr
Copy link
Member

tomschr commented Oct 16, 2020

Integrated in commit 6e4b402 so closing this issue.

@tomschr tomschr closed this as completed Oct 16, 2020
tomschr added a commit to tomschr/python-semver that referenced this issue Oct 16, 2020
tomschr added a commit to tomschr/python-semver that referenced this issue Oct 16, 2020
tomschr added a commit to tomschr/python-semver that referenced this issue Oct 16, 2020
@tomschr tomschr mentioned this issue Oct 17, 2020
3 tasks
tomschr added a commit to tomschr/python-semver that referenced this issue Oct 17, 2020
* python-semver#274 / python-semver#275 String Types Py2 vs. Py3 compatibility
* python-semver#277 Turn VersionInfo.parse into classmethod to allow subclasses
* python-semver#286 Add author and update changelog for python-semver#276/python-semver#277
tomschr added a commit that referenced this issue Oct 17, 2020
* #274 / #275 String Types Py2 vs. Py3 compatibility
* #277 Turn VersionInfo.parse into classmethod to allow subclasses
* #286 Add author and update changelog for #276/#277
tomschr added a commit to tomschr/python-semver that referenced this issue Oct 17, 2020
tomschr added a commit to tomschr/python-semver that referenced this issue Oct 17, 2020
tomschr added a commit that referenced this issue Oct 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Blocked Issue depends on a different issue or cannot be solved ATM Enhancement Not a bug, but increases or improves in value, quality, desirability, or attractiveness Question Unclear or open issue subject for debate
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants