Skip to content

Commit a940c01

Browse files
committed
fixes #697
1 parent 6840de0 commit a940c01

6 files changed

Lines changed: 40 additions & 10 deletions

File tree

fastcore/tools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def strs_replace(
131131
old_strs:list[str], # List of strings to find and replace
132132
new_strs:list[str], # List of replacement strings (must match length of old_strs)
133133
):
134-
"Replace for each str pair in old_strs,new_strs call `str_replace"
134+
"Replace for each str pair in old_strs,new_strs"
135135
res = [str_replace(path, old, new) for (old,new) in zip(old_strs,new_strs)]
136136
return 'Results for each replacement:\n' + '; '.join(res)
137137

fastcore/xml.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ class Safe(str):
136136
def __html__(self): return self
137137

138138
# %% ../nbs/09_xml.ipynb
139-
def _escape(s): return '' if s is None else s.__html__() if hasattr(s, '__html__') else escape(s) if isinstance(s, str) else s
139+
def _escape(s):
140+
return '' if s is None else s.__html__() if hasattr(s, '__html__') \
141+
else escape(s, quote=False) if isinstance(s, str) else s
140142
def _noescape(s): return '' if s is None else s.__html__() if hasattr(s, '__html__') else s
141143

142144
# %% ../nbs/09_xml.ipynb

fastcore/xtras.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ def walk(
3939
keep_folder:callable=ret_true, # function that returns True for folders to enter
4040
skip_folder:callable=ret_false, # function that returns True for folders to skip
4141
func:callable=os.path.join, # function to apply to each matched file
42-
ret_folders:bool=False # return folders, not just files
42+
ret_folders:bool=False, # return folders, not just files
43+
sort:bool=True # sort files by name within each folder
4344
):
4445
"Generator version of `os.walk`, using functions to filter files and folders"
4546
from copy import copy
4647
for root,dirs,files in os.walk(path, followlinks=symlinks):
4748
if keep_folder(root,''):
4849
if ret_folders: yield func(root, '')
50+
if sort: files = sorted(files)
4951
yield from (func(root, name) for name in files if keep_file(root,name))
5052
for name in copy(dirs):
5153
if skip_folder(root,name): dirs.remove(name)
@@ -62,7 +64,8 @@ def globtastic(
6264
skip_file_re:str=None, # Skip files matching regex
6365
skip_folder_re:str=None, # Skip folders matching regex,
6466
func:callable=os.path.join, # function to apply to each matched file
65-
ret_folders:bool=False # return folders, not just files
67+
ret_folders:bool=False, # return folders, not just files
68+
sort:bool=True # sort files by name within each folder
6669
)->L: # Paths to matched files
6770
"A more powerful `glob`, including regex matches, symlink handling, and skip parameters"
6871
from fnmatch import fnmatch
@@ -79,7 +82,7 @@ def _keep_file(root, name):
7982
def _keep_folder(root, name): return not folder_re or folder_re.search(os.path.join(root,name))
8083
def _skip_folder(root, name): return skip_folder_re and skip_folder_re.search(name)
8184
return L(walk(path, symlinks=symlinks, keep_file=_keep_file, keep_folder=_keep_folder, skip_folder=_skip_folder,
82-
func=func, ret_folders=ret_folders))
85+
func=func, ret_folders=ret_folders, sort=sort))
8386

8487
# %% ../nbs/03_xtras.ipynb
8588
@contextmanager

nbs/03_xtras.ipynb

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,15 @@
9393
" keep_folder:callable=ret_true, # function that returns True for folders to enter\n",
9494
" skip_folder:callable=ret_false, # function that returns True for folders to skip\n",
9595
" func:callable=os.path.join, # function to apply to each matched file\n",
96-
" ret_folders:bool=False # return folders, not just files\n",
96+
" ret_folders:bool=False, # return folders, not just files\n",
97+
" sort:bool=True # sort files by name within each folder\n",
9798
"):\n",
9899
" \"Generator version of `os.walk`, using functions to filter files and folders\"\n",
99100
" from copy import copy\n",
100101
" for root,dirs,files in os.walk(path, followlinks=symlinks):\n",
101102
" if keep_folder(root,''):\n",
102103
" if ret_folders: yield func(root, '')\n",
104+
" if sort: files = sorted(files)\n",
103105
" yield from (func(root, name) for name in files if keep_file(root,name))\n",
104106
" for name in copy(dirs):\n",
105107
" if skip_folder(root,name): dirs.remove(name)"
@@ -123,7 +125,8 @@
123125
" skip_file_re:str=None, # Skip files matching regex\n",
124126
" skip_folder_re:str=None, # Skip folders matching regex,\n",
125127
" func:callable=os.path.join, # function to apply to each matched file\n",
126-
" ret_folders:bool=False # return folders, not just files\n",
128+
" ret_folders:bool=False, # return folders, not just files\n",
129+
" sort:bool=True # sort files by name within each folder\n",
127130
")->L: # Paths to matched files\n",
128131
" \"A more powerful `glob`, including regex matches, symlink handling, and skip parameters\"\n",
129132
" from fnmatch import fnmatch\n",
@@ -140,7 +143,7 @@
140143
" def _keep_folder(root, name): return not folder_re or folder_re.search(os.path.join(root,name))\n",
141144
" def _skip_folder(root, name): return skip_folder_re and skip_folder_re.search(name)\n",
142145
" return L(walk(path, symlinks=symlinks, keep_file=_keep_file, keep_folder=_keep_folder, skip_folder=_skip_folder,\n",
143-
" func=func, ret_folders=ret_folders))"
146+
" func=func, ret_folders=ret_folders, sort=sort))"
144147
]
145148
},
146149
{
@@ -163,6 +166,26 @@
163166
"globtastic('.', skip_folder_re='^[_.]', folder_re='core', file_glob='*.*py*', file_re='c')"
164167
]
165168
},
169+
{
170+
"cell_type": "code",
171+
"execution_count": null,
172+
"metadata": {},
173+
"outputs": [
174+
{
175+
"data": {
176+
"text/plain": [
177+
"(#5) ['./fastcore/basics.py','./fastcore/dispatch.py','./fastcore/docments.py','./fastcore/docscrape.py','./fastcore/script.py']"
178+
]
179+
},
180+
"execution_count": null,
181+
"metadata": {},
182+
"output_type": "execute_result"
183+
}
184+
],
185+
"source": [
186+
"globtastic('.', skip_folder_re='^[_.]', folder_re='core', file_glob='*.*py*', file_re='c', sort=True)"
187+
]
188+
},
166189
{
167190
"cell_type": "code",
168191
"execution_count": null,

nbs/09_xml.ipynb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,9 @@
364364
"outputs": [],
365365
"source": [
366366
"#| export\n",
367-
"def _escape(s): return '' if s is None else s.__html__() if hasattr(s, '__html__') else escape(s) if isinstance(s, str) else s\n",
367+
"def _escape(s):\n",
368+
" return '' if s is None else s.__html__() if hasattr(s, '__html__') \\\n",
369+
" else escape(s, quote=False) if isinstance(s, str) else s\n",
368370
"def _noescape(s): return '' if s is None else s.__html__() if hasattr(s, '__html__') else s"
369371
]
370372
},

nbs/12_tools.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@
622622
" old_strs:list[str], # List of strings to find and replace\n",
623623
" new_strs:list[str], # List of replacement strings (must match length of old_strs)\n",
624624
"):\n",
625-
" \"Replace for each str pair in old_strs,new_strs call `str_replace\"\n",
625+
" \"Replace for each str pair in old_strs,new_strs\"\n",
626626
" res = [str_replace(path, old, new) for (old,new) in zip(old_strs,new_strs)]\n",
627627
" return 'Results for each replacement:\\n' + '; '.join(res)"
628628
]

0 commit comments

Comments
 (0)