diff options
author | Ammar Askar <ammar@ammaraskar.com> | 2024-02-16 21:17:30 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-16 21:17:30 (GMT) |
commit | 8b776e0f41d7711f3e2be2435bf85f2d5fa6e009 (patch) | |
tree | b6a933055fabe8d9ae1a8c4d9c4df41bd3bed63b | |
parent | 590319072773bd6cdcca655c420d3adb84838e96 (diff) | |
download | cpython-8b776e0f41d7711f3e2be2435bf85f2d5fa6e009.zip cpython-8b776e0f41d7711f3e2be2435bf85f2d5fa6e009.tar.gz cpython-8b776e0f41d7711f3e2be2435bf85f2d5fa6e009.tar.bz2 |
gh-85294: Handle missing arguments to @singledispatchmethod gracefully (GH-21471)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
-rw-r--r-- | Lib/functools.py | 5 | ||||
-rw-r--r-- | Lib/test/test_functools.py | 17 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2020-07-13-23-59-42.bpo-41122.8P_Brh.rst | 3 |
3 files changed, 23 insertions, 2 deletions
diff --git a/Lib/functools.py b/Lib/functools.py index ee4197b..7045be5 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -918,7 +918,6 @@ def singledispatch(func): if not args: raise TypeError(f'{funcname} requires at least ' '1 positional argument') - return dispatch(args[0].__class__)(*args, **kw) funcname = getattr(func, '__name__', 'singledispatch function') @@ -968,7 +967,11 @@ class singledispatchmethod: return _method dispatch = self.dispatcher.dispatch + funcname = getattr(self.func, '__name__', 'singledispatchmethod method') def _method(*args, **kwargs): + if not args: + raise TypeError(f'{funcname} requires at least ' + '1 positional argument') return dispatch(args[0].__class__).__get__(obj, cls)(*args, **kwargs) _method.__isabstractmethod__ = self.__isabstractmethod__ diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 7c66b90..2c814d5 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -2867,11 +2867,26 @@ class TestSingleDispatch(unittest.TestCase): def test_invalid_positional_argument(self): @functools.singledispatch - def f(*args): + def f(*args, **kwargs): pass msg = 'f requires at least 1 positional argument' with self.assertRaisesRegex(TypeError, msg): f() + msg = 'f requires at least 1 positional argument' + with self.assertRaisesRegex(TypeError, msg): + f(a=1) + + def test_invalid_positional_argument_singledispatchmethod(self): + class A: + @functools.singledispatchmethod + def t(self, *args, **kwargs): + pass + msg = 't requires at least 1 positional argument' + with self.assertRaisesRegex(TypeError, msg): + A().t() + msg = 't requires at least 1 positional argument' + with self.assertRaisesRegex(TypeError, msg): + A().t(a=1) def test_union(self): @functools.singledispatch diff --git a/Misc/NEWS.d/next/Library/2020-07-13-23-59-42.bpo-41122.8P_Brh.rst b/Misc/NEWS.d/next/Library/2020-07-13-23-59-42.bpo-41122.8P_Brh.rst new file mode 100644 index 0000000..76568d4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-13-23-59-42.bpo-41122.8P_Brh.rst @@ -0,0 +1,3 @@ +Failing to pass arguments properly to :func:`functools.singledispatchmethod` +now throws a TypeError instead of hitting an index out of bounds +internally. |