Repository: cuthbertLab/music21
Pull request #616 (2020-09-08 09:18:41)

Fix doc problems and use math.inf
Just seems better to have a singleton


Patch:
diff --git a/documentation/source/_static/.gitignore b/documentation/source/_static/.gitignore
deleted file mode 100644
index 8b1378917..000000000
--- a/documentation/source/_static/.gitignore
+++ /dev/null
@@ -1,1 +0,0 @@
-
diff --git a/documentation/source/_themes/m21/static/m21.css b/documentation/source/_themes/m21/static/m21.css
index 30112c00c..27da22fbe 100644
--- a/documentation/source/_themes/m21/static/m21.css
+++ b/documentation/source/_themes/m21/static/m21.css
@@ -21,6 +21,16 @@ body {
     background: radial-gradient(ellipse at center, #d5e899 0%,#7f9152 100%);
     }
 
+.clearer {
+    clear: none;
+    margin: 0 0 0 0;
+    padding: 0 0 0 0;
+}
+
+pre, div[class*="highlight-"] {
+    clear: left;
+}
+
 img {
     padding: 1.5em 1em 1em 1.5em;
     }
@@ -147,7 +157,7 @@ div.footer a {
 
 /* -- body styles ----------------------------------------------------------- */
 
-p {    
+p {
     margin: 0.8em 0 0.5em 0;
     }
 
@@ -188,30 +198,30 @@ h3 {
     border-bottom: 1px solid #eee;
     }
 
-h3, 
-h4, 
-h5, 
-h6, 
+h3,
+h4,
+h5,
+h6,
 p.rubric {
     color: #073642;
-	border-bottom: 1px dotted #eee;
+    border-bottom: 1px dotted #eee;
     }
 
-div.body h1 a, 
-div.body h2 a, 
-div.body h3 a, 
-div.body h4 a, 
-div.body h5 a, 
+div.body h1 a,
+div.body h2 a,
+div.body h3 a,
+div.body h4 a,
+div.body h5 a,
 div.body h6 a,
 p.rubric a {
     color: #657B83!important;
     }
 
-h1 a.anchor, 
-h2 a.anchor, 
-h3 a.anchor, 
-h4 a.anchor, 
-h5 a.anchor, 
+h1 a.anchor,
+h2 a.anchor,
+h3 a.anchor,
+h4 a.anchor,
+h5 a.anchor,
 h6 a.anchor,
 p.rubric a.anchor {
     display: none;
@@ -220,21 +230,21 @@ p.rubric a.anchor {
     color: #aaa!important;
     }
 
-h1:hover a.anchor, 
-h2:hover a.anchor, 
-h3:hover a.anchor, 
+h1:hover a.anchor,
+h2:hover a.anchor,
+h3:hover a.anchor,
 h4:hover a.anchor,
-h5:hover a.anchor, 
+h5:hover a.anchor,
 h6:hover a.anchor,
 p.rubric a.anchor {
     display: inline;
     }
 
-h1 a.anchor:hover, 
-h2 a.anchor:hover, 
-h3 a.anchor:hover, 
+h1 a.anchor:hover,
+h2 a.anchor:hover,
+h3 a.anchor:hover,
 h4 a.anchor:hover,
-h5 a.anchor:hover, 
+h5 a.anchor:hover,
 h6 a.anchor:hover,
 p.rubric a:hover {
     color: #777;
@@ -257,7 +267,7 @@ a.headerlink:hover {
 
 cite, code, tt {
     font-family: 'Source Code Pro', monospace;
-	font-size: 0.9em;
+    font-size: 0.9em;
     letter-spacing: 0.05em;
     font-style: normal;
     }
@@ -276,19 +286,19 @@ hr {
     }
 
 div.ipython-result div.highlight {
-	background-color: #e8e8db;
-	margin-top: -12px; /* close the gap!  */
+    background-color: #e8e8db;
+    margin-top: -12px; /* close the gap!  */
 }
 
 pre {
     font-family: 'Source Code Pro', monospace;
     font-style: normal;
-	font-size: 0.9em;
+    font-size: 0.9em;
     letter-spacing: 0.015em;
     line-height: 120%;
     padding: 0.7em;
-	white-space: pre-wrap;       /* css-3 */
-    }
+    white-space: pre-wrap;       /* css-3 */
+}
 
 div.ipython-result div.highlight pre {
     padding-left: 0px;
@@ -321,7 +331,7 @@ table.docutils {
     }
 
 table.docutils tr {
-    } 
+    }
 
 table.docutils td, table.docutils th {
     /*padding: 0.2em 0.5em 0.2em 0.5em;*/
@@ -422,3 +432,14 @@ div.viewcode-block:target {
     white-space: -o-pre-wrap;
     word-wrap: break-word;
     }
+
+blockquote {
+    clear: none;
+}
+
+div.sidebar::after,
+div.topic::after,
+div.admonition::after,
+blockquote::after {
+    clear: none;
+}
diff --git a/music21/analysis/enharmonics.py b/music21/analysis/enharmonics.py
index d6adc052f..58f1d5d7c 100644
--- a/music21/analysis/enharmonics.py
+++ b/music21/analysis/enharmonics.py
@@ -10,8 +10,11 @@
 # License:      BSD, see license.txt
 # ------------------------------------------------------------------------------
 
-import unittest
 import itertools
+from math import inf
+import unittest
+
+
 from music21 import exceptions21
 from music21 import pitch
 from music21 import musedata
@@ -86,7 +89,7 @@ class EnharmonicSimplifier:
         '''
         self.getProduct()
         bestPitches = []
-        minScore = float('inf')
+        minScore = inf
         for possibility in self.allPossibleSpellings:
             thisAugDimScore = self.getAugDimScore(possibility)
             thisAlterationScore = self.getAlterationScore(possibility)
diff --git a/music21/base.py b/music21/base.py
index 90beec83d..f539e00cf 100644
--- a/music21/base.py
+++ b/music21/base.py
@@ -771,9 +771,9 @@ class Music21Object(prebase.ProtoM21Object):
         That's what this is here for.  If all goes well, you'll never need to call it
         unless you're expanding music21's core functionality.
 
-        **keywords is not used in Music21Object but is included for subclassing.
+        `**keywords` is not used in Music21Object but is included for subclassing.
 
-        Look at :ref:`music21.common.decorators.cacheMethod` for the other half of this
+        Look at :func:`~music21.common.decorators.cacheMethod` for the other half of this
         utility.
 
         New in v.6 -- exposes previously hidden functionality.
diff --git a/music21/duration.py b/music21/duration.py
index 299265bd3..70fc0f273 100644
--- a/music21/duration.py
+++ b/music21/duration.py
@@ -46,9 +46,10 @@ Example usage:
 2
 '''
 
+import copy
 import fractions
 import unittest
-import copy
+from math import inf
 from typing import Union
 
 from collections import namedtuple
@@ -71,7 +72,6 @@ DENOM_LIMIT = defaults.limitOffsetDenominator
 
 POSSIBLE_DOTS_IN_TUPLETS = [0, 1]
 
-_inf = float('inf')
 
 # ------------------------------------------------------------------------------
 # duration constants and reference
@@ -2411,7 +2411,8 @@ class Duration(prebase.ProtoM21Object, SlottedObjectMixin):
 
         Infinite dots...
 
-        >>> d.dots = float('inf')
+        >>> from math import inf
+        >>> d.dots = inf
         >>> d.quarterLength
         4.0
         >>> d.dots
@@ -2440,7 +2441,7 @@ class Duration(prebase.ProtoM21Object, SlottedObjectMixin):
             raise DurationException('only numeric dot values can be used with this method.')
 
         # easter egg...
-        if value == _inf:
+        if value == inf:
             self.type = nextLargerType(self.type)
             self.dots = 0
             return
diff --git a/music21/humdrum/harmparser.py b/music21/humdrum/harmparser.py
index c286ab70c..f9dbb9132 100644
--- a/music21/humdrum/harmparser.py
+++ b/music21/humdrum/harmparser.py
@@ -9,25 +9,28 @@
 # License:      BSD, see license.txt
 # ------------------------------------------------------------------------------
 '''
-The **harm representation is described here: https://www.humdrum.org/rep/harm/
+Harmonic annotations from humdrum to `music21`.
+
+The `**harm` representation is described here: https://www.humdrum.org/rep/harm/
 '''
 import re
 import unittest
-
+from typing import Dict, Any
 
 def convertHarmToRoman(harmStr):
+    # noinspection PyShadowingNames
     '''
-    Converts a **harm string into a string that
+    Converts a `**harm` string into a string that
     can be used to instantiate a RomanNumeral object.
 
     This is necessary because the two notations are not
-    identical. For example, a "V7b" in **harm turns into "V65".
+    identical. For example, a "V7b" in `**harm` turns into "V65".
 
-    Instantiate a HarmParser to process **harm strings
+    Instantiate a HarmParser to process `**harm` strings
 
     >>> convertHarmToRoman = humdrum.harmparser.convertHarmToRoman
 
-    Convert a few **harm strings to music21.roman.RomanNumeral figures
+    Convert a few `**harm` strings to music21.roman.RomanNumeral figures
 
     >>> diatonicTriads = ['I', 'Vc', 'Ib', 'iib', 'V', 'viiob', 'vib']
     >>> [convertHarmToRoman(x) for x in diatonicTriads]
@@ -135,6 +138,7 @@ class HarmDefs:
     '''
 
     # Detect added intervals, e.g., M7, m7, DD7, A6, etc.
+    # noinspection SpellCheckingInspection
     intervals = r'''
     ((?P<intervals>         # Named group _intervals
     \d+|[mMPAD]\d+|         # Detect minor, Major, Augmented or Diminished intervals
@@ -177,7 +181,7 @@ class HarmDefs:
     )?                      # If no secondary function, then the slash symbol should not appear
     '''
     # The definition for a harm expr
-    harmexpr = (r'^('
+    harmExpression = (r'^('
         + accidental
         + roots
         + attribute
@@ -189,42 +193,43 @@ class HarmDefs:
 
 
 class HarmParser:
-    '''Parses an expression in **harm syntax'''
+    '''Parses an expression in `**harm` syntax'''
 
     defs = HarmDefs()
 
     def __init__(self):
-        self.harmp = re.compile(HarmParser.defs.harmexpr, re.VERBOSE)
-        self.impliedp = re.compile(HarmParser.defs.implied, re.VERBOSE)
+        self.harmRegExp = re.compile(HarmParser.defs.harmExpression, re.VERBOSE)
+        self.impliedRegExp = re.compile(HarmParser.defs.implied, re.VERBOSE)
 
-    def parse(self, harmexpr):
+    def parse(self, harmExpression) -> Dict[str, Any]:
         # Check for implied harmony
-        i = self.impliedp.match(harmexpr)
-        if i:
+        impliedMatch = self.impliedRegExp.match(harmExpression)
+        if impliedMatch:
             # This is implied harmony
-            impexpr = i.groupdict()['implied_harmony']
+            impliedHarmony = impliedMatch.groupdict()['implied_harmony']
             # Call the function again over the inner expression
-            m = self.parse(impexpr)
+            m = self.parse(impliedHarmony)
             if m:
                 m['implied'] = True
             return m
         else:
             # Normal expression
-            m = self.harmp.match(harmexpr)
-            if m:
-                m = m.groupdict()
+            matchHarmRegExp = self.harmRegExp.match(harmExpression)
+            if matchHarmRegExp:
+                m: Dict[str, Any] = matchHarmRegExp.groupdict()
                 m['implied'] = False
                 # Finding alternative harmony
                 if m['alternative'] is not None:
-                    altexpr = m['alternative']
-                    a = self.parse(altexpr)
+                    alternativeExpression = m['alternative']
+                    a = self.parse(alternativeExpression)
                     m['alternative'] = a
                 # Finding secondary functions
                 if m['secondary'] is not None:
-                    secexpr = m['secondary']
-                    s = self.parse(secexpr)
+                    secondaryExpression = m['secondary']
+                    s = self.parse(secondaryExpression)
                     m['secondary'] = s
-            return m
+                return m
+            return {}
 
 
 class Test(unittest.TestCase):
@@ -232,6 +237,7 @@ class Test(unittest.TestCase):
         pass
 
     def testTriads(self):
+        # noinspection SpellCheckingInspection
         harmTriads = [
             'I', 'Ib', 'Ic',
             'ii', 'iib', 'iic',
@@ -305,22 +311,3 @@ class Test(unittest.TestCase):
 if __name__ == '__main__':
     import music21
     music21.mainTest(Test)
-
-
-# A legacy CLI version of this parser, left here for completeness
-
-# if __name__ == '__main__':
-#     import argparse
-#     import pprint as pp
-#     parser = argparse.ArgumentParser(
-#         description='Parses an expression in **harm syntax and describes it'
-#     )
-#     parser.add_argument(
-#         'harm',
-#         metavar='harm_expression',
-#         help='Specify a **harm expression to be parsed'
-#     )
-#     args = parser.parse_args()
-#     hp = HarmParser()
-#     x = hp.parse(args.harm)
-#     pp.pprint(x)
diff --git a/music21/humdrum/spineParser.py b/music21/humdrum/spineParser.py
index c76a5d293..a6d8a5dcd 100644
--- a/music21/humdrum/spineParser.py
+++ b/music21/humdrum/spineParser.py
@@ -199,6 +199,7 @@ class HumdrumDataCollection:
 
     # noinspection SpellCheckingInspection
     def determineIfDataStreamIsOpus(self, dataStream=None):
+        # noinspection PyShadowingNames
         r'''
         Some Humdrum files contain multiple pieces in one file
         which are better represented as :class:`~music21.stream.Opus`
@@ -300,11 +301,11 @@ class HumdrumDataCollection:
                 + 'accidentally encoded as a **spine tag.')
 
     def parseOpusDataCollections(self, dataCollections):
+        # noinspection PyShadowingNames
         '''
-        take a dataCollection from `determineIfDataStreamIsOpus`
+        Take a dataCollection from `determineIfDataStreamIsOpus`
         and set self.stream to be an Opus instead.
 
-
         >>> mps = humdrum.testFiles.multipartSanctus
         >>> hdc = humdrum.spineParser.HumdrumDataCollection(mps)
         >>> (hasOpus, dataCollections) = hdc.determineIfDataStreamIsOpus()
@@ -1154,8 +1155,9 @@ class HumdrumSpine:
     spineType = property(_getSpineType, _setSpineType)
 
     def moveElementsIntoMeasures(self, streamIn):
+        # noinspection PyShadowingNames
         '''
-        takes a parsed stream and moves the elements inside the
+        Takes a parsed stream and moves the elements inside the
         measures.  Works with pickup measures, etc. Does not
         automatically create ties, etc...
 
@@ -1163,7 +1165,6 @@ class HumdrumSpine:
         humdrum measures contain extra information about barlines
         etc. and pickups are explicitly defined.
 
-
         >>> s1 = stream.Stream()
         >>> s1.append(meter.TimeSignature('2/4'))
         >>> m1 = stream.Measure()
@@ -1481,8 +1482,8 @@ class HarmSpine(HumdrumSpine):
     attribute set and thus events are processed as if they
     are harmonic analysis annotations in the "harm" syntax.
 
-    The harm roman numeral annotations are parsed using harmalysis,
-    a superset of the original **harm Humdrum representation, written
+    The harm roman numeral annotations are parsed using
+    a superset of the original \*\*harm Humdrum representation, written
     for python and extending the syntax based on other projects like the
     RomanText and the MuseScore roman numeral notations.
     '''
diff --git a/music21/musicxml/m21ToXml.py b/music21/musicxml/m21ToXml.py
index 6cc483ba6..f56e0b68b 100644
--- a/music21/musicxml/m21ToXml.py
+++ b/music21/musicxml/m21ToXml.py
@@ -675,12 +675,46 @@ class GeneralObjectExporter:
         return self.fromMeasure(out)
 
 
+def dumpString(obj, *, noCopy=False) -> str:
+    r'''
+    wrapper around xml.etree.ElementTree as ET that returns a string
+    in every case and indents tags and sorts attributes.  (Prints, does not return)
+
+    >>> from music21.musicxml.m21ToXml import Element
+    >>> e = Element('accidental')
+
+    >>> musicxml.m21ToXml.dumpString(e)
+    '<accidental />'
+
+    >>> e.text = '∆'
+    >>> e.text == '∆'
+    True
+    >>> musicxml.m21ToXml.dumpString(e)
+    '<accidental>∆</accidental>'
+    '''
+    if noCopy is False:
+        xmlEl = copy.deepcopy(obj)  # adds 5% overhead
+    else:
+        xmlEl = obj
+    XMLExporterBase.indent(xmlEl)  # adds 5% overhead
+
+    for el in xmlEl.iter():
+        attrib = el.attrib
+        if len(attrib) > 1:
+            # adjust attribute order, e.g. by sorting
+            attribs = sorted(attrib.items())
+            attrib.clear()
+            attrib.update(attribs)
+    xStr = ET.tostring(xmlEl, encoding='unicode')
+    xStr = xStr.rstrip()
+    return xStr
+
+
 class XMLExporterBase:
     '''
     contains functions that could be called
     at multiple levels of exporting (Score, Part, Measure).
     '''
-
     def __init__(self):
         self.xmlRoot = None
 
@@ -693,11 +727,8 @@ class XMLExporterBase:
         sio = io.BytesIO()
         sio.write(self.xmlHeader())
         rootObj = self.xmlRoot
-        if noCopy is False:
-            rootObj = copy.deepcopy(rootObj)
-        self.indent(rootObj)
-        et = ElementTree(rootObj)
-        et.write(sio, encoding='utf-8', xml_declaration=False)
+        rootObj_string = dumpString(rootObj, noCopy=noCopy)
+        sio.write(rootObj_string.encode('utf-8'))
         v = sio.getvalue()
         sio.close()
         return v
@@ -737,7 +768,7 @@ class XMLExporterBase:
     def dump(obj):
         r'''
         wrapper around xml.etree.ElementTree as ET that prints a string
-        in every case.  (Prints, does not return)
+        in every case and indents tags and sorts attributes.  (Prints, does not return)
 
         >>> from music21.musicxml.m21ToXml import Element
         >>> e = Element('accidental')
@@ -752,19 +783,7 @@ class XMLExporterBase:
         >>> XB.dump(e)
         <accidental>∆</accidental>
         '''
-        xmlEl = copy.deepcopy(obj)  # adds 5% overhead
-        XMLExporterBase.indent(xmlEl)  # adds 5% overhead
-
-        for el in xmlEl.iter():
-            attrib = el.attrib
-            if len(attrib) > 1:
-                # adjust attribute order, e.g. by sorting
-                attribs = sorted(attrib.items())
-                attrib.clear()
-                attrib.update(attribs)
-        xStr = ET.tostring(xmlEl, encoding='unicode')
-        xStr = xStr.rstrip()
-        print(xStr)
+        print(dumpString(obj))
 
     @staticmethod
     def indent(elem, level=0):
diff --git a/music21/pitch.py b/music21/pitch.py
index e11eb8d31..b48041491 100644
--- a/music21/pitch.py
+++ b/music21/pitch.py
@@ -440,7 +440,7 @@ def _dissonanceScore(pitches, smallPythagoreanRatio=True, accidentalPenalty=True
                                         / 26.366694928034633)  # d2 is 1.0
                 score_ratio += penalty
             except interval.IntervalException:
-                return float('inf')
+                return math.inf
 
         score_ratio = score_ratio / len(pitches)
 
diff --git a/music21/sorting.py b/music21/sorting.py
index cb073adbf..32499db5c 100644
--- a/music21/sorting.py
+++ b/music21/sorting.py
@@ -28,10 +28,9 @@ SortTuple(atEnd=0, offset=0.0, priority=-inf, classSortOrder=0, isNotGrace=1, in
 SortTuple(atEnd=0, offset=0.0, priority=inf, classSortOrder=0, isNotGrace=1, insertIndex=0)
 '''
 from collections import namedtuple
+from math import inf as INFINITY
 from music21 import exceptions21
 
-INFINITY = float('inf')
-
 _attrList = ['atEnd', 'offset', 'priority', 'classSortOrder', 'isNotGrace', 'insertIndex']
 
 
@@ -78,7 +77,8 @@ class SortTuple(namedtuple('SortTuple', _attrList)):
     True
     >>> ts_st > 999999
     True
-    >>> ts_st == float('inf')
+    >>> import math
+    >>> ts_st == math.inf
     True
 
     Construct one w/ keywords:
@@ -263,7 +263,7 @@ class SortTuple(namedtuple('SortTuple', _attrList)):
 ZeroSortTupleDefault = SortTuple(atEnd=0, offset=0.0, priority=0, classSortOrder=0,
                                  isNotGrace=1, insertIndex=0)
 
-ZeroSortTupleLow = SortTuple(atEnd=0, offset=0.0, priority=float('-inf'), classSortOrder=0,
+ZeroSortTupleLow = SortTuple(atEnd=0, offset=0.0, priority=-INFINITY, classSortOrder=0,
                              isNotGrace=1, insertIndex=0)
 
 ZeroSortTupleHigh = SortTuple(atEnd=0, offset=0.0, priority=INFINITY, classSortOrder=0,
diff --git a/music21/stream/__init__.py b/music21/stream/__init__.py
index ab3b7d609..0ec906709 100644
--- a/music21/stream/__init__.py
+++ b/music21/stream/__init__.py
@@ -1106,6 +1106,7 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
                *,
                shiftOffsets=False,
                recurse=False):
+        # noinspection PyShadowingNames
         '''
         Remove an object from this Stream. Additionally, this Stream is
         removed from the object's sites in :class:`~music21.sites.Sites`.
@@ -1589,7 +1590,6 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
         Return the offset as an opFrac (float or Fraction) from the offsetMap.
         highly optimized for speed.
 
-
         >>> m = stream.Measure(number=1)
         >>> m.append(note.Note('C'))
         >>> d = note.Note('D')
@@ -1629,7 +1629,6 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
         music21.sites.SitesException: an entry for this object 0x... is not stored in
             stream <music21.stream.Part sPart>
 
-
         Performance note: because it will not follow derivation chains, and does
         not need to unwrap a weakref, this method
         should usually be about 3x faster than element.getOffsetBySite(self) --
@@ -3191,6 +3190,7 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
         return sIterator
 
     def getElementAtOrBefore(self, offset, classList=None):
+        # noinspection PyShadowingNames
         '''
         Given an offset, find the element at this offset,
         or with the offset less than and nearest to.
@@ -6179,10 +6179,13 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
             boundaries[(start, end)] = e
         return boundaries
 
-    def stripTies(self,
-                  inPlace=False,
-                  matchByPitch=False,
-                  retainContainers=True):
+    def stripTies(
+        self,
+        inPlace=False,
+        matchByPitch=False,
+        retainContainers=True
+    ):
+        # noinspection PyShadowingNames
         '''
         Find all notes that are tied; remove all tied notes,
         then make the first of the tied notes have a duration
@@ -7129,17 +7132,13 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
         in quarter lengths. This value usually represents the last
         "release" in the Stream.
 
-
         Stream.duration is usually equal to the highestTime
         expressed as a Duration object, but it can be set separately
         for advanced operations.
 
-
         Example: Insert a dotted half note at position 0 and see where
         it cuts off:
 
-
-
         >>> p1 = stream.Stream()
         >>> p1.highestTime
         0.0
@@ -7790,11 +7789,14 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
     # --------------------------------------------------------------------------
     # transformations
 
-    def transpose(self,
-                  value,
-                  inPlace=False,
-                  recurse=True,
-                  classFilterList=None):
+    def transpose(
+        self,
+        value,
+        inPlace=False,
+        recurse=True,
+        classFilterList=None
+    ):
+        # noinspection PyShadowingNames
         '''
         Transpose all specified classes in the
         Stream by the
@@ -7809,8 +7811,6 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
 
         TODO: for generic interval set accidental by key signature.
 
-
-
         >>> aInterval = interval.Interval('d5')
 
         >>> aStream = corpus.parse('bach/bwv324.xml')
@@ -8044,9 +8044,15 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
         # do not need to call elements changed, as called in sub methods
         return returnObj
 
-    def quantize(self, quarterLengthDivisors=None,
-                 processOffsets=True, processDurations=True,
-                 inPlace=False, recurse=True):
+    def quantize(
+        self,
+        quarterLengthDivisors=None,
+        processOffsets=True,
+        processDurations=True,
+        inPlace=False,
+        recurse=True
+    ):
+        # noinspection PyShadowingNames
         '''
         Quantize time values in this Stream by snapping offsets
         and/or durations to the nearest multiple of a quarter length value
@@ -8133,7 +8139,6 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
         >>> [e.duration.quarterLength for e in v]
         [0.5, 0.5, 0.5, 0.25, 0.25]
 
-
         TODO: test recurse and inPlace etc.
         TODO: recurse should be off by default -- standard
         '''
@@ -9908,6 +9913,7 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
             return voiceCount, voiceIds
 
     def voicesToParts(self, *, separateById=False):
+        # noinspection PyShadowingNames
         '''
         If this Stream defines one or more voices,
         extract each into a Part, returning a Score.
@@ -10930,6 +10936,7 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
             highestNumber, insertedMeasures)
 
     def _insertInsertionVariant(self, v, matchBySpan=True):
+        # noinspection PyShadowingNames
         '''
         Helper function for activateVariants. _removeOrExpandGaps must be called on the
         expanded regions before this function
@@ -13227,6 +13234,7 @@ class Test(unittest.TestCase):
                 continue
             elif callable(part):  # pragma: no cover
                 # environLocal.printDebug(['testing copying on', part])
+                # noinspection PyTypeChecker
                 obj = getattr(self.__module__, part)()
                 a = copy.copy(obj)
                 b = copy.deepcopy(obj)
diff --git a/music21/stream/core.py b/music21/stream/core.py
index 7f465d991..cd3a1250e 100644
--- a/music21/stream/core.py
+++ b/music21/stream/core.py
@@ -286,7 +286,7 @@ class StreamCoreMixin:
         return None
 
     # --------------------------------------------------------------------------
-    def coreGuardBeforeAddElement(self, element, checkRedundancy=True):
+    def coreGuardBeforeAddElement(self, element, *, checkRedundancy=True):
         '''
         Before adding an element, this method provides
         important checks to that element.
@@ -309,18 +309,19 @@ class StreamCoreMixin:
                 # now go slow for safety -- maybe something is amiss in the index.
                 # this should not happen, but we have slipped many times in not clearing out
                 # old _offsetDict entries.
-                for eInStream in self:
-                    if eInStream is element:
-                        raise StreamException(
-                            'the object '
-                            + '(%s, id()=%s) is already found in this Stream (%s, id()=%s)' %
-                            (element, id(element), self, id(self)))
+                for search_place in (self._elements, self._endElements):
+                    for eInStream in search_place:
+                        if eInStream is element:
+                            raise StreamException(
+                                f'the object ({element!r}, id()={id(element)} '
+                                + f'is already found in this Stream ({self!r}, id()={id(self)})'
+                            )
                 # something was old... delete from _offsetDict
                 # environLocal.warn('stale object')
                 del self._offsetDict[idElement]  # pragma: no cover
         # if we do not purge locations here, we may have ids() for
-        # Stream that no longer exist stored in the locations entry
-        # note that dead locations are also purged from .sites during
+        # Streams that no longer exist stored in the locations entry for element.
+        # Note that dead locations are also purged from .sites during
         # all get() calls.
         element.purgeLocations()
 
diff --git a/music21/stream/filters.py b/music21/stream/filters.py
index dfcafcc4b..1e0587b3c 100644
--- a/music21/stream/filters.py
+++ b/music21/stream/filters.py
@@ -16,9 +16,10 @@ decide whether or not a given element matches the list of elements that are bein
 filtered.  Filters are used by methods on streams such as
 :meth:`~music21.stream.Stream.getElementsByClass` to filter elements by classes.
 '''
-
 # import inspect
 import unittest
+from math import inf
+
 from music21 import common
 from music21.common.numberTools import opFrac
 from music21.exceptions21 import Music21Exception
@@ -176,7 +177,7 @@ class IsNotFilter(IsFilter):
 
     def __init__(self, target=()):
         super().__init__(target)
-        self.numToFind = float('inf')  # there can always be more to find
+        self.numToFind = inf  # there can always be more to find
 
     def reset(self):
         pass  # do nothing: inf - 1 = inf
diff --git a/music21/tree/spans.py b/music21/tree/spans.py
index d37ccaabc..9bc539efd 100644
--- a/music21/tree/spans.py
+++ b/music21/tree/spans.py
@@ -18,6 +18,7 @@ organized by start and stop offsets.
 
 import copy
 import unittest
+from math import inf
 
 from music21 import environment
 from music21 import exceptions21
@@ -70,7 +71,7 @@ class Timespan:
     False
     '''
 
-    def __init__(self, offset=float('-inf'), endTime=float('inf')):
+    def __init__(self, offset=-inf, endTime=inf):
         if offset is not None:
             offset = float(offset)
         self._offset = offset
@@ -296,22 +297,23 @@ class ElementTimespan(Timespan):
     '''
 
     # CLASS VARIABLES #
-    _DOC_ATTR = {'parentage': r'''
-                    The Stream hierarchy above the ElementTimespan's element.
-
-                    >>> score = corpus.parse('bwv66.6')
-                    >>> scoreTree = score.asTimespans()
-                    >>> verticality = scoreTree.getVerticalityAt(1.0)
-                    >>> pitchedTimespan = verticality.startTimespans[0]
-                    >>> pitchedTimespan
-                    <PitchedTimespan (1.0 to 2.0) <music21.note.Note A>>
-                    >>> for streamSite in pitchedTimespan.parentage:
-                    ...     streamSite
-                    <music21.stream.Measure 1 offset=1.0>
-                    <music21.stream.Part Soprano>
-                    <music21.stream.Score ...>
-                    '''
-                 }
+    _DOC_ATTR = {
+        'parentage': r'''
+            The Stream hierarchy above the element in a ElementTimespan.
+
+            >>> score = corpus.parse('bwv66.6')
+            >>> scoreTree = score.asTimespans()
+            >>> verticality = scoreTree.getVerticalityAt(1.0)
+            >>> pitchedTimespan = verticality.startTimespans[0]
+            >>> pitchedTimespan
+            <PitchedTimespan (1.0 to 2.0) <music21.note.Note A>>
+            >>> for streamSite in pitchedTimespan.parentage:
+            ...     streamSite
+            <music21.stream.Measure 1 offset=1.0>
+            <music21.stream.Part Soprano>
+            <music21.stream.Score ...>
+            ''',
+    }
 
     # INITIALIZER #
 
diff --git a/music21/tree/trees.py b/music21/tree/trees.py
index b4ae6d9b2..06706fa38 100644
--- a/music21/tree/trees.py
+++ b/music21/tree/trees.py
@@ -17,6 +17,7 @@ and other positions.
 '''
 import unittest
 import weakref
+from math import inf
 from typing import Optional
 
 from music21 import common
@@ -28,10 +29,11 @@ from music21.tree import core
 from music21.tree import node as nodeModule
 
 from music21 import environment
+
 environLocal = environment.Environment('tree.trees')
 
-INFINITY = float('inf')
-NEGATIVE_INFINITY = float('-inf')
+INFINITY = inf
+NEGATIVE_INFINITY = -inf
 
 # -----------------------------------------------------------------------------
 
@@ -93,6 +95,9 @@ class ElementTree(core.AVLTree):
     >>> et.getPositionAfter(4.0).offset
     6.0
     '''
+    # TYPING #
+    rootNode: Optional[nodeModule.ElementNode]
+
     # CLASS VARIABLES #
     nodeClass = nodeModule.ElementNode
 
@@ -112,6 +117,7 @@ class ElementTree(core.AVLTree):
 
     # Special Methods #
     def __contains__(self, element):
+        # noinspection PyShadowingNames
         r'''
         Is true when the ElementTree contains the object within it
 
@@ -167,6 +173,7 @@ class ElementTree(core.AVLTree):
         return self is expr
 
     def __getitem__(self, i):
+        # noinspection PyShadowingNames
         r'''
         Gets elements by integer index or slice.  This is pretty fast in computational time
         (O(log n)), but it's O(log n) in Python while normal list slicing is O(1) in C, so
@@ -289,6 +296,7 @@ class ElementTree(core.AVLTree):
         return msg
 
     def __setitem__(self, i, new):
+        # noinspection PyShadowingNames
         r'''
         Sets elements at index `i` to `new`, but keeping the old position
         of the element there. (This is different from OffsetTrees, where things can move around).
@@ -474,6 +482,7 @@ class ElementTree(core.AVLTree):
         return el.sortTuple(self.source)
 
     def populateFromSortedList(self, listOfTuples):
+        # noinspection PyShadowingNames
         '''
         This method assumes that the current tree is empty (or will be wiped) and
         that listOfTuples is a non-empty
@@ -636,8 +645,8 @@ class ElementTree(core.AVLTree):
             if self.rootNode is None:
                 return []
             indices = i.indices(self.rootNode.subtreeElementsStopIndex)
-            start, stop = indices[0], indices[1]
-            return recurseBySlice(self.rootNode, start, stop)
+            outer_start, outer_stop = indices[0], indices[1]
+            return recurseBySlice(self.rootNode, outer_start, outer_stop)
         else:
             raise TypeError('Indices must be integers or slices, got {}'.format(i))
 
@@ -682,6 +691,7 @@ class ElementTree(core.AVLTree):
             yield n
 
     def index(self, element, position=None):
+        # noinspection PyShadowingNames
         r'''
         Gets index of `element` in tree. position could be none.
 
@@ -885,6 +895,9 @@ class OffsetTree(ElementTree):
     '''
     __slots__ = ()
 
+    # TYPING #
+    rootNode: Optional[nodeModule.OffsetNode]
+
     nodeClass = nodeModule.OffsetNode
 
     # SPECIAL METHODS #
@@ -955,7 +968,7 @@ class OffsetTree(ElementTree):
             elif node.rightChild and node.payloadElementsStopIndex <= index:
                 return recurseByIndex(node.rightChild, index)
 
-        def recurseBySlice(node, start, stop):
+        def recurseBySlice(node: nodeModule.ElementNode, start, stop):
             '''
             Return a slice of the payload elements (plural) where start <= index < stop.
             '''
@@ -986,8 +999,8 @@ class OffsetTree(ElementTree):
             if self.rootNode is None:
                 return []
             indices = i.indices(self.rootNode.subtreeElementsStopIndex)
-            start, stop = indices[0], indices[1]
-            return recurseBySlice(self.rootNode, start, stop)
+            outer_start, outer_stop = indices[0], indices[1]
+            return recurseBySlice(self.rootNode, outer_start, outer_stop)
         else:
             raise TypeError('Indices must be integers or slices, got {}'.format(i))
 
@@ -1123,6 +1136,7 @@ class OffsetTree(ElementTree):
         node.payload.sort(key=self._insertCorePayloadSortKey)
 
     def copy(self):
+        # noinspection PyShadowingNames
         r'''
         Creates a new tree with the same payload as this tree.
 
@@ -1197,20 +1211,20 @@ class OffsetTree(ElementTree):
         <PitchedTimespan (0.0 to 0.5) <music21.note.Note A>>
         <PitchedTimespan (0.0 to 0.5) <music21.note.Note A>>
         '''
-        def recurse(node, offset):
+        def recurse(node):
             result = []
             if node is not None:  # could happen in an empty TimespanTree
                 if node.endTimeLow <= offset <= node.endTimeHigh:
                     if node.leftChild is not None:
-                        result.extend(recurse(node.leftChild, offset))
+                        result.extend(recurse(node.leftChild))
                     for el in node.payload:
                         if self.elementEndTime(el, node) == offset:
                             result.append(el)
                     if node.rightChild is not None:
-                        result.extend(recurse(node.rightChild, offset))
+                        result.extend(recurse(node.rightChild))
             return result
 
-        results = recurse(self.rootNode, offset)
+        results = recurse(self.rootNode)
         return tuple(results)
 
     def elementsOverlappingOffset(self, offset):
@@ -1232,25 +1246,22 @@ class OffsetTree(ElementTree):
         ...
         <PitchedTimespan (0.0 to 1.0) <music21.note.Note E>>
         '''
-        def recurse(node, offset):
+        def recurse(node):
             result = []  # collections.deque()
             if node is not None:
                 if node.position < offset < node.endTimeHigh:
-                    result.extend(recurse(node.leftChild, offset))
+                    result.extend(recurse(node.leftChild))
                     # This currently requires timespans not elements, and list payloads...
                     # TODO: Fix/disambiguate.
                     for el in node.payload:
                         if offset < self.elementEndTime(el, node):
                             result.append(el)
-                    result.extend(recurse(node.rightChild, offset))
+                    result.extend(recurse(node.rightChild))
                 elif offset <= node.position:
-                    result.extend(recurse(node.leftChild, offset))
+                    result.extend(recurse(node.leftChild))
             return result
-        results = recurse(self.rootNode, offset)
-        # if len(results) > 0 and hasattr(results[0], 'element'):
-        #    results.sort(key=lambda x: (x.offset, x.endTime, x.element.sortTuple()[1:]))
-        # else:
-        # results.sort(key=lambda x: (x.offset, x.endTime))
+
+        results = recurse(self.rootNode)
         return tuple(results)
 
     def removeElements(self, elements, offsets=None, runUpdate=True):


Test patch:
diff --git a/music21/test/testStream.py b/music21/test/testStream.py
index 929cb0558..c91a4a280 100644
--- a/music21/test/testStream.py
+++ b/music21/test/testStream.py
@@ -1345,13 +1345,13 @@ class Test(unittest.TestCase):
                          '[<music21.note.Note B>, <music21.note.Note D>]')
         self.assertEqual(len(mEx.flat), 3)
 
-        # make sure source has not chnaged
+        # make sure source has not changed
         mExRaw = p1.getElementsByClass('Measure')[5]
         self.assertEqual(str([n for n in mExRaw.notes]),
                          '[<music21.note.Note B>, <music21.note.Note D>]')
         self.assertEqual(len(mExRaw.flat), 3)
 
-        # test measures with no measure numbesr
+        # test measures with no measure numbers
         c = Stream()
         for dummy in range(4):
             m = Measure()
@@ -1476,7 +1476,7 @@ class Test(unittest.TestCase):
         # self.assertEqual(sorted(list(post.keys())), correctMeasureOffsetMap)
 
         # fom music21 import graph
-        # gaph.plotStream(altoPostTie, 'scatter', values=['pitchclass', 'offset'])
+        # graph.plotStream(altoPostTie, 'scatter', values=['pitchclass', 'offset'])
 
     def testMusicXMLGenerationViaPropertyA(self):
         '''Test output tests above just by calling the musicxml attribute
@@ -1545,6 +1545,7 @@ class Test(unittest.TestCase):
         s = Stream()
         partOffsetShift = 1.25
         partOffset = 0
+        p = None
         for unused_part in range(6):
             p = Stream()
             for pitchName in a:
@@ -1617,7 +1618,7 @@ class Test(unittest.TestCase):
         # makeMeasures
         self.assertTrue(isinstance(sMeasures[0][2], note.Note), sMeasures[0][2])
 
-        # this shows the proper outpt withs the proper clef.
+        # this shows the proper output with the proper clef.
         # sMeasures.show()
 
         # we cannot get clefs from sMeasures b/c that is the topmost
@@ -1824,7 +1825,7 @@ class Test(unittest.TestCase):
         # TODO: this still returns tenor clef for both parts
         # need to examine
 
-        # now we in sert a clef in s2; s2 will get this clef first
+        # now we insert a clef in s2; s2 will get this clef first
         s1.insert(0, clef.BassClef())
         post = s1.getClefs()[0]
         self.assertIsInstance(post, clef.BassClef)
@@ -2125,16 +2126,16 @@ class Test(unittest.TestCase):
         self.assertIs(s3[0], n1)
         self.assertEqual(s3[0].getOffsetBySite(s3), 30)
 
-    def testReplaceDerivated(self):
+    def testReplaceDerived(self):
         from music21 import corpus
         qj = corpus.parse('ciconia/quod_jactatur').parts[0].measures(1, 2)
         qj.id = 'measureExcerpt'
 
-        qjflat = qj.flat
-        dc = list(qjflat.derivation.chain())
+        qj_flat = qj.flat
+        dc = list(qj_flat.derivation.chain())
         self.assertIs(dc[0], qj)
 
-        k1 = qjflat.getElementsByClass(key.KeySignature)[0]
+        k1 = qj_flat.getElementsByClass(key.KeySignature)[0]
         self.assertEqual(k1.sharps, -1)
         k3flats = key.KeySignature(-3)
 
@@ -2143,9 +2144,9 @@ class Test(unittest.TestCase):
         mUnrelated.insert(0, k1)
 
         # here's the big one
-        qjflat.replace(k1, k3flats, allDerived=True)
+        qj_flat.replace(k1, k3flats, allDerived=True)
 
-        kWhich = qjflat.getElementsByClass(key.KeySignature)[0]
+        kWhich = qj_flat.getElementsByClass(key.KeySignature)[0]
         self.assertIs(kWhich, k3flats)
         self.assertEqual(kWhich.sharps, -3)
 
@@ -2498,10 +2499,10 @@ class Test(unittest.TestCase):
     def testScaleOffsetsBasic(self):
         from music21 import stream
 
-        def procCompare(s, scalar, match):
-            oListSrc = [e.offset for e in s]
+        def procCompare(s_inner, scalar, match):
+            oListSrc = [e.offset for e in s_inner]
             oListSrc.sort()
-            sNew = s.scaleOffsets(scalar, inPlace=False)
+            sNew = s_inner.scaleOffsets(scalar, inPlace=False)
             oListPost = [e.offset for e in sNew]
             oListPost.sort()
 
@@ -2566,7 +2567,7 @@ class Test(unittest.TestCase):
     def testScaleOffsetsBasicInPlaceA(self):
         from music21 import stream
 
-        def procCompare(s, scalar, match):
+        def procCompare(scalar, match):
             # test equally spaced half notes starting at zero
             n = note.Note()
             n.quarterLength = 2
@@ -2582,19 +2583,18 @@ class Test(unittest.TestCase):
             #    '\n' + 'post scaled by:', scalar, oListPost])
             self.assertEqual(oListPost[:len(match)], match)
 
-        s = None  # placeholder
         # provide start of resulting values
         # half not spacing becomes whole note spacing
-        procCompare(s, 2, [0.0, 4.0, 8.0])
-        procCompare(s, 4, [0.0, 8.0, 16.0, 24.0])
-        procCompare(s, 3, [0.0, 6.0, 12.0, 18.0])
-        procCompare(s, 0.5, [0.0, 1.0, 2.0, 3.0])
-        procCompare(s, 0.25, [0.0, 0.5, 1.0, 1.5])
+        procCompare(2, [0.0, 4.0, 8.0])
+        procCompare(4, [0.0, 8.0, 16.0, 24.0])
+        procCompare(3, [0.0, 6.0, 12.0, 18.0])
+        procCompare(0.5, [0.0, 1.0, 2.0, 3.0])
+        procCompare(0.25, [0.0, 0.5, 1.0, 1.5])
 
     def testScaleOffsetsBasicInPlaceB(self):
         from music21 import stream
 
-        def procCompare(s, scalar, match):
+        def procCompare(scalar, match):
             # test equally spaced quarter notes start at non-zero
             n = note.Note()
             n.quarterLength = 1
@@ -2610,18 +2610,17 @@ class Test(unittest.TestCase):
             #  '\n' + 'post scaled by:', scalar, oListPost])
             self.assertEqual(oListPost[:len(match)], match)
 
-        s = None  # placeholder
-        procCompare(s, 1, [100, 101, 102, 103])
-        procCompare(s, 2, [100, 102, 104, 106])
-        procCompare(s, 4, [100, 104, 108, 112])
-        procCompare(s, 1.5, [100, 101.5, 103.0, 104.5])
-        procCompare(s, 0.5, [100, 100.5, 101.0, 101.5])
-        procCompare(s, 0.25, [100, 100.25, 100.5, 100.75])
+        procCompare(1, [100, 101, 102, 103])
+        procCompare(2, [100, 102, 104, 106])
+        procCompare(4, [100, 104, 108, 112])
+        procCompare(1.5, [100, 101.5, 103.0, 104.5])
+        procCompare(0.5, [100, 100.5, 101.0, 101.5])
+        procCompare(0.25, [100, 100.25, 100.5, 100.75])
 
     def testScaleOffsetsBasicInPlaceC(self):
         from music21 import stream
 
-        def procCompare(s, scalar, match):
+        def procCompare(scalar, match):
             # test non equally spaced notes starting at zero
             s = stream.Stream()
             n1 = note.Note()
@@ -2640,16 +2639,15 @@ class Test(unittest.TestCase):
             #  '\n' + 'post scaled by:', scalar, oListPost])
             self.assertEqual(oListPost[:len(match)], match)
 
-        # procCompare will  sort offsets; this test non sorted operation
-        s = None  # placeholder
-        procCompare(s, 1, [0.0, 1.0, 3.0, 4.0, 6.0, 7.0])
-        procCompare(s, 0.5, [0.0, 0.5, 1.5, 2.0, 3.0, 3.5])
-        procCompare(s, 2, [0.0, 2.0, 6.0, 8.0, 12.0, 14.0])
+        # procCompare will sort offsets; this test non sorted operation
+        procCompare(1, [0.0, 1.0, 3.0, 4.0, 6.0, 7.0])
+        procCompare(0.5, [0.0, 0.5, 1.5, 2.0, 3.0, 3.5])
+        procCompare(2, [0.0, 2.0, 6.0, 8.0, 12.0, 14.0])
 
     def testScaleOffsetsBasicInPlaceD(self):
         from music21 import stream
 
-        def procCompare(s, scalar, match):
+        def procCompare(scalar, match):
             # test non equally spaced notes starting at non-zero
             s = stream.Stream()
             n1 = note.Note()
@@ -2668,12 +2666,11 @@ class Test(unittest.TestCase):
             # '\n' + 'post scaled by:', scalar, oListPost])
             self.assertEqual(oListPost[:len(match)], match)
 
-        # procCompare will  sort offsets; this test non sorted operation
-        s = None  # placeholder
-        procCompare(s, 1, [100.0, 101.0, 103.0, 104.0, 106.0, 107.0])
-        procCompare(s, 0.5, [100.0, 100.5, 101.5, 102.0, 103.0, 103.5])
-        procCompare(s, 2, [100.0, 102.0, 106.0, 108.0, 112.0, 114.0])
-        procCompare(s, 6, [100.0, 106.0, 118.0, 124.0, 136.0, 142.0])
+        # procCompare will sort offsets; this test non sorted operation
+        procCompare(1, [100.0, 101.0, 103.0, 104.0, 106.0, 107.0])
+        procCompare(0.5, [100.0, 100.5, 101.5, 102.0, 103.0, 103.5])
+        procCompare(2, [100.0, 102.0, 106.0, 108.0, 112.0, 114.0])
+        procCompare(6, [100.0, 106.0, 118.0, 124.0, 136.0, 142.0])
 
     def testScaleOffsetsNested(self):
         from music21 import stream
@@ -2801,8 +2798,8 @@ class Test(unittest.TestCase):
         '''
 
         def procCompare(s, scalar, match):
-            sNew = s.scaleDurations(scalar, inPlace=False)
-            oListPost = [e.quarterLength for e in sNew]
+            sNew_inner = s.scaleDurations(scalar, inPlace=False)
+            oListPost = [e.quarterLength for e in sNew_inner]
             self.assertEqual(oListPost[:len(match)], match)
 
         n1 = note.Note()
@@ -2833,7 +2830,7 @@ class Test(unittest.TestCase):
     def testAugmentOrDiminishBasic(self):
 
         def procCompare(s, scalar, matchOffset, matchDuration):
-            # oistSrc = [e.offset for e in s]
+            # oListSrc = [e.offset for e in s]
             # qListSrc = [e.quarterLength for e in s]
 
             sNew = s.augmentOrDiminish(scalar, inPlace=False)
@@ -3118,7 +3115,7 @@ class Test(unittest.TestCase):
         s.metadata = metadata.Metadata()
         s.metadata.composer = 'Frank the Composer'
         s.metadata.title = 'work title'  # will get as movement name if not set
-        # smetadata.movementName = 'movement name'
+        # s.metadata.movementName = 'movement name'
         GEX = m21ToXml.GeneralObjectExporter()
         unused_mx = GEX.parse(s).decode('utf-8')
         # s.show()
@@ -3266,57 +3263,59 @@ class Test(unittest.TestCase):
         self.assertEqual(match, ['2a', '3a', '3b', 'n3(3b)', 'n4(3b)', '3c'])
 
         # environLocal.printDebug(['upward, with skipDuplicates:'])
-#         match = []
-#         # must provide empty list for memo
-#         for x in s7._yieldReverseUpwardsSearch([], streamsOnly=True, skipDuplicates=True):
-#             match.append(x.id)
-#             # environLocal.printDebug([x, x.id, 'activeSite', x.activeSite])
-#         self.assertEqual(match, ['3c', '2a', '1a', '2b', '2c', '3a', '3b'] )
+        # match = []
+        # # must provide empty list for memo
+        # for x in s7._yieldReverseUpwardsSearch([], streamsOnly=True, skipDuplicates=True):
+        #     match.append(x.id)
+        #     # environLocal.printDebug([x, x.id, 'activeSite', x.activeSite])
+        # self.assertEqual(match, ['3c', '2a', '1a', '2b', '2c', '3a', '3b'] )
 
         # environLocal.printDebug(['upward from a single node, with skipDuplicates'])
-#         match = []
-#         for x in s10._yieldReverseUpwardsSearch([], streamsOnly=True):
-#             match.append(x.id)
-#             # environLocal.printDebug([x, x.id, 'activeSite', x.activeSite])
-#
-#         self.assertEqual(match, ['3f', '2c', '1a', '2a', '2b'] )
+        # match = []
+        # for x in s10._yieldReverseUpwardsSearch([], streamsOnly=True):
+        #     match.append(x.id)
+        #     # environLocal.printDebug([x, x.id, 'activeSite', x.activeSite])
+        #
+        # self.assertEqual(match, ['3f', '2c', '1a', '2a', '2b'] )
 
         # environLocal.printDebug(['upward with skipDuplicates=False:'])
-#         match = []
-#         for x in s10._yieldReverseUpwardsSearch([], streamsOnly=True, skipDuplicates=False):
-#             match.append(x.id)
-#             # environLocal.printDebug([x, x.id, 'activeSite', x.activeSite])
-#         self.assertEqual(match, ['3f', '2c', '1a', '2a', '1a', '2b', '1a'] )
+        # match = []
+        # for x in s10._yieldReverseUpwardsSearch([], streamsOnly=True, skipDuplicates=False):
+        #     match.append(x.id)
+        #     # environLocal.printDebug([x, x.id, 'activeSite', x.activeSite])
+        # self.assertEqual(match, ['3f', '2c', '1a', '2a', '1a', '2b', '1a'] )
 
         # environLocal.printDebug(['upward, with skipDuplicates, streamsOnly=False:'])
-#         match = []
-#         # must provide empty list for memo
-#         for x in s8._yieldReverseUpwardsSearch([], streamsOnly=False,
-#             skipDuplicates=True):
-#             match.append(x.id)
-#             environLocal.printDebug([x, x.id, 'activeSite', x.activeSite])
-#         self.assertEqual(match, ['3d', 'n2(2b)', '2b', 'n(1a)', '1a', '2a', '2c', '3e'] )
+        # match = []
+        # # must provide empty list for memo
+        # for x in s8._yieldReverseUpwardsSearch([], streamsOnly=False,
+        #     skipDuplicates=True):
+        #     match.append(x.id)
+        #     environLocal.printDebug([x, x.id, 'activeSite', x.activeSite])
+        # self.assertEqual(match, ['3d', 'n2(2b)', '2b', 'n(1a)', '1a', '2a', '2c', '3e'] )
 
         # environLocal.printDebug(['upward, with skipDuplicates, streamsOnly=False:'])
-#         match = []
-#         # must provide empty list for memo
-#         for x in s4._yieldReverseUpwardsSearch([], streamsOnly=False,
-#             skipDuplicates=True):
-#             match.append(x.id)
-#             # environLocal.printDebug([x, x.id, 'activeSite', x.activeSite])
-#         # notice that this does not get the nonConatainers for 2b
-#         self.assertEqual(match, ['2c', 'n(1a)', '1a', '2a', '2b'] )
+        # match = []
+        # # must provide empty list for memo
+        # for x in s4._yieldReverseUpwardsSearch([], streamsOnly=False,
+        #     skipDuplicates=True):
+        #     match.append(x.id)
+        #     # environLocal.printDebug([x, x.id, 'activeSite', x.activeSite])
+        # # notice that this does not get the nonContainers for 2b
+        # self.assertEqual(match, ['2c', 'n(1a)', '1a', '2a', '2b'] )
 
     def testMidiEventsBuilt(self):
+        from music21.midi import MetaEvents, ChannelVoiceMessages
+        self.maxDiff = None
 
-        def procCompare(mf, match):
+        def procCompare(mf_inner, match_inner):
             triples = []
-            for i in range(0, len(mf.tracks[0].events), 2):
-                d = mf.tracks[0].events[i]  # delta
-                e = mf.tracks[0].events[i + 1]  # events
-                triples.append((d.time, e.type, e.pitch))
-            # TODO: temporary removed
-            # self.assertEqual(triples, match)
+            for i in range(0, len(mf_inner.tracks[0].events), 2):
+                delta = mf_inner.tracks[0].events[i]  # delta
+                e = mf_inner.tracks[0].events[i + 1]  # events
+                triples.append((delta.time, e.type, e.pitch))
+
+            self.assertEqual(triples, match_inner)
 
         s = Stream()
         n = note.Note('g#3')
@@ -3330,11 +3329,23 @@ class Test(unittest.TestCase):
         self.assertEqual(len(post[0].events) % 2, 0)
 
         mf = midiTranslate.streamToMidiFile(s)
-        match = [(0, 'SEQUENCE_TRACK_NAME', None), (0, 'PITCH_BEND', None), (0, 'NOTE_ON', 56),
-                 (512, 'NOTE_OFF', 56), (0, 'NOTE_ON', 56), (512, 'NOTE_OFF', 56),
-                 (0, 'NOTE_ON', 56), (512, 'NOTE_OFF', 56), (0, 'NOTE_ON', 56),
-                 (512, 'NOTE_OFF', 56), (0, 'NOTE_ON', 56), (512, 'NOTE_OFF', 56),
-                 (0, 'NOTE_ON', 56), (512, 'NOTE_OFF', 56), (0, 'END_OF_TRACK', None)]
+        match = [
+            (0, MetaEvents.SEQUENCE_TRACK_NAME, None),
+            (0, ChannelVoiceMessages.PITCH_BEND, None),
+            (0, ChannelVoiceMessages.NOTE_ON, 56),
+            (512, ChannelVoiceMessages.NOTE_OFF, 56),
+            (0, ChannelVoiceMessages.NOTE_ON, 56),
+            (512, ChannelVoiceMessages.NOTE_OFF, 56),
+            (0, ChannelVoiceMessages.NOTE_ON, 56),
+            (512, ChannelVoiceMessages.NOTE_OFF, 56),
+            (0, ChannelVoiceMessages.NOTE_ON, 56),
+            (512, ChannelVoiceMessages.NOTE_OFF, 56),
+            (0, ChannelVoiceMessages.NOTE_ON, 56),
+            (512, ChannelVoiceMessages.NOTE_OFF, 56),
+            (0, ChannelVoiceMessages.NOTE_ON, 56),
+            (512, ChannelVoiceMessages.NOTE_OFF, 56),
+            (1024, MetaEvents.END_OF_TRACK, None),
+        ]
 
         procCompare(mf, match)
 
@@ -3344,30 +3355,63 @@ class Test(unittest.TestCase):
         s.repeatAppend(n, 3)
 
         mf = midiTranslate.streamToMidiFile(s)
-        match = [(0, 'SEQUENCE_TRACK_NAME', None), (0, 'PITCH_BEND', None), (0, 'NOTE_ON', 56),
-                 (1536, 'NOTE_OFF', 56), (0, 'NOTE_ON', 56), (1536, 'NOTE_OFF', 56),
-                 (0, 'NOTE_ON', 56), (1536, 'NOTE_OFF', 56), (0, 'END_OF_TRACK', None)]
+        match = [
+            (0, MetaEvents.SEQUENCE_TRACK_NAME, None),
+            (0, ChannelVoiceMessages.PITCH_BEND, None),
+            (0, ChannelVoiceMessages.NOTE_ON, 56),
+            (1536, ChannelVoiceMessages.NOTE_OFF, 56),
+            (0, ChannelVoiceMessages.NOTE_ON, 56),
+            (1536, ChannelVoiceMessages.NOTE_OFF, 56),
+            (0, ChannelVoiceMessages.NOTE_ON, 56),
+            (1536, ChannelVoiceMessages.NOTE_OFF, 56),
+            (1024, MetaEvents.END_OF_TRACK, None),
+        ]
         procCompare(mf, match)
 
         # combinations of different pitches and durs
         s = Stream()
-        data = [('c2', 0.25), ('c#3', 0.5), ('g#3', 1.5), ('a#2', 1), ('a4', 2)]
+        data = [
+            ('c2', 0.25),
+            ('c#3', 0.5),
+            ('g#3', 1.5),
+            ('a#2', 1),
+            ('a4', 2),
+        ]
         for p, d in data:
             n = note.Note(p)
             n.quarterLength = d
             s.append(n)
 
         mf = midiTranslate.streamToMidiFile(s)
-        match = [(0, 'SEQUENCE_TRACK_NAME', None), (0, 'NOTE_ON', 36), (256, 'NOTE_OFF', 36),
-                 (0, 'NOTE_ON', 49), (512, 'NOTE_OFF', 49), (0, 'NOTE_ON', 56),
-                 (1536, 'NOTE_OFF', 56), (0, 'NOTE_ON', 46), (1024, 'NOTE_OFF', 46),
-                 (0, 'NOTE_ON', 69), (2048, 'NOTE_OFF', 69), (0, 'END_OF_TRACK', None)]
+        match = [
+            (0, MetaEvents.SEQUENCE_TRACK_NAME, None),
+            (0, ChannelVoiceMessages.PITCH_BEND, None),
+            (0, ChannelVoiceMessages.NOTE_ON, 36),
+            (256, ChannelVoiceMessages.NOTE_OFF, 36),
+            (0, ChannelVoiceMessages.NOTE_ON, 49),
+            (512, ChannelVoiceMessages.NOTE_OFF, 49),
+            (0, ChannelVoiceMessages.NOTE_ON, 56),
+            (1536, ChannelVoiceMessages.NOTE_OFF, 56),
+            (0, ChannelVoiceMessages.NOTE_ON, 46),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 46),
+            (0, ChannelVoiceMessages.NOTE_ON, 69),
+            (2048, ChannelVoiceMessages.NOTE_OFF, 69),
+            (1024, MetaEvents.END_OF_TRACK, None),
+        ]
         procCompare(mf, match)
 
         # rests, basic
         # environLocal.printDebug(['rests'])
         s = Stream()
-        data = [('c2', 1), (None, 0.5), ('c#3', 1), (None, 0.5), ('a#2', 1), (None, 0.5), ('a4', 1)]
+        data = [
+            ('c2', 1),
+            (None, 0.5),
+            ('c#3', 1),
+            (None, 0.5),
+            ('a#2', 1),
+            (None, 0.5),
+            ('a4', 1),
+        ]
         for p, d in data:
             if p is None:
                 n = note.Rest()
@@ -3378,18 +3422,31 @@ class Test(unittest.TestCase):
         # s.show('midi')
         mf = midiTranslate.streamToMidiFile(s)
         match = [
-            (0, 'SEQUENCE_TRACK_NAME', None),
-            (0, 'NOTE_ON', 36), (1024, 'NOTE_OFF', 36),
-            (512, 'NOTE_ON', 49), (1024, 'NOTE_OFF', 49),
-            (512, 'NOTE_ON', 46), (1024, 'NOTE_OFF', 46),
-            (512, 'NOTE_ON', 69), (1024, 'NOTE_OFF', 69),
-            (0, 'END_OF_TRACK', None),
+            (0, MetaEvents.SEQUENCE_TRACK_NAME, None),
+            (0, ChannelVoiceMessages.PITCH_BEND, None),
+            (0, ChannelVoiceMessages.NOTE_ON, 36),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 36),
+            (512, ChannelVoiceMessages.NOTE_ON, 49),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 49),
+            (512, ChannelVoiceMessages.NOTE_ON, 46),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 46),
+            (512, ChannelVoiceMessages.NOTE_ON, 69),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 69),
+            (1024, MetaEvents.END_OF_TRACK, None),
         ]
         procCompare(mf, match)
 
         # environLocal.printDebug(['rests, varied sizes'])
         s = Stream()
-        data = [('c2', 1), (None, 0.25), ('c#3', 1), (None, 1.5), ('a#2', 1), (None, 2), ('a4', 1)]
+        data = [
+            ('c2', 1),
+            (None, 0.25),
+            ('c#3', 1),
+            (None, 1.5),
+            ('a#2', 1),
+            (None, 2),
+            ('a4', 1),
+        ]
         for p, d in data:
             if p is None:
                 n = note.Rest()
@@ -3400,20 +3457,36 @@ class Test(unittest.TestCase):
         # s.show('midi')
         mf = midiTranslate.streamToMidiFile(s)
         match = [
-            (0, 'SEQUENCE_TRACK_NAME', None),
-            (0, 'NOTE_ON', 36), (1024, 'NOTE_OFF', 36),
-            (256, 'NOTE_ON', 49), (1024, 'NOTE_OFF', 49),
-            (1536, 'NOTE_ON', 46), (1024, 'NOTE_OFF', 46),
-            (2048, 'NOTE_ON', 69), (1024, 'NOTE_OFF', 69),
-            (0, 'END_OF_TRACK', None),
+            (0, MetaEvents.SEQUENCE_TRACK_NAME, None),
+            (0, ChannelVoiceMessages.PITCH_BEND, None),
+            (0, ChannelVoiceMessages.NOTE_ON, 36),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 36),
+            (256, ChannelVoiceMessages.NOTE_ON, 49),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 49),
+            (1536, ChannelVoiceMessages.NOTE_ON, 46),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 46),
+            (2048, ChannelVoiceMessages.NOTE_ON, 69),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 69),
+            (1024, MetaEvents.END_OF_TRACK, None),
         ]
         procCompare(mf, match)
 
         # environLocal.printDebug(['rests, multiple in a row'])
         s = Stream()
-        data = [('c2', 1), (None, 1), (None, 1), ('c#3', 1), ('c#3', 1),
-                (None, 0.5), (None, 0.5), (None, 0.5), (None, 0.5),
-                ('a#2', 1), (None, 2), ('a4', 1)]
+        data = [
+            ('c2', 1),
+            (None, 1),
+            (None, 1),
+            ('c#3', 1),
+            ('c#3', 1),
+            (None, 0.5),
+            (None, 0.5),
+            (None, 0.5),
+            (None, 0.5),
+            ('a#2', 1),
+            (None, 2),
+            ('a4', 1),
+        ]
         for p, d in data:
             if p is None:
                 n = note.Rest()
@@ -3423,20 +3496,37 @@ class Test(unittest.TestCase):
             s.append(n)
         # s.show('midi')
         mf = midiTranslate.streamToMidiFile(s)
-        match = [(0, 'SEQUENCE_TRACK_NAME', None),
-                 (0, 'NOTE_ON', 36), (1024, 'NOTE_OFF', 36),
-                 (2048, 'NOTE_ON', 49), (1024, 'NOTE_OFF', 49),
-                 (0, 'NOTE_ON', 49), (1024, 'NOTE_OFF', 49),
-                 (2048, 'NOTE_ON', 46), (1024, 'NOTE_OFF', 46),
-                 (2048, 'NOTE_ON', 69), (1024, 'NOTE_OFF', 69),
-                 (0, 'END_OF_TRACK', None)]
+        match = [
+            (0, MetaEvents.SEQUENCE_TRACK_NAME, None),
+            (0, ChannelVoiceMessages.PITCH_BEND, None),
+            (0, ChannelVoiceMessages.NOTE_ON, 36),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 36),
+            (2048, ChannelVoiceMessages.NOTE_ON, 49),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 49),
+            (0, ChannelVoiceMessages.NOTE_ON, 49),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 49),
+            (2048, ChannelVoiceMessages.NOTE_ON, 46),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 46),
+            (2048, ChannelVoiceMessages.NOTE_ON, 69),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 69),
+            (1024, MetaEvents.END_OF_TRACK, None),
+        ]
         procCompare(mf, match)
 
         # environLocal.printDebug(['w/ chords'])
         s = Stream()
-        data = [('c2', 1), (None, 1), (['f3', 'a-4', 'c5'], 1), (None, 0.5), ('a#2', 1),
-                (None, 2), (['d2', 'a4'], 0.5), (['d-2', 'a#3', 'g#6'], 0.5), (None, 1),
-                (['f#3', 'a4', 'c#5'], 4)]
+        data = [
+            ('c2', 1),
+            (None, 1),
+            (['f3', 'a-4', 'c5'], 1),
+            (None, 0.5),
+            ('a#2', 1),
+            (None, 2),
+            (['d2', 'a4'], 0.5),
+            (['d-2', 'a#3', 'g#6'], 0.5),
+            (None, 1),
+            (['f#3', 'a4', 'c#5'], 4)
+        ]
         for p, d in data:
             if p is None:
                 n = note.Rest()
@@ -3448,16 +3538,37 @@ class Test(unittest.TestCase):
             s.append(n)
         # s.show('midi')
         mf = midiTranslate.streamToMidiFile(s)
-        match = [(0, 'SEQUENCE_TRACK_NAME', None), (0, 'NOTE_ON', 36), (1024, 'NOTE_OFF', 36),
-                 (1024, 'NOTE_ON', 53), (0, 'NOTE_ON', 68), (0, 'NOTE_ON', 72),
-                 (1024, 'NOTE_OFF', 53), (0, 'NOTE_OFF', 68), (0, 'NOTE_OFF', 72),
-                 (512, 'NOTE_ON', 46), (1024, 'NOTE_OFF', 46), (2048, 'NOTE_ON', 38),
-                 (0, 'NOTE_ON', 69), (512, 'NOTE_OFF', 38), (0, 'NOTE_OFF', 69),
-                 (0, 'NOTE_ON', 37), (0, 'NOTE_ON', 58), (0, 'NOTE_ON', 92),
-                 (512, 'NOTE_OFF', 37), (0, 'NOTE_OFF', 58), (0, 'NOTE_OFF', 92),
-                 (1024, 'NOTE_ON', 54), (0, 'NOTE_ON', 69), (0, 'NOTE_ON', 73),
-                 (4096, 'NOTE_OFF', 54), (0, 'NOTE_OFF', 69), (0, 'NOTE_OFF', 73),
-                 (0, 'END_OF_TRACK', None)]
+        match = [
+            (0, MetaEvents.SEQUENCE_TRACK_NAME, None),
+            (0, ChannelVoiceMessages.PITCH_BEND, None),
+            (0, ChannelVoiceMessages.NOTE_ON, 36),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 36),
+            (1024, ChannelVoiceMessages.NOTE_ON, 53),
+            (0, ChannelVoiceMessages.NOTE_ON, 68),
+            (0, ChannelVoiceMessages.NOTE_ON, 72),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 53),
+            (0, ChannelVoiceMessages.NOTE_OFF, 68),
+            (0, ChannelVoiceMessages.NOTE_OFF, 72),
+            (512, ChannelVoiceMessages.NOTE_ON, 46),
+            (1024, ChannelVoiceMessages.NOTE_OFF, 46),
+            (2048, ChannelVoiceMessages.NOTE_ON, 38),
+            (0, ChannelVoiceMessages.NOTE_ON, 69),
+            (512, ChannelVoiceMessages.NOTE_OFF, 38),
+            (0, ChannelVoiceMessages.NOTE_OFF, 69),
+            (0, ChannelVoiceMessages.NOTE_ON, 37),
+            (0, ChannelVoiceMessages.NOTE_ON, 58),
+            (0, ChannelVoiceMessages.NOTE_ON, 92),
+            (512, ChannelVoiceMessages.NOTE_OFF, 37),
+            (0, ChannelVoiceMessages.NOTE_OFF, 58),
+            (0, ChannelVoiceMessages.NOTE_OFF, 92),
+            (1024, ChannelVoiceMessages.NOTE_ON, 54),
+            (0, ChannelVoiceMessages.NOTE_ON, 69),
+            (0, ChannelVoiceMessages.NOTE_ON, 73),
+            (4096, ChannelVoiceMessages.NOTE_OFF, 54),
+            (0, ChannelVoiceMessages.NOTE_OFF, 69),
+            (0, ChannelVoiceMessages.NOTE_OFF, 73),
+            (1024, MetaEvents.END_OF_TRACK, None),
+        ]
         procCompare(mf, match)
 
     def testFindGaps(self):
@@ -3477,7 +3588,6 @@ class Test(unittest.TestCase):
     def testQuantize(self):
 
         def procCompare(srcOffset, srcDur, dstOffset, dstDur, divList):
-
             s = Stream()
             for i in range(len(srcDur)):
                 n = note.Note()
@@ -3679,7 +3789,7 @@ class Test(unittest.TestCase):
         self.assertEqual(collectType(s), [None, None, None, 'start', None, 'stop'])
         # s.show()
 
-        # case of incomplete, single tuplets in the middle of a Strem
+        # case of incomplete, single tuplets in the middle of a Stream
         s = Stream()
         qlList = [1, 1 / 3, 1, 1 / 3, 1, 1 / 3]
         for ql in qlList:
@@ -3732,35 +3842,35 @@ class Test(unittest.TestCase):
     def testMakeNotationA(self):
         '''This is a test of many make procedures
         '''
-        def collectTupletType(s):
+        def collectTupletType(s_inner):
             post = []
-            for e in s:
+            for e in s_inner:
                 if e.duration.tuplets:
                     post.append(e.duration.tuplets[0].type)
                 else:
                     post.append(None)
             return post
 
-        def collectTupletBracket(s):
+        def collectTupletBracket(s_inner):
             post = []
-            for e in s:
+            for e in s_inner:
                 if e.duration.tuplets:
                     post.append(e.duration.tuplets[0].bracket)
                 else:
                     post.append(None)
             return post
 
-#         s = Stream()
-#         qlList = [1, 1/3, 1/3, 1/3, 1, 1, 1/3, 1/3, 1/3, 1, 1]
-#         for ql in qlList:
-#             n = note.Note()
-#             n.quarterLength = ql
-#             s.append(n)
-#         postMake = s.makeNotation()
-#         self.assertEqual(collectTupletType(postMake.flat.notesAndRests),
-#                            [None, 'start', None, 'stop', None, None, 'start',
-#                             None, 'stop', None, None])
-#         # sshow()
+        # s = Stream()
+        # qlList = [1, 1/3, 1/3, 1/3, 1, 1, 1/3, 1/3, 1/3, 1, 1]
+        # for ql in qlList:
+        #     n = note.Note()
+        #     n.quarterLength = ql
+        #     s.append(n)
+        # postMake = s.makeNotation()
+        # self.assertEqual(collectTupletType(postMake.flat.notesAndRests),
+        #                    [None, 'start', None, 'stop', None, None, 'start',
+        #                     None, 'stop', None, None])
+        # # s.show()
 
         s = Stream()
         qlList = [1 / 3, ]
@@ -3959,9 +4069,9 @@ class Test(unittest.TestCase):
 
         from music21 import corpus
 
-        def collectAccidentalDisplayStatus(s):
+        def collectAccidentalDisplayStatus(s_inner):
             post = []
-            for e in s.flat.notesAndRests:
+            for e in s_inner.flat.notesAndRests:
                 if e.pitch.accidental is not None:
                     post.append((e.pitch.name, e.pitch.accidental.displayStatus))
                 else:  # mark as not having an accidental
@@ -4050,7 +4160,7 @@ class Test(unittest.TestCase):
         sSorted = s.sorted
         # original unchanged
         self.assertEqual([x.name for x in s], ['B', 'A'])
-        # new is chnaged
+        # new is changed
         self.assertEqual([x.name for x in sSorted], ['A', 'B'])
         # sort in place
         s.sort()
@@ -4483,6 +4593,8 @@ class Test(unittest.TestCase):
         # test that element may not be in stream elements and at end.
         b2 = bar.Barline()
         s.insert(0, b2)
+        self.assertEqual(b2.offset, 0)
+        self.assertEqual(s.elementOffset(b2, stringReturns=True), 0)
         with self.assertRaises(stream.StreamException):
             s.storeAtEnd(b2)
 
@@ -5114,6 +5226,7 @@ class Test(unittest.TestCase):
         # post.show()
         self.assertEqual(len(post.flat.getElementsByClass('Chord')), 8)
 
+    # noinspection SpellCheckingInspection
     def testOpusSearch(self):
         from music21 import corpus
         import re
@@ -5642,7 +5755,8 @@ class Test(unittest.TestCase):
             if beatStr not in melismaByBeat:
                 melismaByBeat[beatStr] = []
             melismaByBeat[beatStr].append(dur)
-            # environLocal.printDebug(['start note:', n, 'beat:', beatStr, 'slured duration:', dur])
+            # environLocal.printDebug(['start note:', n, 'beat:', beatStr,
+            #     'slurred duration:', dur])
 
         for beatStr in sorted(list(melismaByBeat.keys())):
             unused_avg = sum(melismaByBeat[beatStr]) / len(melismaByBeat[beatStr])
@@ -5702,7 +5816,7 @@ class Test(unittest.TestCase):
     def testStripTiesImportedB(self):
         from music21 import corpus
 
-        # this file was imported by sibelius and does not have completeing ties
+        # this file was imported by sibelius and does not have completed ties
         sMonte = corpus.parse('monteverdi/madrigal.4.2.xml')
         s1 = sMonte.parts['Alto']
         mStream = s1.getElementsByClass('Measure')
@@ -5807,7 +5921,7 @@ class Test(unittest.TestCase):
         s2 = copy.deepcopy(s1Flat)
         self.assertIs(s2.derivation.origin, s1Flat)
         self.assertIs(s2.derivation.origin.derivation.origin, s1)
-        # check low level attrbiutes
+        # check low level attributes
         self.assertIs(s2._derivation.client, s2)
 
     def testDerivationC(self):
@@ -5837,7 +5951,7 @@ class Test(unittest.TestCase):
         s1m1 = s1m.measure(1)
         self.assertEqual(s1m1.derivation.origin, None)
 
-    def testcontainerHierarchyA(self):
+    def testContainerHierarchyA(self):
         from music21 import corpus
         s = corpus.parse('bach/bwv66.6')
         # the part is not derived from anything yet
@@ -6056,10 +6170,10 @@ class Test(unittest.TestCase):
                     # some Measures contain Voices, some do not
                     # do get all notes regardless of Voices, take a flat measure
                     self.assertTrue(meas.flat.notesAndRests)
-        piece = corpus.parse('corelli/opus3no1/1grave')
-        parseMeasures(piece)
-        piece = corpus.parse('bach/bwv7.7')
-        parseMeasures(piece)
+        corelli = corpus.parse('corelli/opus3no1/1grave')
+        parseMeasures(corelli)
+        bach = corpus.parse('bach/bwv7.7')
+        parseMeasures(bach)
 
     def testMakeNotationByMeasuresA(self):
         from music21 import stream
@@ -6404,7 +6518,7 @@ class Test(unittest.TestCase):
                          '[<music21.bar.Barline type=tick>, <music21.bar.Barline type=tick>, '
                          + '<music21.bar.Barline type=tick>, <music21.bar.Barline type=tick>]')
 
-        # can set a heterogenous final barlines
+        # can set heterogeneous final barlines
         s.finalBarline = ['final', 'none']
         self.assertEqual(str(s.finalBarline),
                          '[<music21.bar.Barline type=final>, <music21.bar.Barline type=none>, '
@@ -6771,7 +6885,7 @@ class Test(unittest.TestCase):
         sNew.append(p2)
         self.assertEqual(sNew.duration.quarterLength, 144.0)
 
-        # sost = sNew.chordify()
+        # sPost = sNew.chordify()
         # sPost.show()
 
     def testPartDurationB(self):
@@ -6971,8 +7085,6 @@ class Test(unittest.TestCase):
 
         s = corpus.parse('bwv66.6')
         sChords = s.measures(9, 9).chordify()
-        # sChords.show()
-        # shords = s.chordify()
         sChords.extendTies()
         post = []
         for ch in sChords.flat.getElementsByClass('Chord'):
@@ -7122,7 +7234,7 @@ class Test(unittest.TestCase):
         match = match.replace('\n', '')
         raw = originalRaw.replace(' ', '')
         raw = raw.replace('\n', '')
-        self.assertEqual(raw.find(match) > 0, True, (raw))
+        self.assertEqual(raw.find(match) > 0, True, raw)
 
     def testInvertDiatonicA(self):
         # TODO: Check results
@@ -7347,7 +7459,7 @@ class Test(unittest.TestCase):
     def testMakeVoicesB(self):
         from music21 import corpus
         s = corpus.parse('bwv66.6')
-        # smeasures(6, 7).show()
+        # s.measures(6, 7).show()
         sMeasures = s.measures(6, 7)
         sFlatVoiced = sMeasures.flat.makeVoices(inPlace=False)
         # sFlatVoiced.show('t')
@@ -8018,5 +8130,5 @@ class Test(unittest.TestCase):
 
 
 if __name__ == '__main__':
-    music21.mainTest(Test, 'verbose',)  # runTest='testChordifyTagPartB')
+    music21.mainTest(Test, 'verbose')