toolslm 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- toolslm/__init__.py +1 -1
- toolslm/_modidx.py +8 -7
- toolslm/funccall.py +95 -0
- toolslm/xml.py +38 -51
- {toolslm-0.0.2.dist-info → toolslm-0.0.4.dist-info}/METADATA +2 -2
- toolslm-0.0.4.dist-info/RECORD +11 -0
- toolslm-0.0.4.dist-info/entry_points.txt +5 -0
- toolslm/lmcode.py +0 -53
- toolslm-0.0.2.dist-info/RECORD +0 -11
- toolslm-0.0.2.dist-info/entry_points.txt +0 -2
- {toolslm-0.0.2.dist-info → toolslm-0.0.4.dist-info}/LICENSE +0 -0
- {toolslm-0.0.2.dist-info → toolslm-0.0.4.dist-info}/WHEEL +0 -0
- {toolslm-0.0.2.dist-info → toolslm-0.0.4.dist-info}/top_level.txt +0 -0
toolslm/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.0.
|
|
1
|
+
__version__ = "0.0.4"
|
toolslm/_modidx.py
CHANGED
|
@@ -5,9 +5,12 @@ d = { 'settings': { 'branch': 'main',
|
|
|
5
5
|
'doc_host': 'https://AnswerDotAI.github.io',
|
|
6
6
|
'git_url': 'https://github.com/AnswerDotAI/toolslm',
|
|
7
7
|
'lib_path': 'toolslm'},
|
|
8
|
-
'syms': { 'toolslm.
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
'syms': { 'toolslm.funccall': { 'toolslm.funccall._copy_loc': ('funccall.html#_copy_loc', 'toolslm/funccall.py'),
|
|
9
|
+
'toolslm.funccall._param': ('funccall.html#_param', 'toolslm/funccall.py'),
|
|
10
|
+
'toolslm.funccall._run': ('funccall.html#_run', 'toolslm/funccall.py'),
|
|
11
|
+
'toolslm.funccall._types': ('funccall.html#_types', 'toolslm/funccall.py'),
|
|
12
|
+
'toolslm.funccall.get_schema': ('funccall.html#get_schema', 'toolslm/funccall.py'),
|
|
13
|
+
'toolslm.funccall.python': ('funccall.html#python', 'toolslm/funccall.py')},
|
|
11
14
|
'toolslm.shell': { 'toolslm.shell.TerminalInteractiveShell.run_cell': ( 'shell.html#terminalinteractiveshell.run_cell',
|
|
12
15
|
'toolslm/shell.py'),
|
|
13
16
|
'toolslm.shell.get_shell': ('shell.html#get_shell', 'toolslm/shell.py')},
|
|
@@ -15,9 +18,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
15
18
|
'toolslm.xml.docs_xml': ('xml.html#docs_xml', 'toolslm/xml.py'),
|
|
16
19
|
'toolslm.xml.files2ctx': ('xml.html#files2ctx', 'toolslm/xml.py'),
|
|
17
20
|
'toolslm.xml.folder2ctx': ('xml.html#folder2ctx', 'toolslm/xml.py'),
|
|
18
|
-
'toolslm.xml.
|
|
21
|
+
'toolslm.xml.folder2ctx_cli': ('xml.html#folder2ctx_cli', 'toolslm/xml.py'),
|
|
19
22
|
'toolslm.xml.json_to_xml': ('xml.html#json_to_xml', 'toolslm/xml.py'),
|
|
20
23
|
'toolslm.xml.mk_doc': ('xml.html#mk_doc', 'toolslm/xml.py'),
|
|
21
|
-
'toolslm.xml.mk_doctype': ('xml.html#mk_doctype', 'toolslm/xml.py')
|
|
22
|
-
'toolslm.xml.to_xml': ('xml.html#to_xml', 'toolslm/xml.py'),
|
|
23
|
-
'toolslm.xml.xt': ('xml.html#xt', 'toolslm/xml.py')}}}
|
|
24
|
+
'toolslm.xml.mk_doctype': ('xml.html#mk_doctype', 'toolslm/xml.py')}}}
|
toolslm/funccall.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# AUTOGENERATED! DO NOT EDIT! File to edit: ../01_funccall.ipynb.
|
|
2
|
+
|
|
3
|
+
# %% auto 0
|
|
4
|
+
__all__ = ['empty', 'get_schema', 'python']
|
|
5
|
+
|
|
6
|
+
# %% ../01_funccall.ipynb 2
|
|
7
|
+
import inspect
|
|
8
|
+
from fastcore.utils import *
|
|
9
|
+
from fastcore.docments import docments
|
|
10
|
+
|
|
11
|
+
# %% ../01_funccall.ipynb 3
|
|
12
|
+
empty = inspect.Parameter.empty
|
|
13
|
+
|
|
14
|
+
# %% ../01_funccall.ipynb 11
|
|
15
|
+
def _types(t:type)->tuple[str,Optional[str]]:
|
|
16
|
+
"Tuple of json schema type name and (if appropriate) array item name."
|
|
17
|
+
if t is empty: raise TypeError('Missing type')
|
|
18
|
+
tmap = {int:"integer", float:"number", str:"string", bool:"boolean", list:"array", dict:"object"}
|
|
19
|
+
if getattr(t, '__origin__', None) in (list,tuple): return "array", tmap.get(t.__args__[0], "object")
|
|
20
|
+
else: return tmap[t], None
|
|
21
|
+
|
|
22
|
+
# %% ../01_funccall.ipynb 14
|
|
23
|
+
def _param(name, info):
|
|
24
|
+
"json schema parameter given `name` and `info` from docments full dict."
|
|
25
|
+
paramt,itemt = _types(info.anno)
|
|
26
|
+
pschema = dict(type=paramt, description=info.docment or "")
|
|
27
|
+
if itemt: pschema["items"] = {"type": itemt}
|
|
28
|
+
if info.default is not empty: pschema["default"] = info.default
|
|
29
|
+
return pschema
|
|
30
|
+
|
|
31
|
+
# %% ../01_funccall.ipynb 17
|
|
32
|
+
def get_schema(f:callable, pname='input_schema')->dict:
|
|
33
|
+
"Convert function `f` into a JSON schema `dict` for tool use."
|
|
34
|
+
d = docments(f, full=True)
|
|
35
|
+
ret = d.pop('return')
|
|
36
|
+
d.pop('self', None) # Ignore `self` for methods
|
|
37
|
+
paramd = {
|
|
38
|
+
'type': "object",
|
|
39
|
+
'properties': {n:_param(n,o) for n,o in d.items() if n[0]!='_'},
|
|
40
|
+
'required': [n for n,o in d.items() if o.default is empty and n[0]!='_']
|
|
41
|
+
}
|
|
42
|
+
desc = f.__doc__
|
|
43
|
+
assert desc, "Docstring missing!"
|
|
44
|
+
if ret.anno is not empty: desc += f'\n\nReturns:\n- type: {_types(ret.anno)[0]}'
|
|
45
|
+
if ret.docment: desc += f'\n- description: {ret.docment}'
|
|
46
|
+
return {'name':f.__name__, 'description':desc, pname:paramd}
|
|
47
|
+
|
|
48
|
+
# %% ../01_funccall.ipynb 22
|
|
49
|
+
import ast, time, signal, traceback
|
|
50
|
+
from fastcore.utils import *
|
|
51
|
+
|
|
52
|
+
# %% ../01_funccall.ipynb 23
|
|
53
|
+
def _copy_loc(new, orig):
|
|
54
|
+
"Copy location information from original node to new node and all children."
|
|
55
|
+
new = ast.copy_location(new, orig)
|
|
56
|
+
for field, o in ast.iter_fields(new):
|
|
57
|
+
if isinstance(o, ast.AST): setattr(new, field, _copy_loc(o, orig))
|
|
58
|
+
elif isinstance(o, list): setattr(new, field, [_copy_loc(value, orig) for value in o])
|
|
59
|
+
return new
|
|
60
|
+
|
|
61
|
+
# %% ../01_funccall.ipynb 25
|
|
62
|
+
def _run(code:str ):
|
|
63
|
+
"Run `code`, returning final expression (similar to IPython)"
|
|
64
|
+
tree = ast.parse(code)
|
|
65
|
+
last_node = tree.body[-1] if tree.body else None
|
|
66
|
+
|
|
67
|
+
# If the last node is an expression, modify the AST to capture the result
|
|
68
|
+
if isinstance(last_node, ast.Expr):
|
|
69
|
+
tgt = [ast.Name(id='_result', ctx=ast.Store())]
|
|
70
|
+
assign_node = ast.Assign(targets=tgt, value=last_node.value)
|
|
71
|
+
tree.body[-1] = _copy_loc(assign_node, last_node)
|
|
72
|
+
|
|
73
|
+
compiled_code = compile(tree, filename='<ast>', mode='exec')
|
|
74
|
+
namespace = {}
|
|
75
|
+
stdout_buffer = io.StringIO()
|
|
76
|
+
saved_stdout = sys.stdout
|
|
77
|
+
sys.stdout = stdout_buffer
|
|
78
|
+
try: exec(compiled_code, namespace)
|
|
79
|
+
finally: sys.stdout = saved_stdout
|
|
80
|
+
_result = namespace.get('_result', None)
|
|
81
|
+
if _result is not None: return _result
|
|
82
|
+
return stdout_buffer.getvalue().strip()
|
|
83
|
+
|
|
84
|
+
# %% ../01_funccall.ipynb 30
|
|
85
|
+
def python(code, # Code to execute
|
|
86
|
+
timeout=5 # Maximum run time in seconds before a `TimeoutError` is raised
|
|
87
|
+
): # Result of last node, if it's an expression, or `None` otherwise
|
|
88
|
+
"""Executes python `code` with `timeout` and returning final expression (similar to IPython).
|
|
89
|
+
Raised exceptions are returned as a string, with a stack trace."""
|
|
90
|
+
def handler(*args): raise TimeoutError()
|
|
91
|
+
signal.signal(signal.SIGALRM, handler)
|
|
92
|
+
signal.alarm(timeout)
|
|
93
|
+
try: return _run(code)
|
|
94
|
+
except Exception as e: return traceback.format_exc()
|
|
95
|
+
finally: signal.alarm(0)
|
toolslm/xml.py
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../00_xml.ipynb.
|
|
2
2
|
|
|
3
3
|
# %% auto 0
|
|
4
|
-
__all__ = ['
|
|
5
|
-
'folder2ctx']
|
|
4
|
+
__all__ = ['doctype', 'json_to_xml', 'mk_doctype', 'mk_doc', 'docs_xml', 'files2ctx', 'folder2ctx', 'folder2ctx_cli']
|
|
6
5
|
|
|
7
6
|
# %% ../00_xml.ipynb 3
|
|
8
7
|
import hashlib,xml.etree.ElementTree as ET
|
|
@@ -10,45 +9,13 @@ from collections import namedtuple
|
|
|
10
9
|
|
|
11
10
|
from fastcore.utils import *
|
|
12
11
|
from fastcore.meta import delegates
|
|
12
|
+
from fastcore.xtras import hl_md
|
|
13
|
+
from fastcore.xml import to_xml, Document, Documents, Document_content, Source
|
|
14
|
+
from fastcore.script import call_parse
|
|
13
15
|
try: from IPython import display
|
|
14
16
|
except: display=None
|
|
15
17
|
|
|
16
|
-
# %% ../00_xml.ipynb
|
|
17
|
-
def xt(tag:str, # XML tag name
|
|
18
|
-
c:Optional[list]=None, # Children
|
|
19
|
-
**kw):
|
|
20
|
-
"Helper to create appropriate data structure for `to_xml`."
|
|
21
|
-
kw = {k.lstrip('_'):str(v) for k,v in kw.items()}
|
|
22
|
-
return tag,c,kw
|
|
23
|
-
|
|
24
|
-
# %% ../00_xml.ipynb 9
|
|
25
|
-
g = globals()
|
|
26
|
-
tags = 'div img h1 h2 h3 h4 h5 p hr span html'.split()
|
|
27
|
-
for o in tags: g[o] = partial(xt, o)
|
|
28
|
-
|
|
29
|
-
# %% ../00_xml.ipynb 12
|
|
30
|
-
def hl_md(s, lang='xml'):
|
|
31
|
-
"Syntax highlight `s` using `lang`."
|
|
32
|
-
if display: return display.Markdown(f'```{lang}\n{s}\n```')
|
|
33
|
-
print(s)
|
|
34
|
-
|
|
35
|
-
# %% ../00_xml.ipynb 15
|
|
36
|
-
def to_xml(node:tuple, # XML structure in `xt` format
|
|
37
|
-
hl=False # Syntax highlight response?
|
|
38
|
-
):
|
|
39
|
-
"Convert `node` to an XML string."
|
|
40
|
-
def mk_el(tag, cs, attrs):
|
|
41
|
-
el = ET.Element(tag, attrib=attrs)
|
|
42
|
-
if isinstance(cs, list): el.extend([mk_el(*o) for o in cs])
|
|
43
|
-
elif cs is not None: el.text = str(cs)
|
|
44
|
-
return el
|
|
45
|
-
|
|
46
|
-
root = mk_el(*node)
|
|
47
|
-
ET.indent(root, space=' ' if hl else '')
|
|
48
|
-
res = ET.tostring(root, encoding='unicode')
|
|
49
|
-
return hl_md(res) if hl else res
|
|
50
|
-
|
|
51
|
-
# %% ../00_xml.ipynb 18
|
|
18
|
+
# %% ../00_xml.ipynb 4
|
|
52
19
|
def json_to_xml(d:dict, # JSON dictionary to convert
|
|
53
20
|
rnm:str # Root name
|
|
54
21
|
)->str:
|
|
@@ -64,17 +31,17 @@ def json_to_xml(d:dict, # JSON dictionary to convert
|
|
|
64
31
|
ET.indent(root)
|
|
65
32
|
return ET.tostring(root, encoding='unicode')
|
|
66
33
|
|
|
67
|
-
# %% ../00_xml.ipynb
|
|
34
|
+
# %% ../00_xml.ipynb 9
|
|
68
35
|
doctype = namedtuple('doctype', ['source', 'content'])
|
|
69
36
|
|
|
70
|
-
# %% ../00_xml.ipynb
|
|
37
|
+
# %% ../00_xml.ipynb 11
|
|
71
38
|
def _add_nls(s):
|
|
72
39
|
"Add newlines to start and end of `s` if missing"
|
|
73
40
|
if s[ 0]!='\n': s = '\n'+s
|
|
74
41
|
if s[-1]!='\n': s = s+'\n'
|
|
75
42
|
return s
|
|
76
43
|
|
|
77
|
-
# %% ../00_xml.ipynb
|
|
44
|
+
# %% ../00_xml.ipynb 13
|
|
78
45
|
def mk_doctype(content:str, # The document content
|
|
79
46
|
source:Optional[str]=None # URL, filename, etc; defaults to `md5(content)` if not provided
|
|
80
47
|
) -> namedtuple:
|
|
@@ -82,18 +49,29 @@ def mk_doctype(content:str, # The document content
|
|
|
82
49
|
if source is None: source = hashlib.md5(content.encode()).hexdigest()[:8]
|
|
83
50
|
return doctype(_add_nls(str(source).strip()), _add_nls(content.strip()))
|
|
84
51
|
|
|
85
|
-
# %% ../00_xml.ipynb
|
|
52
|
+
# %% ../00_xml.ipynb 17
|
|
86
53
|
def mk_doc(index:int, # The document index
|
|
87
54
|
content:str, # The document content
|
|
88
55
|
source:Optional[str]=None # URL, filename, etc; defaults to `md5(content)` if not provided
|
|
89
56
|
) -> tuple:
|
|
90
|
-
"Create an `
|
|
57
|
+
"Create an `ft` format tuple for a single doc in Anthropic's recommended format"
|
|
91
58
|
dt = mk_doctype(content, source)
|
|
92
|
-
content =
|
|
93
|
-
source =
|
|
94
|
-
return
|
|
59
|
+
content = ft('document_content', dt.content)
|
|
60
|
+
source = ft('source', dt.source)
|
|
61
|
+
return ft('document', source, content, index=index)
|
|
95
62
|
|
|
96
|
-
# %% ../00_xml.ipynb
|
|
63
|
+
# %% ../00_xml.ipynb 18
|
|
64
|
+
def mk_doc(index:int, # The document index
|
|
65
|
+
content:str, # The document content
|
|
66
|
+
source:Optional[str]=None # URL, filename, etc; defaults to `md5(content)` if not provided
|
|
67
|
+
) -> tuple:
|
|
68
|
+
"Create an `ft` format tuple for a single doc in Anthropic's recommended format"
|
|
69
|
+
dt = mk_doctype(content, source)
|
|
70
|
+
content = Document_content(dt.content)
|
|
71
|
+
source = Source(dt.source)
|
|
72
|
+
return Document(source, content, index=index)
|
|
73
|
+
|
|
74
|
+
# %% ../00_xml.ipynb 22
|
|
97
75
|
def docs_xml(docs:list[str], # The content of each document
|
|
98
76
|
sources:Optional[list]=None, # URLs, filenames, etc; each one defaults to `md5(content)` if not provided
|
|
99
77
|
prefix:bool=True # Include Anthropic's suggested prose intro?
|
|
@@ -101,10 +79,10 @@ def docs_xml(docs:list[str], # The content of each document
|
|
|
101
79
|
"Create an XML string containing `docs` in Anthropic's recommended format"
|
|
102
80
|
pre = 'Here are some documents for you to reference for your task:\n\n' if prefix else ''
|
|
103
81
|
if sources is None: sources = [None]*len(docs)
|
|
104
|
-
docs =
|
|
105
|
-
return pre + to_xml(
|
|
82
|
+
docs = (mk_doc(i+1, *o) for i,o in enumerate(zip(docs,sources)))
|
|
83
|
+
return pre + to_xml(Documents(docs))
|
|
106
84
|
|
|
107
|
-
# %% ../00_xml.ipynb
|
|
85
|
+
# %% ../00_xml.ipynb 29
|
|
108
86
|
def files2ctx(
|
|
109
87
|
fnames:list[Union[str,Path]], # List of file names to add to context
|
|
110
88
|
prefix:bool=True # Include Anthropic's suggested prose intro?
|
|
@@ -113,7 +91,7 @@ def files2ctx(
|
|
|
113
91
|
contents = [o.read_text() for o in fnames]
|
|
114
92
|
return docs_xml(contents, fnames, prefix=prefix)
|
|
115
93
|
|
|
116
|
-
# %% ../00_xml.ipynb
|
|
94
|
+
# %% ../00_xml.ipynb 32
|
|
117
95
|
@delegates(globtastic)
|
|
118
96
|
def folder2ctx(
|
|
119
97
|
folder:Union[str,Path], # Folder name containing files to add to context
|
|
@@ -122,3 +100,12 @@ def folder2ctx(
|
|
|
122
100
|
)->str: # XML for Claude context
|
|
123
101
|
fnames = globtastic(folder, **kwargs)
|
|
124
102
|
return files2ctx(fnames, prefix=prefix)
|
|
103
|
+
|
|
104
|
+
# %% ../00_xml.ipynb 34
|
|
105
|
+
@call_parse
|
|
106
|
+
@delegates(folder2ctx)
|
|
107
|
+
def folder2ctx_cli(
|
|
108
|
+
folder:str, # Folder name containing files to add to context
|
|
109
|
+
**kwargs # Passed to `folder2ctx`
|
|
110
|
+
)->str: # XML for Claude context
|
|
111
|
+
return folder2ctx(folder, **kwargs)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: toolslm
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Tools to make language models a bit easier to use
|
|
5
5
|
Home-page: https://github.com/AnswerDotAI/toolslm
|
|
6
6
|
Author: Jeremy Howard
|
|
@@ -16,7 +16,7 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
16
16
|
Requires-Python: >=3.9
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: fastcore
|
|
19
|
+
Requires-Dist: fastcore >=1.5.47
|
|
20
20
|
Provides-Extra: dev
|
|
21
21
|
|
|
22
22
|
# toolslm
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
toolslm/__init__.py,sha256=1mptEzQihbdyqqzMgdns_j5ZGK9gz7hR2bsgA_TnjO4,22
|
|
2
|
+
toolslm/_modidx.py,sha256=6T36Q2cYKH0lp9Tt9Us8xpZV-Z0FYqrtZGu2ZykHDkg,2068
|
|
3
|
+
toolslm/funccall.py,sha256=mzWNLdZY6cYk-I3O5noRiEB089mPwJhnRQFsS5_JYDs,3856
|
|
4
|
+
toolslm/shell.py,sha256=GVqfL74NHw66zzZ7jvGVLjE55ZNJGBPvEb8kLz4aoYc,1576
|
|
5
|
+
toolslm/xml.py,sha256=dSJOHqSWnZlMK1Qf3396ISSaBHf5miNlLSYCixYB9ng,4398
|
|
6
|
+
toolslm-0.0.4.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
7
|
+
toolslm-0.0.4.dist-info/METADATA,sha256=9Ni6CdLgvxTCx7LqIrnNyUgrfu0t2Wsdabp9jZlFNvw,3782
|
|
8
|
+
toolslm-0.0.4.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
9
|
+
toolslm-0.0.4.dist-info/entry_points.txt,sha256=xFz0Eymlo5X7BGpaO6DI9gMxvN5A7faebzrlr8ctp5I,95
|
|
10
|
+
toolslm-0.0.4.dist-info/top_level.txt,sha256=4hRTrFWayz_Kz5221XjvlpCwVFrW3WPi1P0fllkTq9s,8
|
|
11
|
+
toolslm-0.0.4.dist-info/RECORD,,
|
toolslm/lmcode.py
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# AUTOGENERATED! DO NOT EDIT! File to edit: ../01_lmcode.ipynb.
|
|
2
|
-
|
|
3
|
-
# %% auto 0
|
|
4
|
-
__all__ = ['python']
|
|
5
|
-
|
|
6
|
-
# %% ../01_lmcode.ipynb 3
|
|
7
|
-
import ast, time, signal, traceback
|
|
8
|
-
from fastcore.utils import *
|
|
9
|
-
|
|
10
|
-
# %% ../01_lmcode.ipynb 5
|
|
11
|
-
def _copy_loc(new, orig):
|
|
12
|
-
"Copy location information from original node to new node and all children."
|
|
13
|
-
new = ast.copy_location(new, orig)
|
|
14
|
-
for field, o in ast.iter_fields(new):
|
|
15
|
-
if isinstance(o, ast.AST): setattr(new, field, _copy_loc(o, orig))
|
|
16
|
-
elif isinstance(o, list): setattr(new, field, [_copy_loc(value, orig) for value in o])
|
|
17
|
-
return new
|
|
18
|
-
|
|
19
|
-
# %% ../01_lmcode.ipynb 7
|
|
20
|
-
def _run(code:str ):
|
|
21
|
-
"Run `code`, returning final expression (similar to IPython)"
|
|
22
|
-
tree = ast.parse(code)
|
|
23
|
-
last_node = tree.body[-1] if tree.body else None
|
|
24
|
-
|
|
25
|
-
# If the last node is an expression, modify the AST to capture the result
|
|
26
|
-
if isinstance(last_node, ast.Expr):
|
|
27
|
-
tgt = [ast.Name(id='_result', ctx=ast.Store())]
|
|
28
|
-
assign_node = ast.Assign(targets=tgt, value=last_node.value)
|
|
29
|
-
tree.body[-1] = _copy_loc(assign_node, last_node)
|
|
30
|
-
|
|
31
|
-
compiled_code = compile(tree, filename='<ast>', mode='exec')
|
|
32
|
-
namespace = {}
|
|
33
|
-
stdout_buffer = io.StringIO()
|
|
34
|
-
saved_stdout = sys.stdout
|
|
35
|
-
sys.stdout = stdout_buffer
|
|
36
|
-
try: exec(compiled_code, namespace)
|
|
37
|
-
finally: sys.stdout = saved_stdout
|
|
38
|
-
_result = namespace.get('_result', None)
|
|
39
|
-
if _result is not None: return _result
|
|
40
|
-
return stdout_buffer.getvalue().strip()
|
|
41
|
-
|
|
42
|
-
# %% ../01_lmcode.ipynb 12
|
|
43
|
-
def python(code, # Code to execute
|
|
44
|
-
timeout=5 # Maximum run time in seconds before a `TimeoutError` is raised
|
|
45
|
-
): # Result of last node, if it's an expression, or `None` otherwise
|
|
46
|
-
"""Executes python `code` with `timeout` and returning final expression (similar to IPython).
|
|
47
|
-
Raised exceptions are returned as a string, with a stack trace."""
|
|
48
|
-
def handler(*args): raise TimeoutError()
|
|
49
|
-
signal.signal(signal.SIGALRM, handler)
|
|
50
|
-
signal.alarm(timeout)
|
|
51
|
-
try: return _run(code)
|
|
52
|
-
except Exception as e: return traceback.format_exc()
|
|
53
|
-
finally: signal.alarm(0)
|
toolslm-0.0.2.dist-info/RECORD
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
toolslm/__init__.py,sha256=QvlVh4JTl3JL7jQAja76yKtT-IvF4631ASjWY1wS6AQ,22
|
|
2
|
-
toolslm/_modidx.py,sha256=fmKi8RF2pdYu9iFlVY__PTCgOTaWgWYqUfrQBjimhxA,1860
|
|
3
|
-
toolslm/lmcode.py,sha256=G28x34SsxQPGhSNGHggXh6dWaeGlxQH69nAu9tgdNF8,2104
|
|
4
|
-
toolslm/shell.py,sha256=GVqfL74NHw66zzZ7jvGVLjE55ZNJGBPvEb8kLz4aoYc,1576
|
|
5
|
-
toolslm/xml.py,sha256=4DnFUYG09fB1ZTzcyeugKdkMU40MMMf3zZEHbDfSGIo,4635
|
|
6
|
-
toolslm-0.0.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
7
|
-
toolslm-0.0.2.dist-info/METADATA,sha256=KHlZaY6NAr7a0DCNTeq6rHxaJO5cze8jciBAT4Z7C-g,3773
|
|
8
|
-
toolslm-0.0.2.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
9
|
-
toolslm-0.0.2.dist-info/entry_points.txt,sha256=3os5YWuvVIFuweYaNtnwgv-xCe4Gb1KcZndFz8KWI0E,36
|
|
10
|
-
toolslm-0.0.2.dist-info/top_level.txt,sha256=4hRTrFWayz_Kz5221XjvlpCwVFrW3WPi1P0fllkTq9s,8
|
|
11
|
-
toolslm-0.0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|