Skip to content

Commit ea3fa1c

Browse files
committed
Improves readability of parser code.
1 parent ab6f428 commit ea3fa1c

File tree

1 file changed

+54
-49
lines changed

1 file changed

+54
-49
lines changed

pendulum/parsing/parser.py

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010

1111

1212
class Parser(object):
13+
"""
14+
Parser which parses common formats (like RFC3339 and ISO8601).
15+
"""
16+
1317
COMMON = re.compile(
1418
# Date (optional)
1519
'^'
16-
'('
17-
' (?P<date>' # Classic date (YYYY-MM-DD) or ordinal (YYYY-DDD)
20+
'(?P<date>'
21+
' (?P<classic>' # Classic date (YYYY-MM-DD) or ordinal (YYYY-DDD)
1822
' (?P<year>\d{4})' # Year
1923
' (?P<monthday>'
2024
' (?P<monthsep>-|/)?(?P<month>\d{2})' # Month (optional)
@@ -81,58 +85,57 @@ def parse_common(self, text):
8185
has_date = False
8286

8387
if m:
84-
if m.group('isocalendar'):
85-
date = self._get_iso_8601_week(
86-
m.group('isoyear'),
87-
m.group('isoweek'),
88-
m.group('isoweekday')
89-
)
90-
91-
year = date['year']
92-
month = date['month']
93-
day = date['day']
94-
95-
parsed.update({
96-
'year': year,
97-
'month': month,
98-
'day': day,
99-
})
100-
elif m.group('date'):
101-
has_date = True
88+
if m.group('date'):
10289
# A date has been specified
103-
year = int(m.group('year'))
90+
has_date = True
91+
92+
if m.group('isocalendar'):
93+
# We have a ISO 8601 string defined
94+
# by week number
95+
date = self._get_iso_8601_week(
96+
m.group('isoyear'),
97+
m.group('isoweek'),
98+
m.group('isoweekday')
99+
)
104100

105-
if not m.group('monthday'):
106-
# No month and day
107-
month = 1
108-
day = 1
101+
year = date['year']
102+
month = date['month']
103+
day = date['day']
109104
else:
110-
if m.group('month') and m.group('day'):
111-
# Month and day
112-
if len(m.group('day')) == 1:
113-
# Ordinal day
114-
dt = datetime.strptime(
115-
'{}-{}'.format(year, m.group('month') + m.group('day')),
116-
'%Y-%j'
117-
)
118-
month = dt.month
119-
day = dt.day
120-
elif self._options['day_first']:
121-
month = int(m.group('day'))
122-
day = int(m.group('month'))
105+
# We have a classic date representation
106+
year = int(m.group('year'))
107+
108+
if not m.group('monthday'):
109+
# No month and day
110+
month = 1
111+
day = 1
112+
else:
113+
if m.group('month') and m.group('day'):
114+
# Month and day
115+
if len(m.group('day')) == 1:
116+
# Ordinal day
117+
dt = datetime.strptime(
118+
'{}-{}'.format(year, m.group('month') + m.group('day')),
119+
'%Y-%j'
120+
)
121+
month = dt.month
122+
day = dt.day
123+
elif self._options['day_first']:
124+
month = int(m.group('day'))
125+
day = int(m.group('month'))
126+
else:
127+
month = int(m.group('month'))
128+
day = int(m.group('day'))
123129
else:
130+
# Only month
131+
if not m.group('monthsep'):
132+
# The date looks like 201207
133+
# which is invalid for a date
134+
# But it might be a time in the form hhmmss
135+
ambiguous_date = True
136+
124137
month = int(m.group('month'))
125-
day = int(m.group('day'))
126-
else:
127-
# Only month
128-
if not m.group('monthsep'):
129-
# The date looks like 201207
130-
# which is invalid for a date
131-
# But it might be a time in the form hhmmss
132-
ambiguous_date = True
133-
134-
month = int(m.group('month'))
135-
day = 1
138+
day = 1
136139

137140
parsed.update({
138141
'year': year,
@@ -271,6 +274,8 @@ def _parse(self, text):
271274
if parsed:
272275
return parsed
273276

277+
# We couldn't parse the string
278+
# so we fallback on the dateutil parser
274279
try:
275280
dt = parser.parse(text, dayfirst=self._options['day_first'])
276281
except ValueError:

0 commit comments

Comments
 (0)