diff -r ad92e63de42c Lib/inspect.py --- a/Lib/inspect.py Thu Feb 20 23:26:12 2014 +0100 +++ b/Lib/inspect.py Thu Feb 20 19:51:56 2014 -0500 @@ -1828,8 +1828,17 @@ if self_parameter is not None: assert parameters - if getattr(obj, '__self__', None) and skip_bound_arg: - # strip off self, it's already been bound + self_attr = getattr(obj, '__self__', None) + self_attr_ismod = ismodule(self_attr) + if (self_attr is not None + and (self_attr_ismod + or (not self_attr_ismod and skip_bound_arg))): + # Strip the bound argument. Couple of notes: + # + # 1. We *always* strip first bound argument if + # it is a module. + # 2. We don't strip first bound argument if + # skip_bound_arg is False. parameters.pop(0) else: # for builtins, self parameter is always positional-only! diff -r ad92e63de42c Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py Thu Feb 20 23:26:12 2014 +0100 +++ b/Lib/test/test_inspect.py Thu Feb 20 19:51:56 2014 -0500 @@ -643,6 +643,13 @@ self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, args_e=['self', 'obj'], formatted='(self, obj)') + self.assertFullArgSpecEquals( + os.stat, + args_e=['path'], + kwonlyargs_e=['dir_fd', 'follow_symlinks'], + kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True}, + formatted='(path, *, dir_fd=None, follow_symlinks=True)') + @cpython_only @unittest.skipIf(MISSING_C_DOCSTRINGS, "Signature information for builtins requires docstrings")