How can I tell PyCharm what type a parameter is expected to be?

38,129

Solution 1

Yes, you can use special documentation format for methods and their parameters so that PyCharm can know the type. Recent PyCharm version supports most common doc formats.

For example, PyCharm extracts types from @param style comments.

See also reStructuredText and docstring conventions (PEP 257).

Another option is Python 3 annotations.

Please refer to the PyCharm documentation section for more details and samples.

Solution 2

If you are using Python 3.0 or later, you can also use annotations on functions and parameters. PyCharm will interpret these as the type the arguments or return values are expected to have:

class King:
    def repress(self, peasant: Person) -> bool:
        peasant.knock_over() # Shows a warning. And there was much rejoicing.

        return peasant.badly_hurt() # Lets say, its not known from here that this method will always return a bool

Sometimes this is useful for non-public methods, that do not need a docstring. As an added benefit, those annotations can be accessed by code:

>>> King.repress.__annotations__
{'peasant': <class '__main__.Person'>, 'return': <class 'bool'>}

Update: As of PEP 484, which has been accepted for Python 3.5, it is also the official convention to specify argument and return types using annotations.

Solution 3

PyCharm extracts types from a @type pydoc string. See PyCharm docs here and here, and Epydoc docs. It's in the 'legacy' section of PyCharm, perhaps it lacks some functionality.

class King:
    def repress(self, peasant):
        """
        Exploit the workers by hanging on to outdated imperialist dogma which
        perpetuates the economic and social differences in our society.

        @type peasant: Person
        @param peasant: Person to repress.
        """
        peasant.knock_over()   # Shows a warning. And there was much rejoicing.

The relevant part is the @type peasant: Person line of the docstring.

My intention is not to steal points from CrazyCoder or the original questioner, by all means give them their points. I just thought the simple answer should be in an 'answer' slot.

Solution 4

I'm using PyCharm Professional 2016.1 writing py2.6-2.7 code, and I found that using reStructuredText I can express types in a more succint way:

class Replicant(object):
    pass


class Hunter(object):
    def retire(self, replicant):
        """ Retire the rogue or non-functional replicant.
        :param Replicant replicant: the replicant to retire.
        """
        replicant.knock_over()  # Shows a warning.

See: https://www.jetbrains.com/help/pycharm/2016.1/type-hinting-in-pycharm.html#legacy

Solution 5

You can also assert for a type and Pycharm will infer it:

def my_function(an_int):
    assert isinstance(an_int, int)
    # Pycharm now knows that an_int is of type int
    pass
Share:
38,129

Related videos on Youtube

Joe White
Author by

Joe White

Updated on October 07, 2021

Comments

  • Joe White
    Joe White over 2 years

    When it comes to constructors, and assignments, and method calls, the PyCharm IDE is pretty good at analyzing my source code and figuring out what type each variable should be. I like it when it's right, because it gives me good code-completion and parameter info, and it gives me warnings if I try to access an attribute that doesn't exist.

    But when it comes to parameters, it knows nothing. The code-completion dropdowns can't show anything, because they don't know what type the parameter will be. The code analysis can't look for warnings.

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    peasant = Person("Dennis", 37)
    # PyCharm knows that the "peasant" variable is of type Person
    peasant.dig_filth()   # shows warning -- Person doesn't have a dig_filth method
    
    class King:
        def repress(self, peasant):
            # PyCharm has no idea what type the "peasant" parameter should be
            peasant.knock_over()   # no warning even though knock_over doesn't exist
    
    King().repress(peasant)
    # Even if I call the method once with a Person instance, PyCharm doesn't
    # consider that to mean that the "peasant" parameter should always be a Person
    

    This makes a certain amount of sense. Other call sites could pass anything for that parameter. But if my method expects a parameter to be of type, say, pygame.Surface, I'd like to be able to indicate that to PyCharm somehow, so it can show me all of Surface's attributes in its code-completion dropdown, and highlight warnings if I call the wrong method, and so on.

    Is there a way I can give PyCharm a hint, and say "psst, this parameter is supposed to be of type X"? (Or perhaps, in the spirit of dynamic languages, "this parameter is supposed to quack like an X"? I'd be fine with that.)


    EDIT: CrazyCoder's answer, below, does the trick. For any newcomers like me who want the quick summary, here it is:

    class King:
        def repress(self, peasant):
            """
            Exploit the workers by hanging on to outdated imperialist dogma which
            perpetuates the economic and social differences in our society.
    
            @type peasant: Person
            @param peasant: Person to repress.
            """
            peasant.knock_over()   # Shows a warning. And there was much rejoicing.
    

    The relevant part is the @type peasant: Person line of the docstring.

    If you also go to File > Settings > Python Integrated Tools and set "Docstring format" to "Epytext", then PyCharm's View > Quick Documentation Lookup will pretty-print the parameter information instead of just printing all the @-lines as-is.

    • Wernight
      Wernight about 12 years
      It's to be noted that reStructuredText comment use the same tags just written differently: @param xx: yyy becomes :param xx: yyy. See jetbrains.com/pycharm/webhelp/…
    • Jesvin Jose
      Jesvin Jose over 9 years
      Why can we get away with not specifying fully qualified class name?
  • Lutz Prechelt
    Lutz Prechelt about 10 years
    ...and there are several packages that use such anntoations to perform run-time type-checking. This is both more convenient to use and easier to read than doing the same by assertions and can be used selectively just the same. typecheck-decorator is one such package and has a summary of the others in its documentation. (Flexible, too: you can even do type-checked duck typing!)
  • stubs
    stubs over 6 years
    I think PyCharm changed it's doc format a bit (see jetbrains.com/help/pycharm/…), but thanks! The lack of intellisense on parameters was driving me insane.