No/confusing way to use match-case

current scenario -

  1. for certain types, there is no way to match them,
mppngprxy = (type.__dict__)
dct_kys = {'a': 1}.keys()
dct_vls = {'a': 1}.values()
dct_items = {'a': 1}.items()
for i in [mppngprxy, dct_kys, dct_vls, dct_items]:
  match i:
    case type(type.__dict__): print('mapping proxy') # it does not work
    case ???: print('dictionary keys')
    case ???: print('dictionary values')
    case ???: print('dictionary items')
  1. use of match case on types that could be traversed is also a bit confusing, as,
enmrt = enumerate([1, 2, 3])
for i in [enmrt]:
  match i:
    case enumerate(): print('enumerate')

gives, enumerate as output, similar holds true for range also.
but there is no way to match, iter(list([1, 2, 3])) as there is nothing like specifying list_iterator() after case, similar pattern for list_reverseiterator, set_iterator, …

  1. this one is a bit confusing, 1 == True and 0 == False, both give True, but,
match 1:
  case True: print('yes')

does not match, similar for match 0: to case False:.
one more thing is should 1 and 0 match with bool() also, as again 1 == True and 0 == False

  1. use of NotImplemented in case block, currently it acts as a wildcard.
match 1:
  case NotImplemented: print('1')
  case _: print('2')

gives the error,

SyntaxError: name capture 'NotImplemented' makes remaining patterns unreachable

this is also a bit controversial

expected scenario -

  1. if there is a way to get mappingproxy, dict_keys, dict_values, dict_items matched, then inform me, if there is no way, then probably there should be a way
  2. there should be a way to get list_iterator, set_iterator … matched also.
  3. controversial but one possibility is 1 should match with True and bool(), similar for 0 with False and bool()
  4. NotImplemented should not act as a wildcard, either just raise an error if NotImplemented is specified after case, or add a way to get it matched to a function which raises NotImplemented

For mappingproxy and NotImplemented, you can use types.MappingProxyType and types.NotImplementedType.

For dict_keys, dict_values and dict_items, you can’t access their class as a public object anywhere, but you can use collections.abc.KeysView, collections.abc.ValuesView and collections.abc.ItemsView (respectively).

Similarly for list_iterator (etc.), the actual classes aren’t exposed anywhere, since they’re implementation details. It would be a code smell to have a branch of code that depends on a precise kind of Iterator being passed in. Use collections.abc.Iterator instead, so that the pattern-matching succeeds with any kind of Iterator being passed in.

1 Like