forked from AllenDowney/ThinkPython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththinkpython.py
More file actions
93 lines (73 loc) · 2.68 KB
/
Copy paththinkpython.py
File metadata and controls
93 lines (73 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import contextlib
import io
import re
def extract_function_name(text):
"""Find a function definition and return its name.
text: String
returns: String or None
"""
pattern = r"def\s+(\w+)\s*\("
match = re.search(pattern, text)
if match:
func_name = match.group(1)
return func_name
else:
return None
# as funções que definem comandos mágicos de célula só são definidas
# se estivermos rodando no Jupyter.
try:
from IPython.core.magic import register_cell_magic
from IPython.core.magic_arguments import argument, magic_arguments, parse_argstring
@register_cell_magic
def add_method_to(args, cell):
# obtém o nome da função definida nesta célula
func_name = extract_function_name(cell)
if func_name is None:
return f"This cell doesn't define any new functions."
# obtém a classe à qual vamos adicioná-la
namespace = get_ipython().user_ns
class_name = args
cls = namespace.get(class_name, None)
if cls is None:
return f"Class '{class_name}' not found."
# guarda a versão antiga da função, se ela já estava definida
old_func = namespace.get(func_name, None)
if old_func is not None:
del namespace[func_name]
# Executa a célula para definir a função
get_ipython().run_cell(cell)
# obtém a função recém-definida
new_func = namespace.get(func_name, None)
if new_func is None:
return f"This cell didn't define {func_name}."
# adiciona a função à classe e a remove do namespace
setattr(cls, func_name, new_func)
del namespace[func_name]
# restaura a função antiga no namespace
if old_func is not None:
namespace[func_name] = old_func
@register_cell_magic
def expect_error(line, cell):
try:
get_ipython().run_cell(cell)
except Exception as e:
get_ipython().run_cell("%tb")
@magic_arguments()
@argument("exception", help="Type of exception to catch")
@register_cell_magic
def expect(line, cell):
args = parse_argstring(expect, line)
exception = eval(args.exception)
try:
get_ipython().run_cell(cell)
except exception as e:
get_ipython().run_cell("%tb")
def traceback(mode):
"""Set the traceback mode.
mode: string
"""
with contextlib.redirect_stdout(io.StringIO()):
get_ipython().run_cell(f"%xmode {mode}")
traceback("Minimal")
except (ImportError, NameError):
print("Warning: IPython is not available, cell magic not defined.")