 Hello, everyone. My name is Andrey Blasovsky. A few words about me. I'm from St. Petersburg, Russia. I'm the technical lead of PyCharm. I work for JetBrains. Here is a number of open source projects that I'm maintaining. And I've also been contributing to the typing peps for Python type system. But today we're going to be talking about Python 3.8. As you may know, it is going to be released in October this year. And the second beta is actually available. You can go to the Python.org website, download it, and play with the new features about which I will tell you today. Actually, there are very good docs on what's new in Python 3.8. They go into details about all the new syntax, all the new additions to the standard library, all the new stuff related to performance of the Python interpreter, all the major bugs that were fixed there, and so on. And I'm not going to be retelling this document. Because I just don't see any sense in just reciting documentation, telling what's there, and so on. So the best thing for you to do is just to go to this link and look into the features, all the bits that you are interested in. So this is not what we are going to be discussing today. What we will be discussing is the story behind some of the features of 3.8. I will tell you their history, how they appeared, and what are the pros and cons of the new features of 3.8. Also, I will give you a small overview of some features that might come in the future versus Python beyond 3.8. Well, I said some features, well, yes, some, because there are just too many of them, and I cannot tell you all about every single feature. So I've chosen some features that I like or I don't like for this talk, but I will do my best to try to stay objective. But I'm only half human, half Vulcan, so it may not work out as I expected. Well, actually, Spock was half Vulcan as well, well, not forget it. Okay, let's start with the new syntax because it's something that always catches your eye when you look into the new syntactic changes to your language. Let's start with assignment expressions, maybe the most famous feature of 3.8, everybody is talking about it. It's the new word separator because this assignment expression looks like a little word. Here's an example just to give some context. I guess everyone is familiar with the regular expression module. Everyone has written code like that, only you usually put the assignment for the M much on a separate line, and now it can be more compact like that. All right, so this is what we are talking about. But the initial pep was quite a bit different. In the initial pep, the syntax was that you had to use the required parenthesis around your assignment expression, and instead of this new assignment operator, you would use actually the S keyword. So this was like the initial proposal. Also in the initial proposal, there was this idea of sublocal scopes, meaning that these variables, these names that you introduced via these assignment expressions are local to the statement in which you have assigned them. For example, in our previous case for the much, the M name would be available only if the if statement, and not beyond after this if statement. And since in Python we have only scopes only for functions and for classes and for modules, it required actually some name mangling in order to be able to put it into already existing infrastructure for holding names for local scopes or functions. So the idea was that these names were somehow mangled and put into the local's dictionary so that you cannot access them directly after you get out of the scope for this assignment expression. After the draft of the PEP was published inside Python deaf mailing list, it got a lot of attention of various developers, including a lot of Python core developers, and there were a number of changes proposed to this PEP. Also Guido van Rosson became interested in this PEP and some of these additions were proposed by him. For example, this wall separator appeared instead of S because S is already used in three different contexts, in the context of importing things, in the context of catching exception in the accept clause, and also in the context of the with statement. And since in every one of these cases, S means a bit different thing, the authors of the PEP proposed to use this new operator for that. This operator comes from ancient languages like Pascal and so on. Also it was decided to drop the parenthesis, at least in some cases, and to introduce more regular scoping rules without this name mangling thing. So the names are still available after your statement with these assignments expressions is executed. Also, since now parenthesis are not a required thing, the PEP authors had to deprecate the usage of these assignment operator at the statement level. So you cannot write, for example, X for operator two. You can only use your regular equals expression for that because otherwise you would have had two different ways to do things for one of the most basic cases of using Python. Another thing that was required for this PEP was scoping rules for comprehensions. In list comprehensions and other type of comprehension, the names introduced inside the four here are actually local to this comprehension in Python 3. But for assignment expressions, it was decided to allow these names to be usable after the comprehension is executed. In order to basically allow this pattern of usage where I want to use this assignment expression inside the any function. So I want here to know if any of the lines in this list of lines starts with the hash sign. And for that, I really often need to know the exact line that starts with the hash. And this nice syntax allows us to basically grab this line and to use it further in your code. So it resulted in a quite large PEP with a lot of stuff going on. And many of these things were quite controversial. Some people liked the idea of assignment expression inside people don't like it. So there was this dispute about whether it was to be a part of Python or not. And Guido decided that it's still a good idea to accept this PEP, even though the authors of the PEP had to add a section about the importance of real code right in the beginning of the PEP, stressing the importance of examples that typically occur in your code compared to some complicated examples you can come up with if you think how you can abuse this new operator. But it's still helpful in many practical contexts like the ones I show here. For example, to emulate something like do while that we don't have in Python yet. Or the thing I wanted always to be able to capture the if part of a list comprehension and use it further in my comprehension expression. I think it's a useful thing. So after accepting this PEP, Guido decided to step down from his role as BDFL. I guess because he was too tired with this controversy around this PEP. And also it's something it was something that he was already thinking about. For example, he announces it at some Python US. I guess it was in Montreal several years ago that he will eventually he would eventually step down from his role as BDFL. And now, after some discussions, we now have a new government's model for the Python language, the Python steering console. I wouldn't go into much detail here because it's not the subject of my talk. This is the PEP number that described the process. So to summarize, there are some upsides of the new operator. It makes it more compact to use assignments in some specific situations that very often occur in your code, like the one with the regular expressions. Also the current implementation of this PEP, the current proposal, has relatively simple semantics. So if you don't know anything about the assignment expressions, it's still possible for you to understand what this code does. I guess at least it should be because the code is quite clear. The meaning of this operator could be obvious from the context and so on. So it's not super complicated. But as some downsides, one I said that, yes, you can definitely come up with a very hacky example for which it will be completely obscure what's going on. You won't be able to understand it without running the actual code. Yeah, it's the case. Okay. And now we have basically two assignment operators in Python instead of one. Well, we could have used the same assignment operator like the single equal sign for that. But it would lead to some issues with parsing and to some issues with assigning to attributes and to expressions with subscription indices and so on. And if you want to know more about Python parsing and how this operator was implemented and so on, I recommend you to watch a video of one of the talks at the current Euro Python by Pablo Salgado was one of the core developers. This talk dives deep into the structure of the Python parser, the limitations of its grammar and what can be done and what cannot be done. The next thing also related to the new changes in the syntax positional only parameters. It looks like that with the slash. And the, sorry, the idea is as follows. In the Python CEPI, there were always functions that accepted only positional arguments. For example, this power function they built in from the standard library, you cannot pass your arguments by name, even though the documentation for this function specifies the names of the arguments just because well, it's just how it works, how it's implemented in the CEPI. And for Python, we really didn't have a way to express it in the Python language, only as a part of your C extension. And people used this workaround to have this star arcs argument and then they assigned basically the parts of this tuple to specific local variables, which worked, but it was not ideal because it was hard to get what this function did just by looking at its signature and you had to look into the documentation or the implementation of the thing. So now we have a new syntax where everything that is before this slash separator is actually a keyword, sorry, a positional only argument. And everything after the slash is anything else. Keyword or positional or only keyword and so on. But why slash for positional only? Well, it's because in Python we already have this PEP that describes so-called argument clean DSL. It's a DSL that defines a preprocessor for writing C extension modules for C Python. And in this DSL, slash is used exactly for this case for separating positional only arguments like the ones in the function power from anything else. And also the slash was used I guess before in some documentation for built-in functions as well. So for historical reasons slash seemed like a good way to separate these parameters. But wait, we already have some markers to separate or at least to define keyword parameters, positional parameters, and it's usually the pattern to call them star arcs, double star keyword arcs and so on. Why can't we use just them? For example, single star for positional only parameters and double star for keyword only parameters. Well, the reason is that in Python 3.3 or 3.5, we have now since Python 3.3 or 3.5, we now have this keyword on the arguments and for them, we use single star as a delimiter of the parameters. So the overall scheme for parameters in Python 3.8 looks like that. You have positional only slash keyword oppositional star, single star, and then keyword only arguments. The reason for that is backwards compatibility. We cannot just change things to use star as a delimiter for positional only arguments because it's already in use for keyword only. But why is star used for keyword only arguments? That's a good question. Actually, the reasoning is described in the PEP that introduced keyword only arguments. Basically, the explanation is there was this workaround how you can use keyword only arguments in, say, Python 2. If you have this star ignore argument and then you want any other argument after star ignore to be keyword only, you can check if ignore actually consumed some of the arguments that you passed to your function. For example, if you pass key not as a keyword argument but as a positional only, it will be consumed by ignore. You can check if ignore is not empty and then raise, for example, a type error. If you remove this word ignore, you get this single star that is used now in Python 3 for separating keyword only parameters from anything else. To summarize, we now have a consistent situation when we have syntax to define both positional only and keyword only arguments in Python functions. And it's backwards compatible, which is always a good thing. And the downside is, yeah, it's not consistent with star arcs and double star keyword arcs, but yeah, it's a compromise. Let's talk a bit about stuff that is not related to new syntax changes. About new types in the standard library. There are several of them. I won't go into much detail about them. Just to mention briefly what they give you. Protocol types give you a way to express basically duck typing in Python. Or if we use the terms from type theory, it's structural typing as compared to nominal typing that we had in Python before. Also, there are literal types that allow you to specify a type of a variable by restricting it to be of to accept certain values of type int or string. Also, there are final types that allow you to, for example, for bit reassigning to a variable or you can define the classes of functions that you cannot overwrite later or inherit from later. And also there is type dicts that allows you to specify types for specific keys in your dictionaries. What I wanted to tell you about in this part is that where all these ideas about types come from. Well, actually, this process is a bit different from what I described previously. Yes, there are peps, but the ideas actually come from the implementers of specific type checkers. And there is a repository on GitHub where people discuss these new ideas in issues, in GitHub issues. So the process usually looks like that. Some type checker, let's say, MyPy, comes up with an idea of a new type. And usually this idea comes from some real world code base for which they had issues annotating this code base. So there are some specific situations. And they come up with the new idea of a type and put it into their own module, like MyPy extensions in this case. And later, if this type is interesting, useful, the authors of other type checkers, like PyCharm or PyRA, also become interested in this. And after some discussions, these new types are moved to the typing extension module, which is a PyPI package and so on. But at least it is something that is common for several type checkers, and more and more type checkers start to support new types at this point. And after that, if some type appears to be universally useful, the authors of this extension come up with a pep draft, and then the regular pep process takes place. And after that, things are being moved to the typing module. To summarize the new additions, now we have more cases for more types that cover more cases of the real world code bases, like the one at Dropbox, where the MyPy team actively annotates stuff with the help of PyPy. But the downsides are that the typing module is becoming larger and larger, and it's hard to learn about Python types. It's becoming harder. And also, I would say that it's not always necessary to put stuff in the standard library, especially if it's only used by a type checker, which is not a part of the Python distribution anyway. Also, I can recommend you to watch this video from this EuroPython by Vita Shmid about static typing beyond the basics. I guess in this talk, there will be mentions of types I just described. So now let's talk a bit about stuff that isn't coming into Python in Python 3.8. Something that is currently being discussed or even implemented, but it didn't make it to the point when the Python, when the feature freeze occurred for Python 3.8. The first, like cluster of things I wanted to mention, are the new ideas about the evolution of typing in Python. There are several proposals. Some of them are already pep drafts, and most of them are about usability issues of the Python type system. Many people complain that the type system of Python is really messy because it was something that wasn't there from the beginning, and there were limitations, syntactic limitations, and others. So now it's like you have to import a lot of stuff. For example, you have to import from typing the uppercase list just to express that you have a list of int. And there are a few peps that allow, that propose to clean up the situation. One of them proposes to use the newly introduced done-the-class-get-item method to add, actually, this square brackets operator for the built-in classes, like list, or set, or whatnot, instead of compared to, for example, not introducing done-the-get-item on the, it's their classes, meaning meta classes of the actual lists, the class type. Because in this case, every object in Python would have this done-the-get-item, and so on. So this is done-the-class-get-item to overcome this limitation. Also, there are some ideas how to make it easier to use by not requiring programmer to actually import things from the typing module. So there is this idea that, since type hints can already be evaluated only statically via the new from-future import, import annotations, there is this idea to switch all the syntax of Python typing to use type hints that are evaluated only statically by static type checkers. In that way, it won't be necessary to actually import anything. And you can just specify something that is only there for static type checkers and that doesn't affect your, for example, performance of your runtime when you run your code in Python. And also, there are other ideas as well in this area. Another area where there are some possible changes coming up in the next releases is the area of asynchronous programming, I think await. The idea is to introduce so-called structured concurrency for asynchronous tasks. The idea is simple. When you run an asynchronous task, you don't really control it and it's hard to control it when it's going to be finished, how you cache exceptions from this task and so on. And so one of the core developers, Nathaniel Smith, introduced this library called Trio, where you can actually define so-called nurseries that spawn tasks and their scope of life is limited to this block where the nursery is active. If anything bad happens to one of the tasks, the nursery will wait for all the tasks to finish and then you'll have like a multi-exception that combines all the possible exceptions from all the tasks in the scope and you can be, will be able to handle the situation in a clean way. This is something that is comparable to the classical issue of the go-to statement that, as you know, is considered harmful, but the title of Nathaniel's paper was the go statement considered harmful. Go is a statement of the language go that allows you to spawn coroutines in an uncontrolled manner. So the idea is to have this structure like with wiles and ifs and so on that replaced the go-to. The idea is to have similar structured patterns but for launching asynchronous tasks. And I would also recommend you to watch a talk from this Euro-Python by Linruth where she mentioned trio-like nurseries. And there are also a couple of things I would like to tell you about performance. One of the projects that I'm personally looking forward to is MyPyC. It's something that could make your single core Python applications run faster by basically compiling them to C with a lot of calls to C extension APIs. But the idea is a bit different from what Scython does. In Scython, you are basically adding more C types to convert your Python program into a Scython program with just a different syntax. Whereas in MyPyC, the idea is that you limit yourself in your use of Python and meta-programming, monkey-patching and so on. So your structure of your objects becomes more static and also you are required to use type hints basically everywhere for your code. So it's like a stricter, more statically typed subset of Python. If you restrict yourself to this subset, then MyPyC promises, at least initially for some cases, to give you like 5x performance boost or something like that. And it's actually already there in some production scenarios. For example, MyPyC, as you might have guessed, the name comes from the type checker MyPy. And MyPyC is written by the members of the MyPy team. And they have created this project to make MyPy run faster. And this is the result they got, like 5x performance boost. And it's already there in the current version of MyPy. So if you are using MyPy, you already have this kind of technology working on your laptop. Also, there is the idea of sub-interpretors, but I won't go into much detail here because today we had a keynote about Python performance by Viktor Stiner that had a part about sub-interpretors. And in general, it was a very interesting talk that touched a lot of areas about Python performance. So I would really recommend you to watch his video if you haven't attended the keynote today. So a bit about the release plans. As you might know, the Python 2 is going to be retired on the 1st of January 2020. 3.8, as I said, will be released in a few months. And 3.9, I guess it's not clear yet. At least maybe this information is already outdated. But there was an idea of switching to nine-month release cycles. So Python 3.9 might appear sooner than you expect. So in conclusion, I really recommend you to install Python 3.8 beta, try it by yourself, try the new features, see if you like them or not, and try to run your production code in some environment, at least testing environment, to see if there are any incompatibilities. And please report anything you find to the Python bug tracker and help with fixing bugs, with coming up with new ideas for the next Python releases and so on. And also I should mention then that all the features of Python 3.8 I was talking about today are available in one of the beta builds of PyCharm 2019.2. I guess this concludes my presentation. Thank you. All right, we have time for a few questions. So we have two sets of microphones over there. Please line up and fire away. Hello. Is this working? Okay, great. So I'm the author of argument clinic and you might be wondering why slash in the first place. I used slash for indicating positional arguments in argument clinic because this was a syntax proposed by Guido von Rossum on the main list before people were talking about positional only arguments. And you may be wondering, okay, why did Guido propose it? And the answer is because it's kind of like multiplication and division operators, like one is the opposite of the other. That was really only his thought. Cool. Great. Thank you. Yeah. Hi, nice speech. I wanted to ask you the question about do you know the plans? Will be the question operator similar that we have in C sharp or Java? There are pep drafts about that, maybe even two that talk about this chain of nullity checks. But as far as I know, they are not pushed forward at the moment. Yeah. Thank you. Thank you. The court of developers at all thinking about the size of the syntax of Python over Python two, we have very few additions to the language, whereas we're seeing more and more with the new versions. Yeah, but Python two is actually hard. I teach Python and it's hard to get through the entire syntax of Python in a week. Yeah, it's definitely the case that it's harder to learn Python three than Python two because the language is just bigger. But I should mention that Python two is, I guess, 11 years older than Python three. And Python three just lived a lot longer. So it acquired more and more features. If Python two would have changed beyond Python 2.7, I guess there would be some new additions. But yeah, yeah, I agree that is the problem. And this is one of the things I mentioned about typing, even though it's not related to syntax. But yeah, I guess it's an issue. All right, let's thank Andrea again. Thank you.