Skip to content

Should the dict.get overload with default value not be generic? #9155

@Avasam

Description

@Avasam

When using dict.get with a default value, it is expected that the key may not be found. Most of the time it's because we're not dealing with literal types, so we can't ensure that a key is part of the dict. But other times, it's we explicitely use a value that has a type we know won't be in range (often None).

See the example below (it is of course minimal and abstracted from a real-world example, but should still show the use):

code_events = {
  0: "ZERO_EVENT",
  1: "ONE_EVENT",
  # ...
  127: "LAST_EVENT",
}

def parse_foo_code(self, code: int | None):
  code  = code and (code & 0x7f)  # Some bitwise operation to skip bit 8, this just shows we can't use -1 as default. And who knows what other keys could be used in the dict
  event = code_events.get(code, "SPECIAL_DEFAULT_FOO_EVENT")
  # ... do more with the event
  
def parse_bar_code(self, code: int | None):
  code  = code and (code & 0x7f)  # Some bitwise operation to skip bit 8
  event = code_events.get(code, "SPECIAL_DEFAULT_BAR_EVENT")
  # ... do more with the event

Currently it has to be written as such (without a cast). Which adds redundancy checks and no type-safety:

def parse_foo_code(self, code: int | None):
  code  = code and (code & 0x7f)  # Some bitwise operation to skip bit 8
  if isinstance(code, int):  # You could imagine this could be more complex than just int. Maybe it can't even be easily expressed
    event = code_events.get(code, "SPECIAL_DEFAULT_FOO_EVENT")
  else:
    event = "SPECIAL_DEFAULT_FOO_EVENT"
  # ... do more with the event

What if this definition in dict:

@overload
def get(self, __key: _KT) -> _VT | None: ...
@overload
def get(self, __key: _KT, __default: _VT | _T) -> _VT | _T: ...

was changed to:

@overload
def get(self, __key: _KT) -> _VT | None: ...
@overload
def get(self, __key: object, __default: _VT | _T) -> _VT | _T: ...  # Either object,  or Any if it causes variance issue.

What are your thoughts? Any reason this would be a bad idea? From what I can see there are legit sensible use-cases, it stays type-safe, and allows for more concise code. Or just use a cast and call it a day?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy