[3.7] bpo-36492: Fix passing special keyword arguments to some functions. (GH-12637) (GH-12645)
The following arguments can be passed as keyword arguments for passing
to other function if the corresponding required argument is passed as
positional:
- "func" in functools.partialmethod(), weakref.finalize(),
profile.Profile.runcall(), cProfile.Profile.runcall(),
bdb.Bdb.runcall(), trace.Trace.runfunc() and
curses.wrapper().
- "function" in unittest.addModuleCleanup() and
unittest.TestCase.addCleanup().
- "fn" in the submit() method of concurrent.futures.ThreadPoolExecutor
and concurrent.futures.ProcessPoolExecutor.
- "callback" in contextlib.ExitStack.callback(),
contextlib.AsyncExitStack.callback() and
contextlib.AsyncExitStack.push_async_callback().
- "c" and "typeid" in multiprocessing.managers.Server.create().
- "obj" in weakref.finalize().
(cherry picked from commit 42a139ed88c487f325a241c6ee8b308b3c045975)
diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py
index 4ae8ddc..8e8d28f 100644
--- a/Lib/multiprocessing/managers.py
+++ b/Lib/multiprocessing/managers.py
@@ -351,10 +351,30 @@
finally:
self.stop_event.set()
- def create(self, c, typeid, *args, **kwds):
+ def create(*args, **kwds):
'''
Create a new shared object and return its id
'''
+ if len(args) >= 3:
+ self, c, typeid, *args = args
+ elif not args:
+ raise TypeError("descriptor 'create' of 'Server' object "
+ "needs an argument")
+ else:
+ if 'typeid' not in kwds:
+ raise TypeError('create expected at least 2 positional '
+ 'arguments, got %d' % (len(args)-1))
+ typeid = kwds.pop('typeid')
+ if len(args) >= 2:
+ self, c, *args = args
+ else:
+ if 'c' not in kwds:
+ raise TypeError('create expected at least 2 positional '
+ 'arguments, got %d' % (len(args)-1))
+ c = kwds.pop('c')
+ self, *args = args
+ args = tuple(args)
+
with self.mutex:
callable, exposed, method_to_typeid, proxytype = \
self.registry[typeid]
@@ -576,10 +596,13 @@
util.info('manager serving at %r', server.address)
server.serve_forever()
- def _create(self, typeid, *args, **kwds):
+ def _create(*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: