Skip to content

Commit 1953b17

Browse files
committed
improve date introspection to work with example like adventofcode/2022/02/main.py - closes #95
1 parent a7c5824 commit 1953b17

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

aocd/get.py

+24-3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ def get_day_and_year():
9797
"""
9898
pattern_year = r"201[5-9]|202[0-9]"
9999
pattern_day = r"2[0-5]|1[0-9]|[1-9]"
100+
visited = []
101+
102+
def giveup(msg):
103+
log.info("introspection failure")
104+
for fname in visited:
105+
log.info("stack crawl visited %s", fname)
106+
return AocdError(msg)
107+
100108
for frame in traceback.extract_stack():
101109
filename = frame[0]
102110
linetxt = frame[-1] or ""
@@ -112,6 +120,7 @@ def get_day_and_year():
112120
"aocd" not in linetxt,
113121
"ipykernel" in filename,
114122
]
123+
visited.append(filename)
115124
if not any(reasons_to_skip_frame):
116125
log.debug("stack crawl found %s", filename)
117126
abspath = os.path.abspath(filename)
@@ -126,6 +135,18 @@ def get_day_and_year():
126135
if abspath and re.search(pattern_day, abspath):
127136
basename = os.path.basename(abspath)
128137
break
138+
elif re.search(os.sep + os.sep.join([r"20\d\d", r"[0-2]?\d", ".*.py"]), filename):
139+
year = day = None
140+
for part in filename.split(os.sep):
141+
if not part.isdigit():
142+
continue
143+
if len(part) == 4:
144+
year = int(part)
145+
elif len(part) <= 2:
146+
day = int(part.lstrip("0"))
147+
if year is not None and day is not None:
148+
log.debug("year=%s day=%s filename=%s", year, day, filename)
149+
return day, year
129150
log.debug("skipping frame %s", filename)
130151
else:
131152
import __main__
@@ -135,10 +156,10 @@ def get_day_and_year():
135156
year = most_recent_year()
136157
return day, year
137158
log.debug("non-interactive")
138-
raise AocdError("Failed introspection of filename")
159+
raise giveup("Failed introspection of filename")
139160
years = {int(year) for year in re.findall(pattern_year, abspath)}
140161
if len(years) > 1:
141-
raise AocdError("Failed introspection of year")
162+
raise giveup("Failed introspection of year")
142163
year = years.pop() if years else None
143164
basename_no_years = re.sub(pattern_year, "", basename)
144165
try:
@@ -152,4 +173,4 @@ def get_day_and_year():
152173
log.debug("year=%s day=%s", year or "?", day)
153174
return day, year
154175
log.debug("giving up introspection for %s", abspath)
155-
raise AocdError("Failed introspection of day")
176+
raise giveup("Failed introspection of day")

aocd/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.3.0"
1+
__version__ = "1.3.1"

tests/test_date_introspection.py

+8
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,11 @@ def test_ipynb_fail_no_numbers_in_ipynb_filename(mocker):
6161
mocker.patch("aocd.get.get_ipynb_path", "puzzle.py")
6262
with pytest.raises(AocdError("Failed introspection of filename")):
6363
get_day_and_year()
64+
65+
66+
def test_no_numbers_in_py_filename_but_date_in_abspath(mocker):
67+
fake_stack = [("adventofcode/2022/02/main.py", 1, "<test>", "from aocd import data")]
68+
mocker.patch("aocd.get.traceback.extract_stack", return_value=fake_stack)
69+
day, year = get_day_and_year()
70+
assert day == 2
71+
assert year == 2022

0 commit comments

Comments
 (0)