Title: Nested multiprocessing leads to `AttributeError: is_fork_ctx` with `forkserver` or `spawn` methods · Issue #108520 · python/cpython · GitHub
Open Graph Title: Nested multiprocessing leads to `AttributeError: is_fork_ctx` with `forkserver` or `spawn` methods · Issue #108520 · python/cpython
X Title: Nested multiprocessing leads to `AttributeError: is_fork_ctx` with `forkserver` or `spawn` methods · Issue #108520 · python/cpython
Description: Bug report Checklist I am confident this is a bug in CPython, not a bug in a third-party project I have searched the CPython issue tracker, and am confident this bug has not been reported before CPython versions tested on: 3.11 Operating...
Open Graph Description: Bug report Checklist I am confident this is a bug in CPython, not a bug in a third-party project I have searched the CPython issue tracker, and am confident this bug has not been reported before CP...
X Description: Bug report Checklist I am confident this is a bug in CPython, not a bug in a third-party project I have searched the CPython issue tracker, and am confident this bug has not been reported before CP...
Opengraph URL: https://github.com/python/cpython/issues/108520
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Nested multiprocessing leads to `AttributeError: is_fork_ctx` with `forkserver` or `spawn` methods","articleBody":"# Bug report\n\n### Checklist\n\n- [X] I am confident this is a bug in CPython, not a bug in a third-party project\n- [X] I have searched the [CPython issue tracker](https://github.com/python/cpython/issues?q=is%3Aissue+sort%3Acreated-desc),\nand am confident this bug has not been reported before\n\n\n### CPython versions tested on:\n\n3.11\n\n### Operating systems tested on:\n\nLinux\n\n### Output from running 'python -VV' on the command line:\n\nPython 3.11.5 (main, Aug 26 2023, 00:26:34) [GCC 12.2.1 20220924]\n\n### A clear and concise description of the bug:\n\nUsing nested `multiprocessing` (i.e. spawn a child process inside a child process) is broken as of Python 3.11.5, leading to an attribute error.\n\n```python\nProcess Process-1:\nTraceback (most recent call last):\n File \"/usr/local/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n self.run()\n File \"/usr/local/lib/python3.11/multiprocessing/process.py\", line 108, in run\n self._target(*self._args, **self._kwargs)\n File \"/io/pyi_multiprocessing_nested_process.py\", line 15, in process_function\n process.start()\n File \"/usr/local/lib/python3.11/multiprocessing/process.py\", line 121, in start\n self._popen = self._Popen(self)\n ^^^^^^^^^^^^^^^^^\n File \"/usr/local/lib/python3.11/multiprocessing/context.py\", line 224, in _Popen\n return _default_context.get_context().Process._Popen(process_obj)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/usr/local/lib/python3.11/multiprocessing/context.py\", line 288, in _Popen\n return Popen(process_obj)\n ^^^^^^^^^^^^^^^^^^\n File \"/usr/local/lib/python3.11/multiprocessing/popen_spawn_posix.py\", line 32, in __init__\n super().__init__(process_obj)\n File \"/usr/local/lib/python3.11/multiprocessing/popen_fork.py\", line 19, in __init__\n self._launch(process_obj)\n File \"/usr/local/lib/python3.11/multiprocessing/popen_spawn_posix.py\", line 47, in _launch\n reduction.dump(process_obj, fp)\n File \"/usr/local/lib/python3.11/multiprocessing/reduction.py\", line 60, in dump\n ForkingPickler(file, protocol).dump(obj)\n File \"/usr/local/lib/python3.11/multiprocessing/synchronize.py\", line 106, in __getstate__\n if self.is_fork_ctx:\n ^^^^^^^^^^^^^^^^\nAttributeError: 'Lock' object has no attribute 'is_fork_ctx'\nResults: [1]\n```\n\nMinimal code example below. Invoke with argument `fork`, `forkserver` or `spawn`. `fork` will work. `forkserver` and `spawn` will both raise the above error. All three variants work with Python 3.11.4.\n\n```python\nimport sys\nimport multiprocessing\n\n\ndef nested_process_function(queue):\n print(\"Running nested sub-process!\")\n queue.put(2)\n\n\ndef process_function(queue):\n print(\"Running sub-process!\")\n queue.put(1)\n\n process = multiprocessing.Process(target=nested_process_function, args=(queue,))\n process.start()\n process.join()\n\n\ndef main(start_method):\n multiprocessing.set_start_method(start_method)\n queue = multiprocessing.Queue()\n\n process = multiprocessing.Process(target=process_function, args=(queue,))\n process.start()\n process.join()\n\n results = []\n while not queue.empty():\n results.append(queue.get())\n\n print(f\"Results: {results}\")\n assert results == [1, 2]\n\n\nif __name__ == '__main__':\n if len(sys.argv) != 2:\n raise SystemExit(f\"Usage: {sys.argv[0]} fork|forkserver|spawn\")\n\n main(sys.argv[1])\n```\n\nI believe that the source of this regression is https://github.com/python/cpython/commit/34ef75d3ef559288900fad008f05b29155eb8b59 which adds the attribute `is_fork_ctx` to `multiprocessing.Lock()` but doesn't update the pickle methods (`__getstate__()` and `__setstate__()`) so after being serialised and deserialised, the `Lock()` object looses that attribute.\n\nThe following patch, adding `is_fork_ctx` to the pickle methods, makes the above work again.\n```diff\ndiff --git a/Lib/multiprocessing/synchronize.py b/Lib/multiprocessing/synchronize.py\nindex 2328d33212..9c5c2aada6 100644\n--- a/Lib/multiprocessing/synchronize.py\n+++ b/Lib/multiprocessing/synchronize.py\n@@ -109,10 +109,11 @@ def __getstate__(self):\n 'not supported. Please use the same context to create '\n 'multiprocessing objects and Process.')\n h = sl.handle\n- return (h, sl.kind, sl.maxvalue, sl.name)\n+ return (h, sl.kind, sl.maxvalue, sl.name, self.is_fork_ctx)\n \n def __setstate__(self, state):\n- self._semlock = _multiprocessing.SemLock._rebuild(*state)\n+ self._semlock = _multiprocessing.SemLock._rebuild(*state[:4])\n+ self.is_fork_ctx = state[4]\n util.debug('recreated blocker with handle %r' % state[0])\n self._make_methods()\n```\n\n```[tasklist]\n### Tasks\n```\n\n\n\u003c!-- gh-linked-prs --\u003e\n### Linked PRs\n* gh-108568\n* gh-108691\n* gh-108692\n\u003c!-- /gh-linked-prs --\u003e\n","author":{"url":"https://github.com/bwoodsend","@type":"Person","name":"bwoodsend"},"datePublished":"2023-08-26T18:14:50.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":9},"url":"https://github.com/108520/cpython/issues/108520"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:54c41f18-92de-11b5-6531-7bd11b854f7a |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 99CA:4D95E:852F03:BC2FC4:696A15B3 |
| html-safe-nonce | caf32b7689d1251b9d3a2cd515db21de1f2ad1ea6d54efb42d06f11315968d2a |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5OUNBOjREOTVFOjg1MkYwMzpCQzJGQzQ6Njk2QTE1QjMiLCJ2aXNpdG9yX2lkIjoiMTY1NzEyMTU4NTcwMjI0NTgxMSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 623f1783d5cb3d89c0ec84bb6b3dd8df67de65c1b3c8f5faf6979f026995aa19 |
| hovercard-subject-tag | issue:1868196368 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/cpython/108520/issue_layout |
| twitter:image | https://opengraph.githubassets.com/b277208a927aeb13d89cab715c15fa98cecb343fa7aaa3dd81397d726fb68aa7/python/cpython/issues/108520 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/b277208a927aeb13d89cab715c15fa98cecb343fa7aaa3dd81397d726fb68aa7/python/cpython/issues/108520 |
| og:image:alt | Bug report Checklist I am confident this is a bug in CPython, not a bug in a third-party project I have searched the CPython issue tracker, and am confident this bug has not been reported before CP... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | bwoodsend |
| hostname | github.com |
| expected-hostname | github.com |
| None | 34a52bd10bd674f68e5c1b6b74413b79bf2ca20c551055ace3f7cdd112803923 |
| turbo-cache-control | no-preview |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | e8bd37502700f365b18a4d39acf7cb7947e11b1a |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width