Inspired by this discussion on StackOverflow:
Boto3 lists buckets unhelpfully like this:
{'Buckets': [{'CreationDate': datetime.datetime(1, 1, 1, 0, 0, tzinfo=tzlocal()),
'Name': 'foo'},
{'CreationDate': datetime.datetime(1, 1, 1, 0, 0, tzinfo=tzlocal()),
'Name': 'bar'},
{'CreationDate': datetime.datetime(2024, 7, 30, 15, 4, 59, 150000, tzinfo=tzlocal()),
'Name': 'baz'}],
'Owner': {...}}
If I want to know whether a bucket foo
is at the start of that list, I can write this:
match s3_response:
case {"Buckets": [{"Name": "foo", "CreationDate": _}, *_]}:
print("Bucket 'foo' found")
case _:
print("Bucket 'foo' not found")
And I can think of a similar solution if the bucket is known to be at the end.
But what about finding bucket bar
which is in the middle of the list of buckets? You might hope you could do this:
match s3_response:
case {"Buckets": [*_, {"Name": "bar", "CreationDate": _}, *_]}:
print("Bucket 'bar' found")
case _:
print("Bucket 'bar' not found")
But that gives:
SyntaxError: multiple starred names in sequence pattern
Of course I could do things the boring old way, but where’s the fun in that:
'bar' in [bucket.get("Name", "") for bucket in s3_response.get("Buckets", [])]
As SO user jsbueno suggested, the “two *_
argument solution” looks kind of reasonable.
(Interestingly, ChatGPT actually offers this Syntax Error as a solution already, so clearly it thinks it’s a good idea!)
Another possible, but unattractive, way to write this would be:
match s3_response:
case {"Buckets": [*buckets]}:
for bucket in buckets:
match bucket:
case {"Name": "bar", "CreationDate": _}:
return True # or whatever
case _:
return False