@@ -263,6 +263,54 @@ def escape(pathname):
263263_dir_open_flags  =  os .O_RDONLY  |  getattr (os , 'O_DIRECTORY' , 0 )
264264_no_recurse_symlinks  =  object ()
265265
266+ def  escape_pathname_range_including_seps (pat , seps ):
267+     """Escape ranges containing seperators in a path 
268+     """ 
269+     pat  =  list (pat )
270+     ordinal_seps = set (map (ord , seps ))
271+ 
272+     insideRange  =  False 
273+     ds = []
274+ 
275+     buf = '' 
276+     idx1 = 0 
277+     idx2 = 0 
278+     rangeIncludesSep = False 
279+ 
280+     for  path_idx , path_ch  in  enumerate (pat ):
281+         if  path_idx  >  0 :
282+             if  path_ch  ==  '['  and  pat [path_idx - 1 ] !=  '\\ ' :
283+                 insideRange  =  True 
284+                 idx1 = path_idx 
285+                 continue 
286+             if  path_ch  ==  ']'  and  pat [path_idx - 1 ] !=  '\\ ' :
287+                 insideRange  =  False 
288+                 idx2 = path_idx + 1 
289+ 
290+         if  insideRange :
291+             buf += path_ch 
292+             if  path_ch  ==  '-' :
293+                 glob_range  =  list (range (ord (pat [path_idx - 1 ]), ord (pat [path_idx + 1 ])))
294+                 if  ordinal_seps .intersection (glob_range ):
295+                     rangeIncludesSep  =  True 
296+ 
297+         elif  len (buf )> 0 :
298+             ds .append ([idx1 , idx2 , rangeIncludesSep ])
299+ 
300+             buf = '' 
301+             idx1 = 1 
302+             idx2 = 2 
303+             rangeIncludesSep = False 
304+ 
305+     for  ds_idx , ds_elem  in  enumerate (ds ):
306+         idx1 = ds_elem [0 ]
307+         idx2 = ds_elem [1 ]
308+         rangeIncludesSep = ds_elem [2 ]
309+         if  rangeIncludesSep :
310+             pat .insert (idx1 , '\\ ' )
311+             pat .insert (idx2 , '\\ ' )
312+ 
313+     return  '' .join (pat )
266314
267315def  translate (pat , * , recursive = False , include_hidden = False , seps = None ):
268316    """Translate a pathname with shell wildcards to a regular expression. 
@@ -282,6 +330,8 @@ def translate(pat, *, recursive=False, include_hidden=False, seps=None):
282330            seps  =  (os .path .sep , os .path .altsep )
283331        else :
284332            seps  =  os .path .sep 
333+ 
334+ 
285335    escaped_seps  =  '' .join (map (re .escape , seps ))
286336    any_sep  =  f'[{ escaped_seps }  ]'  if  len (seps ) >  1  else  escaped_seps 
287337    not_sep  =  f'[^{ escaped_seps }  ]' 
@@ -312,10 +362,14 @@ def translate(pat, *, recursive=False, include_hidden=False, seps=None):
312362            if  part :
313363                if  not  include_hidden  and  part [0 ] in  '*?' :
314364                    results .append (r'(?!\.)' )
365+ 
315366                results .extend (fnmatch ._translate (part , f'{ not_sep }  *' , not_sep )[0 ])
367+ 
316368            if  idx  <  last_part_idx :
317369                results .append (any_sep )
370+ 
318371    res  =  '' .join (results )
372+     res = escape_pathname_range_including_seps (res , seps = seps )
319373    return  fr'(?s:{ res }  )\Z' 
320374
321375
0 commit comments