From 2a2bb0d3b2f2a89b00ed57e087cf658ea0cc4abf Mon Sep 17 00:00:00 2001 From: Florian Ludwig Date: Mon, 31 Aug 2020 18:09:48 +0200 Subject: [PATCH 1/2] support day, nonth and year function for date --- rdflib/plugins/sparql/operators.py | 19 +++++++++++++--- test/test_sparql_operators.py | 36 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 test/test_sparql_operators.py diff --git a/rdflib/plugins/sparql/operators.py b/rdflib/plugins/sparql/operators.py index 29bdd5c0e..560baba69 100644 --- a/rdflib/plugins/sparql/operators.py +++ b/rdflib/plugins/sparql/operators.py @@ -12,6 +12,7 @@ import random import uuid import hashlib +import datetime as py_datetime # naming conflict with function within this module from functools import reduce @@ -449,17 +450,17 @@ def Builtin_NOW(e, ctx): def Builtin_YEAR(e, ctx): - d = datetime(e.arg) + d = date(e.arg) return Literal(d.year) def Builtin_MONTH(e, ctx): - d = datetime(e.arg) + d = date(e.arg) return Literal(d.month) def Builtin_DAY(e, ctx): - d = datetime(e.arg) + d = date(e.arg) return Literal(d.day) @@ -998,6 +999,18 @@ def datetime(e): return e.toPython() +def date(e) -> py_datetime.date: + if not isinstance(e, Literal): + raise SPARQLError("Non-literal passed as date: %r" % e) + if e.datatype not in (XSD.date, XSD.dateTime): + raise SPARQLError( + "Literal with wrong datatype passed as date: %r" % e) + result = e.toPython() + if isinstance(result, py_datetime.datetime): + return result.date() + return result + + def string(s): """ Make sure the passed thing is a string literal diff --git a/test/test_sparql_operators.py b/test/test_sparql_operators.py new file mode 100644 index 000000000..49f29c17b --- /dev/null +++ b/test/test_sparql_operators.py @@ -0,0 +1,36 @@ +import datetime + +import nose.tools + +import rdflib +from rdflib.plugins.sparql import operators +from rdflib.plugins.sparql import sparql + + +def test_date_cast(): + now = datetime.datetime.now() + today = now.date() + + literal = rdflib.Literal(now) + result = operators.date(literal) + assert isinstance(result, datetime.date) + assert result == today + + literal = rdflib.Literal(today) + result = operators.date(literal) + assert isinstance(result, datetime.date) + assert result == today + + +def test_datetime_cast(): + now = datetime.datetime.now() + literal = rdflib.Literal(now) + result = operators.datetime(literal) + assert isinstance(result, datetime.datetime) + assert result == now + + +@nose.tools.raises(sparql.SPARQLError) +def test_datetime_cast_type_error(): + literal = rdflib.Literal("2020-01-02") + operators.date(literal) \ No newline at end of file From 7c1d49b19a5790fbd8d6b25e104dba75213d67f3 Mon Sep 17 00:00:00 2001 From: Florian Ludwig Date: Tue, 8 Sep 2020 09:51:30 +0200 Subject: [PATCH 2/2] reformat edited files using black --- rdflib/plugins/sparql/operators.py | 3 +-- test/test_sparql_operators.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/rdflib/plugins/sparql/operators.py b/rdflib/plugins/sparql/operators.py index 560baba69..3393f18ae 100644 --- a/rdflib/plugins/sparql/operators.py +++ b/rdflib/plugins/sparql/operators.py @@ -1003,8 +1003,7 @@ def date(e) -> py_datetime.date: if not isinstance(e, Literal): raise SPARQLError("Non-literal passed as date: %r" % e) if e.datatype not in (XSD.date, XSD.dateTime): - raise SPARQLError( - "Literal with wrong datatype passed as date: %r" % e) + raise SPARQLError("Literal with wrong datatype passed as date: %r" % e) result = e.toPython() if isinstance(result, py_datetime.datetime): return result.date() diff --git a/test/test_sparql_operators.py b/test/test_sparql_operators.py index 49f29c17b..b4e4dacdd 100644 --- a/test/test_sparql_operators.py +++ b/test/test_sparql_operators.py @@ -28,9 +28,9 @@ def test_datetime_cast(): result = operators.datetime(literal) assert isinstance(result, datetime.datetime) assert result == now - + @nose.tools.raises(sparql.SPARQLError) def test_datetime_cast_type_error(): literal = rdflib.Literal("2020-01-02") - operators.date(literal) \ No newline at end of file + operators.date(literal)