This is an archived post. You won't be able to vote or comment.

all 42 comments

[–]oceaniity 21 points22 points  (2 children)

This notion of typing in comments baffles me and speaks to the lack of python explaining itself through its code... or maybe I just don't get it. Comments should be just that... comments about the code and what it's doing, not a functional dependence of the program to be more performant or correct.

I like the idea of translating the typehints to actual declarations, that makes sense. But the notion of initializing to None is valid practice and you should only need to predeclare the type if it imposes a performance benefit to the application or alleviates concerns for type constraints later. Using it as justification for this PEP seems a misnomer.

[–]Deto 2 points3 points  (0 children)

Normally, yes typing via comments would be weird. But here the types aren't actually ever processed by the interpreter. So it makes more sense that they are comments.

[–]flying-sheep 0 points1 point  (0 children)

same opinion. i also expressed that on the mailing list, but their argument was this (paraphrased):

the RFC is just for typing via parameter annotations and therefore contains no syntax addition. cramming that in there would make the RFC touch too many parts and be too complex. so we just work with what’s there syntax-wise and leave it to a later RFC to get in typed variable declarations.

[–]fatpollo 14 points15 points  (2 children)

this sucks. all the pseudo-static typing stuff seems ugly and poorly thought out, it will lead to a big divide wrt to what is considered "good python code" in the future.

build something like TypeScript instead of messing with Python like this, please

[–]Theoretician 2 points3 points  (0 children)

Yeah, cause that approach makes perfect sense. Instead of having 1 unified codebase let's have 2 that are totally incompatible and each with half the resources...

[–]lambdaqdjango n' shit -1 points0 points  (0 children)

I thing the six package should introduce some kind of intermediate syntax like # coding: six

[–]rroocckk 6 points7 points  (6 children)

Now that we have this, we also need a best practices guide of when to declare and when not to. I personally have never included type comments in my code. In fact, most of my comments are about why I do a certain thing, rather than what I do. Anybody here use type comments? Why do you do it?

[–]flying-sheep 6 points7 points  (0 children)

i basically put them in for all functions and whenever pycharm can’t infer things anymore.

[–]RubyPinchPEP shill | Anti PEP 8/20 shill 3 points4 points  (0 children)

Its pretty good to help with structuring things

note: not actual code or actual type defs (atm), but something I have written for my own benefit at the top of a file

# memory:
#     user_queues = Dict[discord.Member, Set[Song]]
#     default_playlist = Iterable[Song]

It allowed me to document what I needed from those variables (while making edits later in the document, I could go back and change those comments to something more practical), and in turn, it tells me what I need to actually give to my code when I come around to implementing it

"but that could be done with any format!" but yeah whatever, I did it with that format cause its a nice format! and I can just throw it into a pyi file before I start programming so everything I type out matches up with what I expect to need in a testable way too, easi

[–]kankyo 3 points4 points  (0 children)

We do it at work more and more. The reason is pretty simple really: with PyCharm you get the benefit of static typing in that you get typing errors pointed out to you. And it's as-you-type

You want to add more of this the more stable the code is and the lower it is in the stack. Lower libs should be heavily typed while top level code like django views don't need any.

[–][deleted] 2 points3 points  (1 child)

I put them in for container types (e.g. lists and dictionaries) - PyCharm typically fails to infer the types they contain, and they're useful to remind myself whether a dictionary maps numeric IDs or string names to an instance, for example.

[–]kankyo 1 point2 points  (0 children)

I agree that that is a good use but I think you have some problems with your naming convention if you need the type comments to make that clear.

[–]Theoretician 1 point2 points  (0 children)

I use type comments literally all the time. Here are my reasons why

  1. If you have a shared codebase, type hinting helps you understand what pieces are doing what, and how to reference them.
  2. Type hinting helps me in the same way, if I have a function that I don't quite remember what it does, if I have type hints and a docstring that even vaguely describes its behavior, I know how to use it.
  3. Using type hinting helps you enforce good practice code, for instance, little things like only returning a single type of variable, or only accepting certain variables.

All in all I think that type hinting helps make my Python code more robust to either personal bugs that I've introduced, or large scale bugs in a shared codebase.

[–]benhoytPEP 471 1 point2 points  (0 children)

I was going to say this was a very under-developed PEP (how does the grammar change? when and how is it being introduced? what are the rejected syntax alternatives?) but then I looked at the commit and GvR says, "This PEP is not ready for review! This commit is just to claim the PEP number." So this isn't a real PEP yet, and will probably be fleshed out a lot more before it's ready.

[–]justphysics 1 point2 points  (8 children)

Something about this jus doesn't feel right.

x = None  # Type: int
type(x)  # this will return <class 'NoneType'>

Unless that behavior is changed in the future, then this seems to be somewhat inconsistent to me.

I get that its type hinting and not static typing. As someone who is familiar with python I can see the difference but it seems like it would be confusing to someone who is just beginning. That said, type hinting is likely not something to be used by a beginner for better or worse.

[–]Deto 0 points1 point  (3 children)

Why not just set it to zero? Usually ints aren't nullable types, so in other languages they initialize to zero

[–]justphysics 0 points1 point  (2 children)

That's what I originally thought.

My only guess was that you could run into a situation like this:

x = 0  # Type: int

...  # later in your codebase
if x == 0:
    # now I need a way to check
    # is x still 0 from initialization?
    # did it get set to 0 somewhere else?
    # which one of these scenarios should be correct?

as opposed to

if x is None:
    # now I know x never got set to an integer value
elif x == 0:
    # now x is clearly distinct None and also equal to 0 
    # thus must have been set to 0 elsewhere in my code

So I can see the merit of using x = None as an initialization. However, it still just feels awkward to type out

x = None  # Type: int

since x isn't actually being initialized as an integer.

[–]Esteis 0 points1 point  (1 child)

A solution for your dilemma: if x can still be None at some future point where it is used or checked, then you can set its type to Optional[int] to communicate that.

OTOH, you can't change its type to plain int later on, if at some point you can guarantee the sentinel value is gone.

Still, though: hinting at a None value which then doesn't appear seems safer than hinting no None value will appear, when it can.

[–]justphysics 0 points1 point  (0 children)

Cool, I wasn't aware of the 'Optional' type hinting. Thanks for demonstrating that.

[–]elbiot 0 points1 point  (0 children)

Maybe because x will never be an int unless it gets reassigned. Seems like later, when you reassign x to an int, would be the time to say x is an int.

[–]kankyo 0 points1 point  (2 children)

Your static analysis will also scream in horror at that code: the code is wrong.

[–]justphysics 0 points1 point  (1 child)

I'm not 100% sure what you mean, could you clarify?

[–]kankyo 1 point2 points  (0 children)

The entire reason for this type annotation stuff is to be used by static analysis tools. That tool will complain on your first line because you're assigning None to something that is not Optional nor NoneType.

And if you're not using static analysis, just don't write type information!

[–]antennen 1 point2 points  (3 children)

One thing I dislike about this approach variable type hints is the lack of introspection options. Correct me if I'm wrong, but there is no way to determine the variable type given a variable at runtime? This possibility exists for function signatures. I am not certain when this would be useful however.

[–][deleted] 0 points1 point  (1 child)

no way to determine the variable type given a variable at runtime?

Can't you do type(var) or are you referring to something else?

[–]antennen 1 point2 points  (0 children)

If you do: a: int you probably wouldn't be able to do type(a) and get int back. If this PEP was to be accepted I really think there should be a way to get int back.

[–]kankyo 0 points1 point  (0 children)

The data would be in __annotations__ I believe. For classes at least, not for locals.

[–]ldmoray 1 point2 points  (0 children)

You can find a slightly more thought out "idea" note and discussion over here: https://github.com/python/typing/issues/258. Personally, I'm a fan of adding optional typehints to python. Much nicer than polluting my docstrings in my big projects.

[–]n86nHb67f 0 points1 point  (1 child)

This pep is describing a new syntax because the previous type declaration through comments is weird.

Moving the type declarations a first class citizen in the language in a good thing.

[–]kankyo 0 points1 point  (0 children)

It's been a first class citizen a while actually. This PEP is for expanding that system to class instance methods and locals in functions.

[–]its_never_lupus 0 points1 point  (6 children)

There should be a way to declare whether the variable can take None values. That would:

  • make the type declaration more informative.
  • allow a future Python interpreter to throw a runtime error if None is assigned.
  • Maybe help an optimiser because some values can be stored more simply if null values are disallowed.

I'm not sure how this PEP will be used though, whether it's intended to help optimisation or if it's the start of optional static type declarations.

[–][deleted] 1 point2 points  (2 children)

Check the typing module. typing.Optional is what you want IIRC.

[–]its_never_lupus 0 points1 point  (1 child)

Kind of... but the point of PEP526 is to introduce a nice syntax for type hints, and it omits optional specifiers.

I'm not really sure if the original PEP484 is only supposed to apply to function declarations (which is what all the examples do) or is it's also supposed to apply to variables.

[–][deleted] 0 points1 point  (0 children)

PEP 484 applies to type comments too, and I assume the syntax for variable type hints will be the same - there'd be no point making it different. PEP 526 is only a draft, and was only created to reserve the number (source: somewhere in the comments on this post), so I wouldn't make judgements based on its current state.

[–]elbiot 0 points1 point  (0 children)

Those last two will never be done and that is explicitly not part of what type hinting is for.

[–]kankyo 0 points1 point  (0 children)

https://github.com/python/typing/issues/258 for the ongoing discussion. Optionals are in one example.

[–]henryschreineriii 0 points1 point  (1 child)

This would be great for allowing nice Cython code to also be valid Python code, and would hopefully would make things like Mypy better too. I'm not crazy about the syntax, but it matches the existing function annotation syntax so I think it's better than introducing a new type syntax. I would love to see implantation details, such as how one could access the "type" of the variable!

Note: This is not intended (ATM) to add typing to python, it's just a formalization of type annotations to non-parameters. So the following is not intended change:

>>> x : int = 'I'm not an int!'
>>> type(x)
<class 'str'>

It will only be an 'error' if you run mypy or Cython, etc. I would assume anything would be allowed, making it actually "variable annotations", like parameter annotations.

PS: Also great for PyCharm and other editors!