diff -r 3a880d640981 Lib/concurrent/futures/process.py --- a/Lib/concurrent/futures/process.py Tue Sep 18 07:21:18 2012 +0300 +++ b/Lib/concurrent/futures/process.py Tue Sep 18 16:58:33 2012 +0100 @@ -382,7 +382,25 @@ p.start() self._processes[p.pid] = p - def submit(self, fn, *args, **kwargs): + def submit(*args, **kwargs): + # Do manual processing of arguments in order to allow 'self' and 'fn' + # as keyword argument names. + if args: + self, *args = args + elif 'self' in kwargs: + self = kwargs.pop('self') + else: + raise TypeError( + "submit() missing required positional argument: 'self'") + + if args: + fn, *args = args + elif 'fn' in kwargs: + fn = kwargs.pop('fn') + else: + raise TypeError( + "submit() missing required positional argument: 'fn'") + with self._shutdown_lock: if self._broken: raise BrokenProcessPool('A child process terminated ' diff -r 3a880d640981 Lib/concurrent/futures/thread.py --- a/Lib/concurrent/futures/thread.py Tue Sep 18 07:21:18 2012 +0300 +++ b/Lib/concurrent/futures/thread.py Tue Sep 18 16:58:33 2012 +0100 @@ -91,7 +91,25 @@ self._shutdown = False self._shutdown_lock = threading.Lock() - def submit(self, fn, *args, **kwargs): + def submit(*args, **kwargs): + # Do manual processing of arguments in order to allow 'self' and 'fn' + # as keyword argument names. + if args: + self, *args = args + elif 'self' in kwargs: + self = kwargs.pop('self') + else: + raise TypeError( + "submit() missing required positional argument: 'self'") + + if args: + fn, *args = args + elif 'fn' in kwargs: + fn = kwargs.pop('fn') + else: + raise TypeError( + "submit() missing required positional argument: 'fn'") + with self._shutdown_lock: if self._shutdown: raise RuntimeError('cannot schedule new futures after shutdown') diff -r 3a880d640981 Lib/test/test_concurrent_futures.py --- a/Lib/test/test_concurrent_futures.py Tue Sep 18 07:21:18 2012 +0300 +++ b/Lib/test/test_concurrent_futures.py Tue Sep 18 16:58:33 2012 +0100 @@ -42,6 +42,10 @@ return x * y +def awkward(*, fn): + return fn * 13 + + def sleep_and_raise(t): time.sleep(t) raise Exception('this is an exception') @@ -396,6 +400,10 @@ self.executor.map(str, [2] * (self.worker_count + 1)) self.executor.shutdown() + def test_awkward_keyword_name(self): + future = self.executor.submit(awkward, fn=7) + self.assertEqual(future.result(), 91) + class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest): def test_map_submits_without_iteration(self):