Skip to content

Commit

Permalink
more metadata DatePrimitive work
Browse files Browse the repository at this point in the history
  • Loading branch information
mscuthbert committed Aug 16, 2022
1 parent ba6f1e4 commit 38d103a
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 19 deletions.
16 changes: 11 additions & 5 deletions music21/metadata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@
from music21.metadata import bundles
from music21.metadata import caching
from music21.metadata import primitives
from music21.metadata.primitives import (Date, DateSingle, DateRelative, DateBetween,
from music21.metadata.primitives import (Date, DatePrimitive,
DateSingle, DateRelative, DateBetween,
DateSelection, Text, Contributor, Creator,
Imprint, Copyright, ValueType)

Expand Down Expand Up @@ -2311,21 +2312,26 @@ def _convertValue(uniqueName: str, value: t.Any) -> ValueType:
raise exceptions21.MetadataException(
f'invalid type for Copyright: {type(value).__name__}')

if valueType is DateSingle:
if valueType is DatePrimitive:
# note -- this may return something other than DateSingle depending
# on the context.
if isinstance(value, Text):
value = str(value)
if isinstance(value, (str, datetime.datetime, Date)):

if isinstance(value, DatePrimitive):
# If you want other DateSingle-derived types (DateRelative,
# DateBetween, or DateSelection), you have to create those
# yourself before adding/setting them.
return value

if isinstance(value, (str, datetime.datetime, Date)):
# noinspection PyBroadException
# pylint: disable=bare-except
try:
return DateSingle(value)
except:
# Couldn't convert; just return unconverted value
return originalValue
# Couldn't convert; just return a generic text.
return Text(str(originalValue))
# pylint: enable=bare-except

raise exceptions21.MetadataException(
Expand Down
3 changes: 1 addition & 2 deletions music21/metadata/primitives.py
Original file line number Diff line number Diff line change
Expand Up @@ -1507,8 +1507,7 @@ def testDateSelection(self):
)

DateParseType = t.Union[Date, datetime.datetime, str]
ValueType = t.Union[DateSingle, DateRelative, DateBetween, DateSelection,
Text, Contributor, Copyright, int]
ValueType = t.Union[DatePrimitive, Text, Contributor, Copyright, int]


if __name__ == '__main__':
Expand Down
24 changes: 12 additions & 12 deletions music21/metadata/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import typing as t
from dataclasses import dataclass

from music21.metadata.primitives import (DateSingle, Text, Contributor, Copyright, ValueType)
from music21.metadata.primitives import (DatePrimitive, Text, Contributor, Copyright, ValueType)


@dataclass
Expand Down Expand Up @@ -94,7 +94,7 @@ class PropertyDescription:
uniqueName='dateAvailable',
name='available',
namespace='dcterms',
valueType=DateSingle, # including DateRelative, DateBetween, DateSelection
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# bibliographicCitation: A bibliographic reference for the resource.
Expand All @@ -115,7 +115,7 @@ class PropertyDescription:
name='created',
namespace='dcterms',
oldMusic21WorkId='date',
valueType=DateSingle, # including DateRelative, DateBetween, DateSelection
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# otherDate: A point or period of time associated with an event in the lifecycle
Expand All @@ -124,28 +124,28 @@ class PropertyDescription:
uniqueName='otherDate',
name='date',
namespace='dcterms',
valueType=DateSingle, # including DateRelative, DateBetween, DateSelection
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# dateAccepted: Date of acceptance of the resource.
PropertyDescription(
name='dateAccepted',
namespace='dcterms',
valueType=DateSingle, # including DateRelative, DateBetween, DateSelection
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# dateCopyrighted: Date of copyright of the resource.
PropertyDescription(
name='dateCopyrighted',
namespace='dcterms',
valueType=DateSingle, # including DateRelative, DateBetween, DateSelection
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# dateSubmitted: Date of submission of the resource.
PropertyDescription(
name='dateSubmitted',
namespace='dcterms',
valueType=DateSingle, # including DateRelative, DateBetween, DateSelection
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# description: An account of the resource.
Expand Down Expand Up @@ -248,7 +248,7 @@ class PropertyDescription:
uniqueName='dateIssued',
name='issued',
namespace='dcterms',
valueType=DateSingle, # including DateRelative, DateBetween, DateSelection
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# isVersionOf: A related resource of which the described resource is a
Expand Down Expand Up @@ -282,7 +282,7 @@ class PropertyDescription:
uniqueName='dateModified',
name='modified',
namespace='dcterms',
valueType=DateSingle, # including DateRelative, DateBetween, DateSelection
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# provenance: A statement of any changes in ownership and custody of
Expand Down Expand Up @@ -381,7 +381,7 @@ class PropertyDescription:
uniqueName='dateValid',
name='valid',
namespace='dcterms',
valueType=DateSingle, # including DateRelative, DateBetween, DateSelection
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# The following 'marcrel' property terms are MARC Relator terms,
Expand Down Expand Up @@ -1009,7 +1009,7 @@ class PropertyDescription:
uniqueName='dateFirstPublished',
name='PDT',
namespace='humdrum',
valueType=DateSingle,
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# publicationTitle: Title of the publication (volume) from which the work
Expand Down Expand Up @@ -1121,7 +1121,7 @@ class PropertyDescription:
uniqueName='electronicReleaseDate',
name='YER',
namespace='humdrum',
valueType=DateSingle,
valueType=DatePrimitive, # including DateSingle, DateRelative, DateBetween, DateSelection
isContributor=False),

# The following properties are in the music21 namespace, and are specific to
Expand Down

6 comments on commit 38d103a

@gregchapman-dev
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some thoughts on DatePrimitive. First, I love it! Second, please make sure that all DatePrimitive-derived classes can be initialized with Dates, not just strings. They could before (and I use this facility in my Humdrum parser), but some of them were type-hinted so, and some were not. Third, it looks like str is returning space-delimited date strings for the different multiple-Date classes. At some point (maybe not now) it would be good to make these strings that can be parsed back into the appropriate DatePrimitive-derived class (without external knowledge of which class is appropriate). Humdrum has a nice string format for these (**zeit format, which is pretty much exactly what load() already knows how to parse), and I have some code that can convert between DateBlah and str, and then back to the appropriate DateBlah.

@gregchapman-dev
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's that snippet of code:
M21ConvertSnippet.py.txt

@gregchapman-dev
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's got some stolen music21 code in it, but then it's enhanced.

@mscuthbert
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha -- yes, let's make sure of that too. But how would it work with DateBetween, and the >2 Dates one? OH, I suppose subclasses can be MORE lenient about what they accept as initialization, just not less. So they can take a list of Date elements as well, like they currently do. I'll get on that

@mscuthbert
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's got some stolen music21 code in it, but then it's enhanced.

BSD license means you can't steal it. It's already free. :-D

@mscuthbert
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah -- that was a TODO I didn't finish. I even made a DateParseType for doing this.

Please sign in to comment.