Issue 24190: Add inspect.BoundArguments.apply_defaults() method.
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index 444d2be..3ee177d 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -667,27 +667,8 @@
 
          Arguments for which :meth:`Signature.bind` or
          :meth:`Signature.bind_partial` relied on a default value are skipped.
-         However, if needed, it is easy to include them.
-
-      ::
-
-        >>> def foo(a, b=10):
-        ...     pass
-
-        >>> sig = signature(foo)
-        >>> ba = sig.bind(5)
-
-        >>> ba.args, ba.kwargs
-        ((5,), {})
-
-        >>> for param in sig.parameters.values():
-        ...     if (param.name not in ba.arguments
-        ...             and param.default is not param.empty):
-        ...         ba.arguments[param.name] = param.default
-
-        >>> ba.args, ba.kwargs
-        ((5, 10), {})
-
+         However, if needed, use :meth:`BoundArguments.apply_defaults` to add
+         them.
 
    .. attribute:: BoundArguments.args
 
@@ -703,6 +684,24 @@
 
       A reference to the parent :class:`Signature` object.
 
+   .. method:: BoundArguments.apply_defaults()
+
+      Set default values for missing arguments.
+
+      For variable-positional arguments (``*args``) the default is an
+      empty tuple.
+
+      For variable-keyword arguments (``**kwargs``) the default is an
+      empty dict.
+
+      ::
+
+        >>> def foo(a, b='ham', *args): pass
+        >>> ba = inspect.signature(foo).bind('spam')
+        >>> ba.apply_defaults()
+        >>> ba.arguments
+        OrderedDict([('a', 'spam'), ('b', 'ham'), ('args', ())])
+
    The :attr:`args` and :attr:`kwargs` properties can be used to invoke
    functions::
 
diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst
index 7c845cd..92e1142 100644
--- a/Doc/whatsnew/3.5.rst
+++ b/Doc/whatsnew/3.5.rst
@@ -400,6 +400,9 @@
   picklable and hashable.  (Contributed by Yury Selivanov in :issue:`20726`
   and :issue:`20334`.)
 
+* New method :meth:`inspect.BoundArguments.apply_defaults`.  (Contributed
+  by Yury Selivanov in :issue:`24190`.)
+
 * New class method :meth:`inspect.Signature.from_callable`, which makes
   subclassing of :class:`~inspect.Signature` easier.  (Contributed
   by Yury Selivanov and Eric Snow in :issue:`17373`.)
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 9389f3b..8d2920a 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -2443,6 +2443,36 @@
 
         return kwargs
 
+    def apply_defaults(self):
+        """Set default values for missing arguments.
+
+        For variable-positional arguments (*args) the default is an
+        empty tuple.
+
+        For variable-keyword arguments (**kwargs) the default is an
+        empty dict.
+        """
+        arguments = self.arguments
+        if not arguments:
+            return
+        new_arguments = []
+        for name, param in self._signature.parameters.items():
+            try:
+                new_arguments.append((name, arguments[name]))
+            except KeyError:
+                if param.default is not _empty:
+                    val = param.default
+                elif param.kind is _VAR_POSITIONAL:
+                    val = ()
+                elif param.kind is _VAR_KEYWORD:
+                    val = {}
+                else:
+                    # This BoundArguments was likely produced by
+                    # Signature.bind_partial().
+                    continue
+                new_arguments.append((name, val))
+        self.arguments = OrderedDict(new_arguments)
+
     def __eq__(self, other):
         return (self is other or
                     (issubclass(other.__class__, BoundArguments) and
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index bed3bad..e712efb 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -3153,6 +3153,41 @@
         ba = sig.bind(20, 30, z={})
         self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
 
+    def test_signature_bound_arguments_apply_defaults(self):
+        def foo(a, b=1, *args, c:1={}, **kw): pass
+        sig = inspect.signature(foo)
+
+        ba = sig.bind(20)
+        ba.apply_defaults()
+        self.assertEqual(
+            list(ba.arguments.items()),
+            [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
+
+        # Make sure that we preserve the order:
+        # i.e. 'c' should be *before* 'kw'.
+        ba = sig.bind(10, 20, 30, d=1)
+        ba.apply_defaults()
+        self.assertEqual(
+            list(ba.arguments.items()),
+            [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
+
+        # Make sure that BoundArguments produced by bind_partial()
+        # are supported.
+        def foo(a, b): pass
+        sig = inspect.signature(foo)
+        ba = sig.bind_partial(20)
+        ba.apply_defaults()
+        self.assertEqual(
+            list(ba.arguments.items()),
+            [('a', 20)])
+
+        # Test no args
+        def foo(): pass
+        sig = inspect.signature(foo)
+        ba = sig.bind()
+        ba.apply_defaults()
+        self.assertEqual(list(ba.arguments.items()), [])
+
 
 class TestSignaturePrivateHelpers(unittest.TestCase):
     def test_signature_get_bound_param(self):
diff --git a/Misc/NEWS b/Misc/NEWS
index 46da169..95c5332 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -131,6 +131,9 @@
 - Issue 22547: Implement informative __repr__ for inspect.BoundArguments.
   Contributed by Yury Selivanov.
 
+- Issue 24190: Implement inspect.BoundArgument.apply_defaults() method.
+  Contributed by Yury Selivanov.
+
 Tests
 -----