Calling str() on a CalledProcessError crashes if its returncode is None.
The __str__ method uses if self.returncode and self.returncode < 0 for the "died with a signal" case, and otherwise formats the return code with %d. When returncode is None, that first check is falsy, so it falls through to the %d branch, and %d can't format None, so it raises TypeError. Having the exception's own string representation blow up is a pretty bad way to fail.
import subprocess
err = subprocess.CalledProcessError(None, "cmd")
str(err) # TypeError: %d format: a real number is required, not NoneType
The fix is to check for returncode is None before the %d branch and return a plain message instead.
Found while going through devdanzin's audit of the standard library, item 9: https://gist.github.com/devdanzin/3198710e3c0128fda5e0a7b4e0768e5f
Linked PRs
Calling
str()on aCalledProcessErrorcrashes if itsreturncodeisNone.The
__str__method usesif self.returncode and self.returncode < 0for the "died with a signal" case, and otherwise formats the return code with%d. WhenreturncodeisNone, that first check is falsy, so it falls through to the%dbranch, and%dcan't formatNone, so it raisesTypeError. Having the exception's own string representation blow up is a pretty bad way to fail.The fix is to check for
returncode is Nonebefore the%dbranch and return a plain message instead.Found while going through devdanzin's audit of the standard library, item 9: https://gist.github.com/devdanzin/3198710e3c0128fda5e0a7b4e0768e5f
Linked PRs
CalledProcessError.__str__crash when returncode is None #153971