fastcore 2.1.2__tar.gz → 2.1.3__tar.gz
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.
- {fastcore-2.1.2/fastcore.egg-info → fastcore-2.1.3}/PKG-INFO +1 -1
- fastcore-2.1.3/fastcore/__init__.py +1 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/_modidx.py +9 -3
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/nbio.py +71 -15
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/tools.py +38 -12
- {fastcore-2.1.2 → fastcore-2.1.3/fastcore.egg-info}/PKG-INFO +1 -1
- fastcore-2.1.2/fastcore/__init__.py +0 -1
- {fastcore-2.1.2 → fastcore-2.1.3}/CONTRIBUTING.md +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/LICENSE +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/MANIFEST.in +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/README.md +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/aio.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/all.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/ansi.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/basics.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/dispatch.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/docments.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/docscrape.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/foundation.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/imghdr.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/imports.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/meta.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/nb_imports.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/net.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/parallel.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/py2pyi.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/script.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/shutil.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/style.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/test.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/transform.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/utils.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/xdg.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/xml.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore/xtras.py +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore.egg-info/SOURCES.txt +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore.egg-info/dependency_links.txt +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore.egg-info/entry_points.txt +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore.egg-info/requires.txt +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/fastcore.egg-info/top_level.txt +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/pyproject.toml +0 -0
- {fastcore-2.1.2 → fastcore-2.1.3}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.1.3"
|
|
@@ -521,6 +521,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
521
521
|
'fastcore.nbio._join': ('nbio.html#_join', 'fastcore/nbio.py'),
|
|
522
522
|
'fastcore.nbio._meta_directives': ('nbio.html#_meta_directives', 'fastcore/nbio.py'),
|
|
523
523
|
'fastcore.nbio._mkout': ('nbio.html#_mkout', 'fastcore/nbio.py'),
|
|
524
|
+
'fastcore.nbio._nb_cell': ('nbio.html#_nb_cell', 'fastcore/nbio.py'),
|
|
524
525
|
'fastcore.nbio._read_json': ('nbio.html#_read_json', 'fastcore/nbio.py'),
|
|
525
526
|
'fastcore.nbio._rejoin_cell': ('nbio.html#_rejoin_cell', 'fastcore/nbio.py'),
|
|
526
527
|
'fastcore.nbio._rejoin_mime': ('nbio.html#_rejoin_mime', 'fastcore/nbio.py'),
|
|
@@ -529,6 +530,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
529
530
|
'fastcore.nbio._split_mime': ('nbio.html#_split_mime', 'fastcore/nbio.py'),
|
|
530
531
|
'fastcore.nbio._unparse_dir': ('nbio.html#_unparse_dir', 'fastcore/nbio.py'),
|
|
531
532
|
'fastcore.nbio.cell2xml': ('nbio.html#cell2xml', 'fastcore/nbio.py'),
|
|
533
|
+
'fastcore.nbio.cell_edit': ('nbio.html#cell_edit', 'fastcore/nbio.py'),
|
|
532
534
|
'fastcore.nbio.cells2xml': ('nbio.html#cells2xml', 'fastcore/nbio.py'),
|
|
533
535
|
'fastcore.nbio.concat_streams': ('nbio.html#concat_streams', 'fastcore/nbio.py'),
|
|
534
536
|
'fastcore.nbio.dict2nb': ('nbio.html#dict2nb', 'fastcore/nbio.py'),
|
|
@@ -552,6 +554,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
552
554
|
'fastcore.nbio.repair_nb': ('nbio.html#repair_nb', 'fastcore/nbio.py'),
|
|
553
555
|
'fastcore.nbio.validate_cell': ('nbio.html#validate_cell', 'fastcore/nbio.py'),
|
|
554
556
|
'fastcore.nbio.validate_nb': ('nbio.html#validate_nb', 'fastcore/nbio.py'),
|
|
557
|
+
'fastcore.nbio.view_cell': ('nbio.html#view_cell', 'fastcore/nbio.py'),
|
|
555
558
|
'fastcore.nbio.write_nb': ('nbio.html#write_nb', 'fastcore/nbio.py')},
|
|
556
559
|
'fastcore.net': { 'fastcore.net.HTTP4xxClientError': ('net.html#http4xxclienterror', 'fastcore/net.py'),
|
|
557
560
|
'fastcore.net.HTTP5xxServerError': ('net.html#http5xxservererror', 'fastcore/net.py'),
|
|
@@ -677,14 +680,17 @@ d = { 'settings': { 'branch': 'main',
|
|
|
677
680
|
'fastcore.test.test_warns': ('test.html#test_warns', 'fastcore/test.py')},
|
|
678
681
|
'fastcore.tools': { 'fastcore.tools._norm_lines': ('tools.html#_norm_lines', 'fastcore/tools.py'),
|
|
679
682
|
'fastcore.tools.ast_replace': ('tools.html#ast_replace', 'fastcore/tools.py'),
|
|
683
|
+
'fastcore.tools.create_file': ('tools.html#create_file', 'fastcore/tools.py'),
|
|
680
684
|
'fastcore.tools.del_lines': ('tools.html#del_lines', 'fastcore/tools.py'),
|
|
681
|
-
'fastcore.tools.file_create': ('tools.html#file_create', 'fastcore/tools.py'),
|
|
682
685
|
'fastcore.tools.file_edit': ('tools.html#file_edit', 'fastcore/tools.py'),
|
|
683
|
-
'fastcore.tools.file_view': ('tools.html#file_view', 'fastcore/tools.py'),
|
|
684
686
|
'fastcore.tools.insert_line': ('tools.html#insert_line', 'fastcore/tools.py'),
|
|
687
|
+
'fastcore.tools.line_hash': ('tools.html#line_hash', 'fastcore/tools.py'),
|
|
688
|
+
'fastcore.tools.lnhash': ('tools.html#lnhash', 'fastcore/tools.py'),
|
|
689
|
+
'fastcore.tools.lnhash_at': ('tools.html#lnhash_at', 'fastcore/tools.py'),
|
|
685
690
|
'fastcore.tools.replace_lines': ('tools.html#replace_lines', 'fastcore/tools.py'),
|
|
686
691
|
'fastcore.tools.str_replace': ('tools.html#str_replace', 'fastcore/tools.py'),
|
|
687
|
-
'fastcore.tools.strs_replace': ('tools.html#strs_replace', 'fastcore/tools.py')
|
|
692
|
+
'fastcore.tools.strs_replace': ('tools.html#strs_replace', 'fastcore/tools.py'),
|
|
693
|
+
'fastcore.tools.view_file': ('tools.html#view_file', 'fastcore/tools.py')},
|
|
688
694
|
'fastcore.transform': {},
|
|
689
695
|
'fastcore.utils': {},
|
|
690
696
|
'fastcore.xdg': { 'fastcore.xdg._path_from_env': ('xdg.html#_path_from_env', 'fastcore/xdg.py'),
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
"""Reading and writing Jupyter notebooks
|
|
2
2
|
|
|
3
|
+
Cell tools apply `fastcore.tools`' string editing primitives to one notebook cell's source, addressed by path and cell id, mirroring that module's file tools: the same operations and parameters, with `path, cell_id` in place of `path`. Each editor returns a diff of the change, and `view_cell` shows a cell's source with optional line numbers or exhash addresses.
|
|
4
|
+
|
|
3
5
|
Docs: https://fastcore.fast.ai/nbio.html.md"""
|
|
4
6
|
|
|
5
7
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/13_nbio.ipynb.
|
|
6
8
|
|
|
7
9
|
# %% auto #0
|
|
8
|
-
__all__ = ['langs', '
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
10
|
+
__all__ = ['langs', 'cell_insert_line', 'cell_str_replace', 'cell_strs_replace', 'cell_replace_lines', 'cell_del_lines',
|
|
11
|
+
'nb_lang', 'NbCell', 'dict2nb', 'read_nb', 'mk_cell', 'new_nb', 'first_code_ln', 'nb2dict', 'nb2str',
|
|
12
|
+
'write_nb', 'cell_edit', 'view_cell', 'validate_cell', 'validate_nb', 'repair_cell', 'repair_nb',
|
|
13
|
+
'preferred_out', 'mk_stream', 'mk_result', 'mk_display', 'mk_error', 'concat_streams', 'preferred_msg_out',
|
|
14
|
+
'render_output', 'render_outputs', 'render_text', 'cell2xml', 'cells2xml', 'Notebook']
|
|
12
15
|
|
|
13
16
|
# %% ../nbs/13_nbio.ipynb #954ca1aa
|
|
14
17
|
from .basics import *
|
|
15
|
-
from .xtras import rtoken_hex,clean_cli_output,take_lines
|
|
18
|
+
from .xtras import rtoken_hex,clean_cli_output,take_lines,str_diff
|
|
16
19
|
from .imports import *
|
|
17
20
|
from .ansi import ansi2html
|
|
18
|
-
from .meta import delegates
|
|
21
|
+
from .meta import delegates,splice_sig
|
|
22
|
+
from .tools import insert_line,str_replace,strs_replace,replace_lines,del_lines,lnhash
|
|
19
23
|
|
|
20
24
|
import ast,functools
|
|
21
25
|
from collections import defaultdict
|
|
@@ -151,18 +155,15 @@ def _directive(s, lang='python'):
|
|
|
151
155
|
|
|
152
156
|
# %% ../nbs/13_nbio.ipynb #16c08410
|
|
153
157
|
def _meta_directives(cell):
|
|
154
|
-
"Directives from the `nbdev` dict in cell metadata, as `{name: value}`"
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return {k:_v(v) for k,v in cell.get('metadata',{}).get('nbdev',{}).items()}
|
|
158
|
+
"Directives from the `nbdev` dict in cell metadata, as `{name: value}`; values must be str (`'true'` for a bare directive)"
|
|
159
|
+
d = cell.get('metadata',{}).get('nbdev',{})
|
|
160
|
+
if bad := [k for k,v in d.items() if not isinstance(v,str)]:
|
|
161
|
+
raise TypeError(f"`nbdev` metadata directive values must be str (e.g 'true'/'false'), got non-str for: {bad}")
|
|
162
|
+
return {k:'' if v=='true' else v for k,v in d.items()}
|
|
160
163
|
|
|
161
164
|
def _unparse_dir(v):
|
|
162
165
|
"Inverse of `_meta_directives` value parsing: value string back to a metadata value"
|
|
163
|
-
if v==''
|
|
164
|
-
if v=='false': return False
|
|
165
|
-
return v
|
|
166
|
+
return 'true' if v=='' else v
|
|
166
167
|
|
|
167
168
|
def _dir_line(k, v, lang='python', quarto=False):
|
|
168
169
|
"A canonical directive comment line; with `quarto`, bare directives render as `: true`"
|
|
@@ -255,6 +256,61 @@ def write_nb(nb, path):
|
|
|
255
256
|
if new!=old:
|
|
256
257
|
with open(path, 'w', encoding='utf-8') as f: f.write(new)
|
|
257
258
|
|
|
259
|
+
# %% ../nbs/13_nbio.ipynb #3453e541
|
|
260
|
+
_cell_edit_doc = """
|
|
261
|
+
This is a *cell* editing function.
|
|
262
|
+
|
|
263
|
+
Cell editing standard parameters are `path`: notebook file to modify, and `cell_id`: id of the cell to edit (exact, or unique prefix)
|
|
264
|
+
|
|
265
|
+
returns: diff of changes, or "none: No changes.", or "error: ..."
|
|
266
|
+
"""
|
|
267
|
+
|
|
268
|
+
def _nb_cell(nb, cell_id):
|
|
269
|
+
"Cell in `nb` with id `cell_id` (exact match, or unique prefix)"
|
|
270
|
+
res = [c for c in nb.cells if c.id==cell_id] or [c for c in nb.cells if c.id.startswith(cell_id)]
|
|
271
|
+
if len(res)!=1: raise KeyError(f"{'ambiguous' if res else 'no'} cell id: {cell_id!r}")
|
|
272
|
+
return res[0]
|
|
273
|
+
|
|
274
|
+
def cell_edit(f, name=None):
|
|
275
|
+
def wrapper(path:str, cell_id:str, *args, **kw):
|
|
276
|
+
nb = read_nb(path)
|
|
277
|
+
cell = _nb_cell(nb, cell_id)
|
|
278
|
+
text = cell.source
|
|
279
|
+
try: new_text = f(text, *args, **kw)
|
|
280
|
+
except ValueError as e: return PrettyString(f'error: {e}')
|
|
281
|
+
cell.source = new_text
|
|
282
|
+
write_nb(nb, path)
|
|
283
|
+
return PrettyString(str_diff(text, new_text) or 'none: No changes.')
|
|
284
|
+
res = splice_sig(wrapper, f, 'text')
|
|
285
|
+
if name: res.__name__ = res.__qualname__ = name
|
|
286
|
+
res.__doc__ = (f.__doc__ or '') + _cell_edit_doc
|
|
287
|
+
return res
|
|
288
|
+
|
|
289
|
+
# %% ../nbs/13_nbio.ipynb #bde31026
|
|
290
|
+
cell_insert_line = cell_edit(insert_line, 'cell_insert_line')
|
|
291
|
+
cell_str_replace = cell_edit(str_replace, 'cell_str_replace')
|
|
292
|
+
cell_strs_replace = cell_edit(strs_replace, 'cell_strs_replace')
|
|
293
|
+
cell_replace_lines = cell_edit(replace_lines, 'cell_replace_lines')
|
|
294
|
+
cell_del_lines = cell_edit(del_lines, 'cell_del_lines')
|
|
295
|
+
|
|
296
|
+
# %% ../nbs/13_nbio.ipynb #421b2b9c
|
|
297
|
+
def view_cell(
|
|
298
|
+
path:str, # Notebook file to read
|
|
299
|
+
cell_id:str, # Id of the cell to view (exact, or unique prefix)
|
|
300
|
+
start_line:int=1, # Starting line to view
|
|
301
|
+
end_line:int=None, # End line (defaults to last line if None; may be past EOF, which clamps to the last line)
|
|
302
|
+
nums:bool=True, # Show line numbers?
|
|
303
|
+
lnhashs:bool=False # Show exhash `lineno|hash|` addresses instead of line numbers?
|
|
304
|
+
):
|
|
305
|
+
"View a cell's source, optionally limited to 1-based line range"
|
|
306
|
+
lines = _nb_cell(read_nb(path), cell_id).source.splitlines()
|
|
307
|
+
if not lines: return ''
|
|
308
|
+
if end_line is None or end_line > len(lines): end_line = len(lines)
|
|
309
|
+
if end_line < 0: end_line = len(lines)+end_line+1
|
|
310
|
+
if not (1 <= start_line <= len(lines)): return f'error: Invalid start_line {start_line}. Valid range: 1-{len(lines)}'
|
|
311
|
+
fmt = (lambda i,l: lnhash(i,l)+l) if lnhashs else (lambda i,l: f'{i}: {l}') if nums else (lambda i,l: l)
|
|
312
|
+
return PrettyString('\n'.join(fmt(i,l) for i,l in enumerate(lines[start_line-1:end_line], start_line)))
|
|
313
|
+
|
|
258
314
|
# %% ../nbs/13_nbio.ipynb #86453c0f
|
|
259
315
|
def validate_cell(cell, idx=None):
|
|
260
316
|
"Raise `ValueError` for structural problems in notebook cell dict `cell`; returns it unchanged if fine"
|
|
@@ -2,26 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
The editors here are string-level: each takes `text` plus edit parameters and returns the new text, raising `ValueError` when an edit can't apply. The file tools below wrap them with path I/O and diff reporting; message-level wrappers live in llmsurgery. (This module previously held experimental LLM path-editing and command tools, superseded by safecmd, rgapi, and the tools here.)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`line_hash`, `lnhash`, and `lnhash_at` implement the [exhash](https://answerdotai.github.io/exhash) line-address format in pure Python: `lineno|hash|`, where the hash is 4 hex chars of crc32. They let any tool create lnhash-addressed views of text it holds, without depending on the exhash package.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
File tools wrap the primitives with path I/O, returning unified diffs of what changed ("none: No changes." / "error: ..." otherwise). The path is the first argument (with `view_file`/`create_file` named verb-first, since the file is the verb's object rather than the location of an edit), e.g:
|
|
8
|
+
|
|
9
|
+
view_file('~/a/b.py', 3)
|
|
10
|
+
create_file('~/a/b/c.py', 'content here')
|
|
9
11
|
file_str_replace('myfile.py', 'old_name', 'new_name')
|
|
10
12
|
file_del_lines('myfile.py', 2, 4)
|
|
11
13
|
file_replace_lines('myfile.py', new_content=src) # no line numbers: replace the entire contents
|
|
12
14
|
|
|
13
|
-
`file_str_replace`, `file_strs_replace`, and `file_del_lines` support `re_filter` and `invert_filter` for targeting only lines matching (or not matching) a regex, like ex's `g//` and `g!//`, combined with `start_line`/`end_line` to restrict to a region. `ast_replace(text, repls)` and `
|
|
15
|
+
`file_str_replace`, `file_strs_replace`, and `file_del_lines` support `re_filter` and `invert_filter` for targeting only lines matching (or not matching) a regex, like ex's `g//` and `g!//`, combined with `start_line`/`end_line` to restrict to a region. `ast_replace(text, repls)` and `file_ast_replace(path, repls)` apply ast-grep `(pattern, replacement)` rules with `$VAR` metavariables (requires the optional `remold` package). Where the `exhash` package is available, prefer it for editing: its hash-verified addressing fails loudly on stale context instead of editing nearby text.
|
|
14
16
|
|
|
15
17
|
Docs: https://fastcore.fast.ai/tools.html.md"""
|
|
16
18
|
|
|
17
19
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/12_tools.ipynb.
|
|
18
20
|
|
|
19
21
|
# %% auto #0
|
|
20
|
-
__all__ = ['file_insert_line', 'file_str_replace', 'file_strs_replace', 'file_replace_lines', 'file_del_lines',
|
|
21
|
-
'insert_line', 'str_replace', 'strs_replace', 'replace_lines', 'del_lines', '
|
|
22
|
-
'file_edit', 'ast_replace']
|
|
22
|
+
__all__ = ['file_insert_line', 'file_str_replace', 'file_strs_replace', 'file_replace_lines', 'file_del_lines',
|
|
23
|
+
'file_ast_replace', 'insert_line', 'str_replace', 'strs_replace', 'replace_lines', 'del_lines', 'line_hash',
|
|
24
|
+
'lnhash', 'lnhash_at', 'view_file', 'create_file', 'file_edit', 'ast_replace']
|
|
23
25
|
|
|
24
26
|
# %% ../nbs/12_tools.ipynb #578246d2
|
|
27
|
+
import zlib
|
|
25
28
|
from .imports import *
|
|
26
29
|
from .meta import splice_sig
|
|
27
30
|
from .basics import PrettyString
|
|
@@ -138,11 +141,34 @@ def del_lines(
|
|
|
138
141
|
else: del lines[s-1:e]
|
|
139
142
|
return ''.join(lines)
|
|
140
143
|
|
|
144
|
+
# %% ../nbs/12_tools.ipynb #6274581f
|
|
145
|
+
def line_hash(
|
|
146
|
+
line:str # A single line of text, without trailing newline
|
|
147
|
+
)->str:
|
|
148
|
+
"4-char hex exhash hash of `line`"
|
|
149
|
+
return f'{zlib.crc32(line.encode()) & 0xffff:04x}'
|
|
150
|
+
|
|
151
|
+
def lnhash(
|
|
152
|
+
lineno:int, # 1-based line number
|
|
153
|
+
line:str # The line's current text
|
|
154
|
+
)->str:
|
|
155
|
+
"`lineno|hash|` exhash address for `line` at `lineno`"
|
|
156
|
+
return f'{lineno}|{line_hash(line)}|'
|
|
157
|
+
|
|
158
|
+
def lnhash_at(
|
|
159
|
+
s:str|list|tuple, # A document as a str, or its lines
|
|
160
|
+
line:int # 1-based line number within `s`
|
|
161
|
+
)->str:
|
|
162
|
+
"`lineno|hash|` exhash address of line `line` of `s`"
|
|
163
|
+
if isinstance(s,str): s = s.splitlines()
|
|
164
|
+
return lnhash(line, s[line-1])
|
|
165
|
+
|
|
141
166
|
# %% ../nbs/12_tools.ipynb #806c957b
|
|
142
|
-
def
|
|
167
|
+
def view_file(
|
|
143
168
|
path:str, # Path to view (expands `~` if needed)
|
|
144
169
|
start_line:int=1, # Starting line to view
|
|
145
|
-
end_line:int=None # End line (defaults to last line if None; may be past EOF, which clamps to the last line - handy when the file size is unknown)
|
|
170
|
+
end_line:int=None, # End line (defaults to last line if None; may be past EOF, which clamps to the last line - handy when the file size is unknown)
|
|
171
|
+
lnhashs:bool=False # Prefix `lineno|hash|` exhash addresses instead of `lineno: `
|
|
146
172
|
):
|
|
147
173
|
"Read file contents, optionally limited to 1-based line range"
|
|
148
174
|
path = Path(path).expanduser()
|
|
@@ -152,10 +178,10 @@ def file_view(
|
|
|
152
178
|
if end_line < 0: end_line = len(lines)+end_line+1
|
|
153
179
|
if not (1 <= start_line <= len(lines)): return f'error: Invalid start_line {start_line}. Valid range: 1-{len(lines)}'
|
|
154
180
|
if end_line > len(lines): end_line = len(lines)
|
|
155
|
-
return PrettyString('\n'.join(f'{i}:
|
|
181
|
+
return PrettyString('\n'.join((lnhash(i,l) if lnhashs else f'{i}: ')+l for i,l in enumerate(lines[start_line-1:end_line], start_line)))
|
|
156
182
|
|
|
157
183
|
# %% ../nbs/12_tools.ipynb #424d09e1
|
|
158
|
-
def
|
|
184
|
+
def create_file(
|
|
159
185
|
path:str, # Path to create (expands `~` if needed)
|
|
160
186
|
contents:str, # Contents of file to create
|
|
161
187
|
overwrite:bool=False, # Replace the file if it already exists?
|
|
@@ -218,4 +244,4 @@ def ast_replace(
|
|
|
218
244
|
except ImportError as e: raise ImportError('ast_replace requires the optional `remold` package: `pip install remold`') from e
|
|
219
245
|
return astmap(*repls)(text)
|
|
220
246
|
|
|
221
|
-
|
|
247
|
+
file_ast_replace = file_edit(ast_replace, 'file_ast_replace')
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.1.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|