Coverage for jutil/parse.py : 83%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import logging
2from datetime import datetime, time, date
3from typing import Optional, Any
4from django.utils.translation import gettext as _
5from rest_framework.exceptions import ValidationError
6import pytz
7from django.utils.dateparse import parse_datetime as django_parse_datetime
8from django.utils.dateparse import parse_date as django_parse_date
10logger = logging.getLogger(__name__)
12TRUE_VALUES = (
13 'true',
14 '1',
15 'yes',
16)
18FALSE_VALUES = (
19 'none',
20 'null',
21 'false',
22 '0',
23 'no',
24)
27def parse_bool(v: str) -> bool:
28 """
29 Parses boolean value
30 :param v: Input string
31 :return: bool
32 """
33 s = str(v).lower()
34 if s in TRUE_VALUES:
35 return True
36 if s in FALSE_VALUES:
37 return False
38 raise ValidationError(_("%(value)s is not one of the available choices") % {'value': v})
41def parse_datetime(v: str, tz: Any = None) -> datetime:
42 """
43 Parses ISO date/datetime string to timezone-aware datetime.
44 Supports YYYY-MM-DD date strings where time part is missing.
45 Returns always timezone-aware datetime (assumes UTC if timezone missing).
46 :param v: Input string to parse
47 :param tz: Default pytz timezone or if None then use UTC as default
48 :return: datetime with timezone
49 """
50 try:
51 t = django_parse_datetime(v)
52 if t is None:
53 t_date: Optional[date] = django_parse_date(v)
54 if t_date is None:
55 raise ValidationError(_(
56 "“%(value)s” value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format.") % {
57 'value': v})
58 t = datetime.combine(t_date, time())
59 if tz is None: 59 ↛ 61line 59 didn't jump to line 61, because the condition on line 59 was never false
60 tz = pytz.utc
61 return t if t.tzinfo else tz.localize(t)
62 except Exception:
63 raise ValidationError(_("“%(value)s” value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format.") % {'value': v})
66def parse_bool_or_none(v: str) -> Optional[bool]:
67 """
68 Parses boolean value, or returns None if parsing fails.
69 :param v: Input string
70 :return: bool or None
71 """
72 s = str(v).lower()
73 if s in TRUE_VALUES:
74 return True
75 if s in FALSE_VALUES:
76 return False
77 return None
80def parse_datetime_or_none(v: str, tz: Any = None) -> Optional[datetime]:
81 """
82 Parses ISO date/datetime string to timezone-aware datetime.
83 Supports YYYY-MM-DD date strings where time part is missing.
84 Returns timezone-aware datetime (assumes UTC if timezone missing) or None if parsing fails.
85 :param v: Input string to parse
86 :param tz: Default pytz timezone or if None then use UTC as default
87 :return: datetime with timezone or None
88 """
89 try:
90 t = django_parse_datetime(v)
91 if t is None:
92 t_date: Optional[date] = django_parse_date(v)
93 if t_date is None:
94 return None
95 t = datetime.combine(t_date, time())
96 if tz is None: 96 ↛ 98line 96 didn't jump to line 98, because the condition on line 96 was never false
97 tz = pytz.utc
98 return t if t.tzinfo else tz.localize(t)
99 except Exception:
100 return None