Page MenuHome GnuPG

[python-gpgme] Traceback when running with python -OO
Closed, ResolvedPublic

Description

The python gpgme binding ships with some code that rewrites the docstrings at runtime. This creates an issue when we run the code under python(3) -OO, i.e. with the optimization flags that say "discard all docstrings" (value of __doc__ set to None), which tracebacks when trying to rewrite the docstrings.

This works just fine:

python3 -c "import gpg; gpg.Context()"

And this does not:

python3 -OO -c "import gpg; gpg.Context()"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.8/site-packages/gpg/core.py", line 218, in __init__
    self.signers = signers
  File "/usr/lib/python3.8/site-packages/gpg/core.py", line 169, in __setattr__
    super(GpgmeWrapper, self).__setattr__(key, value)
  File "/usr/lib/python3.8/site-packages/gpg/core.py", line 1098, in signers
    old = self.signers
  File "/usr/lib/python3.8/site-packages/gpg/core.py", line 1094, in signers
    return [self.signers_enum(i) for i in range(self.signers_count())]
  File "/usr/lib/python3.8/site-packages/gpg/core.py", line 150, in __getattr__
    doc = self._munge_docstring.sub(r'\2.\1(\3', getattr(func, "__doc__"))
TypeError: expected string or bytes-like object

The guilty line is from core.py:

doc = self._munge_docstring.sub(r'\2.\1(\3', getattr(func, "__doc__"))

All versions are affected (initially found in the debian stretch version, 1.12.0).

Details

Version
1.14.0

Revisions and Commits

Event Timeline

IIUC, fix can be like this:

diff --git a/lang/python/src/core.py b/lang/python/src/core.py
index 996c3b0f..646bbc60 100644
--- a/lang/python/src/core.py
+++ b/lang/python/src/core.py
@@ -147,7 +147,12 @@ class GpgmeWrapper(object):
                     gpgme.gpg_raise_callback_exception(slf)
                 return result
 
-        doc = self._munge_docstring.sub(r'\2.\1(\3', getattr(func, "__doc__"))
+        doc_orig = getattr(func, "__doc__")
+        if doc_orig:
+            doc = self._munge_docstring.sub(r'\2.\1(\3', doc_orig)
+        else:
+            doc = None
+
         _funcwrap.__doc__ = doc
 
         # Monkey-patch the class.

I don't know the detail, so, I may be wrong.
How do you think?

gniibe triaged this task as Normal priority.

Pushed the change.