17
17
from .models import User
18
18
from .utils import AOC_TZ
19
19
from .utils import blocker
20
+ from ._ipykernel import get_ipynb_path
20
21
21
22
22
23
log = getLogger (__name__ )
@@ -96,23 +97,36 @@ def get_day_and_year():
96
97
"""
97
98
pattern_year = r"201[5-9]|202[0-9]"
98
99
pattern_day = r"2[0-5]|1[0-9]|[1-9]"
99
- stack = [f [0 ] for f in traceback .extract_stack ()]
100
- for name in stack :
101
- basename = os .path .basename (name )
100
+ for frame in traceback .extract_stack ():
101
+ filename = frame [0 ]
102
+ linetxt = frame [- 1 ] or ""
103
+ basename = os .path .basename (filename )
102
104
reasons_to_skip_frame = [
103
105
not re .search (pattern_day , basename ), # no digits in filename
104
- name == __file__ , # here
105
- "importlib" in name , # Python 3 import machinery
106
- "/IPython/" in name , # IPython adds a tonne of stack frames
107
- name .startswith ("<" ), # crap like <decorator-gen-57>
108
- name .endswith ("ython3" ), # ipython3 alias
106
+ filename == __file__ , # here
107
+ "importlib" in filename , # Python 3 import machinery
108
+ "/IPython/" in filename , # IPython adds a tonne of stack frames
109
+ filename .startswith ("<" ), # crap like <decorator-gen-57>
110
+ filename .endswith ("ython3" ), # ipython3 alias
109
111
basename .startswith ("pydev_ipython_console" ), # PyCharm Python Console
112
+ "aocd" not in linetxt ,
113
+ "ipykernel" in filename ,
110
114
]
111
115
if not any (reasons_to_skip_frame ):
112
- log .debug ("stack crawl found %s" , name )
113
- abspath = os .path .abspath (name )
116
+ log .debug ("stack crawl found %s" , filename )
117
+ abspath = os .path .abspath (filename )
114
118
break
115
- log .debug ("skipping frame %s" , name )
119
+ elif "ipykernel" in filename :
120
+ log .debug ("stack crawl found %s, attempting to detect an .ipynb" , filename )
121
+ try :
122
+ abspath = get_ipynb_path ()
123
+ except Exception as err :
124
+ log .debug ("failed getting .ipynb path with %s %s" , type (err ), err )
125
+ else :
126
+ if abspath and re .search (pattern_day , abspath ):
127
+ basename = os .path .basename (abspath )
128
+ break
129
+ log .debug ("skipping frame %s" , filename )
116
130
else :
117
131
import __main__
118
132
if getattr (__main__ , "__file__" , "<input>" ) == "<input>" :
@@ -135,7 +149,7 @@ def get_day_and_year():
135
149
assert not day .startswith ("0" ), "regex pattern_day must prevent any leading 0"
136
150
day = int (day )
137
151
assert 1 <= day <= 25 , "regex pattern_day must only match numbers in range 1-25"
138
- log .debug ("year=%d day=%d " , year , day )
152
+ log .debug ("year=%s day=%s " , year or "?" , day )
139
153
return day , year
140
154
log .debug ("giving up introspection for %s" , abspath )
141
155
raise AocdError ("Failed introspection of day" )
0 commit comments