Python 3.12
python.org
python.org
from typing import TypedDict, Unpack
class Movie(TypedDict):
name: str
year: int
def foo(*kwargs: Unpack[Movie]): ...
Maybe now I'll be able to actually figure out what data to send libraries without actually reading their source code.1. https://docs.python.org/3.12/whatsnew/3.12.html#pep-692-usin...
One could hope, but any library abusing kwargs in all their methods is showing they’re willing to go through the absolute minimum to make their code usable, let alone readable and self-documenting.
It's a tiny hope. But a hope nonetheless. Fortran is fun.
Also, do you prefer a specific version of Fortran, or is the latest one fine?
You can read more about the language and its high-level features here: https://fortran-lang.org
That website/community was created in part by the original author of the Python Sympy library, Ondřej Čertík. He is also working on his own Fortran compiler that you can use via webassembly to play around with Fortran; find links if you want to play here: https://lfortran.org
I've only dabbled a little, but I like the general idea, and I appreciate a F/OSS Fortran compiler being developed like this alongside actively seeking to grow the Fortran community & push the language & its libraries forward.
I expect more widespread adoption of Fortran to be quite a ways out, but what Ondřej is doing for Fortran is necessary (not sufficient) for such adoption to be the case.
[1] Is Fortran easier to optimize than C for heavy calculations?
Fortran has also added support for e.g. object-oriented programming, pure functions (no side effects for better optimization), and pointers. So idiomatic modern Fortran code looks very different from the “Fortran 77” code that many people might think of when they hear the name :).
The next step is Idris, where you define starting and desired type and start interactive shell to figure out right way to get there.
However....
Nim is unlikely to go mainstream. It's not the next Rust and not for technical reasons.
Julia won't budge Python out of the top slot anytime soon, although it should in many scenarios past simple scripting.
The Azure SDK is full of them, making liberal use of kwargs.pop. What a nightmare.
At first I was kinda giggling. But actually there are such things, if the Mapping is also ordered.
LRU cache, trees, tries… and—oh wait—all CPython dicts are ordered these days!
(Honestly I have only used the modern ordered-nature of `dict` for serialization to versioned or human-editable files. But why not an algorithm with a “`stackdict`” I guess?)
Naked kwargs is so difficult to work with that I hesitate to think of a use case where it wouldn’t be an anti pattern.
Preferable for whom? I do not prefer it. I much prefer to avoid the extra work it creates for me vs. the simplicity of kwargs. I use explicit args for the function I made and then add *kwargs on the end and then I don't have to write bespoke config objects or copy and paste a bunch of stuff that might be obsolete by a future update to some library and also pollute my function's signature. I would very much welcome a way to tell callers where kwargs is going without having to do extra work.
For code with many users, creating a few extra minutes of work for one dev is preferable when the alternative would be every dev who uses that code has to spend that same extra work and then some to grok what exactly is going on with the method signatures. Being explicit also creates traceable code, in that you can search a keyword to find everywhere it’s used or passed rather than tracing methods where it might be used.
I can promise very few users would be thankful for the elegance and minimalism of args/kwargs when they’re source-diving trying to figure out how to get some basic functionality to work.
Looking at it another way, the hunk of code in charge of serializing your message does not care one whit about the innards of each message, and making it become aware would add tremendous complexity with no real value.
One significant issue with static typing in Python is how much boilerplate is required to use types when also doing the sorts of things that dynamic Python is really good at - for instance proxying functions. If you want to do that now and preserve the types, you need to re-declare the types of everything in the wrapper.
Now, if the underlying function already made use of Unpack, you could "reuse" that type in your own wrapper with low boilerplate and less chance of things diverging in hard-to-refactor ways.
E.g setup something and then pass the kwargs through to the other function.
from collections.abc import Callable
from typing import TypeVar, ParamSpec
import logging
T = TypeVar('T')
P = ParamSpec('P')
def add_logging(f: Callable[P, T]) -> Callable[P, T]:
'''A type-safe decorator to add logging to a function.'''
def inner(*args: P.args, **kwargs: P.kwargs) -> T:
logging.info(f'{f.__name__} was called')
return f(*args, **kwargs)
return inner
@add_logging
def add_two(x: float, y: float) -> float:
'''Add two numbers together.'''
return x + yJust reading this sent a chill down my spine. I have horrible memories of having to read the code to figure out what something was doing (in JavaScript, Python, Ruby, etc), due to the disaster of an anti-feature called dynamic typing having been used.
It was a massive waste of time to have to read piles of code code, use a debugger and inspect object structure, to understand how some parts of certain large codebases worked.
In my experience, dynamic typing has simply been horrible for team collaboration, code readability (and ease of understanding), and it results in a large number of bugs that could easily have been eliminated with static type checking.
> But this debate is decades old and people always dogmatically choose one side, so not really any point in trying to convince you.
You’re right about that. I am indeed very dogmatic and take a hard-line on this. I take a stronger position on this than most things (for example: something very subjective like curly braces versus white space indentation), to the point that I’ll say this: dynamic typing is simply a wrong and bad engineering decision.
Another example of a bad language design decision is allowing null to be a part of every type instead of requiring an explicit ? in the type, or the use of an Optional wrapper. This has been recognized as an ill, andis something many modern languages (to name a few: Rust, Kotlin, etc) fixes.
But that isn’t meant to level a personal attack against the languages designers of the past (or to say that they were stupid). Allowing every type to be Union[T, null] was a simply a language design mistake (that potentially cost wasted billions of dollars), but it's been recognized as a mistake today that we need to rectify and move forward from (as is reflected by decision made by more recent languages).
However, imo, in comparison, dynamic typing is a 100 times worse than not having null safety (or not having memory safety like C or C++). I can work with a C or C++ without much trouble, but not with dynamic typing. Dynamic typing makes it difficult and unpleasant to work with a large codebase, to an inexcusable degree.
Untyped languages tend to be at the forefront of paradigms, and typed languages come in toward the end when reliability and need for tooling are more important than innovation/discovery.
In the 90s a bunch of kids were building websites with LAMP stacks while serious engineers were building aging/about-to-be-irrelevant desktop software in serious, typed languages.
I kickstarted a project in Python a decade ago that was wild on dynamic typing. As it passed a critical threshold of ~10k LoC, it became nearly ummaintainable.
What's that `response` passed here? A verbatim response object from `requests`? A proxy mapping? Bytes? A JSON string? If so, a list or a dict? And what fields are inside?
Multiply it by tens or hundreds of methods and classes, and it's easy to see why projects based on purely dynamic patterns fail to scale.
By now I have almost completely rewritten that project to use type hints everywhere I could. And guess what? In 95% of the cases I knew exactly what was being passed - or the choice was about 2-3 types at most, so a Union sufficed.
Yes, there's a 5% of cases where Python's dynamic typing features are a blessing. The power of meta programming in Python is often underestimated. Reflection is amazingly intuitive compared to the patchwork mess of Java, Kotlin and friends. Everything can be mocked without hassle and boilerplate. And duck typing can really be useful sometimes.
But, again, in an average project I wouldn't expect code that benefits from these features to make up more than 5-10% of the codebase.
For everything else, just do yourself, your future self and anyone who will work on your code a favour, and use type hints.
The P in the LAMP stack is still a bit of a mystery to me. It could (one could wish) have been Haskell instead, but oh well.
Now I just have to wait 5 more years until 3.12 is sufficiently old that work lets me use it.
Bets on user-upgradable Python on Linux by 2030?
(Of course, then you take on the responsibility of keeping up with patch releases yourself, which is why we use distros. But if it's just a small number of packages on top of a distro-managed base system, it's perhaps not so bad.)
Have you ever worked in a place that uses Python? When someone says to you "hey it's not working" are you really going to say with a straight face "oh yes, you just need to compile Python from source". Come on, this is one of those obviously stupid situations that for some reason people feel the need to defend. It's not defensible.
You don't need to compile Node or Rust or Go or Deno from source to install the latest version.
https://realpython.com/python-versions-docker/#running-pytho...
Use asdf. You don’t want to manage your project’s dependencies at the system level any more than you have to.
for i in range(len(lst) // batch_size + 1): batch = lst[i * batch_size : (i + 1) * batch_size]
Personally I think I'd actually write it like this:
for i in range(0, len(lst), batch_size):
batch = lst[i:i+batch_size]
The docs give another pretty nice implementation using iter() and islice() in a loop (but it uses the walrus operator `:=` so it requires Python 3.8+ as written).there's 1-2 other stuff from more_itertools that I think should make it to itertools. I'd actually like to see statistics from huge monorepos/opensource about usage stats of various more_itertools functions.
> PEP 669 defines a new API for profilers, debuggers, and other tools to monitor events in CPython. It covers a wide range of events, including calls, returns, lines, exceptions, jumps, and more. This means that you only pay for what you use, providing support for near-zero overhead debuggers and coverage tools. See sys.monitoring for details.
Low-overhead instrumentation opens up a whole bunch of interesting interactive use cases (i.e. Jupyter etc.), and as the author of one library that relies heavily on instrumentation (https://github.com/ipyflow/ipyflow), I'm very keen to explore the possibilities here.
Summary, sorry for poor formatting, I'm not sure HN can do a list of any kind?
New features
More flexible f-string parsing, allowing many things previously disallowed (PEP 701).
Support for the buffer protocol in Python code (PEP 688).
A new debugging/profiling API (PEP 669).
Support for isolated subinterpreters with separate Global Interpreter Locks (PEP 684).
Even more improved error messages. More exceptions potentially caused by typos now make suggestions to the user.
Support for the Linux perf profiler to report Python function names in traces.
Many large and small performance improvements (like PEP 709 and support for the BOLT binary optimizer), delivering an estimated 5% overall performance improvement.
Type annotations
New type annotation syntax for generic classes (PEP 695).
New override decorator for methods (PEP 698).
Deprecations
The deprecated wstr and wstr_length members of the C implementation of unicode objects were removed, per PEP 623.
In the unittest module, a number of long deprecated methods and classes were removed. (They had been deprecated since Python 3.1 or 3.2).
The deprecated smtpd and distutils modules have been removed (see PEP 594 and PEP 632. The setuptools package continues to provide the distutils module.
A number of other old, broken and deprecated functions, classes and methods have been removed.
Invalid backslash escape sequences in strings now warn with SyntaxWarning instead of DeprecationWarning, making them more visible. (They will become syntax errors in the future.)
The internal representation of integers has changed in preparation for performance enhancements. (This should not affect most users as it is an internal detail, but it may cause problems for Cython-generated code.)
In the end, we ended up with quite a number of layers wrapping each other:
1. actual C++ implementation
2. actual C++ header
3. C++ wrapper implementation, avoiding constructs that Cython doesn't support
4. C++ wrapper header
5. Cython .pxd for step 4
6. Cython .pyx exposing `cdef class`es to Python with a nice Python-style API for the original C++ library.
7. Hand-written .pyi for type checking the remaining Python code, because Cython doesn't have support for auto-generating these yet.
Had we used pybind11 / nanobind instead, we could have stopped at step 3. Cython started easy, but ended up being a major maintenance burden.The f-string changes arrived because there was a need to formalize the syntax, so other Python parsers, for CPython to move off having a special sub-parser just for f-strings, and to be able decide whether weird edge cases were bugs or features.
Once formalized it was decided not to put arbitrary limits on it just because people can write badly formatted code, people are can already do that and it's up to the Python community to choose what is or isn't "Pythonic".
FYI, one of the things I'm really looking forward to is being able to write: f"Rows: {'\n'.join(rows)}\n Done!"
Which in Python 3.11 is illegal syntax.
It can, just use `-` characters for bullets, like in Markdown. They won't render as Unicode bullet points but dashes are fine enough.
- If you don't - Your list looks like this
Whereas:
- This list
- Has two newlines between
- Each item
It's basically web workers / isolates for Python.
Using multiprocessing was actually pretty easy (apart from the communication primitives, which obviously suck).
> You get the same cumbersome communication primitive (channels), except now native code can easily get messed up.
I'm not sure what you mean by that. Native code has to be thread safe sure, but now it also can be thread safe! You can have native code that is actually properly multithreaded. A big win.
> And it requires more care when developing the interpreter itself.
Maybe. Not really an issue for the user though.
[0] https://rich.readthedocs.io/en/stable/logging.html
[1] Try this example: https://github.com/Textualize/rich/blob/master/examples/exce...
[2] Side note: does anyone know how to get these properly working when using DDP with pytorch? I get flickering when using this and I think it is actually down to a pytorch issue and how they're handling their loggers and flushing the screen. I know pytorch doesn't want to depend on rich, but hey, pip uses rich so why shouldn't everyone?
It has a lot of dependencies of its own, and dependency creep is real. I know pytorch isn't exactly lightweight in terms of dependencies. But I prefer using libraries that make an effort do only pull in absolutely necessary dependencies.
r.e. pytorch: It's a love hate with me. I do think they should incorporate things that are extremely common and solve things that are daily issues. As a simple example, new users are often confused with loading and saving models when using distributed data parallel (DDP) because it creates this extra "module" name in the state_dict and so can require different usage for saving/loading models if you're distributed training or not. This can be quite annoying. Similarly there are no built in infinite samplers, which are common among generative modelers. People who don't iterate over epochs of data, but rather steps. There's of course many solutions to deal with this, but it does make sense with how prolific it is (and has been since 2015) that there just be a built in dataloader. I'd argue things like progress bars and loggers would also be highly beneficial, especially because pytorch's forte is generating research code.
But we're digressing. These are just opinions.
It's scheduled to be delivered next year if I'm not mistaken.
The new syntax for generic types is also a very nice QOL improvement, you can now just do:
class MyList[T]:
...Previously this required rewriting the whole C++ library to support either pickling (multiplying the total memory consumption by the number of cores), or support allocating everything in shared memory (which means normal C++ types like `std::string` are unusable, need to switch e.g. to boost::interprocess).
Now is sufficient to pickle a pointer to a C++ object as an integer, and it'll still be a valid pointer in the other subinterpreter.
At least in theory this what would happen.
There is no GIL in C/C++/Rust/Zig/Whatever, just use threads.
Rewriting most/all of the Python analyses in a different (GIL-free language) is a no-go, the analyses have accumulated over the years and now there's more than a thousand of them. It would consume all our development resources for the next ~5 years. In retrospect I can say that choosing Python for these was major mistake, but it's one that cannot be fixed without a company-killing rewrite :(
We actually invested several months of developer time in allocating our core data structure in shared memory, allowing us to parallelize with multiprocessing. But there's still a whole bunch of ancillary data structures written in C++ that are not so easy to put in shared memory, so all analyses touching those are limited to a single process, which by Amdahl's law immediately starting dominating our execution time.
Can sub-interpreters be used to share a db/http/etc connection pool across multiple processes?
I find the convergent evolution of features in these two languages pretty funny, as it is very clear that they don't really look at implementation details of the other language even if they quite often land on ideas that are pretty close in practice.
PEP 632: Remove the distutils package. See the migration guide for advice replacing the APIs it provided. The third-party Setuptools package continues to provide distutils, if you still require it in Python 3.12 and beyond.
gh-95299: Do not pre-install setuptools in virtual environments created with venv. This means that distutils, setuptools, pkg_resources, and easy_install will no longer available by default; to access these run pip install setuptools in the activated virtual environment.
The asynchat, asyncore, and imp modules have been removed, along with several unittest.TestCase method aliases.
PEP 669: Low impact monitoring for CPython
PEP 669 defines a new API for profilers, debuggers, and other tools to monitor events in CPython. It covers a wide range of events, including calls, returns, lines, exceptions, jumps, and more. This means that you only pay for what you use, providing support for near-zero overhead debuggers and coverage tools. See sys.monitoring for details.
Unexplained claim about what's being reached for.
> Morals are more general than that.
Yes, obviously. How does this apply to what I said?
> This isn't high school debate club.
Okay?
My response is to point out that your narrowing of the space of dicussion is not only noticed but acknowledged and explicitly challenged. In a conversation about morals this framing of yours is inappropriate and counterproductive. It is notable that you responded in the way you did, implying you're trying to keep this tactic subversive rather than explicitly acknowledging it. Classic move in rhetoric, to be sure.
You're acting like a smarmy high schooler who thinks they're good at reasoning because they're good at "debate".
Clear?
No, it doesn't "just so happen", any more than saying "everyone should be given a fair trial" in a legal system "just so happens" to apply to the guilty and innocent.
> Clear?
Your response is entirely rhetoric, attempting to criticise me rather than my argument. It's clear how you feel; not what you think.
One of the two opinions, which are all that exists. All reasonable people have the one opinion, and all other people are all idiots who all have the other opinion.
Just to take an extreme example, imagine someone put in a note expressing empathy for the families of the victims of a natural disaster in their release notes. The following conversation takes place on Hacker News:
A: I don't really think these sorts of statements have a place in release notes. They don't ultimately accomplish anything or help anyone.
B: I think there's no problem with expressing compassion like this. It's not particularly obtrusive and isn't harming anyone.
You: How would you feel if the release notes had expressed glee at the disaster instead? You would oppose that, right? That means you must also oppose empathetic messages in release notes, to be consistent.
Or to sum up this whole thing in a dril Tweet: https://twitter.com/dril/status/473265809079693312
>That means you must also oppose empathetic messages in release notes, to be consistent.
Yes. It will be interesting reading these cultural artifacts after 50 further years of geo-political development.
The opposing cutesy poem wouldn't be defaming immigrants!
It would be acknowledging a nation can't exist without borders, sovereignty matters, and unchecked migration is not universally good.
That so many commenters here are missing a key factor here (that the opposing view is presented as a disingenuous straw-man in the release notes) is quite illustrative of why it's not being seen as an issue.
So the EU and US are both monolithic blocks with no internal diversity, right?
"Acknowledging" is an especially interesting choice of word here, as if presupposing that your misunderstanding of the world is inherently correct.
The US was built on unchecked migration and it did pretty well out of it.
It's also worth pointing out that Python (and it's ecosystem) is developed by an international team of people, most of whom volunteer their time out of good will and sense of shared purpose across diverse cultures.
The "both sides" logic seems to miss the point that world without mutual aid and international, cross-cultural cooperation would be one that would not have Python and it's ecosystem. It's not political for the Python developers to support such a view, such a view is foundational for the existence of Python.
They wrote about how abortion is very often immoral and unnecessary. That would get people up in arms.
When you include the contemporary context of illegal US border crossings at record numbers [1], it's clearly making a political statement. Pretending the development of a programming language is inexorably linked to unchecked immigration is disingenuous.
[1] https://www.washingtonpost.com/immigration/2023/08/31/border...
The statement there only reads to me as a call to have compassion for those caught up in what will be a perpetually escalating migration crisis (and will likely soon make migrants of those who are currently protecting their borders).
> Pretending the development of a programming language is inexorably linked to unchecked immigration is disingenuous.
Where am I (or anyone else) making that claim? I'm claiming cross-cultural/international cooperation and mutual aid are unquestionably tied to the development of not just a programming language, but all open source software. Anyone who has worked in this space at all can likely list someone they have worked with on nearly every continent.
The fact that you view calls for compassion and empathy as calls for "unchecked migration" is a bit concerning.
>Do not be so stupid to think that
>A place should only belong to those who are born there
>...
>It is not okay to say
>Build a wall to keep them out
>Do not be so stupid to think that >A place should only belong to those who are born there
Does not imply unchecked migration since the entire social fabric of the United States is a based upon people moving here from somewhere else. Currently around 14% of US citizens are foreign born. Claiming they don't belong here would be considered an extreme view even among fairly right-wing Americans. Implying that only people born here belong here is, in fact, a absolutely 0 immigration view, that would essentially destroy the United States since our population growth is almost entirely from immigration.
Likewise:
>It is not okay to say >Build a wall to keep them out
US immigration has not resorted to wall building as a form of immigration control for all but the most recent years. Again, nobody I know who is opposed to wall building supports "unchecked migration".
More immigrants than ever are pouring over the US / Mexico border. The mayor of NYC (a self-proclaimed "sanctuary city") is now warning of the city's destruction as a result of the overwhelming influx [1]. This mayor is politically aligned with the party of our President, who presumably has no political interest in embarrassments like this, yet it's still happening.
"Unchecked migration" is essentially what is already happening, at least in the US. A cutesy poem in the release notes of software (??) that paints the side opposing it as mouth-breathing bigots and the supportive side as empathetic truth-tellers is unnecessary at best.
[1] https://cbs4local.com/news/local/nyc-mayor-warns-of-citys-de...
At a minimum, you are confusing “nation” with “state”, as the former manifestly can exist without borders, which are a feature of the latter.
You're all free to stop using Python.
"Share our food, Share our homes and Share our countries" is quite a big demand on everyone else. I am certainly not willing to do so without limit and without regard to context (e.g. the Muslim gang war that flared up in Sweden).
Neither are a lot of the people who initially advocated for the policies, ie NYC, as we're finding out.
Immigration is great. Unfettered illegal immigration is not. It puts pressure on social infrastructure and causes social strife. Look at us here in Canada. Most of our immigration is legal, and yet our wealth-per-person is shrinking because we can't build infrastructure fast enough to keep up with population growth.
A lot of Green/Progressive voters in Western Europe live in affluent neighbourhoods where practical effects of current migration waves are very limited, and often positive (e.g. cheap workforce for your household, but your kids' school does not suffer from any gang activity).
Voting patterns across income groups tend to reflect that discrepancy.
Just 2 counter examples (anecdotes but I'm sure a bit of searching will reveal numbers to back this up): the first electorate that directly voted a green candidate Was the Friedrichshain-Kreuzberg electorate in 2002, likely one of the places in Germany with the highest proportion of immigrants (when it was still not gentrified like it is today.). Another anecdote, this map of the French elections https://img.lemde.fr/2022/04/11/0/0/1051/1674/800/0/75/0/869...
Showing that the anti immigration party of le pen is mainly winning in rural areas, and the urban centre of Paris is in fact voting the most left candidate
That is an egg-and-chicken question. "White flight" is a thing and people who moved away from ghettoizing cities/neigbourhoods into the surrounding suburbia will likely vote against further immigration.
On top of that, we are now seeing that outer suburbs which were guaranteed winning electorates for right parties are now becoming more and more left leaning because young urban dwellers are moving there because they can't afford the cities.
Maybe rurals are well aware of what's happening in urban regions and don't want it ? Maybe these people like their environment as it is and see no point in change ? I don't know, just guessing. :-)
It's a statement about immigrants being people, that the hateful stories we tell about them are false that we have responsibility to them as fellow humans. It advocates for no specific political action, you can hold these beliefs and still be against immigration for whatever reason.
Same applies to entire countries; their capabilities and societal will are greater than an individual's, but still limited.
Declarations of very broad commitments towards the rest of humanity may sound noble, but wise(r) people should stay away from them.
And in this case to me the blank is "take on the world's tired huddled masses and set them up to be just as self-sufficient and successful as their native born." And I think that's pretty actionable, just about anyone could probably think of more than a few things that would push us closer to this.
It's also a statement against rational thinking and discussions because it portrays both sides to an almost satirical level: "no borders" vs "all migrants are thieves/murderer/bombers"
It is positively totalitarian to drag politics into everything. The very meaning of "totalitarian" is that nothing is allowed to remain non-political.
So the only choices are "let's abolish borders and live happily ever after" or "all migrants are killers/thieves/bombers we should build a wall". How diverse and subtile! If you frame problems like that it's easy to think you're in the "good guys" camp
I would find it fortunate and valuable if at least certain human activites stayed out of political culture wars entirely. If, instead of "my side, your side", there simply wasn't any need to think of a side for a moment.
I already deleted my FB and TW account to get rid of incessant political flamewars and I feel aghast that they are now following me to Python release notes of all places.
"If they said something else wouldn't you feel different?"
A key insight is that the poem doesn't contain an abortion-related proclamation that you don't agree with.
Or Terry Davis of Losethos/TempleOS fame https://streamable.com/ty65k
And you know what? Most people are kinda chill about that.
Perhaps there's a reason the anti-abortion guy isn't releasing Python.
But I upvoted your comment because I don't think there's a reason for people to downvote your comment.
It's absolutely acceptable that someone dislikes the poem and wants to express it here.
People confuse the purpose of "downvote". It's not for disagreement. Downvoting buries a comment. We shouldn't bury something just because we disagree with it. That's against one of the most basic human freedom value. If it's just a disagreement, reply to it expressing your view.
Users should vote and comment when they run across something they personally find interesting
Also: Please don't comment about the voting on comments. It never does any good, and it makes boring reading.
Well... sorry then :-)And final:
Please don't use Hacker News for political or ideological battle. That tramples curiosity.I do feel like it can help to break the herd mentality thing of "if it's already downvoted, downvote it more" by making people think about why they've done it
Also like others have said, upvotes are not for agreeing. They are for rewarding higher quality discussion, on topic discussion, etc.
I wouldn't upvote if people were not unfairly downvoting.
This person has the right to express here and to have their expression viewed by others.
If too many people downvote, they're denied this right.
My comment starts with a disagreement, actually.
I said I upvoted because I think it's a fair expression that does not deserve to be buried. Downvotes can bury someone else's comment.
The reversibility trick is kind of cute - but can anyone write a legitimate Python code statement that also works in reverse? I sort of doubt it, the function declaration has to come first.
Needless and pointless on release notes page of a programming language.
Secondly, why does adding this section affect that even if you think that?
Even Python is no longer the same language that I learned almost 20 years ago, but I'm happy of what its current stewards have made of it.
That’s what I adore about truly open source projects such as Python, but also Linux or Rust, for example. They’re not polished products of faceless corporations. They have rough edges, as everything does, and that’s okay.
And time and again some human spirit shines through, like it does here. A welcome reminder we’re all in this together, and that next quarter’s shareholder revenue is genuinely meaningless in the bigger picture.
Most corporation products are absolutely horrible comparing to Python, the polished ones you know of are few exceptions. I've seen a few internal programming languages and anything publicly known is ... at least usable.
It's better to stick to programming. Leave politics to politicians.
f"This is the playlist: {", ".join([
'Take me back to Eden', # My, my, those eyes like fire
'Alkaline', # Not acid nor alkaline
'Ascensionism' # Take to the broken skies at last
])}" "This is the playlist: " + ", ".join([
'Take me back to Eden', # My, my, those eyes like fire
'Alkaline', # Not acid nor alkaline
'Ascensionism' # Take to the broken skies at last
])
Which is easier to read and exactly as long.(In fact, without 3.12-compatible syntax highlighting, my first intuition upon reading the first line would be to suspect the code of having a typo.)
"This is the playlist: " + ", ".join([
"Take me back to Eden", # My, my, those eyes like fire
"Alkaline", # Not acid nor alkaline
"Ascensionism", # Take to the broken skies at last
])"
edit: jinx>>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}"
'2'
Is anyone aware of the change to the interpreter that allows for this?
s = `something ${cond ? `(${v})` : ''} something` $ node
> `${`${`${1+1}`}`}`
'2' > `${`${`${`${`${1 + 1}`}`}`}`}`
'2'
It was simply a limitation with the Python parser.Heck, it even works in Vimscript
:echo $'{$'{$'{1 + 1}'}'}'
2 "Hello, it's #{"#{Time.now}"}"
=> "Hello, it's 2023-10-02 09:41:40 -0400"> puts “h#{”#{i}”}”
You “just” have to make your parser understand how to have all expressions or whatever inside braces. No idea how the python parser works but think about how you can nest json arbitrarily.
Why answer your question when I could just brag about how my personal favorite language has supported this for awhile?
/s
> When f-strings were originally introduced in PEP 498, the specification was provided without providing a formal grammar for f-strings. Additionally, the specification contains several restrictions that are imposed so the parsing of f-strings could be implemented into CPython without modifying the existing lexer. [...]
> The other issue that f-strings have is that the current implementation in CPython relies on tokenising f-strings as STRING tokens and a post processing of these tokens. This has the following problems: [...]
At https://peps.python.org/pep-0701/#rationale
> By building on top of the new Python PEG Parser (PEP 617), this PEP proposes to redefine “f-strings”, especially emphasizing the clear separation of the string component and the expression (or replacement, {...}) component.
Wonder if it could be used to add lazy evaluation to other libraries, like numpy?
asdf install python 3.12.0
[1]: https://justinmayer.com/posts/homebrew-python-is-not-for-you...Python will probably never have a built-in type checker beyond Python's existing strong typing at runtime.
We are on the track to remove GIL!
For your usecase, eventually that ProcessPoolExecutor.map will be GillFreeThreadPoolExecutor.map and all the cross process serialization shenanigans will go away.
There is support in the newest pickle protocol for using a shared buffer to transfer data more efficiently, but that would work in multiprocessing [0] just as well as in subinterpreters (and currently isn't implemented in either one).
Queues, immutable records, atomic refcounts, a global object heap for shared items. There are lots of way forward here that don't involve a full SERDES round trip.
> is already solved
Has been for decades outside python
The features of Per-Interpreter GIL are - for now - only available using C-API, so there's no direct interface for Python developers. Such interface is expected to come with PEP 554, which - if accepted - is supposed to land in Python 3.13, until then we will have to hack our way to the sub-interpreter implementation.
I wonder if the original 500% improvement they targeted at the start of the `faster cpython` project is still a realistic target.
- Inlined list and set comprehensions.
- Reduced data copying in asyncio.
However, the recent no-GIL decision I think has sent a few things back to the drawing board to see what can and cannot be salvaged from their progress and plans so far.
Kind of a crazy project but the "just go ahead and import any Python module and we'll embed the VM in your binary" approach is interesting, at least.
More info: https://justinmayer.com/posts/homebrew-python-is-not-for-you...
https://github.com/Homebrew/homebrew-core/blob/c1321e2629203...
A comment in Homebrew's formula says that Homebrew adds the --enable-optimizations flag during compilation because Homebrew has separate binaries whereas the official Python release doesn't add this flag because "they want one build that will work across many macOS releases"
https://github.com/Homebrew/homebrew-core/blob/c1321e2629203...
and it looks to me that pyenv just installs the official binary
https://github.com/pyenv/pyenv/blob/28e7000b485bff61235d8a69...
So I would expect it to be the other way around, Homebrew's Python should be faster.
def foobar(things: list[tuple[int, Floob | None]]) -> dict[int, int]):
Possible since 3.11 I think, maybe even 3.10.
sweet
2/ python is type safe, actually
3/ if you need python for leetcode you can’t really look down on anyone
2. Right, at run time. My great-grandma always did say "the best time to catch bugs is in production, use Python sonny".
3. It's not that I need it, it's just that I can't think of any other use for it. Hopefully big data and IoT catches on to the first two points soon enough.
I recently started using Python again for a side project, and I had forgotten how good of a dev experience Python offers. I wish I could explain better than that though.
Part B of that course is about weakly typed languages like Ruby. Your comment is motivating me to go and finish Part B, because I wish I could articulate better what exactly it is that makes weakly typed languages useful in their own right.
Not only is there the type safety issue, the standard testing and ORM libraries are way behind with .NET and Java have. Even Node seems better.