Repository: cuthbertLab/music21

Issue:
voicesToParts
voicesToParts seemingly doesn't transfers initial time and key signatures if the first measure doesn't contain a second voice (even if subsequent measures do).

The images show how this looks when opened in MuseScore, (some other notation softwares will 'correct' the issue, masking the problem).

![Before](https://user-images.githubusercontent.com/19486660/87411703-fe0e5900-c5bf-11ea-822a-7f71bea1a8b2.png)
![After](https://user-images.githubusercontent.com/19486660/87411716-023a7680-c5c0-11ea-8a09-f2ddb1551ec3.png)


Comments:

Patch:
diff --git a/music21/stream/__init__.py b/music21/stream/__init__.py
index 5133aa68f..e3d28c408 100644
--- a/music21/stream/__init__.py
+++ b/music21/stream/__init__.py
@@ -9970,6 +9970,7 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
                 ...
                 {3.5} <music21.note.Note A>
             {8.0} <music21.stream.Measure 3 offset=8.0>
+                {0.0} <music21.bar.Barline type=final>
         <BLANKLINE>
 
         If `separateById` is True then all voices with the same id
@@ -10054,7 +10055,7 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
             # merge everything except Voices; this will get
             # clefs
             mActive.mergeElements(m, classFilterList=(
-                'Bar', 'TimeSignature', 'Clef', 'KeySignature'))
+                'Barline', 'TimeSignature', 'Clef', 'KeySignature'))
 
             # vIndex = 0 should not be necessary, but pylint warns on loop variables
             # that could possibly be undefined used out of the loop.
@@ -10105,6 +10106,9 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
                     for i in range(1, partCount):
                         mEmpty = Measure()
                         mEmpty.mergeAttributes(m)
+                        # Propagate bar, meter, key elements to lower parts
+                        mEmpty.mergeElements(m, classFilterList=('Barline',
+                                            'TimeSignature', 'KeySignature'))
                         s.parts[i].insert(self.elementOffset(m), mEmpty)
         # if part has no measures but has voices, contents of each voice go into the part
         elif self.hasVoices():
@@ -12836,7 +12840,7 @@ class Score(Stream):
                         # attributes; possible other parts may have other attributes
                         mActive.mergeAttributes(m)
                         mActive.mergeElements(m, classFilterList=(
-                            'Bar', 'TimeSignature', 'Clef', 'KeySignature'))
+                            'Barline', 'TimeSignature', 'Clef', 'KeySignature'))
 
                         # if m.timeSignature is not None:
                         #     mActive.timeSignature = m.timeSignature
@@ -12855,7 +12859,7 @@ class Score(Stream):
                         if setStems and hasattr(e, 'stemDirection'):
                             e.stemDirection = 'up' if pIndex % 2 == 0 else 'down'
                         v.insert(e.getOffsetBySite(m), e)
-                    # insert voice in new  measure
+                    # insert voice in new measure
                     # environLocal.printDebug(['inserting voice', v, v.id, 'into measure', mActive])
                     mActive.insert(0, v)
                     # mActive.show('t')


Test patch:
diff --git a/music21/test/testStream.py b/music21/test/testStream.py
index ecc105b2b..8925c2bef 100644
--- a/music21/test/testStream.py
+++ b/music21/test/testStream.py
@@ -5391,6 +5391,34 @@ class Test(unittest.TestCase):
 
         # s1.show()
 
+    def testVoicesToPartsNonNoteElementPropagation(self):
+        k = key.Key('E')
+        ts = meter.TimeSignature('2/4')
+        b1 = bar.Barline('regular')
+        b2 = bar.Barline('final')
+
+        s = Score()
+        m1 = Measure()  # No voices
+        m1.append((k, ts, note.Note(type='half')))
+        m1.rightBarline = b1
+        m2 = Measure()  # Has voices
+        v1 = Voice()
+        v2 = Voice()
+        v1.append(note.Note(type='half'))
+        v2.append(note.Note(type='half'))
+        m2.insert(0, v1)
+        m2.insert(0, v2)
+        m2.rightBarline = b2
+        s.append((m1, m2))
+
+        partScore = s.voicesToParts()
+        for part in partScore.parts:
+            flattenedPart = part.flat
+            self.assertIn(k, flattenedPart)
+            self.assertIn(ts, flattenedPart)
+            self.assertIsNotNone(part.getElementsByClass("Measure")[0].rightBarline)
+            self.assertIsNotNone(part.getElementsByClass("Measure")[1].rightBarline)
+
     def testMergeElements(self):
         from music21 import stream
         s1 = stream.Stream()