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:

positional-only-random

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.

assignment-expressions

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:

final-decorator-attribute

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.

f-strings-equals

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!

This entry was posted in Education. Bookmark the permalink.

8 Responses to Python 3.8 support in PyCharm

  1. noah says:

    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…

  2. Derek says:

    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 :

    Snippet:

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

    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

  3. Kyle says:

    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. Dom says:

    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. :-(

Leave a Reply to Ernst Haagsman Cancel reply

Your email address will not be published. Required fields are marked *