
                            d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl m!Z! ddl"m#Z# ddl"m$Z$ ejJ                  re&Z' e
jP                  d      Z)dZ* G d de+      Z, G d de,      Z-d Z. G d de,      Z/ G d  d!e'      Z0	 	 	 	 	 d#d"Z1y)$z1Wildcard iterator class and supporting functions.    )absolute_import)print_function)division)unicode_literalsN)BucketListingBucket)BucketListingObject)BucketListingPrefix)AccessDeniedException)CloudApi)NotFoundException)CommandException)ContainsWildcard)GenerationFromUrlAndString)StorageUrlFromString)StripOneSlash)WILDCARD_REGEX)storage_v1_messages)UTF8)FixWindowsEncodingIfNeeded)PrintableStrz (?P<before>.*?)\*\*(?P<after>.*)a\  Invalid Unicode path encountered (%s). gsutil cannot proceed with such files present. Please remove or rename this file and try again. NOTE: the path printed above replaces the problematic characters with a hex-encoded printable representation. For more details (including how to convert to a gsutil-compatible encoding) see `gsutil help encoding`.c                       e Zd ZdZd Zy)WildcardIteratora  Class for iterating over Google Cloud Storage strings containing wildcards.

  The base class is abstract; you should instantiate using the
  wildcard_iterator() static factory method, which chooses the right
  implementation depending on the base string.
  c                 4    d| j                   j                  z  S )z2Returns string representation of WildcardIterator.zWildcardIterator(%s))wildcard_url
url_stringselfs    *platform/gsutil/gslib/wildcard_iterator.py__repr__zWildcardIterator.__repr__I   s    !D$5$5$@$@@@    N)__name__
__module____qualname____doc__r    r    r   r   r   ?   s    Ar    r   c                   r    e Zd ZdZ	 	 	 ddZ	 	 ddZd Zd Zd ZddZ	dd	Z
dd
Zd ZddZddZddZy)CloudWildcardIteratoraV  WildcardIterator subclass for buckets, bucket subdirs and objects.

  Iterates over BucketListingRef matching the Url string wildcard. It's
  much more efficient to first get metadata that's available in the Bucket
  (for example to get the name and size of each object), because that
  information is available in the object list results.
  Nc                 v    || _         || _        || _        || _        |xs t	        j
                         | _        y)a  Instantiates an iterator that matches the wildcard URL.

    Args:
      wildcard_url: CloudUrl that contains the wildcard to iterate.
      gsutil_api: Cloud storage interface.  Passed in for thread safety, also
                  settable for testing/mocking.
      all_versions: If true, the iterator yields all versions of objects
                    matching the wildcard.  If false, yields just the live
                    object version.
      project_id: Project ID to use for bucket listings.
      logger: logging.Logger used for outputting debug messages during
              iteration. If None, the root logger will be used.
    N)r   all_versions
gsutil_api
project_idlogging	getLoggerlogger)r   r   r*   r)   r+   r.   s         r   __init__zCloudWildcardIterator.__init__W   s7    & %D$D DO DO/G--/DKr    c           	   #    
  K   | j                   j                         }d}|rt               }|D ]  }|j                  |        | j	                  |      }|j                  ddg       |j                  dg       |s| j                  r&|j                  ddg       |j                  dd	g       | j                  d
g      D ]2  }|j                  }| j                   j                         r|rt        |      }| j                  j                  |j                  d| j                  | j                   j                  |      D ]r  }	|	j                  t         j"                  j$                  k(  r+| j'                  ||	j(                  | j                         U| j+                  ||	j(                         t | t-        | j                   j                        s| j                   j/                         r| j                  s	 | j                  j1                  | j                   j                  | j                   j2                  | j                   j4                  | j                   j                  |      }
| j'                  | j                   j6                  |
| j                  xs |        y|r2|| j                   j2                  d| j                   j4                  }n'|t=        | j                   j2                        xs d}|g}|sLt        |j?                  d            }| jA                  |j2                        \  }}}}| jC                  |      }|rt        dg      n|}| j                  j                  |j                  ||| j                  xs || j                   j                  |      D ]7  }	|D ].  }|	j                  t         j"                  j$                  k(  r|	j(                  }|jE                  |jF                        sS|rt=        |jF                        |k(  rA|r| jI                  |j4                        r$| j'                  ||| j                  xs |        |	j(                  }t-        |      rtK        d||d      t=        |      }|jE                  |      s|r#||k7  r||dz   |z   }|jM                  |       n| j+                  ||        7 : |r5 y# t8        t:        f$ r Y _w xY ww)a!  Iterator that gets called when iterating over the cloud wildcard.

    In the case where no wildcard is present, returns a single matching object,
    single matching prefix, or one of each if both exist.

    Args:
      bucket_listing_fields: Iterable fields to include in bucket listings.
                             Ex. ['name', 'acl'].  Iterator is
                             responsible for converting these to list-style
                             format ['items/name', 'items/acl'] as well as
                             adding any fields necessary for listing such as
                             prefixes.  API implementation is responsible for
                             adding pagination fields.  If this is None,
                             all fields are returned.
      expand_top_level_buckets: If true, yield no BUCKET references.  Instead,
                                expand buckets into top-level objects and
                                prefixes.

    Yields:
      BucketListingRef of type BUCKET, OBJECT or PREFIX.
    N)
get_fieldsz
items/nameprefixesnamezitems/generationzitems/metageneration
generationmetagenerationidbucket_fields/)	delimiterr)   providerfields)with_version)r4   r;   r<   #r   )prefixr:   r)   r;   r<   zCloud folder z] contains a wildcard; gsutil does not currently support objects with wildcards in their name.)'r   HasGenerationsetadd_GetToListFieldsupdater)   _ExpandBucketWildcardsr   IsBucketr   r*   ListObjectsbucket_nameschemedatatyper   CsObjectOrPrefixTypeOBJECT_GetObjectRefdata_GetPrefixRefr   IsObjectGetObjectMetadataobject_namer4   bucket_url_stringr   r
   r   pop_BuildBucketFilterStrings_GetRegexPatternsmatchr3   _SingleVersionMatchesr   append)r   bucket_listing_fieldsexpand_top_level_bucketssingle_version_requestr1   fieldbucket_listing_refrS   urlobj_or_prefix
get_objectr   urls_needing_expansionr?   r:   prefix_wildcardsuffix_wildcardregex_patternslisting_fieldspattern
gcs_objectrstripped_prefixurl_append_strings                          r   __iter__zCloudWildcardIterator.__iter__p   s    0 "..<<> J5j(%u )"33* 4 ,""L*#=>! 
 4#4#4$$!78	:<)9:;
 #999O,77				#	#	% $$%67##::oo,,((//*  ;  ,m %%)F)F)M)MM&&'8'4'9'9484E4E ' G G &&'8-:L:LMM , #
"
 !!2!2!=!=>&&(1B1B::!!--!!--,,77**11! ; #J $$T%6%6%H%H%/373D3D 4J3I % L L  "$5$($5$5$A$A$($5$5$@$@B*  t/@/@/L/L!M ""* #-$$%;%?%?%BC##==cooN69o11/B.  /  -4I   $::oo!,,F0F((//#  ;  %m *''8+H+H+O+OO*//
==1(]:??-K0?.@122:3H3HI ..+$(,(9(9 )?(>	 / A A
 &++#F+
 ) "3F<= = $1#8 ==!12$)9_)L2C2BS2H2A3B)C% +112CD ,,->GGS * % %u PN $%:; sG   G>TB(S8)A"TD TB!T0AT4T8TT
TTc                 0   |g}d|v r$|j                  dd      }|j                  |       n|}||fD ](  }|j                  d      s|j                  |dd        * |D cg c]*  }t        j                  t        j                  |            , c}S c c}w )a  Returns list of regex patterns derived from the wildcard patterns.

    Args:
      wildcard_pattern (str): A wilcard_pattern to filter the resources.

    Returns:
      List of compiled regex patterns.

    This translates the wildcard_pattern and also creates some additional
    patterns so that we can treat ** in a/b/c/**/d.txt as zero or more folders.
    This means, a/b/c/d.txt will also be returned along with a/b/c/e/f/d.txt.
    z/**/r9   **/   N)replacerY   
startswithrecompilefnmatch	translate)r   wildcard_patternwildcard_patternsupdated_patternrg   ps         r   rV   z'CloudWildcardIterator._GetRegexPatterns  s     **!! )00=o/(o$o6			E	" 	  - 7 7HH6GBJJw((+,6GHHHs   !/Bc           
         t        j                  |      }|s	|}d}|}d}n|j                         dkD  r'|d|j                          }||j                         d }nd}|}|j                  d      }|dk7  r|d|dz    }|xs d|z   }|j	                  d      st        |      }||j                         d }|j                  d      }|dk(  rd}n||dz   d }|j                  d      dk7  r
d}||z  }d}nd}| j                  j                  d	t        |      t        |      t        |      t        |      t        |             ||||fS )
a  Builds strings needed for querying a bucket and filtering results.

    This implements wildcard object name matching.

    Args:
      wildcard: The wildcard string to match to objects.

    Returns:
      (prefix, delimiter, prefix_wildcard, suffix_wildcard)
      where:
        prefix is the prefix to be sent in bucket GET request.
        delimiter is the delimiter to be sent in bucket GET request.
        prefix_wildcard is the wildcard to be used to filter bucket GET results.
        suffix_wildcard is wildcard to be appended to filtered bucket GET
          results for next wildcard expansion iteration.
      For example, given the wildcard gs://bucket/abc/d*e/f*.txt we
      would build prefix= abc/d, delimiter=/, prefix_wildcard=d*e, and
      suffix_wildcard=f*.txt. Using this prefix and delimiter for a bucket
      listing request will then produce a listing result set that can be
      filtered using this prefix_wildcard; and we'd use this suffix_wildcard
      to feed into the next call(s) to _BuildBucketFilterStrings(), for the
      next iteration of listing/filtering.

    Raises:
      AssertionError if wildcard doesn't contain any wildcard chars.
    r9    r   N   rm   z**zMwildcard=%s, prefix=%s, delimiter=%s, prefix_wildcard=%s, suffix_wildcard=%s
)
r   searchstartfindendswithr   endr.   debugr   )	r   wildcardrW   r?   r:   rc   rd   wildcard_partr   s	            r   rU   z/CloudWildcardIterator._BuildBucketFilterStrings9  sw   : !!(+E fi oo		 .5;;=) 0 s#c	%hsQw/26o%%e, (8 .o  %c	)#'(3 
		d	#r	)	?*	 	KK	34@4JVl95_%|O'D	F
 I@@r    c                     t        | j                  |      }t        | j                  j                        t        |      k(  S N)r   r   strr4   )r   listed_generationdecoded_generations      r   rX   z+CloudWildcardIterator._SingleVersionMatches  s;    3D4E4E4EGt  ++,4F0GGGr    c              #     K   t        | j                  j                        }|rEt        |      t        dg      k(  r-t	        | j                  j
                        st        |       y| j                  j                         rst	        | j                  j
                        sTt        || j                  j                  | j                  j
                  | j                  j                  |             yt        j                  | j                  j
                        }t        j                  |      }| j                  |      }|r|j!                  d       | j                  j#                  || j$                  | j                  j                        D ]\  }|j'                  |j(                        st        | j                  j                  d|j(                  d      }t        ||       ^ yw)	aG  Expands bucket and provider wildcards.

    Builds a list of bucket url strings that can be iterated on.

    Args:
      bucket_fields: If present, populate only these metadata fields for
                     buckets.  Example value: ['acl', 'defaultObjectAcl']

    Yields:
      BucketListingRefereneces of type BUCKET.
    r6   )r;   r<   root_objectzitems/id)r<   r+   r;   z://r9   N)r   r   rS   rA   r   rH   r   rF   r*   	GetBucketrI   rs   rt   rq   rr   rC   rB   ListBucketsr+   rW   r6   )r   r8   
bucket_urlregexprogr<   bucketr_   s           r   rE   z,CloudWildcardIterator._ExpandBucketWildcards  s     &d&7&7&I&IJJ#m,TF;T..::;  
++



$
$
&t00<<=
,0OO,E,E$($5$5$A$A-1->->-E-E+8 -F -:; ;  1 1 = =>eZZd$$]3f	

:OO//__$$++ 0 -& ::fii $&*&7&7&>&>		&K L##CV<
<-s   F0G43AG4c                 V    |r't               }|D ]  }|j                  d|z           |S y)a  Prepends 'items/' to the input fields and converts it to a set.

    This way field sets requested for GetBucket can be used in ListBucket calls.
    Note that the input set must contain only bucket or object fields; listing
    fields such as prefixes or nextPageToken should be added after calling
    this function.

    Args:
      get_fields: Iterable fields usable in GetBucket/GetObject calls.

    Returns:
      Set of fields usable in ListBuckets/ListObjects calls.
    zitems/N)rA   rB   )r   r1   list_fieldsr]   s       r   rC   z&CloudWildcardIterator._GetToListFields  s4     Ek%5() 	 r    c                     |r@|j                   4t        | j                  |j                         }||j                  d|}n||j                  }t	        |      }t        ||      S )ah  Creates a BucketListingRef of type OBJECT from the arguments.

    Args:
      bucket_url_string: Wildcardless string describing the containing bucket.
      gcs_object: gsutil_api root Object for populating the BucketListingRef.
      with_version: If true, return a reference with a versioned string.

    Returns:
      BucketListingRef of type OBJECT.
    r>   r   )r4   r   r   r3   r   r   )r   rS   rh   r=   generation_strobject_string
object_urls          r   rM   z#CloudWildcardIterator._GetObjectRef  sh     
--91$2C2C2<2G2GIn#4joo#13m !2:??Cm%m4JzzBBr    c                 :    t        ||      }t        ||      S )a  Creates a BucketListingRef of type PREFIX from the arguments.

    Args:
      bucket_url_string: Wildcardless string describing the containing bucket.
      prefix: gsutil_api Prefix for populating the BucketListingRef

    Returns:
      BucketListingRef of type PREFIX.
    r   )r   r	   )r   rS   r?   
prefix_urls       r   rO   z#CloudWildcardIterator._GetPrefixRef  s!     &0A6&JKJzv>>r    c              #   B   K   | j                  |      D ]  }|  yw)ah  Iterates over the wildcard, returning refs for each expanded bucket.

    This ignores the object part of the URL entirely and expands only the
    the bucket portion.  It will yield BucketListingRefs of type BUCKET only.

    Args:
      bucket_fields: Iterable fields to include in bucket listings.
                     Ex. ['defaultObjectAcl', 'logging'].  This function is
                     responsible for converting these to listing-style
                     format ['items/defaultObjectAcl', 'items/logging'], as
                     well as adding any fields necessary for listing such as
                     'items/id'.  API implemenation is responsible for
                     adding pagination fields.  If this is None, all fields are
                     returned.

    Yields:
      BucketListingRef of type BUCKET, or empty iterator if no matches.
    r7   N)rE   )r   r8   blrs      r   IterBucketsz!CloudWildcardIterator.IterBuckets  s&     & ***Gi H   c              #   D   K   | j                  ||      D ]  }|  yw)a}  Iterates over the wildcard, yielding bucket, prefix or object refs.

    Args:
      bucket_listing_fields: If present, populate only these metadata
                             fields for listed objects.
      expand_top_level_buckets: If true and the wildcard expands only to
                                Bucket(s), yields the expansion of each bucket
                                into a top-level listing of prefixes and objects
                                in that bucket instead of a BucketListingRef
                                to that bucket.

    Yields:
      BucketListingRef, or empty iterator if no matches.
    rZ   r[   Nrk   )r   rZ   r[   r   s       r   IterAllzCloudWildcardIterator.IterAll  s-      }}3H6N  PiPs    c              #   f   K   | j                  |d      D ]  }|j                         s|  yw)a&  Iterates over the wildcard, yielding only object BucketListingRefs.

    Args:
      bucket_listing_fields: If present, populate only these metadata
                             fields for listed objects.

    Yields:
      BucketListingRefs of type OBJECT or empty iterator if no matches.
    Tr   N)rk   rP   )r   rZ   r   s      r   IterObjectsz!CloudWildcardIterator.IterObjects  s4      }}3H6:  <		<s   '11)FNNNFr   )F)r!   r"   r#   r$   r/   rk   rV   rU   rX   rE   rC   rM   rO   r   r   r   r%   r    r   r'   r'   N   s`     "04 &*(-fPIBSAjH
(=T(C.?,&r    r'   c                 h    t        j                  t        j                  j	                  |             S )a0  Returns an apitools Object class with supported file attributes.

  To provide size estimates for local to cloud file copies, we need to retrieve
  expose the local file's size.

  Args:
    filepath: Path to the file.

  Returns:
    apitools Object that with file name and size attributes filled-in.
  )size)apitools_messagesObjectospathgetsize)filepaths    r   _GetFileObjectr   .  s"     
	!	!rwwx'@	AAr    c                   J    e Zd ZdZ	 	 	 d
dZddZd Zd ZddZddZ	dd	Z
y)FileWildcardIteratora  WildcardIterator subclass for files and directories.

  If you use recursive wildcards ('**') only a single such wildcard is
  supported. For example you could use the wildcard '**/*.txt' to list all .txt
  files in any subdirectory of the current directory, but you couldn't use a
  wildcard like '**/abc/**/*.txt' (which would, if supported, let you find .txt
  files in any subdirectory named 'abc').
  Nc                 h    || _         || _        || _        |xs t        j                         | _        y)a'  Instantiates an iterator over BucketListingRefs matching wildcard URL.

    Args:
      wildcard_url: FileUrl that contains the wildcard to iterate.
      exclude_tuple: (base_url, exclude_pattern), where base_url is
                     top-level URL to list; exclude_pattern is a regex
                     of paths to ignore during iteration.
      ignore_symlinks: If True, ignore symlinks during iteration.
      logger: logging.Logger used for outputting debug messages during
              iteration. If None, the root logger will be used.
    N)r   exclude_tupleignore_symlinksr,   r-   r.   )r   r   r   r   r.   s        r   r/   zFileWildcardIterator.__init__I  s1      %D&D*D/G--/DKr    c              #     K   |xr dt        |      v }| j                  j                  }t        j	                  |      }|rz|j                  d      dd }|j                  d      }|j                  d      rt        d|z        |sd}|j                  t        j                        }| j                  ||      }nt        j                  |      }|D ]  }t        |      }		 | j                  rHt        j                   j#                  |      r)| j$                  r| j$                  j'                  d|       ct        j                   j)                  |      rt+        |	       n|rt-        |      nd}
t/        |	|
	        y# t0        $ r> t3        d
j5                  t7        j8                  t:        t=        |      z                    w xY ww)a@  Iterator that gets called when iterating over the file wildcard.

    In the case where no wildcard is present, returns a single matching file
    or directory.

    Args:
      bucket_listing_fields: Iterable fields to include in listings.
          Ex. ['size']. Currently only 'size' is supported.
          If present, will populate yielded BucketListingObject.root_object
          with the file name and size.

    Raises:
      WildcardException: if invalid wildcard found.

    Yields:
      BucketListingRef of type OBJECT (for files) or PREFIX (for directories)
    r   beforeNr{   after*z5Invalid wildcard with more than 2 consecutive *s (%s)zSkipping symbolic link %s...r   
)rA   r   rR   FLAT_LIST_REGEXrW   grouprp   WildcardExceptionlstripr   sep_IterDirglobiglobr   r   r   islinkr.   infoisdirr	   r   r   UnicodeEncodeErrorr   jointextwrapwrap_UNICODE_EXCEPTION_TEXTrepr)r   rZ   include_sizer   rW   base_dirremaining_wildcard	filepathsr   expanded_url
blr_objects              r   rk   zFileWildcardIterator.__iter__^  s    $ * 9c"788    ,,H!!(+E X&s+h ;;w/ 
	&	&s	+ !*,4!5 6 	6
   -44RVV<--*<=i **X&i)(3lFBGGNN8$<[[KK;XF
77=="#L1
13?~h/T*#LjI
I    FtyyMM1DNBC E F 	FFs-   CG!AF4G5AF GAG

Gc              #   Z  K   t         j                  j                  |      d   |k(  r|dz  }t        j                  t	        j
                  |      d      D ]  \  }}}g }|D ]  }t         j                  j                  ||      }| j                  |      s|j                  |       nG| j                  sTt         j                  j                  |      st| j                  j                  d|        ||dd t        j                  ||      D ].  }		 t         j                  j                  |t        |	             0  y# t        $ r\ t!        dj                  t#        j$                  t&        t)        t         j                  j                  ||	            z                    w xY ww)a  An iterator over the specified dir and wildcard.

    Args:
      directory (unicode): The path of the directory to iterate over.
      wildcard (str): The wildcard characters used for filename pattern
          matching.

    Yields:
      (str) A string containing the path to a file somewhere under the directory
      hierarchy of `directory`.

    Raises:
      ComandException: If this method encounters a file path that it cannot
      decode as UTF-8.
    r   \T)topdownzSkipping symlink directory "%s"Nr   )r   r   
splitdrivewalksixensure_textr   _ExcludeDirrY   r.   r   r   rs   filterr   UnicodeDecodeErrorr   r   r   r   r   )
r   	directoryr   dirpathdirnames	filenamesfiltered_dirnamesdirnamefull_dir_pathfs
             r   r   zFileWildcardIterator._IterDir  sc      
ww)$Q'94 4i )+	0J8<)>$9'Wg6 .

"
"7
+  ;;277>>-8
++

<m
L  &hqk~~i2!	>W&@&CD
D 3))>. " 	>6 !mm3 gq!9:; <"= > >7	>s+   B3F+6F+<F++E>F+A%F((F+c                 b   | j                   y| j                   \  }}}|syt        |      j                  t        |j                        d }|j	                  | j
                  j                        r|dd }|j                  |      r)| j                  r| j                  j                  d|       yy)zCheck a directory to see if it should be excluded from os.walk.

    Args:
      dir: String representing the directory to check.

    Returns:
      True if the directory should be excluded.
    NFr|   z!Skipping excluded directory %s...T)
r   r   r   lenrp   r   delimrW   r.   r   )r   dirbase_urlexclude_dirsexclude_patternstr_to_checks         r   r   z FileWildcardIterator._ExcludeDir  s     !040B0B-X|_'ZH//013Lt00667!!"%l\*	<cB +r    c              #   d   K   | j                  |      D ]  }|j                         s|  yw)a  Iterates over the wildcard, yielding only object (file) refs.

    Args:
      bucket_listing_fields: Iterable fields to include in listings.
          Ex. ['size']. Currently only 'size' is supported.
          If present, will populate yielded BucketListingObject.root_object
          with the file name and size.

    Yields:
      BucketListingRefs of type OBJECT or empty iterator if no matches.
    rZ   N)r   rP   )r   rZ   r^   s      r   r   z FileWildcardIterator.IterObjects  s6      #ll3 + 5		$	$	&  5s   &00c              #   B   K   | j                  |      D ]  }|  yw)a  Iterates over the wildcard, yielding BucketListingRefs.

    Args:
      bucket_listing_fields: Iterable fields to include in listings.
          Ex. ['size']. Currently only 'size' is supported.
          If present, will populate yielded BucketListingObject.root_object
          with the file name and size.
      expand_top_level_buckets: Ignored; filesystems don't have buckets.

    Yields:
      BucketListingRefs of type OBJECT (file) or PREFIX (directory),
      or empty iterator if no matches.
    r   Nr   )r   rZ   r[   r^   s       r   r   zFileWildcardIterator.IterAll  s*      #mm3 , 55r   c                     t        d      )zPlaceholder to allow polymorphic use of WildcardIterator.

    Args:
      unused_bucket_fields: Ignored; filesystems don't have buckets.

    Raises:
      WildcardException: in all cases.
    z6Iterating over Buckets not possible for file wildcards)r   )r   unused_bucket_fieldss     r   r   z FileWildcardIterator.IterBuckets*  s     @B Br    )NFNr   r   )r!   r"   r#   r$   r/   rk   r   r   r   r   r   r%   r    r   r   r   ?  s:     "$	0*:FxR>h0!$$
Br    r   c                   "    e Zd ZdZd Zd Zd Zy)r   z+Exception raised for invalid wildcard URLs.c                 <    t         j                  |        || _        y r   )StandardErrorr/   reason)r   r   s     r   r/   zWildcardException.__init__:  s    4 DKr    c                      d| j                   z  S NzWildcardException: %sr   r   s    r   r   zWildcardException.__repr__>      "T[[00r    c                      d| j                   z  S r   r   r   s    r   __str__zWildcardException.__str__A  r   r    N)r!   r"   r#   r$   r/   r   r   r%   r    r   r   r   7  s    311r    r   c                     t        |       }|xs t        j                         }|j                         rt	        ||||      S t        ||||      S )a  Instantiate a WildcardIterator for the given URL string.

  Args:
    url_str: URL string naming wildcard object(s) to iterate.
    gsutil_api: Cloud storage interface.  Passed in for thread safety, also
                settable for testing/mocking.
    all_versions: If true, the iterator yields all versions of objects
                  matching the wildcard.  If false, yields just the live
                  object version.
    project_id: Project id to use for bucket listings.
    exclude_tuple: (base_url, exclude_pattern), where base_url is
                   top-level URL to list; exclude_pattern is a regex
                   of paths to ignore during iteration.
    ignore_symlinks: For FileUrls, ignore symlinks during iteration if true.
    logger: logging.Logger used for outputting debug messages during iteration.
            If None, the root logger will be used.

  Returns:
    A WildcardIterator that handles the requested iteration.
  )r   r   r.   )r)   r+   )r   r,   r-   	IsFileUrlr   r'   )url_strr*   r)   r+   r   r   r.   r_   s           r   CreateWildcardIteratorr   E  s\    8 	W%#(W&&(&]]_.;0?'-/ /
 !!+.:,68 8r    )FNNFN)2r$   
__future__r   r   r   r   rs   r   r,   r   rq   r   r   gslib.bucket_listing_refr   r   r	   gslib.cloud_apir
   r   r   gslib.exceptionr   gslib.storage_urlr   r   r   r   r   "gslib.third_party.storage_apitoolsr   r   gslib.utils.constantsr   gslib.utils.text_utilr   r   PY3	Exceptionr   rr   r   r   objectr   r'   r   r   r   r   r%   r    r   <module>r     s    8 & %  '    	 	  
 8 8 8 1 $ - , . 8 2 + , W & < .77-"**@A> Av A], ]@B"uB+ uBp1 1  ).&*)-+0"&'8r    