]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Base time loader on regexp
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 15 May 2021 11:23:26 +0000 (13:23 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 15 May 2021 11:23:26 +0000 (13:23 +0200)
Some 5x faster

psycopg3/psycopg3/types/date.py

index d9e7c737fcad2732f35301ddc794335f3c4faef1..2f3f2d656192cd39b2cd16719c0fa6b273058800 100644 (file)
@@ -323,28 +323,27 @@ class DateBinaryLoader(Loader):
 class TimeLoader(Loader):
 
     format = Format.TEXT
-    _format = "%H:%M:%S.%f"
-    _format_no_micro = _format.replace(".%f", "")
+
+    _re_format = re.compile(rb"^(\d+):(\d+):(\d+)(?:\.(\d+))?")
 
     def load(self, data: Buffer) -> time:
-        # check if the data contains microseconds
-        if isinstance(data, memoryview):
-            data = bytes(data)
-        fmt = self._format if b"." in data else self._format_no_micro
-        try:
-            return datetime.strptime(data.decode("utf8"), fmt).time()
-        except ValueError as e:
-            return self._raise_error(data, e)
+        m = self._re_format.match(data)
+        if not m:
+            s = bytes(data).decode("utf8", "replace")
+            raise DataError(f"can't parse time {s!r}")
 
-    def _raise_error(self, data: bytes, exc: ValueError) -> time:
-        # Most likely, time 24:00
-        if data.startswith(b"24"):
-            raise DataError(
-                f"time not supported by Python: {data.decode('ascii')}"
-            )
+        ho, mi, se, ms = m.groups()
+
+        if ms is None:
+            ms = b"0"
+        elif len(ms) < 6:
+            ms += b"0" * (6 - len(ms))
 
-        # We genuinely received something we cannot parse
-        raise exc
+        try:
+            return time(int(ho), int(mi), int(se), int(ms))
+        except ValueError as e:
+            s = bytes(data).decode("utf8", "replace")
+            raise DataError(f"can't manage time {s!r}: {e}")
 
 
 class TimeBinaryLoader(Loader):