
What’s New in Python 3.8 - supakeen
https://docs.python.org/3/whatsnew/3.8.html
======
CivBase
As a developer who has primarily developed applications in Python for his
entire professional career, I can't say I'm especially excited about any of
the "headlining" features of 3.8.

The "walrus operator" will occasionally be useful, but I doubt I will find
many effective uses for it. Same with the forced positional/keyword arguments
and the "self-documenting" f-string expressions. Even when they have a use,
it's usually just to save one line of code or a few extra characters.

The labeled breaks and continues proposed in PEP-3136 [0] also wouldn't be
used very frequently, but they would at least eliminate multiple lines of code
and reduce complexity.

PEP-3136 was rejected because "code so complicated to require this feature is
very rare". I can understand a stance like that. Over complicating a language
with rarely-used features can definitely create problems. I just don't see why
the three "headline" features I mentioned are any different.

[0]:
[https://www.python.org/dev/peps/pep-3136/](https://www.python.org/dev/peps/pep-3136/)

~~~
paulddraper
> As a developer who has primarily developed applications in Python for his
> entire professional career, I can't say I'm especially excited about any of
> the "headlining" features of 3.8.

Python is a fairly old, mature language.

What features _would_ you have been especially excited about?

~~~
levi_n
Though not a language feature per say, I would love if the language would take
on the packaging ecosystem and deliver a ground up approach that isn't just a
kludge on a kludge on a kludge.

~~~
xapata
Unfortunately, that'd mean a package manager for C, Fortran, etc. as well,
since so many Python packages have non-Python dependencies.

I've started using Docker for ensuring prod behaves the same as dev. Going
from Mac dev to Linux prod would otherwise cause trouble.

~~~
j88439h84
Sounds like Conda.

~~~
xapata
Conda can't fix some problems, like Python 3.7 wanting ncurses >6, but a
dependency wanting ncurses 5.9

------
robocat

      def f(a, b, /, c, d, *, e, f):
    

Wow: IMHO that is a very ugly syntax to define a fn with 6 parameters,
although it looks to be a path dependency on previous decisions (*, and
CPython ,/) and clearly there was much discussion of the need for the
functionality and the compromises:
[https://www.python.org/dev/peps/pep-0570/](https://www.python.org/dev/peps/pep-0570/)

It amazes me to see how certain features make it into languages via
community/committee (octal numbers in JavaScript - arrgh!).

One thing I find really difficult to deal with in languages is the overloading
of different syntactic(edit:semantic) usages of different symbols, which
itself is a result of limiting ourselves to the ASCII symbols that can be
typed. I don't recall written mathematics having the issue badly (although I
haven't had to write any for a long time!).

~~~
BurningFrog
> _which itself is a result of limiting ourselves to the ASCII symbols that
> can be typed_

I think we're ready for programming languages using some visually good Unicode
characters, instead of overloading `[]{}!@#$%^&*()-_/` for everything!

~~~
Pxtl
Oh god, this. I want a language that as I type, != Gets replaced with a proper
≠ not equals sign and proper symbols for AND, OR, and NOT.

~~~
roywiggins
Use a ligature font!

[https://www.hanselman.com/blog/MonospacedProgrammingFontsWit...](https://www.hanselman.com/blog/MonospacedProgrammingFontsWithLigatures.aspx)

------
Xophmeister
This got missed from the release announcement, but now there's
`functools.singledispatchmethod`,[1] as the class method sibling to
`functools.singledispatch`.[2] This allows you to overload the implementation
of a function (and now a method) based on the type of its first argument. This
saves you writing code like:

    
    
        def foo(bar):
            if isinstance(bar, Quux):
                # Treat bar as a Quux
    
            elif isinstance(bar, Xyzzy):
                # Treat bar as an Xyzzy
    
            # etc.
    

I understand runtime type checking like that is considered a bit of a Python
antipattern. With `singledispatch`, you can do this instead:

    
    
        @singledispatch
        def foo(bar:Quux):
            # Quux implementation
    
        @foo.register
        def _(bar:Xyzzy):
            # Xyzzy implementation
    

With `singledispatchmethod`, you can now also do this to class methods, where
the type of the first non-self/class is used by the interpreter to check the
type, based on its annotation (or using the argument to its `register`
method). You could mimic this behaviour using `singledispatch` in your
constructor, but this syntax is much nicer.

[1]
[https://docs.python.org/3/library/functools.html#functools.s...](https://docs.python.org/3/library/functools.html#functools.singledispatchmethod)

[2]
[https://docs.python.org/3/library/functools.html#functools.s...](https://docs.python.org/3/library/functools.html#functools.singledispatch)

~~~
hirowan
The issue with this and `singledispatch` is that they no longer support
pseudo-types from the `typing` module [1] so you can't use them with
containers of type `x`, e.g. `List[str]`, or protocols like `Sequence`.

[1] [https://bugs.python.org/issue34498](https://bugs.python.org/issue34498)

~~~
spott
Yea, this one is really annoying... required a lot of rewriting of code to
make some old code work with 3.7.

------
airstrike
The expansion of f-strings is a welcome addition. The more I use them, the
happier I am that they exist

[https://docs.python.org/3/whatsnew/3.8.html#f-strings-
suppor...](https://docs.python.org/3/whatsnew/3.8.html#f-strings-support-for-
self-documenting-expressions-and-debugging)

~~~
bhl
Why didn’t Python ship with the opposite functionality as well? Parsing
instead of formatting. Given a string and a format string, return a list of
variables (or a dictionary).

~~~
ash
Are you talking about parsing f-strings? How would that look like?

As far I understand the following:

    
    
        print(f"your name is {name}")
    

is roughly equivalent to:

    
    
        print(f"your name is " + format(name))
    

What is there to parse?

~~~
bhl
For example, to checkpoint a model, I would save it as
“ckpt-{epoch_number}-{val_loss}”. Given this file name and the original format
string, I would like to recover the epoch number and validation loss variables
back.

From: ckpt-8-0.300 To: epoch=8, val_loss=0.300

------
metalliqaz
This is the release that contains the controversial assignment expressions,
which sparked the debate that convinced GvR to quit as BDFL.

They didn't select my preferred syntax, but I'm still looking forward to using
assignment expressions for testing my re.match() objects.

I haven't used 3.8.0 yet but I hope its a good one because 2020 is the year
that 2.7 dies and there will be a lot of people switching.

~~~
diminoten
Because of the luddites at RedHat, Python2.7 isn't actually dead until 2024.
It's infuriating.

[https://access.redhat.com/solutions/4455511](https://access.redhat.com/solutions/4455511)

~~~
Nullabillity
If you want other people to make a change then it's on you to make a
convincing argument for _why_ the new thing is an improvement, not just go on
tirades about how people should get with the times.

Personally, I lost faith in the Python core team because of the Py3 migration.
Yes, 3.x now has a bunch of nice features that 2.x did, but almost none of
them actually depend on the 3.0's breakage (as proven by Tauthon).

If you want people to follow you through a break-the-world migration then you
need to motivate why it is needed and why it couldn't be done incrementally,
not try tempt them with a bunch of unrelated carrots that are bundled together
with the breaking change.

~~~
madhadron
> If you want people to follow you through a break-the-world migration then
> you need to motivate why it is needed and why it couldn't be done
> incrementally

They did. I remember looking through this, and I remain convinced that the
core developers were correct and there was no way to fix Unicode handling
incrementally.

~~~
Nullabillity
Add the u-sigil for unicode (as they did), add the b-sigil for bytestrings (as
they eventually did), and then go through a regular deprecation cycle for
sigil-less strings (rather than releasing a 3.0 where the u-sigils were
removed completely). Maybe at some point re-add sigil-less strings as an alias
for u-strings, but I'd rather have old stuff break with a clear message than
have a bunch of weird side bugs.

Do the same for the type names.

------
mintplant
Buried in the notes for the `typing` module:

> “Final” variables, functions, methods and classes. See PEP 591, typing.Final
> and typing.final(). The final qualifier instructs a static type checker to
> restrict subclassing, overriding, or reassignment:

> pi: Final[float] = 3.1415926536

As I understand it, this means Python now has a way of marking variables as
constant (though it doesn't propagate into the underlying values as in the
case of C++'s `const`).

The equivalent Java:

    
    
        final float pi = 3.1415926536;

~~~
spott
The thing is, it is only enforced in mypy... code that modifies a Final object
(pi = 3 for example) later on will run fine.

~~~
dharmab
Correct- as usual the annotation indicates intent, but is not enforced at
runtime.

------
amanzi
Real Python have a great post out today going through most of the changes:
[https://realpython.com/python38-new-
features/](https://realpython.com/python38-new-features/)

They have a lot of code samples and examples about how and when to use the new
features.Personally, I love the new debugging support in F strings.

~~~
rapfaria
Too bad I'm losing good articles like this one because of those patronizing,
click-baity newsletters that they started sending out a year or two ago.

~~~
amanzi
They appear to have toned down their marketing efforts recently. You no longer
get bombarded with clickbait pop ups or alerts.

------
ohazi
> The typing module incorporates several new features:

> A dictionary type with per-key types.

Ah, I've been waiting for this. I've been able to use Python's optional types
pretty much everywhere _except_ for dictionaries that are used as pseudo-
objects, which is a fairly common pattern in Python. This should patch that
hole nicely.

~~~
j88439h84
IMO A better fix is to use [http://attrs.org](http://attrs.org) or dataclasses
to replace the dicts entirely.

~~~
ben509
And then use a library like json-syntax[1] to translate those into JSON.

[1]: [https://pypi.org/project/json-syntax/](https://pypi.org/project/json-
syntax/)

~~~
ledauphin
this looks interesting. we use cattrs, which has worked well for us but has a
long-delayed 1.0 release.

------
supakeen
Arguably one of the hotter debated functions is assignment-as-expression
through the := or walrus operator.

Quite happy with the new SyntaxWarning for identity comparison on literals and
missing commas :)

Especially neat is also the `python -m asyncio` shell which allows you to run
top-level awaits in your repl instead of needing to start a new event loop
each time!

~~~
j88439h84
IPython has supported top-level async for a while too, plus many other
features!

------
pcr910303
I like the additions of the f-strings and walrus operator, but I find myself
wishing a breaking-release removing the old features that the new features
covers. Python's philosophy was to have one way to do something, but the
current situation of Python is very inconsistent. Python 3 has like 4~5 ways
to format strings, and due to the addition of the walrus operator, we have (I
understand the differences between := and = but) two different syntaxes for
variable declaration/assignment.

I understand that Python can't break all kinds of code (as the 2->3 conversion
is still a pain), but still I imagine a Python-esque language without all the
warts that Python have with it's 'organic' growth.

~~~
jakear
That's a good use case for a linter. Ban outdated constructs in your code, but
still allow you to depend on things that use them. Beats another 2->3 split
again.

~~~
pcr910303
Yeah, and I already use linters to remove all outdated constructs; but... It's
a pity that "There's only one way to do it" doesn't work in 2019 :-(

~~~
gimboland
It was never "there's only one way to do it".

It is: "There should be one-- and preferably only one --obvious way to do it."

The core of that statement is "There should be one obvious way to do it" \-
there's no "only" there, it just says that when you need to do something,
there should be an/some obvious way to do it. Then, _preferably_ , that should
be the only obvious way — though of course that doesn't preclude there being
many other less-obvious ways.

With string interpolation we've certainly now got multiple ways to do it; that
doesn't violate the principle. I agree that at least two of those are
"obvious" (f-strings and .format()), and you could argue that %-interpolation
is obvious too — but none of that is in violation of the principle that there
should be an obvious way to do it, just of the preference that there's only
one.

Finally it's worth remembering where this idea came from: it was in contrast
to the perl mantra of "there's more than one way to do it", and a reaction to
the resultant confusion frequently experienced when reading someone else's
perl code — this was python saying "we're not perl, we value clarity and
comprehension". I think that much of that problem was bound up in perl's
syntax choices, and that in the cases in python where there's more than one
way to do it (say, string formatting, dataclasses/attrs/namedtuples/etc.),
it's usually pretty obvious what machinery is actually being used. When was
the last time you looked at a line of python and said "I have no idea what the
fuck is going on here?" That was a frequent experience with perl in the heady
days of the late 1990s.

------
bratao
I do not know exactly what caused this, but my internal project test-suite got
a much appreciated 5% speedup! Thank you Python team!

~~~
The_rationalist
I you care about performance, maybe you should try pypy (the alternative
python compiler)

~~~
bratao
I try PyPy every 3 months. It has improved greatly and for some periods I
migrated to it. But for this particular project, most of time is spent inside
lxml, pandas, scikit-learn and other extensions. CPython is actually faster
than PyPy for this project. Maybe GraalVM / GraalPython can improve on this
use-case.

~~~
vojta_letal
Like, if graalpython gets ever released.

------
svara
> Added new multiprocessing.shared_memory module

Hard to understand why this is so far down. This is fantastic news!

------
Pxtl
Ugh, I hate assignment expressions. I liked that they were missing from
Python.

I've been coding in algolesque languages for 20 years and hiding assignments
inside of expressions instead of putting them on the left like a statement has
always tripped me up.

~~~
jtdev
But, but, but... now you don’t need to write that extra line of code! It’s
going to make everything sooooo much better, code will practically write
itself now.

I’ll just leave this here:

“There should be one—and preferably only one—obvious way to do it.”

~~~
codr7
At this point it's about as true as G not being evil.

Which is fine by me, it was a silly idea to begin with. What you really want
is separated concerns that compose well, obvious here doesn't mean anything
over there.

------
w-m
> The list constructor does not overallocate the internal item buffer if the
> input iterable has a known length (the input implements __len__). This makes
> the created list 12% smaller on average. (Contributed by Raymond Hettinger
> and Pablo Galindo in bpo-33234.)

Wow. I believe it's a stated goal of CPython to prefer simple maintainable
code over maximum performance. But relatively low-hanging fruit like this
makes me wonder how much overall CPython perf could be improved by
specialising for a few more of these.

------
archie2
I don't mind the walrus operator, but holy cow the "positional operators"
syntax is completely unintelligble...what the hell were they thinking?!

~~~
toyg
It really is not supposed to be used unless you are wrapping a C library. Or
at least that’s the original reasoning, I think. Let’s hope it doesn’t get
abused.

------
santiagobasulto
Shared Memory is the star of this release IMHO.

~~~
diminoten
Is shared memory one of those things that I should try to access/use
immediately, or wait for someone to write a wrapper library around, due to the
large number of edge cases/strangeness that might occur?

~~~
sidlls
Why not both? You get a great feel for what the edge cases are and how they
occur, and thus a better understanding of why decisions in "wrapper libraries"
were made, when these edge cases bite you.

~~~
diminoten
Mostly because I don't want to be up at 3am on a Saturday night debugging
production code...

------
herpderperator
Damn... this is rather confusing:
[https://www.python.org/dev/peps/pep-0572/](https://www.python.org/dev/peps/pep-0572/)

I really like the walrus operator, but I didn't realize how many "you
shouldn't do this" and "this is too hard already" cases exist where they are
discouraging using the walrus operator.

------
jxy
It's interesting to see Python's gradual acceptance to TMTOWTDI.

------
blumomo
The new assignment expression is great and I wish that an optional operator
(`?`) and Elvis operator (`?:`) will make it to Python one day, too. I would
love to write:

    
    
        v = obj?.prop1?.prop2 ?: "default"
    

instead of long if conditions:

    
    
        v = obj.prop1.prop2 if obj and obj.prop1 and obj.prop1.prop2 else "default"
    

A PEP for Python 3.8 existed but has been deferred:
[https://www.python.org/dev/peps/pep-0505/](https://www.python.org/dev/peps/pep-0505/)

------
agf
I gave a talk on this at the PyBay conference this summer, and more recently
at the ChiPy meetup in Chicago last week.

Presentation:
[https://docs.google.com/presentation/d/1a3Zoav7NmeN_gXjGcV_l...](https://docs.google.com/presentation/d/1a3Zoav7NmeN_gXjGcV_lalROR8Mo8CxDpgV1qAdof9U/edit?usp=sharing)

Video from PyBay:
[https://www.youtube.com/watch?v=OtdQN24Z5MA](https://www.youtube.com/watch?v=OtdQN24Z5MA)

It covers assignment expressions in some depth, as well as highlights
elsewhere.

------
sys_64738
Looks like python is trying to out C++ the C++ language with kitchen sink bolt
ons.

------
svnpenn
> In this example, the assignment expression helps avoid calling len() twice:
    
    
        if (n := len(a)) > 10:
           print(f"List is too long ({n} elements, expected <= 10)")
    

Um, no it doesnt?:

    
    
        a1 = [10, 20, 30]
        n1 = len(a1)
        if n1 > 2:
           print(f'{n1} is greater than two')

~~~
hermitdev
Yes, but your example is less efficient than the new code.

Remember: every variable is an assignment into a dict, and every lookup a
query into a dict. Reducing name lookups and assignments can yield good
speedup in tight loops. For instance, caching os.path.join, os.path.split into
local names can significantly speed up tight loops iterating over a
filesystem. For example, os.path.split is potentially 5 dictionary lookups.
Checking locals, nonlocals and globals for os. Then another to find path, and
a final one for split. And this happens at runtime, for every invocation.

~~~
murkt
Local variables aren’t stored in a dict, likewise when a class has defined
__slots__. Globals, modules and usual classes do use dicts internally, but
locals do not. So from the efficiency standpoint it’s (almost?) the same. I
haven’t checked the bytecode, maybe there is some slight difference.

~~~
jakear
I checked the bytecode, in the walrus version you get [...DUP_TOP, STORE_FAST,
...] in the non-walrus you get [...STORE_FAST, LOAD_FAST, ...]. Besides that
identical. I imagine DUP_TOP is faster than LOAD_FAST, but I feel either way
this is useless micro optimization at its finest.

~~~
jakear
In cpython:

DUP_TOP:

    
    
                PyObject *top = TOP();
                Py_INCREF(top);
                PUSH(top);
                FAST_DISPATCH();
    

TOP:

    
    
                (stack_pointer[-1])
    

LOAD_FAST:

    
    
                PyObject *value = GETLOCAL(oparg);
                if (value == NULL) { /* throw */ }
                Py_INCREF(value);
                PUSH(value);
                FAST_DISPATCH();
    

GETLOCAL:

    
    
                (fastlocals[i])
    

So looks like either way, you have an array access of something definitely in
cache, a Py_INCREF, a PUSH, and a FAST_DISPATCH. The walrus operator saves you
a null-check, but that check is probably skipped right over by the branch
predictor, as it always throws. I'd bet the performance is indistinguishable,
but I'd be interested to see for real.

------
louis8799
New "f-strings support = for self-documenting expressions" but you cannot use
f-strings as doc string ;)

------
nilsandrey
The := operator is the assignment operator on Object Pascal, just saying,
remembering my old days. BTW not so old for everyone ->
[https://news.ycombinator.com/item?id=15490345](https://news.ycombinator.com/item?id=15490345)

------
omginternets
I stepped away from Python for about a year, and now I'm coming back to it. I
hardly recognize the language. I'm not happy about this at all.

I don't really have a point, except that Python 3 feels like a moving target.

~~~
probably_wrong
I feel the same way as you do. For me, which version of an interpreter I'm
using should be the kind of issue I only need to worry when solving extremely
specific, deep-level problems. Python 3+ breaks this pact too often for my
taste.

Considering this f-string example taken from another announcement:

    
    
       f"Diameter {(diam := 2 * r)} gives circumference {math.pi * diam:.2f}"
    

This is valid Python 3.8, but it's not valid in Python 3.7 (no walrus
operator). And removing the walrus operator still doesn't work in Python 3.5
(no f-strings). On top of that, other comments already mention how f-strings
have lots of weird corner cases anyway.

The entire point of Python in my circle of friends was that it made
programming easy. Instead, I feel more and more in need of those "It works in
my machine!" stickers. And good luck solving these issues if you are not a
full-time programmer...

~~~
Liquid_Fire
I'm not sure why you frame this as an issue with Python 3. This has always
been the case, even in the 2.x days every release added new features, and if
you ran code using them in an older version it wouldn't work.

The minor releases are always backward-compatible, so just run the latest
version and everything will work.

~~~
omginternets
The issue is that the ecosystem as a whole tends to follow the tip of the
version chain. This means that any human-oriented Python stuff (e.g.
documentation/tutorials/code-review/etc...) requires you stay up to date with
the language changes.

Asyncio was the worst culprit, as it essentially introduces an inner-platform
with its own dataflow semantics, but at least there the upsides were large and
tangible.

------
robomartin
I don't understand why the walrus operator is needed at all. Why not allow,
this to work:

    
    
        if m=whatever():
            do_something
    

Why create a new assignment operator? For all the talk about making code not
confusing, etc., some of these decisions sure seem nonsensical.

Oh, OK, it confuses passing arguments into a function by name? Really? C'mon.

Also, I can't understand the nearly religious rejection of pre and post
increment/decrement (++/\--) and, for the love of Picard, the switch()
statement.

I enjoy using Python but some of these things are just silly. Just my opinion,
of course. What do I know anyhow? I've only been writing software for over
thirty years while using over a dozen languages ranging from machine language
(as in op codes) to APL and every new fad and modern language in between.

As I watch languages evolve what I see is various levels of ridiculous
reinvention of the wheel for very little in the way of real gains in
productivity, code quality, bug eradication, expressiveness, etc. Python,
Objective-C, Javascript, PHP, C# and a bunch of other mutants are just C and
C++ that behave differently. Sure, OK, not strictly true at a technical level,
but I'll be damned if it all doesn't end-up with machine code that does pretty
much the same darn thing.

The world did exist before all of these "advanced" languages were around and
we wrote excellent software (and crappy software too, just like today).

What's worse is that some of these languages waste a tremendous amount of
resources and clock cycles to do the same thing we used to do in "lower"
languages without any issues whatsoever. Mission critical, failure tolerant,
complex software existed way before someone decided that the switch()
statement was an abomination and that pre and post increment/decrement are
somehow confusing or unrefined. Kind of makes you wonder what mental image
they have of a programmer, doesn't it? Really. In my 30+ years in the industry
I have yet to meet someone who is laid to waste, curled-up into a fetal
position confused about pre and post increment/decrement, switch statements
and other things deemed too complex and inelegant in some of these languages
and pedantic circles.

Geez!

</rant off>

------
molteanu
Is Python now becoming the new C++?

~~~
davb
This is fair criticism. I've worked with Python for many years now, and one of
the things that attracted me was that there was always a fsirly static
"Pythonic" way to do things. The language has now grown so much that 80% of
the people only use 20% of the language, but not always the same 20%, making
it difficult to read other people's code. And all the syntactic changes
contribute to fragmentation (not every project can have its Python interpreter
upgraded regularly).

There's something to be said for a more stable, if less elegant, language.

------
vikinghckr
Disappointing that Python sill has no support for a sorted container in its
standard library, akin to C++ `set` or `map` classes.

~~~
carapace
[https://docs.python.org/3.0/library/bisect.html](https://docs.python.org/3.0/library/bisect.html)

> This module provides support for maintaining a list in sorted order without
> having to sort the list after each insertion.

~~~
vikinghckr
Problem with bisect is that bisect.insort() insertion is O(n), whereas C++
set.insert() is O(log n).

~~~
stfwn
It is somewhat strange that Python does not have a binary tree in the standard
library. I also couldn't find any discussion on the topic either. It might be
a nice contribution.

Edit: it was coined a few times on the python-ideas mailing list but it seems
it just died a silent death there.
[https://mail.python.org/archives/list/python-
ideas@python.or...](https://mail.python.org/archives/list/python-
ideas@python.org/message/3XA5XVGOPQNOVP6PRODTARAFPFXWG3PX/)

~~~
carapace
I suspect it's because you rarely need them in Python because the existing
built-ins (list, tuple, dict, set) usually work well enough for a given job,
or you're already using e.g. Pandas or something.

FWIW:
[https://github.com/calroc/xerblin/blob/master/xerblin/btree....](https://github.com/calroc/xerblin/blob/master/xerblin/btree.py)

------
varelaz
Everything of this looks like syntax sugar. I would expect more work on
internals. Python has a lot of awkward edge cases in standard lib. In a lot of
cases None is valid output for not-done states. Also I hate multithreading
programming in Python 3, it has all drawbacks of C with additions of GIL.

------
spicyramen
I'm still migrating from 2.7...to 3.5

------
ram_rar
Does the python community care about concurrency at all? I havent seen
anything new in terms of concurrency in a while. I might be wrong about this,
but walrus operator seems like a gateway to writing obfuscated perlesque code.

~~~
aeyes
3.8 brings shared memory to multiprocessing:
[https://docs.python.org/3/library/multiprocessing.shared_mem...](https://docs.python.org/3/library/multiprocessing.shared_memory.html#module-
multiprocessing.shared_memory)

------
cryptos
It would be nice if the Python web site would be mobile friendly.

------
ameliaquining
Anyone else most excited about PYTHONCACHEPREFIX? :-P

~~~
rcfox
Not sure about _most_ excited, but I am looking forward to setting
PYTHONCACHEPREFIX to a location that isn't in a volume mounted into my Docker
container for development.

~~~
dowst
+1

------
maest
Can I chain the walrus operator? All examples I've seen were part of if/while
blocks.

Something like:

    
    
        r1 = foo(x:=bar)
        r2 = baz(x)

------
Timothycquinn
Assignment expression is something I miss from JavaScript which I used a lot
to strip lines of code. Great to see in Python.

------
tolgahanuzun
Updates on `f-string` are quite fun. :)

`f'{username= }'` 'username="tolgahanuzun"'

I like it.

------
cutler
Any idea how long it will take before it's an option with pyenv?

------
qwerty456127
Still no pattern matching and no immutable vars :-(

------
bp294
Interesting! Thanks for the share!

------
heyflyguy
man do I wish they would make multiprocessing easier

~~~
mintplant
Subinterpreters are coming in 3.9, which should fill most of the same roles as
multiprocessing but without the complexities and edge cases of multiple real
OS processes.

[https://www.python.org/dev/peps/pep-0554/](https://www.python.org/dev/peps/pep-0554/)

~~~
blumomo
According to [https://www.python.org/dev/peps/pep-0554/#provisional-
status](https://www.python.org/dev/peps/pep-0554/#provisional-status) they
should already be present in 3.8 for evaluation.

