11from collections import defaultdict
2+ from collections .abc import Generator , Iterable , Sequence
23from dataclasses import dataclass , field
3- from typing import Generator , Iterable , Optional , Sequence , Tuple
4+ from typing import Optional
45
56# By default, buckets are accessible to any logged in users. This is
67# represented by an empty set.
78_DEFAULT_PERMISSION_FACTORY = set
89
910
1011def _is_accessible (
11- required_groups : Optional [set ],
12- groups : Optional [Iterable [str ]]
12+ required_groups : Optional [set [ str ] ],
13+ groups : Optional [Iterable [str ]],
1314) -> bool :
1415 # Check for public access
1516 if required_groups is None :
@@ -30,7 +31,7 @@ class BucketMapEntry():
3031 headers : dict = field (default_factory = dict )
3132 _access_control : Optional [dict ] = None
3233
33- def is_accessible (self , groups : Iterable [str ] = None ) -> bool :
34+ def is_accessible (self , groups : Optional [ Iterable [str ] ] = None ) -> bool :
3435 """Check if the object is accessible with the given permissions.
3536
3637 Setting `groups` to an iterable implies that the user has logged in,
@@ -41,7 +42,7 @@ def is_accessible(self, groups: Iterable[str] = None) -> bool:
4142 required_groups = self .get_required_groups ()
4243 return _is_accessible (required_groups , groups )
4344
44- def get_required_groups (self ) -> Optional [set ]:
45+ def get_required_groups (self ) -> Optional [set [ str ] ]:
4546 """Get a set of permissions protecting this object.
4647
4748 It is sufficient to have one of the permissions in the set in order to
@@ -126,7 +127,7 @@ def get_path(self, path: Sequence[str]) -> Optional[BucketMapEntry]:
126127
127128 return None
128129
129- def entries (self ):
130+ def entries (self ) -> Generator [ BucketMapEntry ] :
130131 for bucket , path_parts , headers in _walk_entries (self ._get_map ()):
131132 yield self ._make_entry (
132133 bucket = bucket ,
@@ -135,7 +136,7 @@ def entries(self):
135136 headers = headers
136137 )
137138
138- def to_iam_policy (self , groups : Iterable [str ] = None ) -> dict :
139+ def to_iam_policy (self , groups : Optional [ Iterable [str ]] = None ) -> Optional [ dict ] :
139140 if not self ._iam_compatible :
140141 _check_iam_compatible (self .access_control )
141142 generator = IamPolicyGenerator (groups )
@@ -150,8 +151,8 @@ def _make_entry(
150151 bucket : str ,
151152 bucket_path : str ,
152153 object_key : str ,
153- headers : Optional [dict ] = None
154- ):
154+ headers : Optional [dict ] = None ,
155+ ) -> BucketMapEntry :
155156 return BucketMapEntry (
156157 bucket = self .bucket_name_prefix + bucket ,
157158 bucket_path = bucket_path ,
@@ -164,7 +165,7 @@ def _make_entry(
164165 )
165166
166167
167- def _walk_entries (node : dict , path = ()) -> Generator [Tuple [str , tuple , Optional [dict ]], None , None ]:
168+ def _walk_entries (node : dict , path = ()) -> Generator [tuple [str , tuple , Optional [dict ]]]:
168169 """A generator to recursively yield all leaves of a bucket map"""
169170
170171 for key , val in node .items ():
@@ -294,7 +295,7 @@ def _access_text(access) -> str:
294295
295296
296297class IamPolicyGenerator :
297- def __init__ (self , groups : Iterable [str ]):
298+ def __init__ (self , groups : Optional [ Iterable [str ] ]):
298299 self .groups = groups
299300
300301 def _is_accessible (self , required_groups : Optional [set ]) -> bool :
0 commit comments