[Python-Dev] Is static typing still optional? (original) (raw)
Nick Coghlan ncoghlan at gmail.com
Mon Jan 29 01:34:37 EST 2018
- Previous message (by thread): [Python-Dev] Is static typing still optional?
- Next message (by thread): [Python-Dev] Is static typing still optional?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 29 January 2018 at 12:08, Guido van Rossum <guido at python.org> wrote:
I think this is a good candidate for fine-tuning during the beta period.
Though honestly Python's own rules for when a class is hashable or not are the root cause for the complexity here -- since we decided to implicitly set hash = None when you define eq, it's hardly surprising that dataclasses are having a hard time making natural rules.
In Raymond's example, the problem is the opposite: data classes are currently interpreting "hash=False" as "Don't add a hash implementation" rather than "Make this unhashable". That interpretation isn't equivalent due to object.hash existing by default. (Reviewing Eric's table again, I believe this problem still exists in the 3.7b1 variant as well - I just missed it the first time I read that)
I'd say the major argument in favour of Raymond's suggestion (i.e. always requiring an explicit "hash=True" in the dataclass decorator call if you want the result to be hashable) is that even if we do come up with a completely consistent derivation rule that the decorator can follow, most readers aren't going to know that rule. It would become a Python gotcha question for tech interviews:
============= Which of the following class definitions are hashable and what is their hash based on?:
@dataclass
class A:
field: int
@dataclass(eq=False)
class B:
field: int
@dataclass(frozen=True)
class C:
field: int
@dataclass(eq=False, frozen=True) class D: field: int
@dataclass(eq=True, frozen=True)
class E:
field: int
@dataclass(hash=True)
class F:
field: int
@dataclass(frozen=True, hash=True)
class G:
field: int
@dataclass(eq=True, frozen=True, hash=True)
class H:
field: int
=============
Currently the answers are:
- A: not hashable
- B: hashable (by identity) # Wat?
- C: hashable (by field hash)
- D: hashable (by identity) # Wat?
- E: hashable (by field hash)
- F: hashable (by field hash)
- G: hashable (by field hash)
- H: hashable (by field hash)
If we instead make the default "hash=False" (and interpret that as meaning "Inject hash=None"), then you end up with the following much simpler outcome that can be mapped directly to the decorator "hash" parameter:
- A: not hashable
- B: not hashable
- C: not hashable
- D: not hashable
- E: not hashable
- F: hashable (by field hash)
- G: hashable (by field hash)
- H: hashable (by field hash)
Inheritance of hash could then be made explicitly opt-in by way of a "dataclasses.INHERIT" constant.
Cheers, Nick.
-- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
- Previous message (by thread): [Python-Dev] Is static typing still optional?
- Next message (by thread): [Python-Dev] Is static typing still optional?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]