Skip to content
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

repo.index.commit fails on python 3.10.0-rc2 (but not 3.10.0-rc1) #1341

Closed
muggenhor opened this issue Sep 10, 2021 · 6 comments
Closed

repo.index.commit fails on python 3.10.0-rc2 (but not 3.10.0-rc1) #1341

muggenhor opened this issue Sep 10, 2021 · 6 comments

Comments

@muggenhor
Copy link
Contributor

This is an excerpt of Hopic's pytest run in the python:3.10.0rc2-slim docker image. With python:3.10.0rc1-slim this same error does not occur.

I don't have the time right now to fully analyze this. But it looks suspiciously similar to a problem that I observed in Hopic itself and fixed with tomtom-international/hopic@a0f5a93. That one was triggered by this Python change: https://bugs.python.org/issue44806 / python/cpython@2cc19a5.

This if failing in a different location in the same function. But given the CPython commit message it seems to me that it's somehow achieving the opposite of its intent: it looks like non-protocol classes do call the __init__ method (via super) of the protocol class they inherit from.

>           repo.index.commit(message='Initial commit', **_commitargs)                                                                                             [2921/9962]
                                                                                                                                                                              
hopic/test/test_version_bump.py:173:                                                                                                                                          
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.tox/py310/lib/python3.10/site-packages/git/index/base.py:1002: in commit                                                                                                     
    rval = Commit.create_from_tree(self.repo, tree, message, parent_commits,                                                                                                  
.tox/py310/lib/python3.10/site-packages/git/objects/commit.py:459: in create_from_tree                                                                                        
    new_commit = cls(repo, cls.NULL_BIN_SHA, tree,                                                                                                                            
.tox/py310/lib/python3.10/site-packages/git/objects/commit.py:130: in __init__                                                                                                
    super(Commit, self).__init__(repo, binsha)                                                                                                                                
.tox/py310/lib/python3.10/site-packages/git/objects/base.py:57: in __init__                                                                                                       super(Object, self).__init__()                                                                                                                                            
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <[AttributeError("'Commit' object has no attribute 'binsha'") raised in repr()] Commit object at 0x7f669cbdc8b0>, args = (), kwargs = {}
cls = <class 'git.objects.commit.Commit'>, base = <class 'git.objects.commit.Commit'>, init = <function Commit.__init__ at 0x7f669d820af0>

    def _no_init_or_replace_init(self, *args, **kwargs):
        cls = type(self)
     
        if cls._is_protocol:
            raise TypeError('Protocols cannot be instantiated')
     
        # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`.
        # The first instantiation of the subclass will call `_no_init_or_replace_init` which
        # searches for a proper new `__init__` in the MRO. The new `__init__`
        # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent
        # instantiation of the protocol subclass will thus use the new
        # `__init__` and no longer call `_no_init_or_replace_init`.
        for base in cls.__mro__:
            init = base.__dict__.get('__init__', _no_init_or_replace_init)
            if init is not _no_init_or_replace_init:
                cls.__init__ = init
                break
        else:
            # should not happen
            cls.__init__ = object.__init__
     
>       cls.__init__(self, *args, **kwargs) 
E       TypeError: Commit.__init__() missing 2 required positional arguments: 'repo' and 'binsha'

/usr/local/lib/python3.10/typing.py:1422: TypeError
@Byron
Copy link
Member

Byron commented Sep 10, 2021

Thanks for reporting. I wouldn't know how to go about this though. Is it a bug in the upcoming python release and thus should be reported there? Or is it a 'breaking-change-in-minor-release' that is justified as bugfix so GitPython should be adjusted?

Admittedly, GItPython clearly fell into the OO trap and probably pays for that more than a decade later, so cleaning this up is probably merely paying tech debt (with a lot of accumulated compound interest ;)).

@Yobmod
Copy link
Contributor

Yobmod commented Sep 24, 2021

Yeah, i think this is the same issue with Protocol classes that cropped up a few times. #1332
Our Protocol classes worked for 3.10.0.b4, then broke in rc1. I fixed that, and then it broke again in rc2 😭.

I have to check if we can just revert to the our original code or it needs a different fix. I might end up just stripping Protocols back out like I did for TypeGuard, until python changes calm down. Either way, we'll need a new GitPython release for py 3.10.0 compat (due Oct 4th).

@silvanocerza
Copy link

silvanocerza commented Sep 24, 2021

Having a similar issue with Python 3.9.7. Is it related or should I open a new issue?

>           repo.index.commit("First commit")

test/test_lib.py:960: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../.cache/pypoetry/virtualenvs/arduino-cli-P0JdEWiU-py3.9/lib/python3.9/site-packages/git/index/base.py:1000: in commit
    tree = self.write_tree()
../../.cache/pypoetry/virtualenvs/arduino-cli-P0JdEWiU-py3.9/lib/python3.9/site-packages/git/index/base.py:574: in write_tree
    root_tree = Tree(self.repo, binsha, path='')
../../.cache/pypoetry/virtualenvs/arduino-cli-P0JdEWiU-py3.9/lib/python3.9/site-packages/git/objects/tree.py:215: in __init__
    super(Tree, self).__init__(repo, binsha, mode, path)
../../.cache/pypoetry/virtualenvs/arduino-cli-P0JdEWiU-py3.9/lib/python3.9/site-packages/git/objects/base.py:168: in __init__
    super(IndexObject, self).__init__(repo, binsha)
../../.cache/pypoetry/virtualenvs/arduino-cli-P0JdEWiU-py3.9/lib/python3.9/site-packages/git/objects/base.py:56: in __init__
    super(Object, self).__init__()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[AttributeError('binsha') raised in repr()] Tree object at 0x7f5858690db0>, args = (), kwargs = {}

    def _no_init(self, *args, **kwargs):
>       raise TypeError('Protocols cannot be instantiated')
E       TypeError: Protocols cannot be instantiated

/usr/lib/python3.9/typing.py:1083: TypeError

@muggenhor
Copy link
Contributor Author

@silvanocerza different stack trace but the same issue as far as I can tell (i.e. triggered by inheritance from typing.Protocol).

@silvanocerza
Copy link

The issue is not present in Python 3.9.6 by the way.

@mhsmith
Copy link

mhsmith commented Sep 27, 2022

I also got the error in the original post with Python 3.10.0-rc2. But it worked fine with the final release of Python 3.10.0, which I guess explains why this issue hasn't had any activity over the last year. So I think it can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

5 participants