summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmmar Askar <ammar@ammaraskar.com>2024-02-16 21:17:30 (GMT)
committerGitHub <noreply@github.com>2024-02-16 21:17:30 (GMT)
commit8b776e0f41d7711f3e2be2435bf85f2d5fa6e009 (patch)
treeb6a933055fabe8d9ae1a8c4d9c4df41bd3bed63b
parent590319072773bd6cdcca655c420d3adb84838e96 (diff)
downloadcpython-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.py5
-rw-r--r--Lib/test/test_functools.py17
-rw-r--r--Misc/NEWS.d/next/Library/2020-07-13-23-59-42.bpo-41122.8P_Brh.rst3
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.