I don't have a simple reproduction as our codebase is stuck with graphql-core 2.x (which is a legacy branch), but we often see the garbage collector report reference cycles created by orphaned Promise objects that reference a stack trace that in turn points back to a local scope that contains the Promise.
Adding a simple destructor gets rid of this problem and allows objects to be freed without relying on the garbage collection cycles:
class Promise:
...
def __del__(self) -> None:
self._fulfillment_handler0 = None
self._rejection_handler0 = None
self._promise0 = None
self._traceback = None