As noted in a code review (#49 (comment)), it is confusing to reason about how the sync/async _[a]get_by_metadata code paths. __contains__ only uses the synchronous _get_by_metadata as it does not need ever intiailize objects, where as aget/get need to be conscious of which _aget_by_metadata method they use.
A possible refactor could be to convert _get_by_metadata and _aget_by_metadata into the following methods:
_get_by_metadata - only gets by metadata if present, never sets by metdata
- _set_by_metatdata` - only sets metadata for synchronous objects, throws on async objects
aysnc _aset_by_metadata - sets metadata for async objects or sync objects using asyncio.to_thread
This would be a clearer split between what code paths need to be split into async and sync (creating new objects) and what code paths can be shared between async / sync code (getting / checking for existence of objects).
As noted in a code review (#49 (comment)), it is confusing to reason about how the
sync/async_[a]get_by_metadatacode paths.__contains__only uses the synchronous_get_by_metadataas it does not need ever intiailize objects, where asaget/getneed to be conscious of which_aget_by_metadatamethod they use.A possible refactor could be to convert
_get_by_metadataand_aget_by_metadatainto the following methods:_get_by_metadata- only gets by metadata if present, never sets by metdataaysnc _aset_by_metadata- sets metadata for async objects or sync objects usingasyncio.to_threadThis would be a clearer split between what code paths need to be split into async and sync (creating new objects) and what code paths can be shared between async / sync code (getting / checking for existence of objects).