Skip to content

Support multi-line # type: comments for functions #1102

Closed

Description

@gvanrossum

Some linters get mad about long lines, even comments, so we would like to be able to break long # type: comments into multiple lines. This is especially desirable for function annotations if the function has lots of arguments, since you can't shorten those using type aliases. (And claiming that's just bad code doesn't do anyone any good -- I know, but sometimes I can't afford to fix it.)

Activity

  1. JukkaL commented on Jan 8, 2016

    @JukkaL
    Collaborator

    Yes. I've actually been waiting for somebody to complain about this :-)

  2. gvanrossum commented on Jan 8, 2016

    @gvanrossum
    MemberAuthor

    But what should it look like? # type: on every line, or just on the first line? If the latter, we could get in trouble trying to parse a # type: comment followed by an ordinary comment. So I propose the former:

    def whatever(arg1, arg2, arg3,
                 arg5, arg5, arg6):
        # type: (int, int, int,
        # type:  str, str, str) -> float
        # this is not a type comment
        return (arg1 + arg2 + arg3 +
                float(arg4) + float(arg5) + float(arg6))
    
  3. refi64 commented on Jan 8, 2016

    @refi64
    Contributor

    What about only considering the next line to be type comment if it simply isn't complete? e.g. (a, isn't finished (no closing paren), so the next line would be considered the rest. Same this for a ->, a[b, etc.

  4. gvanrossum commented on Jan 8, 2016

    @gvanrossum
    MemberAuthor
  5. JukkaL commented on Jan 8, 2016

    @JukkaL
    Collaborator

    I always assumed that we'd keep track of open parens and square brackets to determine when the type annotation ends. Example:

    def whatever(arg1, arg2, arg3,
                 arg5, arg5, arg6):
        # type: (int, int, int,
        #        str, str, str) -> float
        # this is not a type comment
        return (arg1 + arg2 + arg3 +
                float(arg4) + float(arg5) + float(arg6))
    

    Reporting parse errors correctly might be a little tricky. Mypy should perhaps explicitly mention in a parse error message whether the error is within an (assumed) type annotation.

    However, repeating # type: would also work and would probably be a little easier to implement. I don't have a strong opinion on this, though the single # type: alternative looks a little cleaner to me.

    Should we discuss this in https://github.com/ambv/typehinting as well?

  6. gvanrossum commented on Jan 8, 2016

    @gvanrossum
    MemberAuthor
  7. JukkaL commented on Feb 8, 2016

    @JukkaL
    Collaborator

    Another idea is to support optionally including argument names in comments:

    def whatever(arg1, arg2, arg3,
                 arg4, arg5, arg6):
        # type: (arg1: int, arg2: int, arg3: int,
        #        arg4: str, arg5: str, arg6: str) -> float
        # this is not a type comment
        return (arg1 + arg2 + arg3 +
                float(arg4) + float(arg5) + float(arg6))
    

    This way it would be easier to map argument names to types, especially if there are a ton of arguments. The obvious tradeoff is that there would be more redundancy, but mypy could check that the argument names match, and we could have a tool that automatically inserts dummy annotations with the correct argument names.

    Another idea for specifying signatures of functions with many arguments:

    def whatever(
             arg1,  # type: int 
             arg2,  # type: int
             arg3,  # type: int
             arg4,  # type: str
             arg5,  # type: str
             arg6,  # type: str
             ):
        # type: (...) -> float
        # this is not a type comment (note that "..." above is literal)
        return (arg1 + arg2 + arg3 +
                float(arg4) + float(arg5) + float(arg6))
    

    This way argument name and type would closer to each other, a bit like in the Python 3 annotation syntax. The tradeoff is that there can only be a single argument per line. For functions with only a few arguments the original annotation syntax is fine and we'll want to preserve it as the common case option.

  8. gvanrossum commented on Feb 8, 2016

    @gvanrossum
    MemberAuthor

    I'd like to hear from the PyCharm developers -- @vlasovskikh do you have any preference? How easy would any of these be to add to PyCharm?

  9. vlasovskikh commented on Feb 9, 2016

    @vlasovskikh
    Member

    Either form would be relatively easy to support in PyCharm.

    There are a couple of minor issues with the first named-arguments-in-comments form. Our code formatter can automatically reformat the second form (with #type: ...) according to the project code style, while the first one would require a special formatter for this custom multi-line syntax. For the first form we would have update named references as a part of the rename parameter refactoring while the second form doesn't require that.

  10. added this to the milestone on Mar 2, 2016
  11. ddfisher commented on Mar 2, 2016

    @ddfisher
    Collaborator

    The second form seems preferable to me. My understanding is that good style generally dictates having one arg per line once you need to wrap arguments anyway, so it's a pretty natural fit.

  12. gvanrossum commented on Mar 2, 2016

    @gvanrossum
    MemberAuthor

    OK, let's go with 2.

  13. 11 remaining items

  14. ddfisher commented on Apr 8, 2016

    @ddfisher
    Collaborator

    It's looking like the new parser will be in 0.3.2 now. I'll implement this after it lands (see #1353).

  15. modified the milestones: , on May 19, 2016
  16. modified the milestones: , on Jun 9, 2016
  17. added a commit that references this issue on Jun 23, 2016
    ad9024d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions