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", [])]
The match expression in match..case
statements in Python has an special syntax, that is not Python - so all, possible matches are restricted to what is listed inPEP-0622 .
And what is mentioned there for sequences is:
A sequence pattern looks like [a, *rest, b] and is similar to a list unpacking. An important difference is that the elements nested within it can be any kind of patterns, not just names or sequences. It matches only sequences of appropriate length, as long as all the sub-patterns also match. It makes all the bindings of its sub-patterns.
So, there is no match expression equivalent for the in
operator - sorry to spoil your fun. The best you can get is using a guard expression in your case
- as guard expressions are again valid Python:
match s3_response:
case {"Buckets": [*buckets] if any((bucket["Name"] == "bar" and "CreationDate" in bucket and len(bucket) == 2) for bucket in buckets):
print("Bucket 'bar' found")