[Python-Dev] Is static typing still optional?

Paul Moore p.f.moore at gmail.com
Fri Dec 15 16:14:34 EST 2017


On 15 December 2017 at 20:07, Chris Barker <chris.barker at noaa.gov> wrote:
> And if I understand the rest of the PEP, while typing itself is optional,
> the use of type Annotation is not -- it is exactly what's being used to
> generate the fields the user wants.
>
> And the examples are all using typing -- granted, primarily the built in
> types, but still:
>
>
> @dataclass
> class C:
>     a: int       # 'a' has no default value
>     b: int = 0   # assign a default value for 'b'
>
>
> This sure LOOKS like typing is required. It also makes me nervous because,
> as I understand it, the types aren't actually used in the implementation
> (presumable they would be by mypy and the like?). So I think for folks that
> aren't using typing and a type checker in their development process, it
> would be pretty confusing that this means and what it actually does.
> Particularly folks that are coming from a background of a statically typed
> language.

I actually don't have any problem with this. It looks natural to me,
reads perfectly fine, and is a far better way of defining fields than
many of the other approaches that I've seen in the past (that don't
use annotations).

The one thing I would find surprising is that the actual type used is ignored.

@dataclass
class C:
    a: str = 0

AIUI this is valid, but it looks weird to me. There's an easy answer,
though - just don't do that.

> Then I see:
>
> """
> Field objects describe each defined field.
> ...
> Its documented attributes are:
>
> name: The name of the field.
> type: The type of the field.
> ...
> """
>
> So again, typing looks to be pretty baked in to the whole concept.

Well, being able to see the type the class author intended is a
feature. I don't know I'd consider that as meaning typing is "baked
in". It's useful but ignorable data.

> and then:
>
> """
> One place where dataclass actually inspects the type of a field is to
> determine if a field is a class variable as defined in PEP 526.
> """
>
> and
>
> """
> The other place where dataclass inspects a type annotation is to determine
> if a field is an init-only variable. It does this by seeing if the type of a
> field is of type dataclasses.InitVar.
> """

Those are somewhat more explicit cases of directly using type
annotations as declarations. But what alternative would you propose?
It still seems fine to me.

> """
> Data Classes will raise a TypeError if it detects a default parameter of
> type list, dict, or set.
> """

Doesn't that mean that

@dataclass
class C:
    a: int = []

raises an error? The problem here is the same as that of mutable
function default parameters - we don't want every instance of C to
share a single list object as their default value for a. It's got
nothing to do with the annotation (that's why I used the
deliberately-inconsistent annotation of int here). I'm a strong +1 on
making this an error, as it's likely to be an easy mistake to make,
and quite hard to debug.

> So: it seems that type hinting, while not required to use Data Classes, is
> very much baked into the implementation an examples.

Annotations and the annotation syntax are fundamental to the design.
But that's core Python syntax. But I wouldn't describe types as being
that significant to the design, it's more "if you supply them we'll
make use of them".

Don't forget, function parameter annotations were around long before
typing. Variable annotations weren't, but they could have been - it's
just that typing exposed a use case for them. Data classes could just
as easily have been the motivating use case for PEP 526.

> As I said -- this makes me uneasy -- It's a very big step that essentially
> promotes the type hinting to a new place in Python -- you will not be able
> to use a standard library class without at least a little thought about
> types and typing.

I will say that while I don't use typing or mypy at all in my code, I
don't have any particular dislike of the idea of typing, or the syntax
for declaring annotations. So I find it hard to understand your
concerns here. My personal uneasiness is actually somewhat the
opposite - I find it disconcerting that if I annotate a
variable/parameter as having type int, nothing stops me assigning a
string to it. But that's *precisely* what typing being optional means,
so while it seems odd to my static typing instincts, it's entirely
within the spirit of not forcing typing onto Python.

> If nothing else, the documentation should make it very clear that the typing
> aspects of Data Classes is indeed optional, and preferably give some untyped
> examples, something like:
>
> @dataclass
> class C:
>     a: None      # 'a' has no default value
>     b: None = 0   # assign a default value for 'b'

This does seem like a reasonable option to note. Something along the
lines of "If you don't use type annotations in your code, and you want
to avoid introducing them, using None as a placeholder for the type is
sufficient". However, I suspect that using None as a "I don't really
want to assign a type" value might well confuse mypy - I don't know.
But using typing.Any (which is what mypy would expect) clearly doesn't
meet the "avoid typing totally" requirement here. Maybe (mis-)using
string annotations, like

@dataclass
class C:
    a: 'variable'      # 'a' has no default value
    b: 'variable' = 0   # assign a default value for 'b'

would work? But honestly, this feels like jumping through hoops purely
to avoid using int "because it means I've bought into the idea of
typing".

I guess if you're that adamant about never wanting to use typing in
your code, data classes would make you uncomfortable. But conversely,
I don't see the value in making data classes clumsier than they need
to be out of a purist principle to not use a perfectly valid Python
syntax.

Paul


More information about the Python-Dev mailing list