Skip to content

Commit 662801c

Browse files
committed
fix: remove Literal.toPython casting for gYear and gYearMonth
Issue #3078 reports, that toPython-casting of xsd:gYear and xsd:gYearMonth to datetime objects is not possible, as there is no appropriate Python equivalence for those types. The current implementation casts xsd:gYear and xsd:gYearMonth to datetime objects assuming Jannuary 1st for xsd:gYear and the 1st day of the given month for xsd:gYearMonth. This is plain wrong. The change removes casting to datetime objects in rdflib.Literal.toPython for xsd:gYear and xsd:gYearMonth. Closes #3078 .
1 parent 9f76b0f commit 662801c

File tree

2 files changed

+0
-77
lines changed

2 files changed

+0
-77
lines changed

rdflib/term.py

-4
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@
6969
parse_time,
7070
parse_xsd_date,
7171
parse_xsd_duration,
72-
parse_xsd_gyear,
73-
parse_xsd_gyearmonth,
7472
)
7573

7674
if TYPE_CHECKING:
@@ -2085,8 +2083,6 @@ def _castPythonToLiteral( # noqa: N802
20852083
None: None, # plain literals map directly to value space
20862084
URIRef(_XSD_PFX + "time"): parse_time,
20872085
URIRef(_XSD_PFX + "date"): parse_xsd_date,
2088-
URIRef(_XSD_PFX + "gYear"): parse_xsd_gyear,
2089-
URIRef(_XSD_PFX + "gYearMonth"): parse_xsd_gyearmonth,
20902086
URIRef(_XSD_PFX + "dateTime"): parse_datetime,
20912087
URIRef(_XSD_PFX + "duration"): parse_xsd_duration,
20922088
URIRef(_XSD_PFX + "dayTimeDuration"): parse_xsd_duration,

rdflib/xsd_datetime.py

-73
Original file line numberDiff line numberDiff line change
@@ -593,79 +593,6 @@ def parse_xsd_date(date_string: str):
593593
return parse_date(date_string if not minus else ("-" + date_string))
594594

595595

596-
def parse_xsd_gyear(gyear_string: str):
597-
"""
598-
XSD gYear has more features than ISO8601 dates, specifically
599-
XSD allows timezones on a gYear, that must be stripped off.
600-
"""
601-
if gyear_string.endswith("Z") or gyear_string.endswith("z"):
602-
gyear_string = gyear_string[:-1]
603-
if gyear_string.startswith("-"):
604-
gyear_string = gyear_string[1:]
605-
minus = True
606-
else:
607-
minus = False
608-
has_plus = gyear_string.rfind("+")
609-
if has_plus > 0:
610-
# Drop the +07:00 timezone part
611-
gyear_string = gyear_string[:has_plus]
612-
else:
613-
split_parts = gyear_string.rsplit("-", 1)
614-
if len(split_parts) > 1 and ":" in split_parts[-1]:
615-
# Drop the -09:00 timezone part
616-
gyear_string = split_parts[0]
617-
if len(gyear_string) < 4:
618-
raise ValueError("gYear string must be at least 4 numerals in length")
619-
gyear_string = gyear_string.lstrip("0") # strip all leading zeros
620-
try:
621-
y = int(gyear_string if not minus else ("-" + gyear_string))
622-
except ValueError:
623-
raise ValueError("gYear string must be a valid integer")
624-
return date(y, 1, 1)
625-
626-
627-
def parse_xsd_gyearmonth(gym_string: str):
628-
"""
629-
XSD gYearMonth has more features than ISO8601 dates, specifically
630-
XSD allows timezones on a gYearMonth, that must be stripped off.
631-
"""
632-
if gym_string.endswith("Z") or gym_string.endswith("z"):
633-
gym_string = gym_string[:-1]
634-
if gym_string.startswith("-"):
635-
gym_string = gym_string[1:]
636-
minus = True
637-
else:
638-
minus = False
639-
has_plus = gym_string.rfind("+")
640-
if has_plus > 0:
641-
# Drop the +07:00 timezone part
642-
gym_string = gym_string[:has_plus]
643-
else:
644-
split_parts = gym_string.rsplit("-", 1)
645-
if len(split_parts) > 1 and ":" in split_parts[-1]:
646-
# Drop the -09:00 timezone part
647-
gym_string = split_parts[0]
648-
year_month_parts = gym_string.split("-", 1)
649-
if len(year_month_parts) < 2:
650-
raise ValueError("XSD gYearMonth string must contain one dash")
651-
652-
if len(year_month_parts[0]) < 4:
653-
raise ValueError("gYearMonth Year part must be at least 4 numerals in length")
654-
elif len(year_month_parts[1]) < 2:
655-
raise ValueError("gYearMonth Month part must be exactly 2 numerals in length")
656-
year_string = year_month_parts[0].lstrip("0") # strip all leading zeros
657-
month_string = year_month_parts[1].lstrip("0") # strip all leading zeros
658-
try:
659-
y = int(year_string if not minus else ("-" + year_string))
660-
except ValueError:
661-
raise ValueError("gYearMonth Year part must be a valid integer")
662-
try:
663-
m = int(month_string)
664-
except ValueError:
665-
raise ValueError("gYearMonth Month part must be a valid integer")
666-
return date(y, m, 1)
667-
668-
669596
# Parse XSD Datetime is the same as ISO8601 Datetime
670597
# It uses datetime.fromisoformat for python 3.11 and above
671598
# or isodate.parse_datetime for older versions

0 commit comments

Comments
 (0)