Tips & Tricks

Python 3.8 support in PyCharm

The release of Python 3.8 brought new features to the Python coding realm. The language is evolving according to its community’s needs by addressing cases where new syntax or logic become necessary. From new ways of assigning expressions to restriction of usage of function declarations, calls, and variable assignations, this latest release presents new options to code. Of course, PyCharm couldn’t get behind, so we now support some of the major features coming with this new version.

This article will walk you through the features currently supported by our latest PyCharm release. To try them out, get the latest version of PyCharm and download the current beta release of Python 3.8 from here. From there you will just need to switch to Python 3.8 as your interpreter in PyCharm (if you’re not sure how to switch the interpreter, jump into our documentation for help).

Positional-only parameters

Function definitions are a key element when designing libraries and APIs for user consumption. The more explicit these definitions are, the easier they are to implement. One way to achieve such explicitness is by how the function can be called with its arguments. As of now, Python only had the option to define arguments as positional, keyword, or keyword-only, but with this new version we now have another way to define them by using positional-only parameters.

To use this feature, just set the arguments in your function definition and write a forward slash`/` after the last positional-only argument you want to declare. This is closely analogous to the keyword-only arguments syntax, but instead of setting the arguments after the asterisk`*`, you do it before the slash`/`.

Let’s look at an example. Say, you have a function in your library that selects a value randomly from different values passed as arguments. Such values can be passed in any position and the function will return you a random choice. The semantic meaning stays the same, regardless of the order of the values in the function call. By design, you decide that those arguments should be positional-only:


By doing this, you ensure that your library’s users won’t be able to call your function with the arguments’ keywords. In the past, if you renamed the arguments of your function for refactoring purposes (or any other reason), the code of your library’s users would be at risk if they were to make a function call with keyword arguments (for example, `select_random(a=3, b=89, c=54)`). One of the advantages of positional-only parameters is that, if you decide to change the variable names in the function definition, your library’s users won’t be affected as there are no keyword dependencies in the function calls they make to begin with.

Assignment expressions

A new way to assign values to variables is available with this latest Python version. Now, expressions can also assign values as part of their declaration, which removes the necessity to initialize variables in advance. As a result, you can make your code less verbose and add compactness, as declarations can be made within expressions in the same line.

The syntax to declare a variable consists of the walrus operator `:=` inside an expression enclosed by parentheses. An important note is that the walrus operator is different from the equals operator. For example, comma-separated assignments with the equals operator are not the same as the ones made by the walrus operator.

One example of such usage can be a while loop with a control variable. When you use this feature, the loop’s control expression will also hold the variable definition and reassignment.


In the previous example, the ‘before’ while loop has a variable assignment before it and also inside its execution code. The ‘after’ loop has the assignment inside its control statement definition by using an assignment expression.

Final annotation and final decorator

When you design a class, you have to make sure your methods are used properly. With this new version, a final decorator and a `Final` type annotation are introduced to help restrict the usage of methods, classes, and variables. If needed, this feature will let you declare that a method should not be overridden, that a class should not be subclassed, or that a variable or attribute should not be reassigned.

The final decorator prohibits any class decorated with `@final` from being subclassed, and any method decorated with `@final` from being overridden in a subclass. Let’s say you have a class that declares a method and that method is being used inside the class at different points. If the user modifies that method by overriding it while subclassing, there are risks that the base class behavior might change or run into errors. To avoid this, you can use the final decorator to prevent the user from overriding such a class.

Let’s say you have a signature generator class like the following:


When initialized, the signature is generated through a `create_signature ` method which is called within the `__init__` constructor method. Depending on your class design, you may opt to protect your `create_signature` method with the final decorator so it is not overridden if subclassed. With the final decorator, you ensure that any other method that depends on this method inside the class is not affected by a method override. In this case, the `__init__` constructor method is using the `create_signature` method. By using the final decorator, you ensure that the initialization of the class will not be affected by any change that might be introduced by subclassing.

Another thing to notice is that in this example, we use the `Final` attribute with the `ENCODER` attribute. This class attribute holds the type of string encoding used in the `create_signature` method. By class design, we choose to use the `Final` attribute because we use that value within the methods of the class and we don’t want it to be overridden as that would change the methods’ behavior.

Equals sign in f-strings

String formatting makes code more concise, readable, and less prone to error when exposing values. Variable names and values now can coexist in string contexts with the introduction of the equals sign in f-strings.

To take advantage of this new feature, type your f-string as follows: `f'{expr=}’` where `expr` is the variable that you want to expose. In this way, you get to generate a string that will show both your expression and its output.


This feature is helpful when you’d like to write variable values to your log. If you happen to use this for debugging purposes, you may want to check out PyCharm’s debugger.

Learn more

For more information about usages and examples where these features can be useful, take a look at PEP-0570, PEP-0572, PEP-0591, and bpo-36817.

We at PyCharm continue to work on supporting Python 3.8 fully, and we hope these features will come in handy for you when setting up or working with a project using Python 3.8. Support for other features should be expected in the near future, so be sure to pay close attention to our latest releases.

If you have any questions or suggestions, drop us a comment. Thanks!

Comments below can no longer be edited.

9 Responses to Python 3.8 support in PyCharm

  1. Avatar

    noah says:

    August 22, 2019

    Assignment expressions is exactly the type of constructs modern languages are avoiding for the sake of clarity and side-effect, it’s strange to see that popping up in Python while they refuse to implement a much-needed ‘case’ statement which would go a long way to clarify code.

    I hope the language responsibles are not leading this language more inconsistent, we saw what happened to Java…

    • Avatar

      Paul Everitt says:

      September 30, 2019

      Perhaps, but that’s not germane to PyCharm. It’s in the language, we support it.

  2. Avatar

    Derek says:

    October 19, 2019

    I’m currently on PyCharm Community 2019.2.3 and started a new project with Python 3.8. When I use an example with the walrus operator, I have warnings from PyCharm about having whitespace before the : and not having whitespace after the :


    def walrus_operator(num_iterations):
    count = 0
    while (count := (count + 1)) <= num_iterations:

    The equals sign in the f-string, positional-only parameters, Final annotation and final decorator don't raise any warnings, though.

    It's important to remember that with the Final annotation and final decorator, you need to import them from the typing class:

    from typing import Final, final

    • Avatar

      Casey says:

      October 24, 2019

      Confirming this same PEP8 warning in 2019.2.3. Was checking to see if I needed to update inspections independently.

      • Avatar

        Casey says:

        October 24, 2019

        For others interested, this is being tracked as a major bug: PY-37196 Assignment expressions and PEP8 warnings

  3. Avatar

    Kyle says:

    October 23, 2019

    I’m trying to use Python 3.8 as the Python interpreter for a project, but I can’t seem to get it to work or find the option. This seemed easier on my other PC with 3.7 and I’m not sure if this is because of the change in python or the new PC.

  4. Avatar

    Dom says:

    October 30, 2019

    MODE = typing.Literal[‘r’, ‘rb’, ‘w’, ‘wb’]

    According to Python 3.8 documentation:
    def open_helper(file: str, mode: MODE) -> str:

    open_helper(‘/some/path’, ‘r’) # Passes type check
    open_helper(‘/other/path’, ‘typo’) # Error in type checker

    But no Error shown. 🙁

  5. Avatar

    Andrew Simons says:

    February 15, 2020

    Is debugging Python 3.8 code supported in PyCharm 2018.2? We recently upgraded a project to Python 3.8 and Django 3 (from Python 3.6 and Django 2.2) and although I can start the django server from PyCharm with it pointing at my venv and it says the debugger has attached, it never stops on any breakpoints I set.

    /Users/blah/Workspace/acme/proj/venv38/bin/python3 “/Applications/PyCharm” –multiproc –save-signatures –qt-support=auto –client –port 62462 –file /Users/blah/Workspace/acme/proj/src/ runserver localhost:8000
    pydev debugger: process 9878 is connecting

    Connected to pydev debugger (build 182.5262.4)

    Is this a case of PyCharm 2018.2 will never work with Python 3.8 and I need to upgrade, or shall I continue trying to find/fix problems with the debugger configuration?

Discover more