bpo-37116: Use PEP 570 syntax for positional-only parameters. (GH-13700)

This commit is contained in:
Serhiy Storchaka 2019-06-01 11:00:15 +03:00 committed by GitHub
parent 4a686504eb
commit 2085bd0877
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 126 additions and 261 deletions

View File

@ -1140,7 +1140,7 @@ variants of :func:`functools.lru_cache`::
class LRU(OrderedDict):
'Limit size, evicting the least recently looked-up key when full'
def __init__(self, maxsize=128, *args, **kwds):
def __init__(self, maxsize=128, /, *args, **kwds):
self.maxsize = maxsize
super().__init__(*args, **kwds)

View File

@ -637,7 +637,7 @@ even further by means of a small helper class::
from contextlib import ExitStack
class Callback(ExitStack):
def __init__(self, callback, *args, **kwds):
def __init__(self, callback, /, *args, **kwds):
super(Callback, self).__init__()
self.callback(callback, *args, **kwds)

View File

@ -107,7 +107,7 @@ headers.
method if it wishes to set additional attributes beyond those provided by
``BaseHeader`` itself. Such an ``init`` method should look like this::
def init(self, *args, **kw):
def init(self, /, *args, **kw):
self._myattr = kw.pop('myattr')
super().init(*args, **kw)

View File

@ -221,7 +221,7 @@ The :mod:`functools` module defines the following functions:
Returning NotImplemented from the underlying comparison function for
unrecognised types is now supported.
.. function:: partial(func, *args, **keywords)
.. function:: partial(func, /, *args, **keywords)
Return a new :ref:`partial object<partial-objects>` which when called
will behave like *func* called with the positional arguments *args*
@ -230,7 +230,7 @@ The :mod:`functools` module defines the following functions:
supplied, they extend and override *keywords*.
Roughly equivalent to::
def partial(func, *args, **keywords):
def partial(func, /, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = {**keywords, **fkeywords}
return func(*args, *fargs, **newkeywords)

View File

@ -1022,7 +1022,7 @@ Classes and functions
metatype is in use, cls will be the first element of the tuple.
.. function:: getcallargs(func, *args, **kwds)
.. function:: getcallargs(func, /, *args, **kwds)
Bind the *args* and *kwds* to the argument names of the Python function or
method *func*, as if it was called with them. For bound methods, bind also the

View File

@ -339,7 +339,7 @@ expect a function argument.
[('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]
.. function:: methodcaller(name[, args...])
.. function:: methodcaller(name, /, *args, **kwargs)
Return a callable object that calls the method *name* on its operand. If
additional arguments and/or keyword arguments are given, they will be given
@ -352,7 +352,7 @@ expect a function argument.
Equivalent to::
def methodcaller(name, *args, **kwargs):
def methodcaller(name, /, *args, **kwargs):
def caller(obj):
return getattr(obj, name)(*args, **kwargs)
return caller

View File

@ -88,7 +88,7 @@ implementation as the built-in :meth:`~str.format` method.
The :class:`Formatter` class has the following public methods:
.. method:: format(format_string, *args, **kwargs)
.. method:: format(format_string, /, *args, **kwargs)
The primary API method. It takes a format string and
an arbitrary set of positional and keyword arguments.
@ -720,7 +720,7 @@ these rules. The methods of :class:`Template` are:
The constructor takes a single argument which is the template string.
.. method:: substitute(mapping, **kwds)
.. method:: substitute(mapping={}, /, **kwds)
Performs the template substitution, returning a new string. *mapping* is
any dictionary-like object with keys that match the placeholders in the
@ -729,7 +729,7 @@ these rules. The methods of :class:`Template` are:
and there are duplicates, the placeholders from *kwds* take precedence.
.. method:: safe_substitute(mapping, **kwds)
.. method:: safe_substitute(mapping={}, /, **kwds)
Like :meth:`substitute`, except that if placeholders are missing from
*mapping* and *kwds*, instead of raising a :exc:`KeyError` exception, the

View File

@ -327,7 +327,7 @@ Additional Utility Classes and Functions
The type is roughly equivalent to the following code::
class SimpleNamespace:
def __init__(self, **kwargs):
def __init__(self, /, **kwargs):
self.__dict__.update(kwargs)
def __repr__(self):

View File

@ -848,7 +848,7 @@ Here's an example implementation:
>>> from copy import deepcopy
>>> class CopyingMock(MagicMock):
... def __call__(self, *args, **kwargs):
... def __call__(self, /, *args, **kwargs):
... args = deepcopy(args)
... kwargs = deepcopy(kwargs)
... return super(CopyingMock, self).__call__(*args, **kwargs)
@ -1042,7 +1042,7 @@ that it takes arbitrary keyword arguments (``**kwargs``) which are then passed
onto the mock constructor:
>>> class Subclass(MagicMock):
... def _get_child_mock(self, **kwargs):
... def _get_child_mock(self, /, **kwargs):
... return MagicMock(**kwargs)
...
>>> mymock = Subclass()

View File

@ -1456,7 +1456,7 @@ Test cases
.. versionadded:: 3.1
.. classmethod:: addClassCleanup(function, *args, **kwargs)
.. classmethod:: addClassCleanup(function, /, *args, **kwargs)
Add a function to be called after :meth:`tearDownClass` to cleanup
resources used during the test class. Functions will be called in reverse
@ -2313,7 +2313,7 @@ To add cleanup code that must be run even in the case of an exception, use
``addModuleCleanup``:
.. function:: addModuleCleanup(function, *args, **kwargs)
.. function:: addModuleCleanup(function, /, *args, **kwargs)
Add a function to be called after :func:`tearDownModule` to cleanup
resources used during the test class. Functions will be called in reverse

View File

@ -396,7 +396,7 @@ the referent is accessed::
import weakref
class ExtendedRef(weakref.ref):
def __init__(self, ob, callback=None, **annotations):
def __init__(self, ob, callback=None, /, **annotations):
super(ExtendedRef, self).__init__(ob, callback)
self.__counter = 0
for k, v in annotations.items():

View File

@ -941,8 +941,7 @@ Deprecated
:meth:`profile.Profile.runcall`, :meth:`cProfile.Profile.runcall`,
:meth:`bdb.Bdb.runcall`, :meth:`trace.Trace.runfunc` and
:func:`curses.wrapper`.
- *function* in :func:`unittest.addModuleCleanup` and
:meth:`unittest.TestCase.addCleanup`.
- *function* in :meth:`unittest.TestCase.addCleanup`.
- *fn* in the :meth:`~concurrent.futures.Executor.submit` method of
:class:`concurrent.futures.ThreadPoolExecutor` and
:class:`concurrent.futures.ProcessPoolExecutor`.

View File

@ -821,21 +821,12 @@ class MutableMapping(Mapping):
except KeyError:
pass
def update(*args, **kwds):
def update(self, other=(), /, **kwds):
''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F.
If E present and has a .keys() method, does: for k in E: D[k] = E[k]
If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v
In either case, this is followed by: for k, v in F.items(): D[k] = v
'''
if not args:
raise TypeError("descriptor 'update' of 'MutableMapping' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('update expected at most 1 arguments, got %d' %
len(args))
if args:
other = args[0]
if isinstance(other, Mapping):
for key in other:
self[key] = other[key]

View File

@ -32,7 +32,7 @@ class ABCMeta(type):
# external code.
_abc_invalidation_counter = 0
def __new__(mcls, name, bases, namespace, **kwargs):
def __new__(mcls, name, bases, namespace, /, **kwargs):
cls = super().__new__(mcls, name, bases, namespace, **kwargs)
# Compute set of abstract method names
abstracts = {name

View File

@ -56,7 +56,7 @@ You can create custom local objects by subclassing the local class:
>>> class MyLocal(local):
... number = 2
... def __init__(self, **kw):
... def __init__(self, /, **kw):
... self.__dict__.update(kw)
... def squared(self):
... return self.number ** 2
@ -204,7 +204,7 @@ def _patch(self):
class local:
__slots__ = '_local__impl', '__dict__'
def __new__(cls, *args, **kw):
def __new__(cls, /, *args, **kw):
if (args or kw) and (cls.__init__ is object.__init__):
raise TypeError("Initialization arguments are not supported")
self = object.__new__(cls)

View File

@ -93,16 +93,10 @@ class OrderedDict(dict):
# Individual links are kept alive by the hard reference in self.__map.
# Those hard references disappear when a key is deleted from an OrderedDict.
def __init__(*args, **kwds):
def __init__(self, other=(), /, **kwds):
'''Initialize an ordered dictionary. The signature is the same as
regular dictionaries. Keyword argument order is preserved.
'''
if not args:
raise TypeError("descriptor '__init__' of 'OrderedDict' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
try:
self.__root
except AttributeError:
@ -110,7 +104,7 @@ class OrderedDict(dict):
self.__root = root = _proxy(self.__hardroot)
root.prev = root.next = root
self.__map = {}
self.__update(*args, **kwds)
self.__update(other, **kwds)
def __setitem__(self, key, value,
dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link):
@ -413,8 +407,8 @@ def namedtuple(typename, field_names, *, rename=False, defaults=None, module=Non
_make.__func__.__doc__ = (f'Make a new {typename} object from a sequence '
'or iterable')
def _replace(_self, **kwds):
result = _self._make(_map(kwds.pop, field_names, _self))
def _replace(self, /, **kwds):
result = self._make(_map(kwds.pop, field_names, self))
if kwds:
raise ValueError(f'Got unexpected field names: {list(kwds)!r}')
return result
@ -543,7 +537,7 @@ class Counter(dict):
# http://code.activestate.com/recipes/259174/
# Knuth, TAOCP Vol. II section 4.6.3
def __init__(*args, **kwds):
def __init__(self, iterable=None, /, **kwds):
'''Create a new, empty Counter object. And if given, count elements
from an input iterable. Or, initialize the count from another mapping
of elements to their counts.
@ -554,14 +548,8 @@ class Counter(dict):
>>> c = Counter(a=4, b=2) # a new counter from keyword args
'''
if not args:
raise TypeError("descriptor '__init__' of 'Counter' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
super(Counter, self).__init__()
self.update(*args, **kwds)
self.update(iterable, **kwds)
def __missing__(self, key):
'The count of elements not in the Counter is zero.'
@ -617,7 +605,7 @@ class Counter(dict):
raise NotImplementedError(
'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
def update(*args, **kwds):
def update(self, iterable=None, /, **kwds):
'''Like dict.update() but add counts instead of replacing them.
Source can be an iterable, a dictionary, or another Counter instance.
@ -637,13 +625,6 @@ class Counter(dict):
# contexts. Instead, we implement straight-addition. Both the inputs
# and outputs are allowed to contain zero and negative counts.
if not args:
raise TypeError("descriptor 'update' of 'Counter' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
iterable = args[0] if args else None
if iterable is not None:
if isinstance(iterable, _collections_abc.Mapping):
if self:
@ -657,7 +638,7 @@ class Counter(dict):
if kwds:
self.update(kwds)
def subtract(*args, **kwds):
def subtract(self, iterable=None, /, **kwds):
'''Like dict.update() but subtracts counts instead of replacing them.
Counts can be reduced below zero. Both the inputs and outputs are
allowed to contain zero and negative counts.
@ -673,13 +654,6 @@ class Counter(dict):
-1
'''
if not args:
raise TypeError("descriptor 'subtract' of 'Counter' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
iterable = args[0] if args else None
if iterable is not None:
self_get = self.get
if isinstance(iterable, _collections_abc.Mapping):
@ -1141,7 +1115,7 @@ class UserList(_collections_abc.MutableSequence):
def count(self, item): return self.data.count(item)
def index(self, item, *args): return self.data.index(item, *args)
def reverse(self): self.data.reverse()
def sort(self, *args, **kwds): self.data.sort(*args, **kwds)
def sort(self, /, *args, **kwds): self.data.sort(*args, **kwds)
def extend(self, other):
if isinstance(other, UserList):
self.data.extend(other.data)
@ -1240,7 +1214,7 @@ class UserString(_collections_abc.Sequence):
if isinstance(sub, UserString):
sub = sub.data
return self.data.find(sub, start, end)
def format(self, *args, **kwds):
def format(self, /, *args, **kwds):
return self.data.format(*args, **kwds)
def format_map(self, mapping):
return self.data.format_map(mapping)

View File

@ -377,8 +377,7 @@ class _BaseExitStack:
return MethodType(cm_exit, cm)
@staticmethod
def _create_cb_wrapper(*args, **kwds):
callback, *args = args
def _create_cb_wrapper(callback, /, *args, **kwds):
def _exit_wrapper(exc_type, exc, tb):
callback(*args, **kwds)
return _exit_wrapper
@ -553,8 +552,7 @@ class AsyncExitStack(_BaseExitStack, AbstractAsyncContextManager):
return MethodType(cm_exit, cm)
@staticmethod
def _create_async_cb_wrapper(*args, **kwds):
callback, *args = args
def _create_async_cb_wrapper(callback, /, *args, **kwds):
async def _exit_wrapper(exc_type, exc, tb):
await callback(*args, **kwds)
return _exit_wrapper

View File

@ -962,10 +962,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
return cls
# _cls should never be specified by keyword, so start it with an
# underscore. The presence of _cls is used to detect if this
# decorator is being called with parameters or not.
def dataclass(_cls=None, *, init=True, repr=True, eq=True, order=False,
def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
unsafe_hash=False, frozen=False):
"""Returns the same class as was passed in, with dunder methods
added based on the fields defined in the class.
@ -983,12 +980,12 @@ def dataclass(_cls=None, *, init=True, repr=True, eq=True, order=False,
return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
# See if we're being called as @dataclass or @dataclass().
if _cls is None:
if cls is None:
# We're called with parens.
return wrap
# We're called as @dataclass without parens.
return wrap(_cls)
return wrap(cls)
def fields(class_or_instance):

View File

@ -273,15 +273,9 @@ class partial:
__slots__ = "func", "args", "keywords", "__dict__", "__weakref__"
def __new__(*args, **keywords):
if not args:
raise TypeError("descriptor '__new__' of partial needs an argument")
if len(args) < 2:
raise TypeError("type 'partial' takes at least one argument")
cls, func, *args = args
def __new__(cls, func, /, *args, **keywords):
if not callable(func):
raise TypeError("the first argument must be callable")
args = tuple(args)
if hasattr(func, "func"):
args = func.args + args
@ -295,10 +289,7 @@ class partial:
self.keywords = keywords
return self
def __call__(*args, **keywords):
if not args:
raise TypeError("descriptor '__call__' of partial needs an argument")
self, *args = args
def __call__(self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(*self.args, *args, **keywords)
@ -402,8 +393,7 @@ class partialmethod(object):
keywords=keywords)
def _make_unbound_method(self):
def _method(*args, **keywords):
cls_or_self, *args = args
def _method(cls_or_self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(cls_or_self, *self.args, *args, **keywords)
_method.__isabstractmethod__ = self.__isabstractmethod__

View File

@ -299,7 +299,7 @@ class IdbProxy:
self.conn = conn
self.shell = shell
def call(self, methodname, *args, **kwargs):
def call(self, methodname, /, *args, **kwargs):
##print("*** IdbProxy.call %s %s %s" % (methodname, args, kwargs))
value = self.conn.remotecall(self.oid, methodname, args, kwargs)
##print("*** IdbProxy.call %s returns %r" % (methodname, value))

View File

@ -603,7 +603,7 @@ class MethodProxy(object):
self.oid = oid
self.name = name
def __call__(self, *args, **kwargs):
def __call__(self, /, *args, **kwargs):
value = self.sockio.remotecall(self.oid, self.name, args, kwargs)
return value

View File

@ -1329,14 +1329,12 @@ def _too_many(f_name, args, kwonly, varargs, defcount, given, values):
(f_name, sig, "s" if plural else "", given, kwonly_sig,
"was" if given == 1 and not kwonly_given else "were"))
def getcallargs(*func_and_positional, **named):
def getcallargs(func, /, *positional, **named):
"""Get the mapping of arguments to values.
A dict is returned, with keys the function argument names (including the
names of the * and ** arguments, if any), and values the respective bound
values from 'positional' and 'named'."""
func = func_and_positional[0]
positional = func_and_positional[1:]
spec = getfullargspec(func)
args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec
f_name = func.__name__
@ -3027,19 +3025,19 @@ class Signature:
return self._bound_arguments_cls(self, arguments)
def bind(*args, **kwargs):
def bind(self, /, *args, **kwargs):
"""Get a BoundArguments object, that maps the passed `args`
and `kwargs` to the function's signature. Raises `TypeError`
if the passed arguments can not be bound.
"""
return args[0]._bind(args[1:], kwargs)
return self._bind(args, kwargs)
def bind_partial(*args, **kwargs):
def bind_partial(self, /, *args, **kwargs):
"""Get a BoundArguments object, that partially maps the
passed `args` and `kwargs` to the function's signature.
Raises `TypeError` if the passed arguments can not be bound.
"""
return args[0]._bind(args[1:], kwargs, partial=True)
return self._bind(args, kwargs, partial=True)
def __reduce__(self):
return (type(self),

View File

@ -80,7 +80,7 @@ def freeze_support():
#
class Namespace(object):
def __init__(self, **kwds):
def __init__(self, /, **kwds):
self.__dict__.update(kwds)
def __repr__(self):
items = list(self.__dict__.items())

View File

@ -615,13 +615,10 @@ class BaseManager(object):
util.info('manager serving at %r', server.address)
server.serve_forever()
def _create(*args, **kwds):
def _create(self, typeid, /, *args, **kwds):
'''
Create a new shared object; return the token and exposed tuple
'''
self, typeid, *args = args
args = tuple(args)
assert self._state.value == State.STARTED, 'server not yet started'
conn = self._Client(self._address, authkey=self._authkey)
try:
@ -738,7 +735,7 @@ class BaseManager(object):
)
if create_method:
def temp(self, *args, **kwds):
def temp(self, /, *args, **kwds):
util.debug('requesting creation of a shared %r object', typeid)
token, exp = self._create(typeid, *args, **kwds)
proxy = proxytype(
@ -978,7 +975,7 @@ def MakeProxyType(name, exposed, _cache={}):
dic = {}
for meth in exposed:
exec('''def %s(self, *args, **kwds):
exec('''def %s(self, /, *args, **kwds):
return self._callmethod(%r, args, kwds)''' % (meth, meth), dic)
ProxyType = type(name, (BaseProxy,), dic)
@ -1017,7 +1014,7 @@ def AutoProxy(token, serializer, manager=None, authkey=None,
#
class Namespace(object):
def __init__(self, **kwds):
def __init__(self, /, **kwds):
self.__dict__.update(kwds)
def __repr__(self):
items = list(self.__dict__.items())

View File

@ -154,7 +154,7 @@ class _PoolCache(dict):
notification is done by the use of a queue that is provided when
instantiating the cache.
"""
def __init__(self, *args, notifier=None, **kwds):
def __init__(self, /, *args, notifier=None, **kwds):
self.notifier = notifier
super().__init__(*args, **kwds)

View File

@ -302,15 +302,11 @@ class methodcaller:
"""
__slots__ = ('_name', '_args', '_kwargs')
def __init__(*args, **kwargs):
if len(args) < 2:
msg = "methodcaller needs at least one argument, the method name"
raise TypeError(msg)
self = args[0]
self._name = args[1]
def __init__(self, name, /, *args, **kwargs):
self._name = name
if not isinstance(self._name, str):
raise TypeError('method name must be a string')
self._args = args[2:]
self._args = args
self._kwargs = kwargs
def __call__(self, obj):

View File

@ -100,7 +100,7 @@ class Random(_random.Random):
self.seed(x)
self.gauss_next = None
def __init_subclass__(cls, **kwargs):
def __init_subclass__(cls, /, **kwargs):
"""Control how subclasses generate random integers.
The algorithm a subclass can use depends on the random() and/or

View File

@ -52,6 +52,8 @@ def capwords(s, sep=None):
import re as _re
from collections import ChainMap as _ChainMap
_sentinel_dict = {}
class _TemplateMetaclass(type):
pattern = r"""
%(delim)s(?:
@ -104,19 +106,11 @@ class Template(metaclass=_TemplateMetaclass):
raise ValueError('Invalid placeholder in string: line %d, col %d' %
(lineno, colno))
def substitute(*args, **kws):
if not args:
raise TypeError("descriptor 'substitute' of 'Template' object "
"needs an argument")
self, *args = args # allow the "self" keyword be passed
if len(args) > 1:
raise TypeError('Too many positional arguments')
if not args:
def substitute(self, mapping=_sentinel_dict, /, **kws):
if mapping is _sentinel_dict:
mapping = kws
elif kws:
mapping = _ChainMap(kws, args[0])
else:
mapping = args[0]
mapping = _ChainMap(kws, mapping)
# Helper function for .sub()
def convert(mo):
# Check the most common path first.
@ -131,19 +125,11 @@ class Template(metaclass=_TemplateMetaclass):
self.pattern)
return self.pattern.sub(convert, self.template)
def safe_substitute(*args, **kws):
if not args:
raise TypeError("descriptor 'safe_substitute' of 'Template' object "
"needs an argument")
self, *args = args # allow the "self" keyword be passed
if len(args) > 1:
raise TypeError('Too many positional arguments')
if not args:
def safe_substitute(self, mapping=_sentinel_dict, /, **kws):
if mapping is _sentinel_dict:
mapping = kws
elif kws:
mapping = _ChainMap(kws, args[0])
else:
mapping = args[0]
mapping = _ChainMap(kws, mapping)
# Helper function for .sub()
def convert(mo):
named = mo.group('named') or mo.group('braced')
@ -173,16 +159,7 @@ class Template(metaclass=_TemplateMetaclass):
# The field name parser is implemented in _string.formatter_field_name_split
class Formatter:
def format(*args, **kwargs):
if not args:
raise TypeError("descriptor 'format' of 'Formatter' object "
"needs an argument")
self, *args = args # allow the "self" keyword be passed
try:
format_string, *args = args # allow the "format_string" keyword be passed
except ValueError:
raise TypeError("format() missing 1 required positional "
"argument: 'format_string'") from None
def format(self, format_string, /, *args, **kwargs):
return self.vformat(format_string, args, kwargs)
def vformat(self, format_string, args, kwargs):

View File

@ -137,7 +137,7 @@ def run_python_until_end(*args, **env_vars):
err = strip_python_stderr(err)
return _PythonRunResult(rc, out, err), cmd_line
def _assert_python(expected_success, *args, **env_vars):
def _assert_python(expected_success, /, *args, **env_vars):
res, cmd_line = run_python_until_end(*args, **env_vars)
if (res.rc and expected_success) or (not res.rc and not expected_success):
res.fail(cmd_line)

View File

@ -283,7 +283,7 @@ class _Final:
__slots__ = ('__weakref__',)
def __init_subclass__(self, *args, **kwds):
def __init_subclass__(self, /, *args, **kwds):
if '_root' not in kwds:
raise TypeError("Cannot subclass special typing classes")

View File

@ -86,23 +86,10 @@ def _id(obj):
_module_cleanups = []
def addModuleCleanup(*args, **kwargs):
def addModuleCleanup(function, /, *args, **kwargs):
"""Same as addCleanup, except the cleanup items are called even if
setUpModule fails (unlike tearDownModule)."""
if args:
function, *args = args
elif 'function' in kwargs:
function = kwargs.pop('function')
import warnings
warnings.warn("Passing 'function' as keyword argument is deprecated",
DeprecationWarning, stacklevel=2)
else:
raise TypeError('addModuleCleanup expected at least 1 positional '
'argument, got %d' % (len(args)-1))
args = tuple(args)
_module_cleanups.append((function, args, kwargs))
addModuleCleanup.__text_signature__ = '(function, /, *args, **kwargs)'
def doModuleCleanups():
@ -501,22 +488,11 @@ class TestCase(object):
self._cleanups.append((function, args, kwargs))
addCleanup.__text_signature__ = '($self, function, /, *args, **kwargs)'
def addClassCleanup(*args, **kwargs):
@classmethod
def addClassCleanup(cls, function, /, *args, **kwargs):
"""Same as addCleanup, except the cleanup items are called even if
setUpClass fails (unlike tearDownClass)."""
if len(args) >= 2:
cls, function, *args = args
elif not args:
raise TypeError("descriptor 'addClassCleanup' of 'TestCase' object "
"needs an argument")
else:
raise TypeError('addClassCleanup expected at least 1 positional '
'argument, got %d' % (len(args)-1))
args = tuple(args)
cls._class_cleanups.append((function, args, kwargs))
addClassCleanup.__text_signature__ = '($cls, function, /, *args, **kwargs)'
addClassCleanup = classmethod(addClassCleanup)
def setUp(self):
"Hook method for setting up the test fixture before exercising it."

View File

@ -106,7 +106,7 @@ def _check_signature(func, mock, skipfirst, instance=False):
if sig is None:
return
func, sig = sig
def checksig(_mock_self, *args, **kwargs):
def checksig(self, /, *args, **kwargs):
sig.bind(*args, **kwargs)
_copy_func_details(func, checksig)
type(mock)._mock_check_sig = checksig
@ -243,7 +243,7 @@ def _setup_async_mock(mock):
# Mock is not configured yet so the attributes are set
# to a function and then the corresponding mock helper function
# is called when the helper is accessed similar to _setup_func.
def wrapper(attr, *args, **kwargs):
def wrapper(attr, /, *args, **kwargs):
return getattr(mock.mock, attr)(*args, **kwargs)
for attribute in ('assert_awaited',
@ -387,7 +387,7 @@ class _MockIter(object):
class Base(object):
_mock_return_value = DEFAULT
_mock_side_effect = None
def __init__(self, *args, **kwargs):
def __init__(self, /, *args, **kwargs):
pass
@ -395,7 +395,7 @@ class Base(object):
class NonCallableMock(Base):
"""A non-callable version of `Mock`"""
def __new__(cls, *args, **kw):
def __new__(cls, /, *args, **kw):
# every instance has its own class
# so we can create magic methods on the
# class without stomping on other mocks
@ -602,7 +602,7 @@ class NonCallableMock(Base):
ret.reset_mock(visited)
def configure_mock(self, **kwargs):
def configure_mock(self, /, **kwargs):
"""Set attributes on the mock through keyword arguments.
Attributes plus return values and side effects can be set on child
@ -820,10 +820,9 @@ class NonCallableMock(Base):
else:
return _call
def assert_not_called(_mock_self):
def assert_not_called(self):
"""assert that the mock was never called.
"""
self = _mock_self
if self.call_count != 0:
msg = ("Expected '%s' to not have been called. Called %s times.%s"
% (self._mock_name or 'mock',
@ -831,19 +830,17 @@ class NonCallableMock(Base):
self._calls_repr()))
raise AssertionError(msg)
def assert_called(_mock_self):
def assert_called(self):
"""assert that the mock was called at least once
"""
self = _mock_self
if self.call_count == 0:
msg = ("Expected '%s' to have been called." %
self._mock_name or 'mock')
raise AssertionError(msg)
def assert_called_once(_mock_self):
def assert_called_once(self):
"""assert that the mock was called only once.
"""
self = _mock_self
if not self.call_count == 1:
msg = ("Expected '%s' to have been called once. Called %s times.%s"
% (self._mock_name or 'mock',
@ -851,12 +848,11 @@ class NonCallableMock(Base):
self._calls_repr()))
raise AssertionError(msg)
def assert_called_with(_mock_self, *args, **kwargs):
def assert_called_with(self, /, *args, **kwargs):
"""assert that the mock was called with the specified arguments.
Raises an AssertionError if the args and keyword args passed in are
different to the last call to the mock."""
self = _mock_self
if self.call_args is None:
expected = self._format_mock_call_signature(args, kwargs)
actual = 'not called.'
@ -874,10 +870,9 @@ class NonCallableMock(Base):
raise AssertionError(_error_message()) from cause
def assert_called_once_with(_mock_self, *args, **kwargs):
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
self = _mock_self
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
@ -924,7 +919,7 @@ class NonCallableMock(Base):
) from cause
def assert_any_call(self, *args, **kwargs):
def assert_any_call(self, /, *args, **kwargs):
"""assert the mock has been called with the specified arguments.
The assert passes if the mock has *ever* been called, unlike
@ -940,7 +935,7 @@ class NonCallableMock(Base):
) from cause
def _get_child_mock(self, **kw):
def _get_child_mock(self, /, **kw):
"""Create the child mocks for attributes and return value.
By default child mocks will be the same type as the parent.
Subclasses of Mock may want to override this to customize the way
@ -1016,20 +1011,19 @@ class CallableMixin(Base):
self.side_effect = side_effect
def _mock_check_sig(self, *args, **kwargs):
def _mock_check_sig(self, /, *args, **kwargs):
# stub method that can be replaced with one with a specific signature
pass
def __call__(_mock_self, *args, **kwargs):
def __call__(self, /, *args, **kwargs):
# can't use self in-case a function / method we are mocking uses self
# in the signature
_mock_self._mock_check_sig(*args, **kwargs)
return _mock_self._mock_call(*args, **kwargs)
self._mock_check_sig(*args, **kwargs)
return self._mock_call(*args, **kwargs)
def _mock_call(_mock_self, *args, **kwargs):
self = _mock_self
def _mock_call(self, /, *args, **kwargs):
self.called = True
self.call_count += 1
@ -1840,7 +1834,7 @@ _non_defaults = {
def _get_method(name, func):
"Turns a callable object (like a mock) into a real function"
def method(self, *args, **kw):
def method(self, /, *args, **kw):
return func(self, *args, **kw)
method.__name__ = name
return method
@ -1954,7 +1948,7 @@ def _set_return_value(mock, method, name):
class MagicMixin(object):
def __init__(self, *args, **kw):
def __init__(self, /, *args, **kw):
self._mock_set_magics() # make magic work for kwargs in init
_safe_super(MagicMixin, self).__init__(*args, **kw)
self._mock_set_magics() # fix magic broken by upper level init
@ -1996,7 +1990,7 @@ class NonCallableMagicMock(MagicMixin, NonCallableMock):
class AsyncMagicMixin:
def __init__(self, *args, **kw):
def __init__(self, /, *args, **kw):
self._mock_set_async_magics() # make magic work for kwargs in init
_safe_super(AsyncMagicMixin, self).__init__(*args, **kw)
self._mock_set_async_magics() # fix magic broken by upper level init
@ -2067,7 +2061,7 @@ class AsyncMockMixin(Base):
await_args = _delegating_property('await_args')
await_args_list = _delegating_property('await_args_list')
def __init__(self, *args, **kwargs):
def __init__(self, /, *args, **kwargs):
super().__init__(*args, **kwargs)
# asyncio.iscoroutinefunction() checks _is_coroutine property to say if an
# object is a coroutine. Without this check it looks to see if it is a
@ -2084,8 +2078,7 @@ class AsyncMockMixin(Base):
code_mock.co_flags = inspect.CO_COROUTINE
self.__dict__['__code__'] = code_mock
async def _mock_call(_mock_self, *args, **kwargs):
self = _mock_self
async def _mock_call(self, /, *args, **kwargs):
try:
result = super()._mock_call(*args, **kwargs)
except (BaseException, StopIteration) as e:
@ -2110,30 +2103,27 @@ class AsyncMockMixin(Base):
return await proxy()
def assert_awaited(_mock_self):
def assert_awaited(self):
"""
Assert that the mock was awaited at least once.
"""
self = _mock_self
if self.await_count == 0:
msg = f"Expected {self._mock_name or 'mock'} to have been awaited."
raise AssertionError(msg)
def assert_awaited_once(_mock_self):
def assert_awaited_once(self):
"""
Assert that the mock was awaited exactly once.
"""
self = _mock_self
if not self.await_count == 1:
msg = (f"Expected {self._mock_name or 'mock'} to have been awaited once."
f" Awaited {self.await_count} times.")
raise AssertionError(msg)
def assert_awaited_with(_mock_self, *args, **kwargs):
def assert_awaited_with(self, /, *args, **kwargs):
"""
Assert that the last await was with the specified arguments.
"""
self = _mock_self
if self.await_args is None:
expected = self._format_mock_call_signature(args, kwargs)
raise AssertionError(f'Expected await: {expected}\nNot awaited')
@ -2148,23 +2138,21 @@ class AsyncMockMixin(Base):
cause = expected if isinstance(expected, Exception) else None
raise AssertionError(_error_message()) from cause
def assert_awaited_once_with(_mock_self, *args, **kwargs):
def assert_awaited_once_with(self, /, *args, **kwargs):
"""
Assert that the mock was awaited exactly once and with the specified
arguments.
"""
self = _mock_self
if not self.await_count == 1:
msg = (f"Expected {self._mock_name or 'mock'} to have been awaited once."
f" Awaited {self.await_count} times.")
raise AssertionError(msg)
return self.assert_awaited_with(*args, **kwargs)
def assert_any_await(_mock_self, *args, **kwargs):
def assert_any_await(self, /, *args, **kwargs):
"""
Assert the mock has ever been awaited with the specified arguments.
"""
self = _mock_self
expected = self._call_matcher((args, kwargs))
actual = [self._call_matcher(c) for c in self.await_args_list]
if expected not in actual:
@ -2174,7 +2162,7 @@ class AsyncMockMixin(Base):
'%s await not found' % expected_string
) from cause
def assert_has_awaits(_mock_self, calls, any_order=False):
def assert_has_awaits(self, calls, any_order=False):
"""
Assert the mock has been awaited with the specified calls.
The :attr:`await_args_list` list is checked for the awaits.
@ -2186,7 +2174,6 @@ class AsyncMockMixin(Base):
If `any_order` is True then the awaits can be in any order, but
they must all appear in :attr:`await_args_list`.
"""
self = _mock_self
expected = [self._call_matcher(c) for c in calls]
cause = expected if isinstance(expected, Exception) else None
all_awaits = _CallList(self._call_matcher(c) for c in self.await_args_list)
@ -2211,17 +2198,16 @@ class AsyncMockMixin(Base):
'%r not all found in await list' % (tuple(not_found),)
) from cause
def assert_not_awaited(_mock_self):
def assert_not_awaited(self):
"""
Assert that the mock was never awaited.
"""
self = _mock_self
if self.await_count != 0:
msg = (f"Expected {self._mock_name or 'mock'} to not have been awaited."
f" Awaited {self.await_count} times.")
raise AssertionError(msg)
def reset_mock(self, *args, **kwargs):
def reset_mock(self, /, *args, **kwargs):
"""
See :func:`.Mock.reset_mock()`
"""
@ -2424,7 +2410,7 @@ class _Call(tuple):
__ne__ = object.__ne__
def __call__(self, *args, **kwargs):
def __call__(self, /, *args, **kwargs):
if self._mock_name is None:
return _Call(('', args, kwargs), name='()')
@ -2439,10 +2425,10 @@ class _Call(tuple):
return _Call(name=name, parent=self, from_kall=False)
def count(self, *args, **kwargs):
def count(self, /, *args, **kwargs):
return self.__getattr__('count')(*args, **kwargs)
def index(self, *args, **kwargs):
def index(self, /, *args, **kwargs):
return self.__getattr__('index')(*args, **kwargs)
def _get_call_arguments(self):
@ -2778,7 +2764,7 @@ class PropertyMock(Mock):
Fetching a `PropertyMock` instance from an object calls the mock, with
no args. Setting it calls the mock with the value being set.
"""
def _get_child_mock(self, **kwargs):
def _get_child_mock(self, /, **kwargs):
return MagicMock(**kwargs)
def __get__(self, obj, obj_type):

View File

@ -410,14 +410,13 @@ class TestModuleCleanUp(unittest.TestCase):
class Module(object):
unittest.addModuleCleanup(cleanup, 1, 2, function='hello')
with self.assertWarns(DeprecationWarning):
with self.assertRaises(TypeError):
unittest.addModuleCleanup(function=cleanup, arg='hello')
with self.assertRaises(TypeError):
unittest.addModuleCleanup()
unittest.case.doModuleCleanups()
self.assertEqual(cleanups,
[((), {'arg': 'hello'}),
((1, 2), {'function': 'hello'})])
[((1, 2), {'function': 'hello'})])
def test_run_module_cleanUp(self):
blowUp = True

View File

@ -99,13 +99,7 @@ class WeakValueDictionary(_collections_abc.MutableMapping):
# objects are unwrapped on the way out, and we always wrap on the
# way in).
def __init__(*args, **kw):
if not args:
raise TypeError("descriptor '__init__' of 'WeakValueDictionary' "
"object needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
def __init__(self, other=(), /, **kw):
def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):
self = selfref()
if self is not None:
@ -120,7 +114,7 @@ class WeakValueDictionary(_collections_abc.MutableMapping):
self._pending_removals = []
self._iterating = set()
self.data = d = {}
self.update(*args, **kw)
self.update(other, **kw)
def _commit_removals(self):
l = self._pending_removals
@ -287,24 +281,17 @@ class WeakValueDictionary(_collections_abc.MutableMapping):
else:
return o
def update(*args, **kwargs):
if not args:
raise TypeError("descriptor 'update' of 'WeakValueDictionary' "
"object needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
dict = args[0] if args else None
def update(self, other=None, /, **kwargs):
if self._pending_removals:
self._commit_removals()
d = self.data
if dict is not None:
if not hasattr(dict, "items"):
dict = type({})(dict)
for key, o in dict.items():
if other is not None:
if not hasattr(other, "items"):
other = dict(other)
for key, o in other.items():
d[key] = KeyedRef(o, self._remove, key)
for key, o in kwargs.items():
d[key] = KeyedRef(o, self._remove, key)
if len(kwargs):
self.update(kwargs)
def valuerefs(self):
"""Return a list of weak references to the values.
@ -488,7 +475,7 @@ class WeakKeyDictionary(_collections_abc.MutableMapping):
def setdefault(self, key, default=None):
return self.data.setdefault(ref(key, self._remove),default)
def update(self, dict=None, **kwargs):
def update(self, dict=None, /, **kwargs):
d = self.data
if dict is not None:
if not hasattr(dict, "items"):