Skip to content

Commit

Permalink
bpo-44483: Fix crash in union object with bad __module__ (pythonG…
Browse files Browse the repository at this point in the history
  • Loading branch information
Fidget-Spinner authored Jun 22, 2021
1 parent bc6c12c commit adfa1ba
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
9 changes: 9 additions & 0 deletions Lib/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,15 @@ def __eq__(self, other):
with self.assertRaises(TypeError):
issubclass(list, type_)

def test_or_type_operator_with_bad_module(self):
class TypeVar:
@property
def __module__(self):
1 / 0
# Crashes in Issue44483
with self.assertRaises(ZeroDivisionError):
str | TypeVar()

def test_ellipsis_type(self):
self.assertIsInstance(Ellipsis, types.EllipsisType)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix a crash in ``types.Union`` objects when creating a union of an object
with bad ``__module__`` field.
17 changes: 14 additions & 3 deletions Objects/unionobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,17 +284,28 @@ is_new_type(PyObject *obj)
return is_typing_module(obj);
}

// Emulates short-circuiting behavior of the ``||`` operator
// while also checking negative values.
#define CHECK_RES(res) { \
int result = res; \
if (result) { \
return result; \
} \
}

// Returns 1 on true, 0 on false, and -1 on error.
static int
is_unionable(PyObject *obj)
{
if (obj == Py_None) {
return 1;
}
PyTypeObject *type = Py_TYPE(obj);
CHECK_RES(is_typevar(obj));
CHECK_RES(is_new_type(obj));
CHECK_RES(is_special_form(obj));
return (
is_typevar(obj) ||
is_new_type(obj) ||
is_special_form(obj) ||
// The following checks never fail.
PyType_Check(obj) ||
PyObject_TypeCheck(obj, &Py_GenericAliasType) ||
type == &_Py_UnionType);
Expand Down

0 comments on commit adfa1ba

Please sign in to comment.