Source code for music21.common.weakrefTools

# ------------------------------------------------------------------------------
# Name:         common/weakrefTools.py
# Purpose:      Utilities for weak references
#
# Authors:      Michael Scott Asato Cuthbert
#               Christopher Ariza
#
# Copyright:    Copyright © 2009-2015 Michael Scott Asato Cuthbert
# License:      BSD, see license.txt
# ------------------------------------------------------------------------------
from __future__ import annotations

__all__ = ['wrapWeakref', 'unwrapWeakref']

import typing as t
import weakref

_T = t.TypeVar('_T')
# ------------------------------------------------------------------------------


[docs] def wrapWeakref(referent: _T) -> weakref.ReferenceType|_T: ''' utility function that wraps objects as weakrefs but does not wrap already wrapped objects; also prevents wrapping the unwrappable "None" type, etc. >>> import weakref >>> class Mock: ... pass >>> a1 = Mock() >>> ref1 = common.wrapWeakref(a1) >>> ref1 <weakref at 0x101f29ae8; to ...Mock' at 0x101e45358> >>> ref2 = common.wrapWeakref(ref1) >>> ref2 <weakref at 0x101f299af; to ...Mock' at 0x101e45358> >>> ref3 = common.wrapWeakref(5) >>> ref3 5 OMIT_FROM_DOCS Note that the ...Mock was needed after Python 3.13. When 3.13 is the lowest version, replace ... with the actual output. ''' # if isinstance(referent, weakref.ReferenceType): # return referent try: return weakref.ref(referent) # if referent is None, will raise a TypeError # if referent is a weakref, will also raise a TypeError # will also raise a type error for string, ints, etc. # slight performance boost rather than checking if None except TypeError: return referent
[docs] def unwrapWeakref(referent: weakref.ReferenceType|t.Any) -> t.Any: ''' Utility function that gets an object that might be an object itself or a weak reference to an object. It returns obj() if it's a weakref. and obj if it's not. >>> class Mock: ... pass >>> a1 = Mock() >>> a2 = Mock() >>> a2.strong = a1 >>> a2.weak = common.wrapWeakref(a1) >>> common.unwrapWeakref(a2.strong) is a1 True >>> common.unwrapWeakref(a2.weak) is a1 True >>> common.unwrapWeakref(a2.strong) is common.unwrapWeakref(a2.weak) True ''' if isinstance(referent, weakref.ReferenceType): return referent() else: return referent
if __name__ == '__main__': import music21 music21.mainTest()