@@ -332,48 +332,48 @@ def _un_chain(path, kwargs):
332
332
# [[url, protocol, kwargs], ...]
333
333
out = []
334
334
previous_bit = None
335
- previous_protocol = None
336
335
for bit in reversed (bits ):
337
336
protocol = split_protocol (bit )[0 ] or "file"
338
337
cls = get_filesystem_class (protocol )
339
338
extra_kwargs = cls ._get_kwargs_from_urls (bit )
340
- kws = kwargs .get (split_protocol ( bit )[ 0 ] or "file" , {})
339
+ kws = kwargs .get (protocol , {})
341
340
kw = dict (** extra_kwargs , ** kws )
341
+ bit = cls ._strip_protocol (bit )
342
342
if (
343
343
protocol in {"blockcache" , "filecache" , "simplecache" }
344
344
and "target_protocol" not in kw
345
345
):
346
- bit = previous_bit . replace ( previous_protocol , protocol , 1 )
346
+ bit = previous_bit
347
347
out .append ((bit , protocol , kw ))
348
348
previous_bit = bit
349
- previous_protocol = protocol
350
349
out = list (reversed (out ))
351
- # We should only do the url rewrite if the cache is in the middle of the chain
352
- if out [0 ][1 ] in {"blockcache" , "filecache" , "simplecache" }:
353
- out [0 ] = (f"{ out [0 ][1 ]} ://" , out [0 ][1 ], out [0 ][2 ])
354
350
return out
355
351
356
352
357
353
def url_to_fs (url , ** kwargs ):
358
354
"""Turn fully-qualified and potentially chained URL into filesystem instance"""
359
355
chain = _un_chain (url , kwargs )
360
356
if len (chain ) > 1 :
361
- kwargs = chain [ 0 ][ 2 ]
362
- inkwargs = kwargs
363
- for i , ch in enumerate (chain ):
357
+ inkwargs = {}
358
+ # Reverse iterate the chain, creating a nested target_* structure
359
+ for i , ch in enumerate (reversed ( chain ) ):
364
360
urls , protocol , kw = ch
365
- if i == 0 :
361
+ if i == len (chain ) - 1 :
362
+ inkwargs = dict (** kw , ** inkwargs )
366
363
continue
364
+ inkwargs ["target_options" ] = dict (** kw , ** inkwargs )
367
365
inkwargs ["target_protocol" ] = protocol
368
- inkwargs ["target_options" ] = kw .copy ()
369
366
inkwargs ["fo" ] = urls
370
- inkwargs = inkwargs ["target_options" ]
371
- protocol = chain [0 ][1 ]
372
- urlpath = chain [- 1 ][1 ] + "://" + split_protocol (urls )[1 ]
373
- fs = filesystem (protocol , ** kwargs )
367
+ urlpath , protocol , _ = chain [0 ]
368
+ fs = filesystem (protocol , ** inkwargs )
374
369
else :
375
- protocol , urlpath = split_protocol (url )
376
- fs = filesystem (protocol , ** kwargs )
370
+ protocol = split_protocol (url )[0 ]
371
+ cls = get_filesystem_class (protocol )
372
+
373
+ options = cls ._get_kwargs_from_urls (url )
374
+ urlpath = cls ._strip_protocol (url )
375
+ update_storage_options (options , kwargs )
376
+ fs = cls (** options )
377
377
urlpath = fs ._strip_protocol (url )
378
378
return fs , urlpath
379
379
@@ -563,72 +563,68 @@ def get_fs_token_paths(
563
563
Expand string paths for writing, assuming the path is a directory
564
564
"""
565
565
if isinstance (urlpath , (list , tuple , set )):
566
+ if not urlpath :
567
+ raise ValueError ("empty urlpath sequence" )
566
568
urlpath = [stringify_path (u ) for u in urlpath ]
567
569
else :
568
570
urlpath = stringify_path (urlpath )
569
571
chain = _un_chain (urlpath , storage_options or {})
570
572
if len (chain ) > 1 :
571
- storage_options = chain [0 ][2 ]
572
- inkwargs = storage_options
573
- urlpath = False
574
- for i , ch in enumerate (chain ):
575
- urls , protocol , kw = ch
576
- if isinstance (urls , str ):
577
- if not urlpath and split_protocol (urls )[1 ]:
578
- urlpath = protocol + "://" + split_protocol (urls )[1 ]
579
- else :
580
- if not urlpath and any (split_protocol (u )[1 ] for u in urls ):
581
- urlpath = [protocol + "://" + split_protocol (u )[1 ] for u in urls ]
582
- if i == 0 :
573
+ inkwargs = {}
574
+ # Reverse iterate the chain, creating a nested target_* structure
575
+ for i , ch in enumerate (reversed (chain )):
576
+ urls , nested_protocol , kw = ch
577
+ if i == len (chain ) - 1 :
578
+ inkwargs = dict (** kw , ** inkwargs )
583
579
continue
584
- inkwargs ["target_protocol " ] = protocol
585
- inkwargs ["target_options " ] = kw . copy ()
580
+ inkwargs ["target_options " ] = dict ( ** kw , ** inkwargs )
581
+ inkwargs ["target_protocol " ] = nested_protocol
586
582
inkwargs ["fo" ] = urls
587
- inkwargs = inkwargs ["target_options" ]
588
- protocol = chain [0 ][1 ]
589
- if isinstance (urlpath , (list , tuple )):
590
- if not urlpath :
591
- raise ValueError ("empty urlpath sequence" )
592
- protocols , paths = zip (* map (split_protocol , urlpath ))
593
- if protocol is None :
594
- protocol = protocols [0 ]
595
- if not all (p == protocol for p in protocols ):
583
+ paths , protocol , _ = chain [0 ]
584
+ fs = filesystem (protocol , ** inkwargs )
585
+ if isinstance (paths , (list , tuple , set )):
586
+ paths = [fs ._strip_protocol (u ) for u in paths ]
587
+ else :
588
+ paths = fs ._strip_protocol (paths )
589
+ else :
590
+ if isinstance (urlpath , (list , tuple , set )):
591
+ protocols , paths = zip (* map (split_protocol , urlpath ))
592
+ if protocol is None :
593
+ protocol = protocols [0 ]
594
+ if not all (p == protocol for p in protocols ):
595
+ raise ValueError (
596
+ "When specifying a list of paths, all paths must "
597
+ "share the same protocol"
598
+ )
599
+ cls = get_filesystem_class (protocol )
600
+ optionss = list (map (cls ._get_kwargs_from_urls , urlpath ))
601
+ paths = [cls ._strip_protocol (u ) for u in urlpath ]
602
+ options = optionss [0 ]
603
+ if not all (o == options for o in optionss ):
596
604
raise ValueError (
597
605
"When specifying a list of paths, all paths must "
598
- "share the same protocol "
606
+ "share the same file-system options "
599
607
)
600
- cls = get_filesystem_class (protocol )
601
- optionss = list (map (cls ._get_kwargs_from_urls , urlpath ))
602
- paths = [cls ._strip_protocol (u ) for u in urlpath ]
603
- options = optionss [0 ]
604
- if not all (o == options for o in optionss ):
605
- raise ValueError (
606
- "When specifying a list of paths, all paths must "
607
- "share the same file-system options"
608
- )
609
- update_storage_options (options , storage_options )
610
- fs = cls (** options )
608
+ update_storage_options (options , storage_options )
609
+ fs = cls (** options )
610
+ else :
611
+ protocols = split_protocol (urlpath )[0 ]
612
+ protocol = protocol or protocols
613
+ cls = get_filesystem_class (protocol )
614
+ options = cls ._get_kwargs_from_urls (urlpath )
615
+ paths = cls ._strip_protocol (urlpath )
616
+ update_storage_options (options , storage_options )
617
+ fs = cls (** options )
618
+
619
+ if isinstance (paths , (list , tuple , set )):
611
620
paths = expand_paths_if_needed (paths , mode , num , fs , name_function )
612
-
613
- elif isinstance (urlpath , str ) or hasattr (urlpath , "name" ):
614
- protocols , path = split_protocol (urlpath )
615
- protocol = protocol or protocols
616
- cls = get_filesystem_class (protocol )
617
-
618
- options = cls ._get_kwargs_from_urls (urlpath )
619
- path = cls ._strip_protocol (urlpath )
620
- update_storage_options (options , storage_options )
621
- fs = cls (** options )
622
-
621
+ else :
623
622
if "w" in mode and expand :
624
- paths = _expand_paths (path , name_function , num )
625
- elif "*" in path :
626
- paths = [f for f in sorted (fs .glob (path )) if not fs .isdir (f )]
623
+ paths = _expand_paths (paths , name_function , num )
624
+ elif "*" in paths :
625
+ paths = [f for f in sorted (fs .glob (paths )) if not fs .isdir (f )]
627
626
else :
628
- paths = [path ]
629
-
630
- else :
631
- raise TypeError ("url type not understood: %s" % urlpath )
627
+ paths = [paths ]
632
628
633
629
return fs , fs ._fs_token , paths
634
630
0 commit comments