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

AutoInterrupt is broken with Python 3.12.9 #2003

Open
ziyao233 opened this issue Feb 16, 2025 · 4 comments
Open

AutoInterrupt is broken with Python 3.12.9 #2003

ziyao233 opened this issue Feb 16, 2025 · 4 comments

Comments

@ziyao233
Copy link

Refer to the comment, CPython is refactoring stdlib modules with lazy import, improving performance on loading.

Unfortunately, this breaks the AutoInterrupt wrapper in GitPython, whose finalizer makes use of subprocess.Popen.terminate(). After the refactor of subprocess module1, the terminate() method may lazily load signal module, which is problematic if it is invoked during the interpreter finalization.

A real-world reproducer is the spdxcheck.py2 script in Linux kernel,

$ ./scripts/spdxcheck.py outgoing/clock/v3/v3-0001-dt-bindings-clock-Document-clock-and-reset-unit-o.patch 
Exception ignored in: <function Git.AutoInterrupt.__del__ at 0x7f25d89cd260>
Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/git/cmd.py", line 790, in __del__
  File "/usr/lib/python3.12/site-packages/git/cmd.py", line 781, in _terminate
  File "/usr/lib/python3.12/subprocess.py", line 2220, in terminate
ImportError: sys.meta_path is None, Python is likely shutting down
@ziyao233 ziyao233 changed the title AutoInterrupt is broken with Python 3.12 AutoInterrupt is broken with Python 3.12.9 Feb 16, 2025
@gpshead
Copy link

gpshead commented Feb 16, 2025

Python-side fixes will be in the next 3.12 and 3.13 patch releases. What gitpython can do to work around it is something along the lines of this workaround within git.cmd._terminate:

import signal   # top of the git/cmd.py file.

...

    def __del__(self):  # Git.AutoInterrupt.__del__
        ...
        try:
            self.$PROC.terminate()
        except ImportError:
            # workaround for https://github.com/python/cpython/issues/118761#issuecomment-2661504264 in 3.12.9 and 3.13.2
            self.$PROC.send_signal(signal.SIGTERM)
        ...

@gpshead
Copy link

gpshead commented Feb 16, 2025

That's somewhat awkward, you could just always import signal at the top level and call .send_signal(signal.SIGTERM) itself as in the exception handler. But at least leave a comment as to why, otherwise someone may see that and want to refactor it into a .terminate() call again. Whether that needs to persist depends on how long unpatched pythons for this remain in the wild after our next patch releases.

@gpshead
Copy link

gpshead commented Feb 16, 2025

That workaround is POSIX platform specific, .send_signal on Windows will still have the issue but .terminate itself should work there as it calls a windows specific API directly.

@Byron
Copy link
Member

Byron commented Feb 17, 2025

Thanks a lot for reporting and sketching out a possible workaround.

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

No branches or pull requests

3 participants