Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions Lib/test/test_extcall.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,22 @@
...
TypeError: Value after ** must be a mapping, not function

>>> class OnlyKeys:
... def keys(self):
... return ['key']
>>> h(**OnlyKeys())
Traceback (most recent call last):
...
TypeError: 'OnlyKeys' object is not subscriptable

>>> class BrokenKeys:
... def keys(self):
... return 1
>>> h(**BrokenKeys())
Traceback (most recent call last):
...
TypeError: test.test_extcall.BrokenKeys.keys() must return an iterable, not int

>>> dir(b=1, **{'b': 1})
Traceback (most recent call last):
...
Expand Down Expand Up @@ -540,6 +556,151 @@

"""

def test_errors_in_iter():
"""
>>> class A:
... def __iter__(self):
... raise exc
...
>>> def f(*args, **kwargs): pass
>>> exc = ZeroDivisionError('some error')
>>> f(*A())
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> exc = AttributeError('some error')
>>> f(*A())
Traceback (most recent call last):
...
AttributeError: some error

>>> exc = TypeError('some error')
>>> f(*A())
Traceback (most recent call last):
...
TypeError: some error
"""

def test_errors_in_next():
"""
>>> class I:
... def __iter__(self):
... return self
... def __next__(self):
... raise exc
...
>>> class A:
... def __iter__(self):
... return I()
...

>>> def f(*args, **kwargs): pass
>>> exc = ZeroDivisionError('some error')
>>> f(*A())
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> exc = AttributeError('some error')
>>> f(*A())
Traceback (most recent call last):
...
AttributeError: some error

>>> exc = TypeError('some error')
>>> f(*A())
Traceback (most recent call last):
...
TypeError: some error
"""

def test_errors_in_keys():
"""
>>> class D:
... def keys(self):
... raise exc
...
>>> def f(*args, **kwargs): pass
>>> exc = ZeroDivisionError('some error')
>>> f(**D())
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> exc = AttributeError('some error')
>>> f(**D())
Traceback (most recent call last):
...
AttributeError: some error

>>> exc = TypeError('some error')
>>> f(**D())
Traceback (most recent call last):
...
TypeError: some error
"""

def test_errors_in_keys_next():
"""
>>> class I:
... def __iter__(self):
... return self
... def __next__(self):
... raise exc
...
>>> class D:
... def keys(self):
... return I()
...
>>> def f(*args, **kwargs): pass
>>> exc = ZeroDivisionError('some error')
>>> f(**D())
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> exc = AttributeError('some error')
>>> f(**D())
Traceback (most recent call last):
...
AttributeError: some error

>>> exc = TypeError('some error')
>>> f(**D())
Traceback (most recent call last):
...
TypeError: some error
"""

def test_errors_in_getitem():
"""
>>> class D:
... def keys(self):
... return ['key']
... def __getitem__(self, key):
... raise exc
...
>>> def f(*args, **kwargs): pass
>>> exc = ZeroDivisionError('some error')
>>> f(**D())
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> exc = AttributeError('some error')
>>> f(**D())
Traceback (most recent call last):
...
AttributeError: some error

>>> exc = TypeError('some error')
>>> f(**D())
Traceback (most recent call last):
...
TypeError: some error
"""

import doctest
import unittest

Expand Down
186 changes: 186 additions & 0 deletions Lib/test/test_unpack_ex.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,22 @@
...
TypeError: 'list' object is not a mapping

>>> class OnlyKeys:
... def keys(self):
... return ['key']
>>> {**OnlyKeys()}
Traceback (most recent call last):
...
TypeError: 'OnlyKeys' object is not subscriptable

>>> class BrokenKeys:
... def keys(self):
... return 1
>>> {**BrokenKeys()}
Traceback (most recent call last):
...
TypeError: test.test_unpack_ex.BrokenKeys.keys() must return an iterable, not int

>>> len(eval("{" + ", ".join("**{{{}: {}}}".format(i, i)
... for i in range(1000)) + "}"))
1000
Expand Down Expand Up @@ -560,6 +576,176 @@

"""

def test_errors_in_iter():
"""
>>> class A:
... def __iter__(self):
... raise exc
...
>>> exc = ZeroDivisionError('some error')
>>> [*A()]
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> {*A()}
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> exc = AttributeError('some error')
>>> [*A()]
Traceback (most recent call last):
...
AttributeError: some error

>>> {*A()}
Traceback (most recent call last):
...
AttributeError: some error

>>> exc = TypeError('some error')
>>> [*A()]
Traceback (most recent call last):
...
TypeError: some error

>>> {*A()}
Traceback (most recent call last):
...
TypeError: some error
"""

def test_errors_in_next():
"""
>>> class I:
... def __iter__(self):
... return self
... def __next__(self):
... raise exc
...
>>> class A:
... def __iter__(self):
... return I()
...

>>> exc = ZeroDivisionError('some error')
>>> [*A()]
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> {*A()}
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> exc = AttributeError('some error')
>>> [*A()]
Traceback (most recent call last):
...
AttributeError: some error

>>> {*A()}
Traceback (most recent call last):
...
AttributeError: some error

>>> exc = TypeError('some error')
>>> [*A()]
Traceback (most recent call last):
...
TypeError: some error

>>> {*A()}
Traceback (most recent call last):
...
TypeError: some error
"""

def test_errors_in_keys():
"""
>>> class D:
... def keys(self):
... raise exc
...
>>> exc = ZeroDivisionError('some error')
>>> {**D()}
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> exc = AttributeError('some error')
>>> {**D()}
Traceback (most recent call last):
...
AttributeError: some error

>>> exc = TypeError('some error')
>>> {**D()}
Traceback (most recent call last):
...
TypeError: some error
"""

def test_errors_in_keys_next():
"""
>>> class I:
... def __iter__(self):
... return self
... def __next__(self):
... raise exc
...
>>> class D:
... def keys(self):
... return I()
...
>>> exc = ZeroDivisionError('some error')
>>> {**D()}
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> exc = AttributeError('some error')
>>> {**D()}
Traceback (most recent call last):
...
AttributeError: some error

>>> exc = TypeError('some error')
>>> {**D()}
Traceback (most recent call last):
...
TypeError: some error
"""

def test_errors_in_getitem():
"""
>>> class D:
... def keys(self):
... return ['key']
... def __getitem__(self, key):
... raise exc
...
>>> exc = ZeroDivisionError('some error')
>>> {**D()}
Traceback (most recent call last):
...
ZeroDivisionError: some error

>>> exc = AttributeError('some error')
>>> {**D()}
Traceback (most recent call last):
...
AttributeError: some error

>>> exc = TypeError('some error')
>>> {**D()}
Traceback (most recent call last):
...
TypeError: some error
"""

__test__ = {'doctests' : doctests}

def load_tests(loader, tests, pattern):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:exc:`AttributeError`\ s raised in :meth:`!keys` or :meth:`!__getitem__`
during dictionary unpacking (``{**mymapping}`` or ``func(**mymapping)``) are
no longer masked by :exc:`TypeError`.
Loading
Loading