Anton Bryzgalov <tony.bryzgal...@gmail.com> added the comment:
Example code (also is attached to the issue): import asyncio async def count_smth(seconds: int) -> int: await asyncio.sleep(seconds) return seconds * 3 async def small_job(d: dict, key: str, seconds: int) -> None: d[key] += await count_smth(seconds) # <-- strange happens here async def main() -> None: d = dict(key=0) await asyncio.gather( small_job(d, 'key', 1), small_job(d, 'key', 2), ) print(d['key']) # expected: 0 + 1 * 3 + 2 * 3 = 9, actual: 6 if __name__ == '__main__': asyncio.run(main()) Expected output: 0 + 1 * 3 + 2 * 3 = 9. Actual: 6. Seems to be a race condition. Same happens for other immutable types: str, tuple (when used as values of dict instead of int). But works correctly with list and custom class with __iadd__ method. Same effect for treading version (output is the same): import time import threading def count_smth(seconds: int) -> int: time.sleep(seconds) return seconds * 3 def small_job(d: dict, key: str, seconds: int) -> None: d[key] += count_smth(seconds) # <-- strange happens here def main() -> None: d = dict(key=0) t1 = threading.Thread(target=small_job, args=(d, 'key', 1)) t2 = threading.Thread(target=small_job, args=(d, 'key', 2)) t1.start() t2.start() t1.join() t2.join() print(d['key']) # expected: 0 + 1 * 3 + 2 * 3 = 9, actual: 6 main() Inplace operation is expected to occur only at the time when the second operand is evaluated. ---------- Added file: https://bugs.python.org/file48718/inplace_bug_threading.py _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue38817> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com