michaelkryukov / mongomock_motor

Library for mocking AsyncIOMotorClient built on top of mongomock.
MIT License
94 stars 23 forks source link

RecursionError: maximum recursion depth exceeded while calling a Python object #49

Closed gbtami closed 4 months ago

gbtami commented 4 months ago

In my chess variant server project I'm working in a branch https://github.com/gbtami/pychess-variants/tree/resume-games where I save every move taken in a game immediately into the mongodb database. Unfortunately the game play unit test using mongomock_motor is failing because it tests all the variants via playing a random game (almost 50) and it wraps every game collection access get_collection() using _patch_collection_internals() again and again and again ... leading to the following error:

tamas@tami:~/pychess-variants$ PYTHONPATH=server python3 tests/test.py 
Variant 'grandhouse' already exists.
Variant 'gothhouse' already exists.
Variant 'embassyhouse' already exists.
Variant 'gorogoroplus' already exists.
Variant 'shogun' already exists.
Variant 'orda' already exists.
Variant 'synochess' already exists.
Variant 'shinobi' already exists.
Variant 'shinobiplus' already exists.
Variant 'ordamirror' already exists.
Variant 'empire' already exists.
Variant 'chak' already exists.
Variant 'chennis' already exists.
Variant 'mansindam' already exists.
test_ratings (__main__.FirstRatedGameTestCase.test_ratings) ... /home/tamas/.local/lib/python3.11/site-packages/aiohttp/web_urldispatcher.py:192: DeprecationWarning: Bare functions are deprecated, use async ones
  warnings.warn(
notify_tournament None **orda** 3+4 tournament starts in **3** hours! https://www.pychess.org/tournament/zQ8pbZGg
ok
test_game_play (__main__.GamePlayTestCase.test_game_play)
Playtest test_player vs Random-Mover ... notify_tournament None **orda** 3+4 tournament starts in **3** hours! https://www.pychess.org/tournament/rvvyzK0i
0 chess
1 chess960
2 crazyhouse
3 crazyhouse960
4 atomic
5 atomic960
6 kingofthehill
7 kingofthehill960
8 3check
9 3check960
ERROR:game:ERROR: Exception in game CYpVfqEN play_move() d7c7
Traceback (most recent call last):
  File "/home/tamas/pychess-variants/server/game.py", line 402, in play_move
    await self.save_moves()
  File "/home/tamas/pychess-variants/server/game.py", line 445, in save_moves
    await self.app_state.db.game.find_one_and_update({"_id": self.id}, {"$set": new_data})
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock_motor/__init__.py", line 43, in wrapper
    return getattr(proxy_source, method_name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/collection.py", line 1309, in find_one_and_update
    return self._find_and_modify(filter, projection, update, upsert,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/collection.py", line 1339, in _find_and_modify
    old = self.find_one(query, projection=projection, sort=sort)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/collection.py", line 1287, in find_one
    return next(self.find(filter, *args, **kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/collection.py", line 1888, in __next__
    doc = self._compute_results(with_limit_and_skip=True)[self._emitted]
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/collection.py", line 1866, in _compute_results
    results = list(self._factory())
              ^^^^^^^^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/collection.py", line 1039, in _get_dataset
    dataset = self._iter_documents(spec)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock_motor/patches.py", line 95, in iter_documents
    return _iter_documents(_normalize_strings(filter))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock_motor/patches.py", line 95, in iter_documents
    return _iter_documents(_normalize_strings(filter))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock_motor/patches.py", line 95, in iter_documents
    return _iter_documents(_normalize_strings(filter))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  [Previous line repeated 957 more times]
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/collection.py", line 1275, in _iter_documents
    return (document for document in list(self._store.documents)
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/store.py", line 133, in documents
    with self._rwlock.reader():
  File "/usr/lib/python3.11/contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/thread.py", line 21, in reader
    self._reader_acquire()
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/thread.py", line 43, in _reader_acquire
    self._read_switch.acquire(self._no_writers)
  File "/home/tamas/.local/lib/python3.11/site-packages/mongomock/thread.py", line 84, in acquire
    self._mutex.acquire()
RecursionError: maximum recursion depth exceeded while calling a Python object

To fix this error I moved calling _patch_collection_internals() to AsyncMongoMockCollection.__init__ like this: https://github.com/michaelkryukov/mongomock_motor/pull/50

But. mongomock_motor own unit tests are OK if you run them one by one, but fails if you run them all at once, like your github workflow does. Any idea how to resolve this?

gbtami commented 4 months ago

May I ask you to create a new release to pypi please?

gbtami commented 4 months ago

Thx!