#internals-and-peps
1 messages Β· Page 156 of 1
it's been suggested that object should do this by default, maybe on python-ideas? but it seems like a lot of complexity for minimal gain. you'd be better off with something like typescript-for-python
does seem like it would slow creation of objects quite a bit if included
I also saw someone suggest that objects should have writeable attributes, and that was immediately shot down because it would give that behavior to all objects, including immutable ones.
i think inheriting ABC and using @abstractmethod is already very readable and pythonic enough
discord really wants to ping someone
I think the main problem about your question is the lack of definition of "what constitutes good language design?" i would propose to step even further outside the box here
because fundamentally, this is a psychological question. you could tackle the problem with stackoverflow surveys
about how happy professional developers are using their language to solve their problems
or maybe even suggest experiments that measure frustration while reading code
like putting people in computer tomographs while trying to make sense of code
i would expect that languages with lots of visual noise will put a heavier mental burden than those with less
coming from sourcery, which does quantify code quality (hint, hint!)
i also would expect that there is an optimal spot between "code is too dense" (one-liners with lots of special syntax) and "code is too sparse" (with lots of variables you need to keep in mind)
and languages that try to push towards that balance are better (in terms of mental burden) than those that promote either extreme
there's another axis you need to keep in mind which requires balance, which is complexity of syntax, amount of keywords but also (which in case of python is mostly seen in a positive way, but..) external packages you need to be aware
if (complexy := amount of syntax + keywords + packages) is too low, the code gets very verbose, which is detrimental in solving a given problem quickly. but on the other hand, if complexity is too high (which is good for quickly solving any given problem!) it will take longer to learn the language
DSLs can be an answer on the language level to this problem, but only to increase the complexity at the meta-level (you have to know many DSLs to effectively solve different problems)
python basically tries to strike a balance here, as well, by making it possible via protocols to build DSL-like code that isn't too different from the core language
some purists would call that heresy and syntax-abuse, but..
practicality beats purity π
yall really having full on debates.. such discordian activity
sure
So I'd like to apologize for loosing my shit yesterday
I had spent the entire morning trying to argue my position and was met with a stiff wall of resistance by many people
As such, I was trying to discuss my own perspective, and was having to contend with three of four people at a time, all of whom were smarter and more experience than I and who I respect, arguing against me quite thoroughly
And, since I havn't yet done the research, I'm not yet armed with the data to be able to make an effective case
rust is an example of language with much visual noise, I know it's a tradeoff they choose
I felt like an unfair fight, is all. So, well, I'm a bit embarrassed about losing my shit
what shit lol
I got salty and stormed off my like a pouting toddler, yesterday, after receiving a healthy intellectual throttling by many of the members here
so you argument was languages should have good syntax
I think you're still misinterpreting. no one was trying to shoot your idea down, we were trying to get you to refine your idea into something more tangible
i.e., what does "good syntax" mean?
I think python does this job of making computers language close to natural language very good
on the other hand, what about non-english speakers that don't get this benefit, or are maybe even hindered by it
I myself am not english speaker
I think non english speakers can handle it well once they learn the syntax, it might be harder for orientals
when using languages who have keywords in my mother language I feel it strange lol
a step further from what python does would make it close to SQL
I think it woud be much verbose
python being a tool can't be "slow" for people that mastered it
Restated, my feelings are as such. It goes without saying that every language will be different, must cater to the subject matter, and that agreement upon what is "good" and what is "bad" will never b e total. However, as we learned with graphic design applied to document setup β web design and other graphic design β there exists a science of effective communication without words. With the application of science, experience, and more effective tools, it should be possible to develop a set of standardized principals which, applied to programming languages, should yield languages which are ubiquitously easier to learn to use.
And, in the face of this notion, I feel the arguments against moving towards "better" (more carefully crafted???) languages fall flat
there will be always a cost to master tools, it's the programmers job
Spoken like someone without a learning disability
that's a non argument
hm two different things
I'm sure the person with dislexia appreciates the sentiment that "they just need to work harder"
When you look at any given classroom, the odds are quite good its going to contain a number of people with dislexia, ADHD, autism, mood disorders, young children, other people who need care, or else other health problems that get in the way of learning
So, yes, any skill requires work
But when the master of that skill state unequivocally that "you've just got to do the work," well
these people benefits better of specialized teachers, no?
I am unconvinced. We can build programming languages that capitalize on a set of rules which make them easier to learn
each disability may require special methods, how can python embed them all?
I don't think anyone disagrees on this general sentiment. the problem is finding the set of rules
I think this job of making learning easier is up to the community, look how great is this discord
best discord server of programming languages
consider that programming languages have to balance objectives other than how easy they are to learn
you might be interested to read about some of the programming languages that are specifically designed for teaching, such as Pyret
Additionally, they must contend with being computer languages. If we could just talk to the computer we wouldn't need them
imo, one of the most common mistakes, probably because python is so english-like, is the or-gotcha
My feeling is this: I am convinced that some antiquated languages β some mathematical notations, and some programming languages β are inherently difficult to learn and use. These languages need to be improved, or replaced.
Is there really a "science" of graphic design for UIs? Honestly asking. Can you provide links to peer-reviewed works showing certain ways of displaying information are more easily understood by certain groups of people? I've seen some legit scientific work in the field ofΒ font design to make fonts that are easier to read for people w/ dyslexia, but that's a dramatically more limited scope than what we're discussing here.
And I'm putting my money where my mouth is on this. My next project, after this damn graphics library which is almost fucking done (I just need a summer off to put all the parts together) is to learn the fuck out of language design and build my own
I'll see if I can track some down. I'm pretty confident though that if they teach classes on graphic design then there must be hard science backing it up
I took a few graphics design courses and the material was solid
I wouldn't be so sure lol
you need to consider that 1) programming languages are tools and 2) they have a purpose
Most graphic design principals these days are backed up by "user tests" β not sure if you'd count that as data
i think that's a valid argument.
we've been teaching psychology in universities since Freud, and w/ modern statistical analysis we know like 95% of that scientific labor was misleading at best and actively bullshit a worst
but i think we are lacking much of necessary research in that area
Graphic design is not philosophy XD
Agreed. The idea of UX has only been around a little while
not just UX
And I can attest that programmers, when you suggest making improvements to their languages, get a bit rigid
psychology, not philosophy
Sorry π
np
I think this science field is called "Human-Computer Interface" and has many researches on it, it's part of computer science curriculum
maybe that IS a key in success of python afterall - that using more keyWORDS is better readable than single character symbols, lowering the barrier of entry
i am speculating though
i am not aware of any research in that area, i think that aspect has been neglected for a long time
I was looking for proofs for the derivative of e^x. Almost all of them were walls of undecipherable notation which I didn't even know where to begin to start trying to understand. And in my soul I felt a bubble of rage β since not a damn character was placed in a way that was meant for ease of understanding
It just got market name of "UX"
It was designed for elegance
well, maths only fairly recently has become the universal language we know and love, before it was all over the place
And elegance is great β if you already speak the language like a master
I'm not sure that's exactly the whole story tho - elegance - mathematical notation is ultimately about one thing: utter precision
the proofs aren't written for someone without the requisite math knowledge
probably we are going offtopic
Just wanting to share the direction I'm coming from
i think your point on language design is much more important, even to masters
Thanks π
masters also can also be dyslexic
all other concerns in how to communicate maths are subordinate to precision. because without that, there is no effective way of communicating mathematics
if avoiding magic symbols helps even masters in reading and understanding code, it's a win for all
The same way all other concerns in programming languages are subordinate to it actually working
but you need to dig into the research in the area before jumping to conclusions
But it's the 1st century. Before we know it, it'll be the 22nd century. On a long enough timeline, the arguments "it isn't so hard", "you just have to do the work", "its too hard to change" and "we couldn't agree on a better way" fall flat
I'd rather do the science now, develop the vocabulary to define "better" languages now, and build them now
well, do the science now and define what is good language design, we're waiting π
in scientific field "make easy to learn" in itself is not a well defined problem
π
you need to define "easy to learn" for which person? need to enumerate all their characteristics
otherwise you can't show a proof your method works
I can think of way to demonstrate the principal
Though, only as a demonstration
Here's some math, can you tell me what it means:
%*#+8
now you're just making up random stuff π
stop π
come back when you found some interesting papers on the subject we can further discuss π
yes, everyone can look at contrived bad examples and agree, but with more complicated actual languages, it gets much murkier
This conversation has been quite good for me actually
The idea of building my own language popped into my head a while back and took root
And since then, and since learning C++ in school this year, I've been realizing just how fascinated I am with languages (much more than the actual practice of them)
But this conversation has really driven home to me just how little science there is the field
well you need to differ lack of search from little science, you know how and where to search?
Do you have any suggestions?
also you know IEEE and ACM for example?
well, there have been many different attempts at coming up with languages that are easy to learn, write and read, so you don't have to come up with your own language. the problem is not the lack of languages but the lack of psychological experiments
I'll check them out
NCBI
also has psychological papers
whatever YOU come up with would also have to be subjected to actual experimental research to confirm or reject your hypothesis and not just confirm your own bias
(and everyone has bias)
I'm down for science impartial science
let it crack
Well, I think finishing my 1st year end of term infotech presentation take precedence
well, you could use your presentation to suggest actual experiments on how to quantify quality of languages
that would be a presentation i'd like to see, myself
I had originally been intending present an argument against antiquated notation. But like a good scientist I have to admit, I don't think I really have a leg to stand on
I'll give that some thought 
that's good start, you need that to be able to proof your method works
and that it's reproducible, etc
I mean, if I had the money and doctorate in hand
I want to start with a study of how well students learn the various mainstream the languages
Given an adequately randomized sample population for each language I'd have everyone sent "1 term" learning the language and then examine their grades
well, you need to realize you're also presenting this to at least one professor who might take your idea and turn it into an actual project
if you want to keep chatting about this go to some offtopic, we are flooding this room
Sure, yeah
go there and ping people here that might want to follow this chat
One last thing: https://www.youtube.com/watch?v=P2yr-3F6PQo
This is the keynote Uncle Bob gave remotely at ACCU 2011.
To see more about Clean Coders: https://cleancoders.com/
Over the last 50 years we've seen a lot of computer languages, from procedural languages, to structured languages, to OO languages, stack languages, logic languages, and even graphical languages, and languages based on the game o...
Uncle Bob gave an interesting talk that is tangentially related to our discussion
He's a funny guy, and I enjoyed the talk. Just thought you all might, also
Single quotes vs double quotes?
My two cents: I prefer double quotes. ' is more common in English sentences than ", most notably with contractions such as 's, n't, 've. So if the default is single quotes, you have to stray away from it quite often.
The only convincing argument I've heard is that it doesn't require Shift. But in my experience, it hardly makes a difference in speed (certainly minimal difference in the bigger picture)
huh, I wonder how many programs will break if repr on strings will use double quotes instead of single quotes
Double quotes for me, it's more ubiquitous that it denotes a string and the same reasons as you said
other languages(speaking not coding) make using single quotes a little harder than in english.
Not only because of the keyboard layout, but also the language as a whole only uses double quotes.
So hitting shift-2 (double quotes) is way more in your muscle memory than hitting either Right shift + # (single quotes) or using both hands to it Shift + # . On my German Keyboard both double and single quotes require the shift key.
That is why I mostly use double quotes, but I actually find it really awesome that python accepts both. It does not feel catered to a specific real world language.
And is there a big problem that limiting to one of those would solve?
When I read code I do not even notice if double or single quotes are used or it changes from string to string, both are this is a string indicator-symbols for me and I couldn't even remember what was used after finishing reading. (Most likely also because growing up with german, but getting exposed and having to understand all the english/USA special things because of the internet)
the only reason to use single quotes is that it's easier to type on ansi keyboards
ansi?
i should have qualified specifically ANSI-US keyboards
because i've seen some weird hybrids (although mostly on people's custom builds)
it's wtf is up with the keys near the enter key
that's the tilde right beside the enter key in the ISO keyboard
Why don't they give list a .discard like sets have
I know the complexity is not the same but lists have .remove anyway 
What would a use case for it be?
Just a convenient way to remove stuff from a list w/o having to check in first or try/excepting π€·
I'm struggling to imagine a time when you'd want that. Though I don't really think .remove() is useful either.
You can always just use contexlib.suppress() for the exception handling, FWIW
:o
!e I didn't know that was a thing ```py
import contextlib
L = [1, 2, 3]
with contextlib.suppress(ValueError):
L.remove(9)
print('A', L)
print('B', L)
@unkempt rock :white_check_mark: Your eval job has completed with return code 0.
B [1, 2, 3]
i don't think i've ever needed to use list.remove either π€
That's how our ENTER key looks like!
I have single quotes right next to the ENTER key so it's super easy to type q single quote, although it's probably faster to type double quotes (uses both hands where they're normally placed)
in the world there are those who use the RIGHT keyboard and the WRONG keyboard
wait, since when are discussions about keyboards related to python internals 
The accessibility of single and double quotes on different layouts has direct connection to python's syntax and it's convenience
then i say dvorak.
Could someone explain something for me? I've heard that Cython (and also Cpython) could easily interact with C code. But I was thinking since compiled C code is just machine code what exactly does that mean? Does the C spec force implementations to structure data/ method calling in a certain way?
__
Also that got me thinking about interpreted vs compiled. If you were to have a python compiler that spit out Cpython runtime and the normal data that is kind of like a compiler. Seeing as data can be hard coded in machine code.
But I was thinking since compiled C code is just machine code what exactly does that mean
Technically, C can compile to machine code. It's not machine code in and of itself.
a python compiler that spit out Cpython runtime
How do you mean? CPython is an interpreter. Packaging that into an executable along with the code is something tools like pyinstaller do already.
Does the C spec force implementations to structure data/ method calling in a certain way?
I'm pretty sure the C standard defines no standard ABI, if that's what you mean. I think it's platform specific?
If you were to have a python compiler
If you mean an AOT compiler that spits out machine code, it's probably possible. But it's possible that it might be limited, because Python is very very dynamic. You can fuck with everything at runtime, which might not be amenable to an executable form. I might be wrong about this, though.
i had no damn idea what the heck he just asked
I still don't really understand. If you could try to explain a bit more @wind crypt, that'd be great.
everything conflicts with what i know about CPython
Cython is basically a superset of Python that also has some C features in it, so you could technically consider it easy interaction with C code
CPython can not easily interact with C code
then you straight up just diverged from the topic and asked "Since compiled C code is just machine code what exactly does that mean?"
Also that got me thinking about interpreted vs compiled. If you were to have a python compiler that spit out Cpython runtime and the normal data that is kind of like a compiler. Seeing as data can be hard coded in machine code.
also this makes no sense to me
I often hear that because Cpython is written in C it is easy to delegate stuff to C, like how numpy works.
what
You can interop with C, yes, but that's not because CPython is written in C.
The FFI is a whole different matter.
Well then i was misinformed.
not python, but for example, Rust can interop with C, but it's not written in C
i have lost a ton of brain cells just reading that sentence
So think about the definition of an interpreted language, it has a runtime (lets say in machine code) that runs the partialy compiled bytecode as data.
Now say instead of having the compiler for this interpreted language just output the bytecode have it output the whole interpreter and include the bytecode as data in the machine code, just like how you can have a number in machine code. So now the output is 100% machine code. But it still doesn't feel like a compiled language you know.
^ I might rewrite this as I had sentinces go on to long.
If you want
π€ what's unreasonable here?
actually i think i just got confused there
So think about the definition of an interpreted language, it has a runtime (lets say in machine code) that runs the partialy compiled bytecode as data.
Do note that runtimes are in AOT compiled languages too.
A garbage collector is part of a runtime, for example.
output the whole interpreter and include ... in the machine code,
I mean, sure? That's just stupid design for a compiler, though. In that case, just write an interpreter. Either that, or compile to machine code.
I'm not proposing anyone do this. I'm just thinking about the definition of interpreted and compiled.
Also https://docs.python.org/3/extending/extending.html, it says that it is easy to extend Python with C. I'm guessing this might have something to do with CPython being written in C.
interpreted - written to evaluate lines one by one
compiled - lines in bytecode often intermixed
The first part of the sentence is correct. The last part, no. You can make calls to binaries (executables) in any decent language.
although it is especially easy, because it's written in C
it's easy because you either use Cython to do it or write C extensions
but i personally hate having to write all the stuff needed to make a C extension work properly
CPython has a public, C-callable API, in the form of the Python.h header. This makes it easier to extend with C than most other languages since your C code can just #include <Python.h> to get access to the public interface of the interpreter in order to interact with it.
other languages can generally call C APIs, so you can also extend CPython with (for instance) Rust, but in that case you need to re-declare those public functions yourself before you can use them
Thanks.
point is, you're half right - the fact that CPython is written in C does make it a bit easier to extend with C (or C++) than with most other languages, because the CPython devs have done some of the work for you
and because the interpreter's public interface follows C idioms.
and this was quite unnecessarily rude.
you know our rules better than this
hello don't know if this is the right channel
but is anyone familiar with gspread/pygsheets?
is there an alternative library for microsoft onedrive excel?
based on your subsequent comment, I figure what you mean here is that you personally found the sentence confusing. Usually, one says that something makes them "lose brain cells" if they're appalled by how poorly conceived it is (ie they think it's stupid).
Since new neurons hardly ever form when your an adult he is probably literally right.
π
rust is written in rust xd
not really relevant to programming but the question of neurogenesis in adults is still an open scientific question. It does happen, but there's AFAIK not much consensus on how much, where in the brain, or what it means. But I'm not a neurology doctor so I can't say much more than that of value on the question. https://scholar.google.com/scholar?hl=en&as_sdt=0%2C22&q=neurogenesis+in+adults&btnG=&oq=neurogenesis+in+ad
Isn't that pretty much what tools like pyinstaller do? They package the interpreter in the executable
Maybe a Union? You can also ask in #type-hinting, this channel is primarily for discussion of python internals and the like
ah forgot that, will move there
I don't want to hardcode all possible returns in base class
That's what I said.
But if you're making it specifically to be a new compiler, that's not great design.
Fair enough
for x1 in range(1,10):
for x2 in range(1,10):
for x3 in range(1,10):
for x4 in range(1,10):
for x5 in range(1,10):
for x6 in range(1,10):
Is there a better way of doing this
A pythonic one
not as i know of
for (x1, x2, x3, x4, x5, x6) in itertools.product(range(1, 10), repeat=6):
ok yeah
what's the best way to manage different python installations on windows?
this is internals right π
@sonic flax this is a discussion channel, but look into the py command.
"py command windows"
your question is not even remotely related to internals
we're talking about python features and the internal python implementation API here
not installation-related stuff
may have been the stretch of all stretches
!e ```py
del open
import builtins
builtins.open("file", "w")
@white nexus :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | NameError: name 'open' is not defined
!e ```py
del open
import('io').open('file', 'w')
@rose schooner :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | NameError: name 'open' is not defined
Lib/io.py lines 54 to 57
from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation,
open, open_code, FileIO, BytesIO, StringIO, BufferedReader,
BufferedWriter, BufferedRWPair, BufferedRandom,
IncrementalNewlineDecoder, text_encoding, TextIOWrapper)```
Is there any way of finding out what is being considered for inclusion in future PEPs? Specifically, I wanted to know if there's any chance of Zstandard/zstd (https://facebook.github.io/zstd/) being included in Python standard library.
@upper karma If something is a PEP, that doesn't mean it will definitely be part of Python. PEPs are merely suggestions that can be accepted or rejected.
In principle anyone can write a PEP (although I never attempted it), I think you might need a "sponsor" (a core developer who will vouch for your proposal) though.
But if you just want to see PEPs that are open (not yet accepted or rejected), there's a section in PEP 0: https://www.python.org/dev/peps/pep-0000/#open-peps-under-consideration
Thanks, @quick snow . I wasn't aware of PEP 0
I don't have the technical knowledge or the community involvement to create a PEP, but I was interested in knowing whether there was any interest in pushing Zstandard to the standard library
@upper karma fwiw, it's been discussed before, on python-ideas: https://mail.python.org/archives/list/python-ideas@python.org/thread/VQIFA7WTNRAOYZGTVP4WZC2CD36KYIVY/#DJ4A5G432PLUE5UNXJ6GSVVL6HB7FFJ7
@sonic flax @boreal umbra they call it the "py launcher" in the docs
docstrings can't have escaped hex chars like \0? I am trying to change source code of some python modules but when writting docstrings back to the file these hex chars are not escaped.
they are written as null bytes
!e
def foo():
"""Bar\0
Baz"""
print(foo.__doc__)
@tacit hawk :white_check_mark: Your eval job has completed with return code 0.
001 | BarοΏ½
002 | Baz
!e
def foo():
r"""Bar\0
Baz"""
print(foo.__doc__)
@tacit hawk :white_check_mark: Your eval job has completed with return code 0.
001 | Bar\0
002 | Baz
so raw docstrings preserve text escapes
It's print that's losing them, not the docstring.
!e ```py
def foo():
"""Bar\0
Baz"""
print(repr(foo.doc))
@raven ridge :white_check_mark: Your eval job has completed with return code 0.
'Bar\x00\n Baz'
here print preserved new lines
the docstring contains a \0 character. Which probably isn't what you want, but - docstrings are exactly like normal strings. A \0 in a docstring is translated to a U+0000 character, just like it would be in any other string.
here the repr() escaped everything
ok, I was trying to generate python code from some specifications and had trouble on this, I will generate as raw docstrings in these cases
Alternatively you could escape the backslash
But raw docstrings do sound like a significantly simpler solution
i think i'm remembering some experimental implementation using the ast or somesuch to get multiline lambdas, has there been any development on that front?
i'm fiddling with brython and multine (or rather multistatement) lambdas would be a boon
i have seen this in some codebases where they use raw docstrings by default
i think asyncpg does it
admittedly im not quite sure what the benefit is
I'm assuming the benefit is not having to screen \ all the time, which is pretty reasonable considering docstrings are for humans moreso than they are for machines and allow you to insert actual newlines and quotes instead of screened variants, which, I imagine, are the most common screened characters. If you have a lot of examples that involve hex values (\x escapes most notably) or similar sequences, which sounds plausible for a package that closely interacts with postgres, having docstrings also be raw literals sounds more than sane
!e import __hello__
@white nexus :white_check_mark: Your eval job has completed with return code 0.
Hello world!
because that's decoded as part of the string, you would need to double-backslash, I think?
multiple statements ?
that would be a big change. seems like you would need some special syntax to indicate the lambda continues past the end of the "expression" (afaik now it only allows one expression)
yes, in the source code that's not a null byte but when python reads the docstring it turns into a null byte. I was expecting them to have same behavior as normal comments, but they are readed as normal strings.
you want to show like as it would appear in source code, but in the docstring?
like a comment but as a docstring, for that I just need to create raw docstrings if escape sequences are present
when the posters above said "raw docstrings" I assumed they meant r"""...""" , but you mean completely uninterpreted, right?
like more of a comment than a string
doesn't seem like it belongs in this channel
you can ask in any of the off-topic channels
I am sure they just wanted to talk about pep 428, it was just their conversation starter ;P
ok
In [26]: class A:
...: def __len__(self):
...: print("called")
...: return 4
...: def __iter__(self):
...: return iter([1, 2, 3, 4])
...:
In [27]: list(A())
called
called
Out[27]: [1, 2, 3, 4]
why is __len__ called twice?
Good question, it seems to be called again after iter, but its correctness doesn't seem to matter much 
yeah, it can be both above and below the actual value. I know one call is for preallocation, but I'm not sure what the second is, gotta check the C source
huh, so list() internally maybe calls __len__() before calling __iter__()?
yeah, that one im aware of
it uses that for the allocation
im not sure what the second call (after __iter__) is
wait what
In [32]: class A:
...: def __length_hint__(self):
...: print("called length hint")
...: return 4
...: def __iter__(self):
...: print("called iter")
...: return iter([1, 2, 3, 4])
...: list(A())
called iter
called length hint
Out[32]: [1, 2, 3, 4]
with length hint its just called once, and after iter π€
list___init___impl(PyListObject *self, PyObject *iterable)
/*[clinic end generated code: output=0f3c21379d01de48 input=b3f3fe7206af8f6b]*/
{
/* Verify list invariants established by PyType_GenericAlloc() */
assert(0 <= Py_SIZE(self));
assert(Py_SIZE(self) <= self->allocated || self->allocated == -1);
assert(self->ob_item != NULL ||
self->allocated == 0 || self->allocated == -1);
/* Empty previous contents */
if (self->ob_item != NULL) {
(void)_list_clear(self);
}
if (iterable != NULL) {
if (_PyObject_HasLen(iterable)) {
Py_ssize_t iter_len = PyObject_Size(iterable);
bottom line is the first use of __len__
Objects/listobject.c line 919
n = PyObject_LengthHint(iterable, 8);```
Objects/listobject.c line 913
it = PyObject_GetIter(iterable);```
before that is use of __iter__, still in list_extend
so it would be like called len called iter called len if __len__ and __iter__ is defined
called iter
called length hint
``` if `__iter__` and `__length_hint__` is defined but not `__len__`
>>> class A:
... def __len__(self):
... print("called len")
... return 4
... def __iter__(self):
... print("called iter")
... return iter([1, 2, 3, 4])
...
>>> list(A())
called len
called iter
called len
[1, 2, 3, 4]
>>> class A:
... def __length_hint__(self):
... print("called length hint")
... return 4
... def __iter__(self):
... print("called iter")
... return iter([1, 2, 3, 4])
...
>>> list(A())
called iter
called length hint
[1, 2, 3, 4]
yep
just as predicted
so call stack, ignoring any other call, is ```py
list() -> [C API]: list_vectorcall -> list___init___impl -> list_extend
| | v
| v len or length_hint by PyObject_LengthHint
v iter by PyObject_GetIter
len by PyObject_GetSize
significant amounts of confusion
so __init__ calls __len__ if defined, but not __length_hint__
then it calls extend, which in turn calls __iter__ and __len__/__length_hint__
why does __init__ need to call __len__
__init__ tries to preallocate exactly the necessary amount of space, based on len(), if the object has len().
extend tries to reserve enough extra space to avoid unnecessary reallocations, based on len() if it's defined or __length_hint__ if it's not.
So, that's why they're doing it. That said, it does look unnecessary - __init__ doesn't need to check len() right before calling extend() since extend() checks len() as well.
so i was messing with the fishhook lib and try to override the object class which is the meta of all classes
but only by explicitly inheriting object did the overridden dunder get called π
In [4]: from fishhook import hook
In [5]: @hook(object)
...: def __str__(self):
...: return "test"
...:
In [6]: class foo:
...: ...
...:
In [7]: print(foo())
<__main__.foo object at 0x0000027A6AB6BC10>
In [8]: class foo(object):
...: ...
...:
...:
In [9]: print(foo())
test
Ah - there's a good reason for this, actually, @native flame @rose schooner - https://github.com/python/cpython/commit/372d705d958964289d762953d0a61622755f5386 explains it in its commit message.
Basically: __init__ tries to get the initial size based on the number of elements in the initializer. It will resize the internal dynamic array to exactly enough space to hold that new size.
extend tries to find the new size based on the initial size plus the number of elements being added. If there isn't enough space to accommodate the new size already, it will resize to at least that new size, but it can overallocate.
So having __init__ grow the array before calling extend is an optimization - in exchange for an extra call to len(), it saves some (apparently substantial) amount of memory.
why does __init__ need to resize/allocate at all? why not leave it all to extend
that's what used to happen, before the linked commit. It was worse because it used more space.
hmm
they could have made the first extend onto a list with 0 capacity allocate the exact amount of space, instead - it would have been an alternative approach that would have saved the extra call to len()
I've proposed changing to do that in https://bugs.python.org/issue39829 - let's see if any core dev bites π
https://github.com/python/cpython/compare/main...thatbirdguythatuknownot:patch-17
so is this what you wanted to do?
you're missing a brace on 897
oh yeah
you could also just make that into an else if, instead of adding an else block
otherwise, yeah, that's what I was picturing
ok
I came up with https://paste.pythondiscord.com/xilubewizu.patch
Didn't try compiling it though π
yeah um i'm getting this ```py
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'
The second one needs to be
if (n && self->ob_item == NULL)
since n can be 0 there and list_preallocate_exact has an assert that the size is positive
oh ok
I don't think that's related to your codecs failure, just something I noticed while double checking myself
Without the change, a debug build should fail on
l = []
l.extend({})
Or just list({})
ok what am i supposed to do here though
No idea. Have you compiled Python from source before? That problem seems likely to be unrelated to your changes. Try a git stash and build from clean sources to check
i don't use git
also i've compiled python from source before
i never usually have this error
Could be there's a problem with the approach, then. I'd start by reverting the changes and seeing if it reproduces
:incoming_envelope: :ok_hand: applied mute to @unkempt rock until <t:1646725668:f> (9 minutes and 59 seconds) (reason: burst rule: sent 8 messages in 10s).
so it's like because of the ob_item == NULL check then list_preallocate_exact
took the burst rule but not the banned words rule
it was a problem with the approach
turns out we only needed to add the check in the second list_resize
According to the language reference, am I correct in thinking that the id() of an object must be any (unique) integer, but does not have to be the memory address?
Every object has an identity, a type and a value. An objectβs identity never changes once it has been created; you may think of it as the objectβs address in memory. The βisβ operator compares the identity of two objects; the id() function returns an integer representing its identity.
https://docs.python.org/3/reference/datamodel.html
I just want to make sure I've understood right
you are correct
Wonderful, thanks
As a CPython implementation detail, it is the memory addresses of the PyObject structure. As far as language guarantees go, it's only required to be a unique integer.
A conforming implementation could just use a counter, where the first call to id() for any given object generates the next value for that counter and caches it on the object, and any future call to id() for the same object returns it.
if ids implementation is implementation specific, then in cases where you rely on the memory address, what would you use instead
you'd never rely on memory addresses
there's loads of internal optimizations which would break code relying on that
Well theoretically what if you did
Ah, fair enough
It would never make sense to fetch the address of a Python object in memory when you're writing portable Python code, because the layout of that object in memory will be different for different interpreters (or even different versions of the same interpreter).
Even if there was a way to portably get the address, there's nothing you could portably do with that address, because you can't portably know what exactly is there.
I see
That's exactly what I was planning to do, thanks
I think there's something in ctypes that lets you get a PyObject*
But yeah, relying on it (id returning the address) is not very wise
PyPy, for example, doesn't return the memory address
Sure, you can, but you can't portably interpret the memory it points to.
Yeah, anything ctypes related is likely not going to be very portable
What was wrong with adding it to the first?
ah - I think I see - we need to call Py_SET_SIZE(self, n); in the case where list_preallocate_exact succeeds, since the alternative is list_resize, and that does set the size
for the second call to list_resize, there was already a call to Py_SET_SIZE afterwards (to throw away the size change made by list_resize), but for the first there wasn't (because in the first case it's a desired side effect).
tested it with all the changes and ```py
list({}): Mean +- std dev: [orig] 119 ns +- 10 ns -> [modif] 173 ns +- 4 ns: 1.45x slower
list({1: 2}): Mean +- std dev: [orig] 132 ns +- 3 ns -> [modif] 122 ns +- 3 ns: 1.08x faster
list({(1,2,3): 4}): Mean +- std dev: [orig] 131 ns +- 8 ns -> [modif] 124 ns +- 9 ns: 1.06x faster
list((3, 3, 4)): Mean +- std dev: [orig] 89.5 ns +- 2.1 ns -> [modif] 82.5 ns +- 3.2 ns: 1.09x faster
list(()): Mean +- std dev: [orig] 73.4 ns +- 3.9 ns -> [modif] 65.8 ns +- 1.8 ns: 1.12x faster
list({0, 1, 2, ...}): Mean +- std dev: [orig] 82.5 us +- 9.8 us -> [modif] 69.8 us +- 3.6 us: 1.18x faster
list({3, 9, 9}): Mean +- std dev: [orig] 136 ns +- 17 ns -> [modif] 123 ns +- 0 ns: 1.10x faster
list(set()): Mean +- std dev: [orig] 115 ns +- 4 ns -> [modif] 175 ns +- 4 ns: 1.52x slower
list([]): Mean +- std dev: [orig] 72.7 ns +- 5.4 ns -> [modif] 66.2 ns +- 1.7 ns: 1.10x faster
list([1,2,1,1]): Mean +- std dev: [orig] 92.5 ns +- 10.0 ns -> [modif] 82.7 ns +- 1.5 ns: 1.12x faster
Benchmark hidden because not significant (2): list((4, 5, 1, ...)), list([4, 1, 3, ...])
Geometric mean: 1.00x slower
weakrefs, you are my friend
this is horribly cursed
i have an object that references itself so when it is no longer useful it deferences itself
and other references to it are weakrefs in a weakvaluesdictionary so it is removed when it deferences itself
i do not like the performance for empty hash tables/maps
please add min and median to timings, those give a more complete picture for timings than just mean and stdev
just mean is very sensitive to extremes
and max timings are worthless since they can be caused by external factors
it's tested using pyperf
dump (may be different from above stats because it was tested multiple times)
oh wait
well, my problem with this kind of comparison is that there is a hard limit to min but not to max. the longer the code runs, the more your system load affects the runs. using the geometric mean is not a bad idea, but i'm not sure if this corrects enough
stats
yeah, i'm looking at it
pyperf looks much better thought out than timeit
finally someone who put some actual thought into performance timing π
if they spit out an html instead of raw text, there could be some actual graphs π
which would be even nicer than just looking at the numbers
or maybe as a jupyter notebook, which gets rendered on github
Interesting
Looks like builtin_function_or_method doesnt implement the descriptor protocol?
#bot-commands message
(the instance is not passed in)
That's correct. Python functions do, C functions don't.
@raven ridge sorry for the ping but do you know why doing list() with empty hash tables/maps are even slower when the changes are made?
Is https://github.com/python/cpython/compare/main...thatbirdguythatuknownot:patch-17 up to date? It's missing the check to ensure that n > 0 before calling list_preallocate_exact on line 936
which would probably explain it; you're probably allocating memory when you don't need to.
oh yeah.
In the end, I wouldn't expect this approach to be noticeably faster than the old approach - though it shouldn't be much slower, either. It should be about break even, just less surprising.
list({}): Mean +- std dev: [orig] 109 ns +- 1 ns -> [modif] 103 ns +- 1 ns: 1.06x faster
list({1: 2}): Mean +- std dev: [orig] 125 ns +- 1 ns -> [modif] 118 ns +- 1 ns: 1.05x faster
list({(1, 2, 3): 4}): Mean +- std dev: [orig] 125 ns +- 1 ns -> [modif] 118 ns +- 1 ns: 1.05x faster
list((3, 3, 4)): Mean +- std dev: [orig] 89.2 ns +- 4.5 ns -> [modif] 82.9 ns +- 4.6 ns: 1.08x faster
list(()): Mean +- std dev: [orig] 70.1 ns +- 0.8 ns -> [modif] 65.5 ns +- 0.8 ns: 1.07x faster
list({0, 1, 2, ...}): Mean +- std dev: [orig] 74.7 us +- 3.6 us -> [modif] 67.6 us +- 1.6 us: 1.11x faster
list({9, 3}): Mean +- std dev: [orig] 131 ns +- 2 ns -> [modif] 126 ns +- 4 ns: 1.04x faster
list(set()): Mean +- std dev: [orig] 115 ns +- 6 ns -> [modif] 110 ns +- 2 ns: 1.05x faster
list([]): Mean +- std dev: [orig] 73.2 ns +- 5.5 ns -> [modif] 67.8 ns +- 3.4 ns: 1.08x faster
list([1, 2, 1, 1]): Mean +- std dev: [orig] 93.5 ns +- 9.8 ns -> [modif] 87.9 ns +- 8.6 ns: 1.06x faster
list([1, 2, 1, 2, 1, 2]): Mean +- std dev: [orig] 93.0 ns +- 3.1 ns -> [modif] 87.0 ns +- 2.7 ns: 1.07x faster
Benchmark hidden because not significant (3): list({0: 0, 1: ...}), list((4, 5, 1, ...)), list([4, 1, 3, ...])
Geometric mean: 1.05x faster
``` `--min-speed 3`
FunctionDef(
name='test',
args=arguments(
posonlyargs=[],
args=[
arg(arg='foo'),
arg(
arg='bar',
annotation=Name(id='int', ctx=Load())),
arg(arg='baz')],
kwonlyargs=[],
kw_defaults=[],
defaults=[
Constant(value=1),
Constant(value=2)]),
body=[
Return(
value=Constant(value=1))],
decorator_list=[])],
i dont get this ._.
how do i check if an argument has default values
like bar to 1 as a key-value thing
do i reverse both defaults and args?
btw im not sure if this is ontopic, if it isnt, give me a ping, i'll delete this (bit flooding)
so like ```py
args: foo bar: int baz
defaults: = 1 = 2
defaults are assigned to the last members of args
thanks
seems like reversing two of them works
:)
because syntax error if it isn't
!e
a = [0, 1, 2, 3]
for a[-1] in a:
print(a[-1], end=',')
@boreal umbra :white_check_mark: Your eval job has completed with return code 0.
0,1,2,2,
!e ```python
a = [0, 1, 2, 3]
for a['not an int'] in a:
print(a[-1], end=',')
@elder blade :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 2, in <module>
003 | TypeError: list indices must be integers or slices, not str
anything that's valid on the lhs of a normal assignment is valid there, afaik
Interesting... So it is validated?!
a.x, a[x] etc
!e ```python
a = [0, 1, 2, 3]
for a[-1] in a:
print(a)
@elder blade :white_check_mark: Your eval job has completed with return code 0.
001 | [0, 1, 2, 0]
002 | [0, 1, 2, 1]
003 | [0, 1, 2, 2]
004 | [0, 1, 2, 2]
btw, what's the reason behind the "identifiers cannot start with a number"?
Avoid ambiguity with numeric literals including scientific notation
Would you want 1e7 to be a variable or a float?
Is 1e a variable or an incomplete literal?
What about 10, it's an identifier technically - numbers are allowed, and it can start with a number too
hm.. the rule could be simply to disallow identifiers that could be mistaken for a number literal, which excludes "1e7" but not "1ea7"
disallowing everything that starts with a number seems a bit brutal
i think it would hurt readability
how so?
This puts additional (albeit not very significant I guess) load on the parser (and I'm not sure how fucky the grammar for that would be), introduce wonkiness (imagine a newcomer that isn't aware of the scientific notation for floats, or complex numbers - is 1j a number or a variable?) and overall enforce a bunch of doubletakes instead of very straightforward rules
Note: it puts load on both Python's parser, and the developer's mental parser
good question, checking..
Forth?
With the rule in place, if you see something start with a number or a quote, you can be certain that it's a literal value and not a variable. It's easy to follow and helps readability when skimming through code (without an IDE), while if you allow identifiers to start with numbers, you need to read the whole thing and make sure that it's a valid numeric literal
Again, if someone isn't aware of 1e3 or 1j, or 1_000_000, for that matter, it's going to be an unpleasant surprise
One thing is knowing that if it starts with a number, it's not an identifier; another is guessing whether it is a literal or an identifier
ok, valid point
i guess one could get around the issue with modern IDEs and proper annotations, coloring etc. but in simple editors that might be an issue, yeah
Besides, having numbers in identifiers is generally discouraged in favor of using more descriptive names (with a few exceptions, such as p1, p2 when referring to two random points; even then, using letters usually helps improve readability, at least I've noticed that personally)
There is an exception to both, matrix arithmetic
i like 2, 4 in long names instead of _to_ and _for_ :p
If you have a 2x2 matrix in the form of local variables (a not-uncommon case), naming them something other than m11, m12, m21, m22 doesn't make as much sense
matrix_element_at_first_row_second_column...
But in general, having numbers in identifiers is not always a mistake, but a reason to reconsider; having identifiers begin with numbers is even worse, imo
I could settle for tl, tr, bl, br
But matrix arithmetic and similar cases usually copy mathematical formulae, and in those situations it's not very desirable to stray away from the way it looked originally
i think notebooks are already capable of that
with numpy it's even better
not for variables, but for display, yeah
yeah, they replace the latex by unicode
Oh, you mean the web interface
but i don't think you can use subscripts
I think you can only use unicode characters that are considered letters (with a few obvious exceptions like underscores and at least decimal numbers)
I'm not certain though
a_1^2 as identifier with 1 subscript and 2 superscript
^ is xor
yeah, would need extra declaration
I imagine the editor wouldn't like that very much
or some kind of preprocessor :/
like [\ a_1^2 \] to denote a latex identifier
if the compiler would just accept it, it could be replaced ad hoc in jupyter notebooks or IDEs in some "presentation" or "read" mode
could be a boon wherever readability really counts
2to3
π
wolfram mathematica allow it π
Anyone know if the function constructor is meant to allow dict subclasses for the global argument?
Because it does, but only calls subclass methods for LOAD_GLOBAL opcode and not the corresponding STORE and DELETE ops
Interesting, what if you pass a mapping that doesn't subclass dict?
!e py class fake_globals(dict): def __getitem__(self, key): print('get', key) return super().__getitem__(key) def __setitem__(self, key, value): print('set', key, value) super().__setitem__(key, value) def __delitem__(self, key): print('del', key) super().__delitem__(key) def foo(): global a a = 1 print(a) del a foo = type(foo)(foo.__code__, fake_globals()) foo()
@pliant tusk :white_check_mark: Your eval job has completed with return code 0.
001 | get print
002 | get a
003 | 1
!e py class fake_globals(): def __getitem__(self, key): print('get', key) return super().__getitem__(key) def __setitem__(self, key, value): print('set', key, value) super().__setitem__(key, value) def __delitem__(self, key): print('del', key) super().__delitem__(key) def foo(): global a a = 1 print(a) del a foo = type(foo)(foo.__code__, fake_globals()) foo() i think it fails in the constructor
@pliant tusk :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 16, in <module>
003 | TypeError: function() argument 'globals' must be dict, not fake_globals
its weird tho, because LOAD_GLOBAL has code specific to non-dict globals that was originally added years ago when support for custom type builtins was added
Python/ceval.c lines 2980 to 2984
/* Slow-path if globals or builtins is not a dict */
/* namespace 1: globals */
name = GETITEM(names, oparg);
v = PyObject_GetItem(GLOBALS(), name);```
def function(event):
document["result"].select()
document.execCommand("copy")
document["clipboard_button"].bind("click", function)
that's one of those situations where multi-expression lambdas would be nice
snippet from a brython script i'm tinkering on
(i know execCommand is deprecated, there's no viable alternative as far as i can see..)
You can use bind(elem, event) as a decorator btw, helped me a lot when working with more or less static elements
ah, pyqt style, yeah
good idea
still, having to name the callback is annoying π¦
As for execCommand, you can use win.navigator.clipboard.writeText("some text"), but that's quite a bit more complicated than execCommand
It also returns a Promise, which is a fun can of worms if you don't have await (and I'm not sure if Brython implements that in a convenient way)
Although in case of button clicks, that shouldn't matter much tbh
ohhh, brython can do that
that's beautiful
document["clipboard_button"].bind("click", lambda event: window.navigator.clipboard.writeText(document["result"].text))
I didn't play with brython's async-await yet (all I know about it is that browser.aio acts as the replacement for asyncio, I'm yet to find out if you can await promises or bind async functions to events
That's horrifying, but also kinda neat
lmao
At least there's no then :)
the lambda is ugly, but the rest makes sense
I mean it makes sense, but the sheer size of this lad, I'm in awe it
xD
Surprisingly, brython handles then pretty nicely
it does? i'm still pretty new to it all
But unfortunately I can't check if it implements neat async-await for promises
brython is a very strange beast
Yeah, I ran win.navigator.clipboard.readText().then(print) as a quick test when I was starting out with brython
Yeah, although it feels really nice fwiw
i'm fiddling with it because i'm dreaming of an interactive error message for justuse, kind of
i want exceptions to be as informative as possible, but that's only possible with lots of info, which sucks in raw text
so i'm jinjaing an html with css and brython so the user gets the full info nicely presented in the browser, alongside with a short summary in terminal
Printing traceback to browser is an interesting idea
What are you using to communicate between the browser and the app?
yeah, but in this case i want to give the user options (multiple hashes according to platforms etc) which is then put into a string which the user can copy&paste into their code to fix things
i'm just writing the html with css and script to the home dir and open it via webbrowser.open(f"file://{home}/web_exception.html")
That's pretty clever, you don't get any overhead from starting a server this way
i only need to write enough info via jinja into the dom from the start, which is a bit tricky
You could also generate a base64 data uri to avoid having to write a file
julia
julia doesnt allow numbers at the beginning of identifiers, it just parses 2x as 2 * x
i thought about that, but that would be a pain to debug
it's easier to inspect the result of the jinja etc. as a file
I wonder if there's a language that allows any sequence of characters as a variable, even whitespace. π€
ah, with backticks, that's quite genius
i wonder how well it works combining variables and strings
okay, nvm, using backticks breaks code highlighting on discord
from base64 import b64encode
def data_uri_from_html(html_string):
return f'data:text/html;base64,{b64encode(html_string.encode()).decode()}'
``` this works
b64encode takes bytes, and produces bytes iirc.
The issue is that you want it to be formatted into a string so it has to be decoded again
ic
https://codepen.io/amogorkon/pen/mdpbwLp - just to give you an idea what i'm using brython for (and why i want multi-expression lambdas π )
instead of a blunt RuntimeWarning
or rather in combination with one
it's not done yet, but you can see the brython code on the bottom of the html
Isn't there a pep out or a discussion about giving docs to variables and attributes through type annotations?
Like all generics will let the last entry of the subscription act as a doc string
some IDEs like vscode already use variable/attribute docstrings
you can just write ```py
foo_factor: int = 3
"number of foos given"
There was something more concrete
Couldn't find anything mentioning that other then the rejected pep 224 π€
Although you can use Annotated to add some form a documentation to attributes
Honestly I think it was on the mailing list some time in past year
hm.. i haven't seen anything related to attribute docstrings other than what i wrote
foo_factor.__doc__ = "hey here's some docstring" π
meh π
>>> def test():
... "hi, docstring here"
...
>>> test.__doc__
'hi, docstring here'
works the same π₯΄
that isn't an attribute/variable docstring
Attribute docstrings are fundamentally different from class/function docstrings, because they're attached to a specific reference, not a specific object.
If you have MAX_X = 100 and MAX_Y = 100 as attributes of a class, you should be able to assign different docstrings to them, even though they're two references to the same object.
o
to implement that is actually impossible
unless you use annotations
That would be the sane way to do it imo
i was thinking of assigning to __doc__
foo_factor: Annotated[int, "number of foos given"] = 3
We already have Annotated, although this isn't really a valid use of it IIRC
Annotated works, but really is not nice to write for this use case
Yeah true
Handling it through a dict like annotations would probably make the most sense
but then you need a new function for accessing it as it won't be just the doc attr
introduce & operator for type which adds annotations, akin to | for union
float & ValueRange(-1, 1)
Tbh I'd unironically like this, as Annotated[T, x] feels clunky to write
int & Doc("Number of foos given")
ts has intersection types like that
yeah, that would be confusing for people who are more familiar with TypeScript's typing system
Although the way it reads is kinda neat, "list[int] & MaxLen(10) & MinLen(5) is a list of ints, and its max length is 10 and it always has at least 5 items"
yeah
not a huge fan of the & Doc() idea though
does any language have docstrings for attributes?
I personally don't really think there's a need for that
Usually the name should speak volumes
Or you'd provide details on how it works in a comment/docstring of the class that actually uses it
But if it were to be implemented, it makes sense to be implemented via Annotated as it's really just some metadata
Although it's not really type metadata, it only talks about the attribute itself π€
MaxLen, ValueRange and such make sense as type metadata, but docstrings don't technically fit in IMO
i think so too
You could also do something funky like
@with_local_docstrings
def foo():
x = 123
"how many exes"
y = 456
"how wise"
return x * y
print(foo.__var_docs__["y"]) # how wise
where the decorator does AST substitutions when you have a simple assignment followed by a literal string expression
Could even do the same for class attrs
unfortunately top level scopes wouldn't be able to use this
Yeah and I thought I read somewhere that this was going to be a possible syntax for variables and attributes
i said that IDEs like vscode ALREADY DO IT
it's not in the language
and don't say it's "impossible", it's not. it may not be simple, but far from impossible
which is entirely dependent on how these would/should be used
How can I enlight a code like this?
I mean: here, on Discord
!code
Here's how to format Python code on Discord:
```py
print('Hello world!')
```
These are backticks, not quotes. Check this out if you can't find the backtick key.
Thank you very much
It's not impossible the rejected pep had acceptable implementation by Guido but he didn't like the syntax
i said it's not impossible..
Yeah dude I'm agreeing with your comment to the other person
I think 224
ty
Python Enhancement Proposals (PEPs)
right
Python-Version 2.1
ouch
20 years π
maybe it's really time to revive that
that pep is older than me π
where can i petition to make newlines in f-strings possible?
having to set a variable with \n just to work around this is just..
what's the reasoning behind not allowing \ anyway?
difficulty to parse, I think. though maybe you wanted a more precise answer than that.
you put the idea on python-ideas and hope that a core developer takes up your cause
kay
but I suspect that if there were a straightforward solution, it would have been implemented when the PEG parser came to be.
i found a problem mentioned in the mailinglist
!e print(f"a\nb")
@raven ridge :white_check_mark: Your eval job has completed with return code 0.
001 | a
002 | b
What are we talking about?
before the f-string parser really gets to process the string. It might
require a new implementation of the f-string parser independent of regular
strings, which I likely would not have time for before beta 1. Although
since this would be a reduction in functionality, maybe it doesn't have to
get done by then.```
SyntaxError: f-string expression part cannot include a backslash
oh, within the expression part?
yeah
but - why are you trying to put \n in the expression part? (as opposed to the string literal part)
i was writing a nice and simple f-string wanted to do something like "... {'\n '.join(hashes}..."
ah. Yeah, I can see that.
wasn't expecting the spanish inquisition there
the single question about when this would be useful?
opposed to "oh, crap, i didn't see that coming. now i have to rewrite the whole thing because this is too dumb to make a simple string manipulation work?"
one could easily do line_join = '\n '.join and then call it in the fstring, but it is kind of an arbitrary constraint
principle of least surprise etc
if it is just a technical limitation and not a deliberate design constraint, you can always just contribute a solution.
well
I also haven't thought of how this would affect raw f-strings.
In any event, I'll take a look at adding this restriction, just to get an
estimate of the magnitude of work involved. The easiest thing to do might
be to disallow backslashes in any part of an f-string for 3.6, although
that seems to be going too far.
it seems they disabled it because they couldn't figure it out and then dropped the ball
It sounds like it's technically challenging to implement, so they decided that the effort wasn't worth the reward
yeah.. π¦
disabling \ in the expression part was a compromise that allows backslashes in the string part, and that allows for the possibility of removing that restriction in the future without breaking backwards compatibility
we should put it in our !projects list for students to tackle and take a shot at :]
maybe not for bloody beginners but maybe a challenge list for the #esoteric-python people
it's actually nedbat's list, so you'll have to petition him directly π
(though I do want to accumulate more project ideas for the resources page)
Actually, the restriction doesn't quite apply anymore, the PEG parser makes it a lot easier I think.
i was looking at python's ast hm
so basically it's if statements are like
if condition1:
statement1
elif condition2:
statement2
else:
statement3
to
if condition1:
statement1
else:
if condition2
statement2
else:
statement3
or did i get it wrong 
oh it seems like so
the ast of these codes are identical
ima try unparsing it to check if it'll produce the second or the first result
the first, as expected
:/
I want to start learning python so suggest me some tips
the question is how to produce the second one with ast.unparse, or is it simply impossible
!resources you can check this out, but keep in mind that this channel is primarily for discussion about python's internals and the like - if you want to get help, you can ask in #python-discussion of in a help channel
The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.
Hi, is there a difference between \u and \U unicode? On the basis of the max length that they can have?
this is how pycharm is higlighting the two
the only difference between the two are u and U
The U accepts 8 digits, u accepts 4
Ah, for \x and \X?
Don't think \X is a valid escape
It takes two hex digits and gives you a character those represent
https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals the valid string escapes can be seen in the table here if you scroll down a bit
Ah thanks for that link π
got me thinking why it accepts 8 digits instead of 6, which already contains the range for all unicode values
utf8 supermacy
...for now. Maybe we can eventually get rid of UTF-16 and use the full theoretical range of utf-8
everyone: it's merged
nice.
oh no grammar error in the merge title
but anyways time to find more stuff to optimize
go go π
crow on his way to make @boreal umbra's tag obsolete
what tag
about the slowness of python
well it might become obsolete in python 3.12
but anyways i found another optimization i can do
https://bugs.python.org/issue37907
whats this?
@native flame you can make that tag if you want, btw
why would i want to make a to-be obsolete tag
I didn't read the context. I just want to offload the tag.
what's the name of it?
it doesnt exist yet
we've discussed making a !slow tag that explains that Python is slow for large CPU-bound operations, but that the bottleneck for most real-world programs is network or file/database IO, that there are compiled libraries to optimize CPU-bound operations, and that Python's rich ecosystem often more than makes up for any performance loss.
oh I see. well it certainly gets asked often enogh at any rate
I think in a lot of cases people think it's too slow when it isn't
it's mostly just "I heard python was slow" or occasionally "python is worse than cpp because it's 1000x slower"
From personal experience I also know part of the problem is just that python happily allows you to write code that's so terrible and makes so little sense at a low-level that a more rigid language (Rust, C++) would just not even compile it
so it's horrendously slow b/c you're copying data left and right and have competing ownership, blah blah blah
one could achieve 90%+ of the speedup you'd get from switching to a different language from just switching to actually doing things in the "python best practice" way.
is there an example of this?
yeah that seems like that will become obsolete when python 3.12/3.13 comes
well this is IF python really becomes JIT in 3.12/generate machine code in 3.13
generate machine code π
does that mean making executables are possible in vanilla python
I've not the mental energy or time to come up with exact examples of this now, but my primary experience in this type of performance problem is in the data science field. If you aren't very familiar with best practices in pandas/numpy/any&all ML or AI frameworks, it's pretty easy to write code that runs but is very suboptimal.
this also happens a lot in my experience with people not understanding how to use databases properly, and having like a dozen threads sharing the same DB connection cursor, or some other trivial problem
we'll see
decided to also optimize the range (iterator) class (for windows 64-bit) by using size_t/Py_ssize_t instead of unsigned long/long
i'm yet to make a report on this
give a man a gun and he'll shoot himself in the foot
of course the solution is to simply amputate

πΏ
what is size_t defined as on Windows ?
8-byte integer on x64 and 4-byte integer on x32/x86
that makes sense ..
a little education goes a long way for these--at least the db misunderstandings are easily straightened out, not sure about AI/ML
more threads != performance >.>
i find that these kinds of mistakes come from people not really understanding how things work internally, and being too used to python being extremely high-level and sometimes magical
thinking in abstract terms and not in terms of chunks of memory in a computer
Hoping this is the right place to ask this
Eventually (soonβ’???) I want to build my own language
But not just a toy β I want to dive head first into the process, learn it back to front and inside out, and understand the theory
Now, I'm comfortable with the standard operating procedure for starting any programming project β identify what you want, break it into subcomponents, learn what you need to learn, implement, debug, and then release it into the world (perhaps committing to keeping it updated)
The problem is that I don't know what I don't know. I have a feeling in my gut about what I want it to be like but I don't have the words to be able to spell it out clearly. So, my question is
If I want to be able to have something useful to say on the topic of language design, what do I need to know?
NOTE: one thought I've had, loose as it is, is that I want the best of both worlds when it comes to typing β optional static typing, precompiled where appropriate but dynamic if and when explicitly designated, and, with a rich templating system
This would probably be quite an undertaking. I would start by asking "for what use case do I want this language to be especially well suited?". I would also learn about the different language paradigms (OOP, functional, imperative, etc) and consider to what extent you want each of them to inform the design.
I want the best of both worlds when it comes to typing β optional static typing, precompiled where appropriate but dynamic if and when explicitly designated
Can you think of what tradeoffs this design might have? Is it possible to have both?
My instincts (and very limited understanding) tell me yes
I've heard rumours about python's JIT focusing on using typehints to predetermine types at compile time, and I know Nuitka compiles what it can based on type hints and treats the rest as dynamic. And the STL in C/C++ performs compile time computation to write new code on the fly according to the templates specified
Another thing I've been learning β I already know Python pretty well, and I've been learnign Cython and C/C++ this year also
Is that languages have different uses that appeal to different people and different jobs. Some people like getting their hands right into the memory. Others are disgusted by the notion
It would be fascinating to write a language (or two β keep reading) which peeled back like an onion. In the same way you can directly write C or Cython that expose directly to Python, the ideal (sucessfully, widely used) new language would be built from the beginning for both high level operations in the dynamic and low level operations, exposable to the latter with ease
But I digress β any thoughts on how I might start the process, and begin getting familiar with the pillars of language design, would be appreciated π
yeah exactly. It's much harder to make that kind of mistake in a lower-level language, as the compiler simply won't let you.
undefined behavior would like to say hello
Why is that an optimization? Are those different sizes on 64 bit Windows?
http://craftinginterpreters.com/ craftinginterpreters is a great place to start, the dragon book is a good resource too
Both are on my list!
I'm a bit worried though that (with the dragon book especially) books that focus on compiled languages will bias me towards compiled languages. I want to keep my heart and mind open to all types of languages
Well, the concepts it explores can be applied to a variety of languages, compiled or not. Learning more about compiled languages won't stop you from learning about other things
And you'll find some form of compilation in quite a few languages. Even if it's not to machine code, you'll see a lot being compiled to some IR, and like python, to bytecode
that sounds like.. oh, wait! python??
No need to be glib
This, by the way, isn't nearly as true as it is humorous
sorry i'm not enthusiastic about the prospect of having yet another language in the world that tries to cover all use cases
Javascript is a prime example of disparate parts coming to agreement upon basic standards
There being a million and one languages in the world is no excuse not to keep pushing the envelope (not that I ever expect I'll be able to make anything that good)
if you want to really push the envelop, then don't go the trodden path.
let me find you the youtube video that explains what i mean
You know, its alright
This is the keynote Uncle Bob gave remotely at ACCU 2011.
To see more about Clean Coders: https://cleancoders.com/
Over the last 50 years we've seen a lot of computer languages, from procedural languages, to structured languages, to OO languages, stack languages, logic languages, and even graphical languages, and languages based on the game o...
Oh I loved this talk
Respectfully though, I don't need anyone's permission to study and develop languages
rust isn't exceptional because it's doing the same old thing in a new envelope
it's doing exactly what uncle bob is talking about (even though he clearly doesn't know about rust)
i don't care what you do or don't. do what you want, i'm just saying that if you want to make an impact, you need to start thinking outside the box - the box being currently known, classic programming paradigms
if you're just making another language inspired by python, you'll just get asked "why should i use YOUR language if julia and c# and cython and.. already is out there and has less bugs than your language?"
you have to ask yourself what should be the unique selling point
i don't want to disuade you from inventing your own language, by all means. you'll learn a lot and if it's innovative enough, it may enrich other languages, as well.
the problem i see rather is that you're tackling this not as a research project but as a competition, which i don't think is helping anyone really
since it will only require you to reimplement all the features other languages also have, forcing you down the same path of the mainstream languages, thus it'll end up as one as many other python-like-but-not-quite-python languages.
be innovative, creative, unique instead π
tbf, that's not everyone's goal. Not everyone's goal is to make something revolutionary. I know my current language isn't anything special, but I'm doing it just for the sake of doing it, and because I find writing it out fun. I think that "making something super unique" is an idea people put too much emphasis on honestly. If you have a "new" idea, sure, pursue it. But if Skywalker just wants to write a language and explore, it's perfectly fine for them to make it similar to another language(s).
that's just my point. he said he doesn't just want to make it for fun but want to have it widely used
which is just calling for mainstream features
I don't recall saying that
there
I think I may have said I want it to have a wide scope
Wide scope, general purpose in nature
Doesn't mean I expect anyone will ever use it
yes they're different sizes in 64-bit windows
actually i don't see the optimization here
the only benefit i can see is a larger range size that's consistent with linux platforms
32 bit longs, I see. What a world.
Otherwise we get similar but marginally better languages and maybe any productivity gain is lost in learning and porting code to the marginally better language....also there are too many languages already ..
hoping this is the best place to ask a more "advanced" question: how can i remove the topmost element of a stacktrace? so, for example, here removing the call to foo (ignoring the interpreter <module>, as this won't be run via interpreter obviously)
oh ffs discord
pictrures of terminals are flagging the nsfw filter again :)
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo(): bar()
...
>>> def bar(): raise SyntaxError
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in foo
File "<stdin>", line 1, in bar
SyntaxError: None
>>>
how can i remove the topmost element of the stacktrace
can you tell us more about why you want to remove a frame from the stack trace?
You want to remove <module> ?
to make output look nicer on a little utility i'm writing to quickly evaluate a python expression from terminal
(ignoring, of course, the <module>, as i won't be running this in interpreter)
it might be easiest to print the stack trace yourself, with the traceback module
i found an SO answer but, while it says the topmost, it's actually the bottommost (at least, when you look at the printed list), which is trivially accomplished with the limit argument of traceback#print_exception
there's https://github.com/python/cpython/blob/main/Lib/importlib/_bootstrap.py#L232 - but that assumes you're in control of where the function is called
Lib/importlib/_bootstrap.py line 232
# Frame stripping magic ###############################################```
(and relying on it would be a terrible, horrible, no good, awful hack)
so I'm inclined to agree with Ned - print the stack yourself, and filter out the frame you don't want
you can get most recent call by passing a negative number to limit
you can get least recent call by passing a positive number
this is of course assuming that the traceback is "most recent call last" mode
"most recent call first" is also a thing though
What you can do is go through the exc.__traceback__.tb_next.tb_next.tb_next... linked list, edit that to remove frames you don't care about. traceback.tb_frame.f_code.co_filename could be used.
thank yo!
you can set sys.excepthook to print out customised tracebacks
you may also be interested in my utility to quickly evaluate python expressions from the terminal: https://github.com/hauntsaninja/pyp (it has some nice traceback + ast hacks)
Python's super builtin in very misunderstood. It does not mean "parent". It means "next in line". What line? The Method Resolution Order (MRO) of an object, which defines the search order for attribute lookups. super() uses some very sneaky techniques, such as examining the current stack frame, and object proxying. All this is explained in great...
fun new video on super and the MRO
imagine not referencing that class directly
Is the issue fixed, rebased and released into 3.7,3.8,3.9 ...
https://bugs.python.org/issue46400
has there been any movement on the mutable default value front?
i don't recall how they called it exactly.. dynamic reevaluation?
late-bound parameters?
!pep 671
probably not for a few months now
hope it won't take another 20 years like some features >.>
NVM, Someone replied in the mailing list
i'm wondering when can __qualname__ be none or ""?
when someone set random keys with globals? π₯΄
!e
globals()[''] = type('', (), {})
print(globals()[''].__qualname__)
@naive adder :warning: Your eval job has completed with return code 0.
[No output]
well this one is ''
I don't think type's first argument can be anything other than string
so basically I think that when the object has a name with '' or None that'll output this :/
Is functools's update_wrapper complete? https://github.com/python/cpython/blob/main/Lib/functools.py#L32-L34
Lib/functools.py lines 32 to 34
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
'__annotations__')
WRAPPER_UPDATES = ('__dict__',)```
Aren't parameters and defaults stored somewhere? Aren't there tools inspecting those?
Does anybody know why __defaults__ and __kwdefaults__ aren't copied?
Because they might be different in the wrapper
I just have *args, **kwargs and pass them along. Do they have special meaning to Python (like __code__)?
Yes, they do. Your wrapper has no __defaults__ / __kwdefaults__, while your original function maybe does. If update_wrapper would copy that info, it would be lying.
!e
def foo(x=23):
print(x)
foo.__defaults__ = (42,)
foo()
@quick snow :white_check_mark: Your eval job has completed with return code 0.
42
Hmm I've been thinking more about it and I think I may actually be able to use this to my advantage lol
Or well, it depends. Right now I need to manually hack-into defaults because actual parameter defaults serve a different purpose
!e Hmm, I just found this: ```python
def test(a=None, b):
return b if a is None else b
Isn't the technical name `parameter`?
@elder blade :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | def test(a=None, b):
003 | ^
004 | SyntaxError: non-default argument follows default argument
def test(a, b) <- parameter
test(1, 2) <- argument
Yes
Well generally I'm not so sure everyone agrees. But in the context of Python, the docs do explicitly make that distinction.
This distinction seems to be shared by JavaScript, C#, C++, psuedo-code (on some odd website) and surely much more.
my C skills is too bad i couldn't understand the cpython source properly. are there other python implementations thats more readable for me?
rust
as in rust python?
yes
pypy
Does anyone know why zipfile.ZipExtFile is called like that? What does the "Ext" mean?
Extension? External? Extracted? Exterminatable? Extinct? Extruded?
The extended file system, or ext, was implemented in April 1992 as the first file system created specifically for the Linux kernel. It has metadata structure inspired by traditional Unix filesystem principles, and was designed by RΓ©my Card to overcome certain limitations of the MINIX file system. It was the first implementation that used the vir...
It wouldn't make sense to have a class for each file system. And there certainly is no ZipNtfsFile.
!pep 8
What is this?
I checked the link and stuff
Is it a guide to code?
!pep 1
!pep 69
PEP 69 does not exist.
π’
Hard to say. For some context, that class came into existence to be able to return a file-like object from ZipFile.open
No one seems to discuss the naming https://bugs.python.org/issue1121142
I guess it might mean "extracted" since it's a file-like object for a specific file within the archive
that is a possibility...
just a minor reminder to not use unnecessary contractions IMO
chkbrklvl might be obvious to you, but not to the next person who sees this, who is perhaps not as familiar with the tiny details of your application or domain
Well... first thing that came to mind was "cheeki breeki level"
I understood that as "check break level"
Does Python implicitly intern 'dynamic' strings used as keys for dictionaries? I read that internalization only happens if a string can be known at compile-time, is this true?
Objects/dictobject.c line 3914
PyUnicode_InternInPlace(&kv); /* XXX Should we really? */```
I believe strings that qualify as identifiers also get interned
And you can always manually intern strings with sys.intern
!d sys.intern
sys.intern(string)```
Enter *string* in the table of βinternedβ strings and return the interned string β which is *string* itself or a copy. Interning strings is useful to gain a little performance on dictionary lookup β if the keys in a dictionary are interned, and the lookup key is interned, the key comparisons (after hashing) can be done by a pointer compare instead of a string compare. Normally, the names used in Python programs are automatically interned, and the dictionaries used to hold module, class or instance attributes have interned keys.
Interned strings are not immortal; you must keep a reference to the return value of [`intern()`](https://docs.python.org/3/library/sys.html#sys.intern "sys.intern") around to benefit from it.
Since PyDict_SetItemString there takes a const char * parameter instead of an object, that's really more used only with constant values in C code, not by anything called by Python code.
TIL
https://github.com/python/cpython/pull/31982 watching history unfold
hello
I was just reading peps since I'm really bored and noticed pep6 seems to talk about CVS, sourceforge, and the BDFL quite a bit... and the actual content hasn't been updated since 2008
wait a second... if it is talking about cvs and sourceforge it is before https://peps.python.org/pep-0347/ which was made in 2004
Python Enhancement Proposals (PEPs)
there was a change to PEP 6 in 2004 (as stated in the PEP header), maybe it was added later
h
Is there any justification for python passing mutable values as references rather than by value?
I've found it unintuitive, and always wished a list would be passed as a value instead of a reference and so on... But perhaps there's a good justification for it - I can't seem to find one ATM though
Performance? Python is already quite slow, and expecting every object to be copied whenever it's passed to any function would exacerbate that a hundredfold
Fair - and this is something which would have been considered at the time i assume
It always felt a bit odd, and languages like R seem to behave more naturally here
I don't think either one is more natural than the other. Not being able to append an element to a list passed to you by your caller doesn't seem natural to me.
just to clarify, python passes all values by reference, assignment ||[edit: to variables specifically, attributes also aren't copied by default, but that can be customized with __setattr__ and __set__]|| never copies, including arguments, for loop receivers, etc etc etc
sure - which would be natural in a functional language, but I wouldn't say that's natural in a procedural language
Hmm ok, maybe I don't understand well enough what it means to be a "procedural language".
and then someone comes along and writes a variant of __setattr__ that copies :]
Hi
hi
well actually, setting an attribute isn't assignment
it's a method call!
exactly, which you can abuse to make foo.bar = baz do crazy stuff and copy baz all over the place - assignment gone rogue :p
i (ab)use this in fuzzylogic to wrap things on the fly for convenience, very useful
what's a good way to avoid naming compflict?
I have this class and I want to overwrite some stuff
from .smth import Smth
class CustomSmth(Smth):
...
from . import smth as s
I mean you can also do
from somewhere import Something
class Something(Something):
...
if you don't need the original class here anymore
but that can cause confusion I might import the original Something
you found an anti-pattern?
Isn't an anti-pattern something you do in your code?
Are you saying that CPython is doing an anti-pattern, or that one is possible to create with Python code?
what did you find?
It's like
createapp, createdb, createworld vs create_bluenix
hu?
example?
and no, this isn't one
Inconsistency then?
design choice
@fossil blade Do you mean that names are in different cases, like int.bit_length vs str.startswith vs logging.getLogger?
Yeah, that's surely an inconsistency, due to historical reasons (nobody would set out to have two or three different cases).
But the names will obviously not get changed since that will break 99.9% of Python programs for little gain.
And new APIs all try to follow PEP8, of course.
A bit of a cursed question I have:
I notice that when a descriptor __get__ is called on the class, it's passed None, cls as arguments, whereas with instances it's passed instance, cls.
Now, suppose the descriptor is defined on NoneType. Would there be any way to distinguish between the two kinds of access?
can you define a descriptor on NoneType?
im not sure if you can do that with forbiddenfruit or one of those other wacky libraries
but i would guess that the answer is "no"
That's exactly what I'm doing :>
And yeah it seems to be a pretty unfortunate situation, even bytecode heuristics don't seem to help (unless you can inspect the stack values directly)
okay okay, even more cursed solution to cursed problem:
in addition to patching the descriptor to NoneType, patch it to type
class Descriptor:
def __get__(self, obj, type):
print("get called", obj, type)
# ONLY works with a data descriptor
def __set__(self, obj, value):
raise AttributeError
import forbiddenfruit
forbiddenfruit.curse(type(None), "test", Descriptor())
forbiddenfruit.curse(type, "test", Descriptor())
type(None).test
None.test
get called <class 'NoneType'> <class 'type'>
get called None <class 'NoneType'>
without the type patch, both calls would print None <class 'NoneType'>. (you also get the same bad result if Descriptor isn't a data descriptor, i.e. doesn't define __set__)
Hi all. I'm not sure where to address this question so I'll post it here.
I've been a python developer four ~4 years now. And sometimes I get asked basic questions on interviews that I can't answer. Problem is, I'm not even sure where to start looking for answers. The nature of these questions is basically "how python works on low level", like how does it work with memory, threads and other resources. It's basic yet more in-depth knowledge about how python operates. Can someone recommend a resource (like video lecture or a book) that explains that fundamental stuff? All I can find is beginner lessons and short articles about certain specific aspects but that doesn't help me build decent overall understanding and more importantly the ability to answer questions like that on interviews.
Thanks in advance π
CPython Internals is one book that probably tells you how python operates
for me i just took some CPython code, started modifying, and learned from mistakes
Do I have to have any knowledge of C?
=/
you can't know the internals of python without knowing C enough
unless you can understand from the API docs
if you don't want to buy then you'll have to learn it by yourself
and that takes a few months to get right when you don't have knowledge about C
there's no easy way here
I don't mind paying for it, but I'm not even sure yet if it's going to help me.
I don't expect it to be easy π
python has a devguide thingy https://devguide.python.org/exploring/
i didn't even know that existed
why?
I'd like to ask a question that I don't think is appropriate in a public chat


