Skip to content

Commit 3fb7eb6

Browse files
authored
Merge pull request #1761 from gregchapman-dev/gregc/no_enclosure
Support enclosure == Enclosure.NO_ENCLOSURE which is different from enclosure == None
2 parents 65c962c + 736785b commit 3fb7eb6

File tree

7 files changed

+23
-18
lines changed

7 files changed

+23
-18
lines changed

music21/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
'''
5151
from __future__ import annotations
5252

53-
__version__ = '9.6.0b1'
53+
__version__ = '9.6.0b2'
5454

5555
def get_version_tuple(vv):
5656
v = vv.split('.')

music21/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<class 'music21.base.Music21Object'>
2828
2929
>>> music21.VERSION_STR
30-
'9.6.0b1'
30+
'9.6.0b2'
3131
3232
Alternatively, after doing a complete import, these classes are available
3333
under the module "base":

music21/musicxml/m21ToXml.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -808,8 +808,6 @@ def setStyleAttributes(self, mxObject, m21Object, musicXMLNames, m21Names=None):
808808
except AttributeError:
809809
continue
810810

811-
if m21Name in xmlObjects.STYLE_ATTRIBUTES_STR_NONE_TO_NONE and m21Value is None:
812-
m21Value = 'none'
813811
if m21Name in xmlObjects.STYLE_ATTRIBUTES_YES_NO_TO_BOOL:
814812
m21Value = xmlObjects.booleanToYesNo(m21Value)
815813

@@ -6159,9 +6157,12 @@ def codaToXml(self, coda: repeat.Coda) -> Element:
61596157
</direction-type>
61606158
</direction>
61616159
6162-
turn coda.useSymbol to `False` to get a text expression instead
6160+
turn coda.useSymbol to `False` to get a text expression instead,
6161+
and set enclosure to NO_ENCLOSURE to explicitly generate
6162+
enclosure="none".
61636163
61646164
>>> c.useSymbol = False
6165+
>>> c.style.enclosure = style.Enclosure.NO_ENCLOSURE
61656166
>>> MEX = musicxml.m21ToXml.MeasureExporter()
61666167
>>> mxCodaText = MEX.codaToXml(c)
61676168
>>> MEX.dump(mxCodaText)
@@ -6213,7 +6214,7 @@ def tempoIndicationToXml(self, ti: tempo.TempoIndication) -> Element:
62136214
>>> MEX.dump(MEX.xmlRoot.findall('direction')[1])
62146215
<direction>
62156216
<direction-type>
6216-
<words default-y="45" enclosure="none" font-weight="bold"
6217+
<words default-y="45" font-weight="bold"
62176218
justify="left">slow</words>
62186219
</direction-type>
62196220
</direction>
@@ -6283,7 +6284,7 @@ def tempoIndicationToXml(self, ti: tempo.TempoIndication) -> Element:
62836284
>>> MEX.dump(mxDirection)
62846285
<direction>
62856286
<direction-type>
6286-
<words default-y="45" enclosure="none" font-weight="bold">Andante</words>
6287+
<words default-y="45" font-weight="bold">Andante</words>
62876288
</direction-type>
62886289
</direction>
62896290

music21/musicxml/test_xmlToM21.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from music21 import repeat
2424
from music21 import spanner
2525
from music21 import stream
26+
from music21 import style
2627
from music21 import tempo
2728
from music21 import text
2829

@@ -1064,7 +1065,8 @@ def testRehearsalMarks(self):
10641065
self.assertEqual(len(rmIterator), 4)
10651066
self.assertEqual(rmIterator[0].content, 'A')
10661067
self.assertEqual(rmIterator[1].content, 'B')
1067-
self.assertEqual(rmIterator[1].style.enclosure, None)
1068+
self.assertEqual(rmIterator[1].style.enclosure,
1069+
style.Enclosure.NO_ENCLOSURE)
10681070
self.assertEqual(rmIterator[2].content, 'Test')
10691071
self.assertEqual(rmIterator[2].style.enclosure, 'square')
10701072

music21/musicxml/xmlObjects.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ class MusicXMLWarning(UserWarning):
134134
# ------------------------------------------------------------------------------
135135
# helpers
136136
STYLE_ATTRIBUTES_YES_NO_TO_BOOL = ('hideObjectOnPrint', )
137-
STYLE_ATTRIBUTES_STR_NONE_TO_NONE = ('enclosure', )
138137

139138

140139
def yesNoToBoolean(value):

music21/musicxml/xmlToM21.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,7 @@ def setStyleAttributes(self, mxObject, m21Object, musicXMLNames, m21Names=None):
319319
if mxValue is None:
320320
continue
321321

322-
if mxValue == 'none' and m21Name in xmlObjects.STYLE_ATTRIBUTES_STR_NONE_TO_NONE:
323-
mxValue = None
324-
elif m21Name in xmlObjects.STYLE_ATTRIBUTES_YES_NO_TO_BOOL:
322+
if m21Name in xmlObjects.STYLE_ATTRIBUTES_YES_NO_TO_BOOL:
325323
mxValue = xmlObjects.yesNoToBoolean(mxValue)
326324

327325
try:

music21/style.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class Enclosure(common.StrEnum):
4545
NONAGON = 'nonagon'
4646
DECAGON = 'decagon'
4747
INVERTED_BRACKET = 'inverted-bracket'
48-
NONE = 'none' # special -- sets to None.
48+
NO_ENCLOSURE = 'none'
4949

5050

5151
class Style(ProtoM21Object):
@@ -87,6 +87,8 @@ def __init__(self) -> None:
8787
# managed by property below.
8888
self._absoluteY: float|int|None = None
8989

90+
# None means enclosure is left unspecified, NO_ENCLOSURE means
91+
# explicitly that there is no enclosure.
9092
self._enclosure: Enclosure|None = None
9193

9294
# how should this symbol be represented in the font?
@@ -105,7 +107,8 @@ def __init__(self) -> None:
105107
@property
106108
def enclosure(self) -> Enclosure|None:
107109
'''
108-
Get or set the enclosure as a style.Enclosure enum or None.
110+
Get or set the enclosure as a style.Enclosure enum (or
111+
None, which means the enclosure is left unspecified).
109112
110113
Valid names are:
111114
@@ -115,7 +118,8 @@ def enclosure(self) -> Enclosure|None:
115118
* "circle"/style.Enclosure.CIRCLE,
116119
* "bracket"/style.Enclosure.BRACKET,
117120
* "inverted-bracket"/style.Enclosure.INVERTED_BRACKET (output in musicxml 4 only)
118-
* None/"none"/style.Enclosure.NONE (returns Python None object)
121+
* "none"/style.Enclosure.NO_ENCLOSURE
122+
* None (i.e. enclosure is unspecified)
119123
120124
or the following other shapes with their ALLCAPS Enclosure equivalents:
121125
@@ -151,15 +155,16 @@ def enclosure(self) -> Enclosure|None:
151155
Traceback (most recent call last):
152156
music21.style.TextFormatException:
153157
Not a supported enclosure: 4
158+
159+
* Changed in v9.7: We now differentiate between no enclosure
160+
(Enclosure.NO_ENCLOSURE) and unspecified enclosure (None).
154161
'''
155162
return self._enclosure
156163

157164
@enclosure.setter
158-
def enclosure(self, value: Enclosure|None):
165+
def enclosure(self, value: Enclosure|str|None):
159166
if value is None:
160167
self._enclosure = value
161-
elif value == Enclosure.NONE:
162-
self._enclosure = None
163168
elif isinstance(value, Enclosure):
164169
self._enclosure = value
165170
elif isinstance(value, str):

0 commit comments

Comments
 (0)