From https://github.com/staggerpkg/stagger/pull/57.patch

From 8b0219ecccadf434905b341ce5e56f8fb582f0e2 Mon Sep 17 00:00:00 2001
From: Michael Cook <michael@waxrat.com>
Date: Sun, 9 Jan 2022 11:48:34 -0500
Subject: [PATCH 1/6] Fix import for Python 3.10

As of Python 3.10 in collections:

- MutableMapping is now abc.MutableMapping

- Container is now abc.Container

Issue #56
---
 stagger/frames.py | 7 ++++++-
 stagger/tags.py   | 7 ++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git stagger/frames.py stagger/frames.py
index f2b914e..6088768 100644
--- stagger/frames.py
+++ stagger/frames.py
@@ -41,6 +41,11 @@
 from stagger.errors import *
 from stagger.specs import *
 
+try:
+    from collections import Container
+except ImportError:
+    from collections.abc import Container
+
 class Frame(metaclass=abc.ABCMeta):
     _framespec = tuple()
     _version = tuple()
@@ -114,7 +119,7 @@ def _in_version(self, *versions):
         "Returns true if this frame is in any of the specified versions of ID3."
         for version in versions:
             if (self._version == version
-                or (isinstance(self._version, collections.Container) 
+                or (isinstance(self._version, Container)
                     and version in self._version)):
                 return True
         return False
diff --git stagger/tags.py stagger/tags.py
index 3949d99..a9e0f29 100644
--- stagger/tags.py
+++ stagger/tags.py
@@ -219,7 +219,12 @@ def __repr__(self):
         return "<FrameOrder: {0}>".format(", ".join(pair[0] for pair in order))
         
 
-class Tag(collections.MutableMapping, metaclass=abc.ABCMeta):
+try:
+    from collections import MutableMapping
+except ImportError:
+    from collections.abc import MutableMapping
+
+class Tag(MutableMapping, metaclass=abc.ABCMeta):
     known_frames = { }        # Maps known frameids to Frame class objects
 
     frame_order = None        # Initialized by stagger.id3

From 9e80d6b104b613b214f1947843e0b52bbfaf2c1b Mon Sep 17 00:00:00 2001
From: Michael Cook <michael@waxrat.com>
Date: Tue, 24 May 2022 11:43:41 -0400
Subject: [PATCH 2/6] tags.py: Move import to top

---
 stagger/tags.py | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git stagger/tags.py stagger/tags.py
index a9e0f29..636b072 100644
--- stagger/tags.py
+++ stagger/tags.py
@@ -48,6 +48,11 @@
 import stagger.frames as Frames
 import stagger.fileutil as fileutil
 
+try:
+    from collections import MutableMapping
+except ImportError:
+    from collections.abc import MutableMapping
+
 _FRAME23_FORMAT_COMPRESSED = 0x0080
 _FRAME23_FORMAT_ENCRYPTED = 0x0040
 _FRAME23_FORMAT_GROUP = 0x0020
@@ -219,11 +224,6 @@ def __repr__(self):
         return "<FrameOrder: {0}>".format(", ".join(pair[0] for pair in order))
         
 
-try:
-    from collections import MutableMapping
-except ImportError:
-    from collections.abc import MutableMapping
-
 class Tag(MutableMapping, metaclass=abc.ABCMeta):
     known_frames = { }        # Maps known frameids to Frame class objects
 

From 4b5f5835398f71a7007f6fba701c89037d41a04a Mon Sep 17 00:00:00 2001
From: Michael Cook <michael@waxrat.com>
Date: Tue, 24 May 2022 11:43:54 -0400
Subject: [PATCH 3/6] frames.py: Handle import of Iterable

---
 stagger/frames.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git stagger/frames.py stagger/frames.py
index 6088768..87e3329 100644
--- stagger/frames.py
+++ stagger/frames.py
@@ -43,8 +43,10 @@
 
 try:
     from collections import Container
+    from collections import Iterable
 except ImportError:
     from collections.abc import Container
+    from collections.abc import Iterable
 
 class Frame(metaclass=abc.ABCMeta):
     _framespec = tuple()
@@ -249,7 +251,7 @@ def extract_strs(values):
                 return
             if isinstance(values, str):
                 yield values
-            elif isinstance(values, collections.Iterable):
+            elif isinstance(values, Iterable):
                 for val in values:
                     for v in extract_strs(val):
                         yield v

From 55f1d91c9c7623bb169194b5f04cacd9db753232 Mon Sep 17 00:00:00 2001
From: Michael Cook <michael@waxrat.com>
Date: Mon, 6 Jun 2022 06:38:02 -0400
Subject: [PATCH 4/6] Fix remaining collections import issues

---
 stagger/specs.py | 13 ++++++++++---
 stagger/tags.py  |  4 +++-
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git stagger/specs.py stagger/specs.py
index 1567a5f..a39b9c9 100644
--- stagger/specs.py
+++ stagger/specs.py
@@ -39,6 +39,13 @@
 from stagger.conversion import *
 from stagger.errors import *
 
+try:
+    from collections import ByteString
+    from collections import Sequence
+except ImportError:
+    from collections.abc import ByteString
+    from collections.abc import Sequence
+
 # The idea for the Spec system comes from Mutagen.
 
 def optionalspec(spec):
@@ -228,7 +235,7 @@ def write(self, frame, value):
     def validate(self, frame, value):
         if value is None:
             return bytes()
-        if not isinstance(value, collections.ByteString):
+        if not isinstance(value, ByteString):
             raise TypeError("Not a byte sequence")
         return value
     def to_str(self, value):
@@ -423,7 +430,7 @@ def validate(self, frame, values):
             return []
         res = []
         for v in values:
-            if not isinstance(v, collections.Sequence) or isinstance(v, str):
+            if not isinstance(v, Sequence) or isinstance(v, str):
                 raise TypeError("Records must be sequences")
             if len(v) != len(self.specs):
                 raise ValueError("Invalid record length")
@@ -453,7 +460,7 @@ def write(self, frame, values):
     def validate(self, frame, values):
         if values is None:
             return []
-        if not isinstance(values, collections.Sequence) or isinstance(values, str):
+        if not isinstance(values, Sequence) or isinstance(values, str):
             raise TypeError("ASPISpec needs a sequence of integers")
         if len(values) != frame.N:
             raise ValueError("ASPISpec needs {0} integers".format(frame.N))
diff --git stagger/tags.py stagger/tags.py
index 636b072..3f0cd25 100644
--- stagger/tags.py
+++ stagger/tags.py
@@ -50,8 +50,10 @@
 
 try:
     from collections import MutableMapping
+    from collections import Iterable
 except ImportError:
     from collections.abc import MutableMapping
+    from collections.abc import Iterable
 
 _FRAME23_FORMAT_COMPRESSED = 0x0080
 _FRAME23_FORMAT_ENCRYPTED = 0x0040
@@ -321,7 +323,7 @@ def __setitem__(self, key, value):
             self._frames[key] = [value]
             return
         if self.known_frames[key]._allow_duplicates:
-            if not isinstance(value, collections.Iterable) or isinstance(value, str):
+            if not isinstance(value, Iterable) or isinstance(value, str):
                 raise ValueError("{0} requires a list of frame values".format(key))
             self._frames[key] = [val if isinstance(val, self.known_frames[key])
                                  else self.known_frames[key](val) 
