cp -rf py2.7/examples .
cp -rf py2.7/doc .
cp -f py2.7/index.html .
cp -rf pypy2.7-v7.3.4-src/pypy/module/_multiprocessing module/_multiprocess
cp -rf pypy2.7-v7.3.4-src/lib-python/2.7/multiprocessing multiprocess
cp -rf pypy2.7-v7.3.4-src/lib-python/2.7/test/test_multiprocessing.py multiprocess/tests/__init__.py
cp -rf pypy2.7-v7.3.4-src/lib-python/2.7/test/mp_*py multiprocess/tests
cp -f py2.7/multiprocess/tests/__main__.py multiprocess/tests
cp -rf py3.7/_multiprocess _multiprocess
# ----------------------------------------------------------------------
EDIT multiprocess/__init__: __version__ 
EDIT multiprocess: multiprocessing --> multiprocess
EDIT multiprocess: pickle --> dill
EDIT multiprocess/dummy: multiprocessing --> multiprocess
EDIT multiprocess/tests: multiprocessing --> multiprocess
ADDED *args, **kwds for ForkingPickler in __init__ and dump
# ----------------------------------------------------------------------
diff py2.7/multiprocess/forking.py pypy2.7/multiprocess/forking.py
83,91c83,88
< def _reduce_method_descriptor(m):
<     return getattr, (m.__objclass__, m.__name__)
< ForkingPickler.register(type(list.append), _reduce_method_descriptor)
< ForkingPickler.register(type(int.__add__), _reduce_method_descriptor)
< 
< #def _reduce_builtin_function_or_method(m):
< #    return getattr, (m.__self__, m.__name__)
< #ForkingPickler.register(type(list().append), _reduce_builtin_function_or_method)
< #ForkingPickler.register(type(int().__add__), _reduce_builtin_function_or_method)
---
> if type(list.append) is not type(ForkingPickler.save):
>     # Some python implementations have unbound methods even for builtin types
>     def _reduce_method_descriptor(m):
>         return getattr, (m.__objclass__, m.__name__)
>     ForkingPickler.register(type(list.append), _reduce_method_descriptor)
>     ForkingPickler.register(type(int.__add__), _reduce_method_descriptor)
diff py2.7/multiprocess/heap.py pypy2.7/multiprocess/heap.py
71c71
<             assert win32.GetLastError() == 0, 'tagname already in use'
---
>             #assert win32.GetLastError() == 0, 'tagname already in use'
81c81
<             assert win32.GetLastError() == win32.ERROR_ALREADY_EXISTS
---
>             #assert win32.GetLastError() == win32.ERROR_ALREADY_EXISTS
diff py2.7/multiprocess/managers.py pypy2.7/multiprocess/managers.py
485a486,489
>     def __reduce__(self):
>         return type(self).from_address, \
>                (self._address, self._authkey, self._serializer)
> 
diff py2.7/multiprocess/synchronize.py pypy2.7/multiprocess/synchronize.py
58c58
< except ImportError:
---
> except (ImportError):
Common subdirectories: py2.7/multiprocess/tests and pypy2.7/multiprocess/tests
diff py2.7/multiprocess/util.py pypy2.7/multiprocess/util.py
41,44c41
< try:
<     from subprocess import _args_from_interpreter_flags
< except ImportError:
<     _args_from_interpreter_flags = lambda :[]
---
> from subprocess import _args_from_interpreter_flags
# ----------------------------------------------------------------------
diff py2.7/multiprocess/tests/__init__.py pypy2.7/multiprocess/tests/__init__.py
4a5,9
> ## FIXME: remove when https://bugs.pypy.org/issue1644 is resolved
> import sys
> if sys.platform.startswith('freebsd'):
>     raise Exception("This test hangs on FreeBSD. Test deactivated for now until https://bugs.pypy.org/issue1644 get resolved")
> 
16a22
> import weakref
18c24
< from test import test_support as support
---
> from test import support
20c26,29
< _multiprocessing = support.import_module('_multiprocess')
---
> try: #XXX
>     _multiprocessing = support.import_module('_multiprocess')
> except unittest.SkipTest:
>     _multiprocessing = support.import_module('_multiprocessing')
177a187,192
> class DummyCallable(object):
>     def __call__(self, q, c):
>         assert isinstance(c, DummyCallable)
>         q.put(5)
> 
> 
357a373,385
>     def test_lose_target_ref(self):
>         c = DummyCallable()
>         wr = weakref.ref(c)
>         q = self.Queue()
>         p = self.Process(target=c, args=(q, c))
>         del c
>         p.start()
>         p.join()
>         support.gc_collect()
>         self.assertIs(wr(), None)
>         self.assertEqual(q.get(), 5)
> 
> 
635d662
<                     del q
644a672,687
>     def test_queue_feeder_donot_stop_onexc(self):
>         # bpo-30414: verify feeder handles exceptions correctly
>         if self.TYPE != 'processes':
>             self.skipTest('test not appropriate for {}'.format(self.TYPE))
> 
>         class NotSerializable(object):
>             def __reduce__(self):
>                 raise AttributeError
>         with test.support.captured_stderr():
>             q = self.Queue()
>             q.put(NotSerializable())
>             q.put(True)
>             # bpo-30595: use a timeout of 1 second for slow buildbots
>             self.assertTrue(q.get(timeout=1.0))
> 
> 
1156a1200,1212
> def identity(x):
>     return x
> 
> class CountedObject(object):
>     n_instances = 0
> 
>     def __new__(cls):
>         cls.n_instances += 1
>         return object.__new__(cls)
> 
>     def __del__(self):
>         type(self).n_instances -= 1
> 
1301a1358,1373
>     def test_release_task_refs(self):
>         # Issue #29861: task arguments and results should not be kept
>         # alive after we are done with them.
>         objs = list(CountedObject() for i in range(10))
>         refs = list(weakref.ref(o) for o in objs)
>         self.pool.map(identity, objs)
> 
>         del objs
>         support.gc_collect()
>         time.sleep(DELTA)  # let threaded cleanup code run
>         self.assertEqual(set(wr() for wr in refs), {None})
>         # With a process pool, copies of the objects are returned, check
>         # they were released too.
>         self.assertEqual(CountedObject.n_instances, 0)
> 
> 
1303c1375,1377
<     return lambda: 42
---
>     class C:
>         pass
>     return C
1521c1595
<         self.assertRaises(Exception, queue.put, time.sleep)
---
>         self.assertRaises(Exception, queue.put, object)
1553a1628
>         support.gc_collect()
1554a1630
> 
1576c1652
<     def test_connection(self):
---
>     def _test_connection(self): #XXX
1749a1826
>         self.addCleanup(support.unlink, support.TESTFN)
1774a1852
>         self.addCleanup(support.unlink, support.TESTFN)
1955a2034,2037
>             # XXX There should be a better way to release resources for a
>             # single block
>             if i % maxblocks == 0:
>                 import gc; gc.collect()
1991,1993c2073,2076
<         thresholds = gc.get_threshold()
<         self.addCleanup(gc.set_threshold, *thresholds)
<         gc.set_threshold(10)
---
>         if support.check_impl_detail(cpython=True):
>             thresholds = gc.get_threshold()
>             self.addCleanup(gc.set_threshold, *thresholds)
>             gc.set_threshold(10)
2055a2139
>     @unittest.skipUnless(support.check_impl_detail(pypy=False), "pypy ctypes differences")
2071a2156,2163
>     def setUp(self):
>         self.registry_backup = util._finalizer_registry.copy()
>         util._finalizer_registry.clear()
> 
>     def tearDown(self):
>         self.assertFalse(util._finalizer_registry)
>         util._finalizer_registry.update(self.registry_backup)
> 
2079a2172
>         support.gc_collect()
2120a2214,2269
>     def test_thread_safety(self):
>         # bpo-24484: _run_finalizers() should be thread-safe
>         def cb():
>             pass
> 
>         class Foo(object):
>             def __init__(self):
>                 self.ref = self  # create reference cycle
>                 # insert finalizer at random key
>                 util.Finalize(self, cb, exitpriority=random.randint(1, 100))
> 
>         finish = False
>         exc = []
> 
>         def run_finalizers():
>             while not finish:
>                 time.sleep(random.random() * 1e-1)
>                 try:
>                     # A GC run will eventually happen during this,
>                     # collecting stale Foo's and mutating the registry
>                     util._run_finalizers()
>                 except Exception as e:
>                     exc.append(e)
> 
>         def make_finalizers():
>             d = {}
>             while not finish:
>                 try:
>                     # Old Foo's get gradually replaced and later
>                     # collected by the GC (because of the cyclic ref)
>                     d[random.getrandbits(5)] = {Foo() for i in range(10)}
>                 except Exception as e:
>                     exc.append(e)
>                     d.clear()
> 
>         old_interval = sys.getcheckinterval()
>         if support.check_impl_detail(cpython=True):
>             old_threshold = gc.get_threshold()
>         try:
>             sys.setcheckinterval(10)
>             if support.check_impl_detail(cpython=True):
>                 gc.set_threshold(5, 5, 5)
>             threads = [threading.Thread(target=run_finalizers),
>                        threading.Thread(target=make_finalizers)]
>             with support.start_threads(threads):
>                 time.sleep(4.0)  # Wait a bit to trigger race condition
>                 finish = True
>             if exc:
>                 raise exc[0]
>         finally:
>             sys.setcheckinterval(old_interval)
>             if support.check_impl_detail(cpython=True):
>                 gc.set_threshold(*old_threshold)
>             gc.collect()  # Collect remaining Foo's
> 
> 
2505c2654
<     def _test_noforkbomb(self):
---
>     def test_noforkbomb(self):
Only in pypy2.7/multiprocess/tests: mp_fork_bomb.py
