#internals-and-peps

1 messages Β· Page 156 of 1

paper echo
#

yeah an ABC checks that abstract methods are implemented non-abstractly when the class is instantiated

#

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

deft pagoda
#

does seem like it would slow creation of objects quite a bit if included

boreal umbra
#

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.

deft pagoda
#

i think inheriting ABC and using @abstractmethod is already very readable and pythonic enough

#

discord really wants to ping someone

verbal escarp
#

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

verbal escarp
#

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 πŸ™‚

unkempt rock
#

yall really having full on debates.. such discordian activity

verbal escarp
#

sure

static bluff
#

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

tacit hawk
static bluff
#

I felt like an unfair fight, is all. So, well, I'm a bit embarrassed about losing my shit

tacit hawk
#

what shit lol

static bluff
# tacit hawk 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

tacit hawk
#

so you argument was languages should have good syntax

feral cedar
#

i.e., what does "good syntax" mean?

tacit hawk
#

I think python does this job of making computers language close to natural language very good

feral cedar
tacit hawk
#

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

static bluff
#

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

tacit hawk
#

there will be always a cost to master tools, it's the programmers job

static bluff
feral cedar
#

that's a non argument

tacit hawk
#

hm two different things

static bluff
#

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

tacit hawk
#

these people benefits better of specialized teachers, no?

static bluff
#

I am unconvinced. We can build programming languages that capitalize on a set of rules which make them easier to learn

tacit hawk
#

each disability may require special methods, how can python embed them all?

feral cedar
tacit hawk
#

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

paper echo
#

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

static bluff
paper echo
#

indeed

#

i often bring this up in help sessions

feral cedar
#

imo, one of the most common mistakes, probably because python is so english-like, is the or-gotcha

static bluff
#

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.

frank dagger
# static bluff Restated, my feelings are as such. It goes without saying that every language wi...

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.

static bluff
#

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

static bluff
#

I took a few graphics design courses and the material was solid

frank dagger
#

I wouldn't be so sure lol

tacit hawk
#

you need to consider that 1) programming languages are tools and 2) they have a purpose

static bluff
#

Most graphic design principals these days are backed up by "user tests" β€” not sure if you'd count that as data

verbal escarp
frank dagger
#

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

verbal escarp
#

but i think we are lacking much of necessary research in that area

static bluff
static bluff
verbal escarp
#

not just UX

static bluff
#

And I can attest that programmers, when you suggest making improvements to their languages, get a bit rigid

frank dagger
static bluff
frank dagger
#

np

tacit hawk
#

I think this science field is called "Human-Computer Interface" and has many researches on it, it's part of computer science curriculum

verbal escarp
#

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

static bluff
#

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

tacit hawk
#

It just got market name of "UX"

static bluff
#

It was designed for elegance

verbal escarp
#

well, maths only fairly recently has become the universal language we know and love, before it was all over the place

static bluff
#

And elegance is great β€” if you already speak the language like a master

frank dagger
#

I'm not sure that's exactly the whole story tho - elegance - mathematical notation is ultimately about one thing: utter precision

feral cedar
tacit hawk
#

probably we are going offtopic

static bluff
verbal escarp
verbal escarp
#

masters also can also be dyslexic

frank dagger
#

all other concerns in how to communicate maths are subordinate to precision. because without that, there is no effective way of communicating mathematics

verbal escarp
#

if avoiding magic symbols helps even masters in reading and understanding code, it's a win for all

static bluff
verbal escarp
#

but you need to dig into the research in the area before jumping to conclusions

static bluff
#

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

verbal escarp
#

well, do the science now and define what is good language design, we're waiting πŸ˜„

tacit hawk
#

in scientific field "make easy to learn" in itself is not a well defined problem

tacit hawk
#

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

static bluff
#

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

verbal escarp
#

now you're just making up random stuff πŸ˜‰

static bluff
#

What about this?

#

Β·Β·Β·|Β·Β·||Β·Β·Β·Β·Β·

verbal escarp
#

stop πŸ™‚

#

come back when you found some interesting papers on the subject we can further discuss πŸ˜‰

static bluff
#

But, yes, I hear you

feral cedar
#

yes, everyone can look at contrived bad examples and agree, but with more complicated actual languages, it gets much murkier

static bluff
#

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

tacit hawk
#

well you need to differ lack of search from little science, you know how and where to search?

static bluff
#

Do you have any suggestions?

tacit hawk
#

also you know IEEE and ACM for example?

verbal escarp
#

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

static bluff
verbal escarp
#

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)

static bluff
#

I'm down for science impartial science

verbal escarp
#

let it crack

static bluff
#

Well, I think finishing my 1st year end of term infotech presentation take precedence

verbal escarp
#

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

static bluff
#

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

tacit hawk
#

that's good start, you need that to be able to proof your method works

#

and that it's reproducible, etc

static bluff
#

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

verbal escarp
#

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

tacit hawk
#

if you want to keep chatting about this go to some offtopic, we are flooding this room

tacit hawk
#

go there and ping people here that might want to follow this chat

static bluff
#

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

grave jolt
#

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

surreal sun
#

Double quotes for me, it's more ubiquitous that it denotes a string and the same reasons as you said

vast saffron
#

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)

paper echo
#

the only reason to use single quotes is that it's easier to type on ansi keyboards

boreal umbra
#

ansi?

rugged harbor
#

ansi is likely the keyboard layout you're typing on right now

#

if you're in the US

paper echo
#

i should have qualified specifically ANSI-US keyboards

#

because i've seen some weird hybrids (although mostly on people's custom builds)

boreal umbra
#

wait what is up what that enter key

#

wtf

rose schooner
#

that's the tilde right beside the enter key in the ISO keyboard

unkempt rock
#

Why don't they give list a .discard like sets have lemon_thinking I know the complexity is not the same but lists have .remove anyway ducky_blurp

raven ridge
unkempt rock
raven ridge
#

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

unkempt rock
#

: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)

fallen slateBOT
#

@unkempt rock :white_check_mark: Your eval job has completed with return code 0.

B [1, 2, 3]
unkempt rock
#

nifty ducky_wizard

#

I still like the remove/discard on lists for symmetry discre3Comfy

native flame
#

i don't think i've ever needed to use list.remove either πŸ€”

elder blade
#

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)

verbal escarp
#

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 lemon_raised_eyebrow

spice pecan
verbal escarp
#

then i say dvorak.

wind crypt
#

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.

rich cradle
#

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.

rose schooner
#

i had no damn idea what the heck he just asked

rich cradle
#

I still don't really understand. If you could try to explain a bit more @wind crypt, that'd be great.

rose schooner
#

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

wind crypt
rose schooner
#

what

rich cradle
#

You can interop with C, yes, but that's not because CPython is written in C.

#

The FFI is a whole different matter.

wind crypt
rich cradle
#

not python, but for example, Rust can interop with C, but it's not written in C

rose schooner
wind crypt
# rose schooner > Also that got me thinking about interpreted vs compiled. If you were to have a...

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

feral cedar
rose schooner
rich cradle
#

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.

wind crypt
rose schooner
#

interpreted - written to evaluate lines one by one
compiled - lines in bytecode often intermixed

rich cradle
feral cedar
#

although it is especially easy, because it's written in C

rose schooner
#

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

raven ridge
#

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

raven ridge
#

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.

raven ridge
#

you know our rules better than this

acoustic glen
#

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?

boreal umbra
wind crypt
#

πŸ˜‹

frank dagger
# wind crypt Since new neurons hardly ever form when your an adult he is probably literally r...

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

median palm
#

Maybe a Union? You can also ask in #type-hinting, this channel is primarily for discussion of python internals and the like

tacit hawk
#

ah forgot that, will move there

#

I don't want to hardcode all possible returns in base class

rich cradle
#

But if you're making it specifically to be a new compiler, that's not great design.

median palm
#

Fair enough

fossil blade
#

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

rose schooner
native flame
#

for (x1, x2, x3, x4, x5, x6) in itertools.product(range(1, 10), repeat=6):

rose schooner
#

ok yeah

sonic flax
#

what's the best way to manage different python installations on windows?

#

this is internals right πŸ˜‰

boreal umbra
#

@sonic flax this is a discussion channel, but look into the py command.

#

"py command windows"

rose schooner
#

we're talking about python features and the internal python implementation API here

#

not installation-related stuff

sonic flax
#

may have been the stretch of all stretches

white nexus
#

!e ```py

del open
import builtins
builtins.open("file", "w")

fallen slateBOT
#

@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
rose schooner
#

!e ```py
del open
import('io').open('file', 'w')

fallen slateBOT
#

@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
fallen slateBOT
#

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)```
upper karma
#

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.

quick snow
#

@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.

upper karma
#

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

quick snow
paper echo
#

@sonic flax @boreal umbra they call it the "py launcher" in the docs

tacit hawk
#

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__)
fallen slateBOT
#

@tacit hawk :white_check_mark: Your eval job has completed with return code 0.

001 | BarοΏ½
002 |     Baz
tacit hawk
#

!e

def foo():
    r"""Bar\0
    Baz"""

print(foo.__doc__)
fallen slateBOT
#

@tacit hawk :white_check_mark: Your eval job has completed with return code 0.

001 | Bar\0
002 |     Baz
tacit hawk
#

so raw docstrings preserve text escapes

raven ridge
#

It's print that's losing them, not the docstring.

#

!e ```py
def foo():
"""Bar\0
Baz"""

print(repr(foo.doc))

fallen slateBOT
#

@raven ridge :white_check_mark: Your eval job has completed with return code 0.

'Bar\x00\n    Baz'
tacit hawk
raven ridge
#

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.

tacit hawk
#

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

spice pecan
#

Alternatively you could escape the backslash

#

But raw docstrings do sound like a significantly simpler solution

verbal escarp
#

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

paper echo
#

i think asyncpg does it

#

admittedly im not quite sure what the benefit is

spice pecan
#

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

white nexus
#

!e import __hello__

fallen slateBOT
#

@white nexus :white_check_mark: Your eval job has completed with return code 0.

Hello world!
lusty scroll
lusty scroll
#

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)

tacit hawk
lusty scroll
#

you want to show like as it would appear in source code, but in the docstring?

tacit hawk
#

like a comment but as a docstring, for that I just need to create raw docstrings if escape sequences are present

lusty scroll
#

like more of a comment than a string

hushed geyser
#

hey

#

im trying to open a file, just using the file name - not the file directory

rose schooner
#

doesn't seem like it belongs in this channel

#

you can ask in any of the off-topic channels

next lion
#

I am sure they just wanted to talk about pep 428, it was just their conversation starter ;P

rose schooner
#

ok

native flame
#
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?

spice pecan
#

Good question, it seems to be called again after iter, but its correctness doesn't seem to matter much lemon_thinking

#

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

paper echo
#

huh, so list() internally maybe calls __len__() before calling __iter__()?

native flame
#

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 πŸ€”

rose schooner
#
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__

fallen slateBOT
#

Objects/listobject.c line 919

n = PyObject_LengthHint(iterable, 8);```
rose schooner
#

use of __len__ or __length_hint__ if __len__ is not defined in list_extend

fallen slateBOT
#

Objects/listobject.c line 913

it = PyObject_GetIter(iterable);```
rose schooner
#

before that is use of __iter__, still in list_extend

rose schooner
#
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

native flame
#

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__

raven ridge
#

__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.

nocturne delta
#

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
raven ridge
# raven ridge `__init__` tries to preallocate exactly the necessary amount of space, based on ...

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.

native flame
#

why does __init__ need to resize/allocate at all? why not leave it all to extend

raven ridge
#

that's what used to happen, before the linked commit. It was worse because it used more space.

native flame
#

hmm

raven ridge
#

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()

raven ridge
rose schooner
raven ridge
#

you're missing a brace on 897

rose schooner
#

oh yeah

raven ridge
#

you could also just make that into an else if, instead of adding an else block

#

otherwise, yeah, that's what I was picturing

rose schooner
#

ok

raven ridge
#

Didn't try compiling it though πŸ˜„

rose schooner
#

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'

raven ridge
#

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

rose schooner
#

oh ok

raven ridge
#

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({})

rose schooner
raven ridge
#

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

rose schooner
#

i don't use git

#

also i've compiled python from source before

#

i never usually have this error

raven ridge
#

Could be there's a problem with the approach, then. I'd start by reverting the changes and seeing if it reproduces

rose schooner
#

found the problem, probably

#

oh nevermind

fallen slateBOT
#

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

rose schooner
white nexus
rose schooner
#

turns out we only needed to add the check in the second list_resize

rich cradle
#

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

feral cedar
#

you are correct

rich cradle
#

Wonderful, thanks

raven ridge
#

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.

median palm
#

if ids implementation is implementation specific, then in cases where you rely on the memory address, what would you use instead

native flame
#

you'd never rely on memory addresses

#

there's loads of internal optimizations which would break code relying on that

median palm
#

Well theoretically what if you did

raven ridge
# median palm Well theoretically what if you did

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.

median palm
#

I see

rich cradle
raven ridge
#

Be careful with threads.

#

You'll need a lock for that.

spice pecan
#

But yeah, relying on it (id returning the address) is not very wise

#

PyPy, for example, doesn't return the memory address

raven ridge
spice pecan
#

Yeah, anything ctypes related is likely not going to be very portable

raven ridge
#

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).

rose schooner
# rose schooner https://github.com/python/cpython/compare/main...thatbirdguythatuknownot:patch-1...

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

white nexus
#

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

rose schooner
verbal escarp
#

just mean is very sensitive to extremes

#

and max timings are worthless since they can be caused by external factors

rose schooner
#

dump (may be different from above stats because it was tested multiple times)

#

oh wait

verbal escarp
#

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

verbal escarp
#

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

rose schooner
#

there's also a histogram command for pyperf

#

histogram command

native flame
#

Interesting
Looks like builtin_function_or_method doesnt implement the descriptor protocol?
#bot-commands message
(the instance is not passed in)

raven ridge
#

That's correct. Python functions do, C functions don't.

rose schooner
raven ridge
#

which would probably explain it; you're probably allocating memory when you don't need to.

rose schooner
#

oh yeah.

raven ridge
#

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.

rose schooner
# raven ridge In the end, I wouldn't expect this approach to be noticeably faster than the old...
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`
rose schooner
#

added more benchmarks

naive adder
#
        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)

rose schooner
#

defaults are assigned to the last members of args

naive adder
#

seems like reversing two of them works

#

:)

rose schooner
boreal umbra
#

!e

a = [0, 1, 2, 3]
for a[-1] in a:
    print(a[-1], end=',')
fallen slateBOT
#

@boreal umbra :white_check_mark: Your eval job has completed with return code 0.

0,1,2,2,
boreal umbra
#

How is it that this works?

#

shouldn't the for statement cause a syntax error?

elder blade
fallen slateBOT
#

@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
native flame
#

anything that's valid on the lhs of a normal assignment is valid there, afaik

elder blade
#

Interesting... So it is validated?!

native flame
#

a.x, a[x] etc

elder blade
fallen slateBOT
#

@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]
elder blade
#

Ah, huh. Interesting

#

Right I forgot about this

naive adder
#

scary stuff, I have no idea how is it working

#

it broke my brain

verbal escarp
#

btw, what's the reason behind the "identifiers cannot start with a number"?

spice pecan
#

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

verbal escarp
#

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

native flame
#

i think it would hurt readability

verbal escarp
#

how so?

native flame
#

i can see myself thinking 2x is 2 * x

#

does any language allow it?

spice pecan
#

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

verbal escarp
#

Forth?

spice pecan
#

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

verbal escarp
#

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

spice pecan
#

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

verbal escarp
#

i like 2, 4 in long names instead of _to_ and _for_ :p

spice pecan
#

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

native flame
#

matrix_element_at_first_row_second_column...

spice pecan
#

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

spice pecan
#

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

verbal escarp
#

how about latex in identifiers? πŸ˜‰

#

you could name your matrix properly

spice pecan
#

[[tl, tr], [bl, br]]

#

no latex, and you get m[0][0]

native flame
#

i think notebooks are already capable of that

spice pecan
#

with numpy it's even better

spice pecan
verbal escarp
spice pecan
#

Oh, you mean the web interface

verbal escarp
#

but i don't think you can use subscripts

spice pecan
#

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

verbal escarp
#

a_1^2 as identifier with 1 subscript and 2 superscript

spice pecan
#

^ is xor

verbal escarp
#

yeah, would need extra declaration

spice pecan
#

I imagine the editor wouldn't like that very much

verbal escarp
#

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

dusk comet
pliant tusk
#

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

spice pecan
#

Interesting, what if you pass a mapping that doesn't subclass dict?

pliant tusk
#

!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()

fallen slateBOT
#

@pliant tusk :white_check_mark: Your eval job has completed with return code 0.

001 | get print
002 | get a
003 | 1
pliant tusk
#

!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

fallen slateBOT
#

@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
pliant tusk
fallen slateBOT
#

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);```
verbal escarp
#
    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..)

spice pecan
verbal escarp
#

ah, pyqt style, yeah

#

good idea

#

still, having to name the callback is annoying 😦

spice pecan
#

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

verbal escarp
#

ohhh, brython can do that

#

that's beautiful

#

document["clipboard_button"].bind("click", lambda event: window.navigator.clipboard.writeText(document["result"].text))

spice pecan
#

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

spice pecan
verbal escarp
#

lmao

spice pecan
#

At least there's no then :)

verbal escarp
#

the lambda is ugly, but the rest makes sense

spice pecan
#

I mean it makes sense, but the sheer size of this lad, I'm in awe it

verbal escarp
#

xD

spice pecan
#

Surprisingly, brython handles then pretty nicely

verbal escarp
#

it does? i'm still pretty new to it all

spice pecan
#

But unfortunately I can't check if it implements neat async-await for promises

verbal escarp
#

brython is a very strange beast

spice pecan
spice pecan
verbal escarp
#

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

spice pecan
#

Printing traceback to browser is an interesting idea

#

What are you using to communicate between the browser and the app?

verbal escarp
#

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

verbal escarp
spice pecan
#

That's pretty clever, you don't get any overhead from starting a server this way

verbal escarp
#

i only need to write enough info via jinja into the dom from the start, which is a bit tricky

pliant tusk
rose schooner
native flame
# rose schooner julia

julia doesnt allow numbers at the beginning of identifiers, it just parses 2x as 2 * x

rose schooner
#

oh you mean that

#

yeah i have no idea what language does that

verbal escarp
#

it's easier to inspect the result of the jinja etc. as a file

pliant tusk
#

Yea but once that part is done

#

Might be better to use base64 uri

verbal escarp
#

yeah, could be

#

do you have a recipe for that handy? i can put a note in the code

quick snow
native flame
verbal escarp
#

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

pliant tusk
verbal escarp
#

ty

#

why the encode-decode dance?

elder blade
#

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

verbal escarp
#

ic

verbal escarp
#

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

swift imp
#

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

verbal escarp
#

you can just write ```py
foo_factor: int = 3
"number of foos given"

swift imp
next lion
#

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

swift imp
verbal escarp
naive adder
#

foo_factor.__doc__ = "hey here's some docstring" 😎

verbal escarp
#

meh πŸ˜‰

naive adder
#
>>> def test():
...     "hi, docstring here"
...
>>> test.__doc__
'hi, docstring here'

works the same πŸ₯΄

verbal escarp
#

that isn't an attribute/variable docstring

raven ridge
#

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.

naive adder
#

o

rose schooner
#

unless you use annotations

spice pecan
#

That would be the sane way to do it imo

rose schooner
#

i was thinking of assigning to __doc__

spice pecan
#

foo_factor: Annotated[int, "number of foos given"] = 3

#

We already have Annotated, although this isn't really a valid use of it IIRC

peak spoke
#

Annotated works, but really is not nice to write for this use case

spice pecan
#

Yeah true

peak spoke
#

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

spice pecan
#

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")

native flame
#

ts has intersection types like that

spice pecan
#

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"

native flame
#

yeah

#

not a huge fan of the & Doc() idea though

#

does any language have docstrings for attributes?

spice pecan
#

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

native flame
#

i think so too

radiant garden
#

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

swift imp
verbal escarp
#

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

old rover
#

I mean: here, on Discord

naive saddle
#

!code

fallen slateBOT
#

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.

old rover
swift imp
verbal escarp
swift imp
#

Yeah dude I'm agreeing with your comment to the other person

verbal escarp
#

right

#

do you have a link to the pep?

swift imp
#

I think 224

verbal escarp
#

ty

swift imp
verbal escarp
#

right

#

Python-Version 2.1

#

ouch

#

20 years πŸ™‚

#

maybe it's really time to revive that

grave jolt
#

that pep is older than me πŸ’€

verbal escarp
#

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

feral cedar
#

what's the reasoning behind not allowing \ anyway?

boreal umbra
#

difficulty to parse, I think. though maybe you wanted a more precise answer than that.

boreal umbra
verbal escarp
#

kay

boreal umbra
#

but I suspect that if there were a straightforward solution, it would have been implemented when the PEG parser came to be.

verbal escarp
#

i found a problem mentioned in the mailinglist

raven ridge
#

!e print(f"a\nb")

fallen slateBOT
#

@raven ridge :white_check_mark: Your eval job has completed with return code 0.

001 | a
002 | b
raven ridge
#

What are we talking about?

verbal escarp
#
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.```
verbal escarp
raven ridge
#

oh, within the expression part?

verbal escarp
#

yeah

raven ridge
#

but - why are you trying to put \n in the expression part? (as opposed to the string literal part)

verbal escarp
#

i was writing a nice and simple f-string wanted to do something like "... {'\n '.join(hashes}..."

raven ridge
#

ah. Yeah, I can see that.

verbal escarp
#

wasn't expecting the spanish inquisition there

raven ridge
#

the single question about when this would be useful?

verbal escarp
#

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?"

boreal umbra
#

one could easily do line_join = '\n '.join and then call it in the fstring, but it is kind of an arbitrary constraint

verbal escarp
#

principle of least surprise etc

raven ridge
#

if it is just a technical limitation and not a deliberate design constraint, you can always just contribute a solution.

verbal escarp
#

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

raven ridge
#

It sounds like it's technically challenging to implement, so they decided that the effort wasn't worth the reward

verbal escarp
#

yeah.. 😦

raven ridge
#

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

verbal escarp
#

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

boreal umbra
#

(though I do want to accumulate more project ideas for the resources page)

prime estuary
#

Actually, the restriction doesn't quite apply anymore, the PEG parser makes it a lot easier I think.

naive adder
#

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 lemon_sweat

naive adder
#

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

#

:/

wicked cedar
#

I want to start learning python so suggest me some tips

naive adder
wicked cedar
#

I want to start learning python so suggest me some tips

#

I am new in

median palm
fallen slateBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

gusty marsh
#

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

peak spoke
#

The U accepts 8 digits, u accepts 4

gusty marsh
#

Ah, for \x and \X?

peak spoke
#

Don't think \X is a valid escape

gusty marsh
#

yeah my bad

#

so teh limit for \x is?

peak spoke
#

It takes two hex digits and gives you a character those represent

gusty marsh
#

Ah thanks for that link πŸ‘

rose schooner
quick snow
raven ridge
#

nice.

rose schooner
#

oh no grammar error in the merge title

#

but anyways time to find more stuff to optimize

verbal escarp
#

go go πŸ™‚

native flame
#

crow on his way to make @boreal umbra's tag obsolete

rose schooner
#

what tag

native flame
#

about the slowness of python

rose schooner
#

well it might become obsolete in python 3.12

tacit hill
#

whats this?

boreal umbra
#

@native flame you can make that tag if you want, btw

native flame
boreal umbra
lusty scroll
native flame
#

it doesnt exist yet

boreal umbra
# lusty scroll what's the name of it?

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.

lusty scroll
#

I think in a lot of cases people think it's too slow when it isn't

feral cedar
#

it's mostly just "I heard python was slow" or occasionally "python is worse than cpp because it's 1000x slower"

frank dagger
#

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.

rose schooner
#

well this is IF python really becomes JIT in 3.12/generate machine code in 3.13

naive adder
#

generate machine code πŸ‘€

#

does that mean making executables are possible in vanilla python

frank dagger
# boreal umbra is there an example of this?

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

naive adder
#

official binaries πŸ‘€

#

wait no that's just dis.dis

rose schooner
#

i'm yet to make a report on this

lusty scroll
#

give a man a gun and he'll shoot himself in the foot

#

of course the solution is to simply amputate

naive adder
lusty scroll
#

pixels_snek_1 🍿

lusty scroll
rose schooner
lusty scroll
#

that makes sense ..

lusty scroll
#

more threads != performance >.>

paper echo
#

thinking in abstract terms and not in terms of chunks of memory in a computer

static bluff
#

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

boreal umbra
#

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?

static bluff
#

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 πŸ™‚

frank dagger
sacred yew
#

undefined behavior would like to say hello

raven ridge
median palm
static bluff
#

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

median palm
#

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

verbal escarp
verbal escarp
static bluff
#

No need to be glib

static bluff
verbal escarp
#

sorry i'm not enthusiastic about the prospect of having yet another language in the world that tries to cover all use cases

static bluff
#

Javascript is a prime example of disparate parts coming to agreement upon basic standards

static bluff
verbal escarp
#

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

static bluff
verbal escarp
static bluff
#

Oh I loved this talk

#

Respectfully though, I don't need anyone's permission to study and develop languages

verbal escarp
#

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)

verbal escarp
#

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 πŸ™‚

rich cradle
# verbal escarp 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).

verbal escarp
#

which is just calling for mainstream features

static bluff
#

I don't recall saying that

static bluff
#

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

rose schooner
#

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

raven ridge
#

32 bit longs, I see. What a world.

ruby willow
limpid sigil
#

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

spark magnet
#

You want to remove <module> ?

limpid sigil
#

to make output look nicer on a little utility i'm writing to quickly evaluate a python expression from terminal

limpid sigil
spark magnet
#

it might be easiest to print the stack trace yourself, with the traceback module

limpid sigil
#

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

raven ridge
fallen slateBOT
#

Lib/importlib/_bootstrap.py line 232

# Frame stripping magic ###############################################```
raven ridge
#

(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

rose schooner
#

"most recent call first" is also a thing though

prime estuary
#

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.

alpine rose
#

you can set sys.excepthook to print out customised tracebacks

alpine rose
hearty drift
#

fun new video on super and the MRO

naive adder
#

imagine not referencing that class directly

olive marsh
verbal escarp
#

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

fallen slateBOT
#
**PEP 671 - Syntax for late-bound function argument defaults**
Status

Draft

Python-Version

3.11

Created

24-Oct-2021

Type

Standards Track

rose schooner
verbal escarp
#

hope it won't take another 20 years like some features >.>

olive marsh
verbal escarp
#

i'm wondering when can __qualname__ be none or ""?

naive adder
#

!e

globals()[''] = type('', (), {})
print(globals()[''].__qualname__)
fallen slateBOT
#

@naive adder :warning: Your eval job has completed with return code 0.

[No output]
naive adder
#

well this one is ''

#

I don't think type's first argument can be anything other than string

naive adder
verbal escarp
#

what about c-wrappers?

#

could that be a cause for missing qualname?

elder blade
fallen slateBOT
#

Lib/functools.py lines 32 to 34

WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
                       '__annotations__')
WRAPPER_UPDATES = ('__dict__',)```
elder blade
#

Aren't parameters and defaults stored somewhere? Aren't there tools inspecting those?

#

Does anybody know why __defaults__ and __kwdefaults__ aren't copied?

quick snow
#

Because they might be different in the wrapper

elder blade
quick snow
elder blade
#

Ah, interesting πŸ€”

#

Thanks

quick snow
#

!e

def foo(x=23):
    print(x)
foo.__defaults__ = (42,)
foo()
fallen slateBOT
#

@quick snow :white_check_mark: Your eval job has completed with return code 0.

42
elder blade
#

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

elder blade
#

!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`?
fallen slateBOT
#

@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
elder blade
#

def test(a, b) <- parameter

test(1, 2) <- argument

charred wagon
#

Yes

#

Well generally I'm not so sure everyone agrees. But in the context of Python, the docs do explicitly make that distinction.

elder blade
#

This distinction seems to be shared by JavaScript, C#, C++, psuedo-code (on some odd website) and surely much more.

naive adder
#

my C skills is too bad i couldn't understand the cpython source properly. are there other python implementations thats more readable for me?

naive adder
rose schooner
#

yes

naive adder
#

thanks

#

any others πŸ‘€

stone field
#

pypy

supple stag
grave jolt
#

Does anyone know why zipfile.ZipExtFile is called like that? What does the "Ext" mean?

#

Extension? External? Extracted? Exterminatable? Extinct? Extruded?

olive marsh
# grave jolt 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...

grave jolt
prime hill
#

!pep 8

fallen slateBOT
#
**PEP 8 - Style Guide for Python Code**
Status

Active

Created

05-Jul-2001

Type

Process

prime hill
#

I checked the link and stuff

#

Is it a guide to code?

#

!pep 1

fallen slateBOT
#
**PEP 1 - PEP Purpose and Guidelines**
Status

Active

Created

13-Jun-2000

Type

Process

prime hill
#

!pep 69

fallen slateBOT
#
PEP not found

PEP 69 does not exist.

prime hill
#

😒

charred wagon
#

I guess it might mean "extracted" since it's a file-like object for a specific file within the archive

grave jolt
#

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

charred wagon
#

Well... first thing that came to mind was "cheeki breeki level"

rich cradle
#

I understood that as "check break level"

lost nexus
#

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?

raven ridge
#

it sometimes does.

fallen slateBOT
#

Objects/dictobject.c line 3914

PyUnicode_InternInPlace(&kv); /* XXX Should we really? */```
spice pecan
#

I believe strings that qualify as identifiers also get interned

#

And you can always manually intern strings with sys.intern

#

!d sys.intern

fallen slateBOT
#

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.
prime estuary
#

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.

verbal escarp
sacred hatch
#

Hi

#

Hello

#

Y’all there

verbal escarp
#

hello

mint jackal
#

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

mint jackal
grave jolt
unkempt rock
#

h

magic python
#

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

raven ridge
#

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

magic python
#

It always felt a bit odd, and languages like R seem to behave more naturally here

raven ridge
#

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.

spice pecan
#

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

magic python
#

You can, you just return the list?

#

That's more "functional"?

raven ridge
#

sure - which would be natural in a functional language, but I wouldn't say that's natural in a procedural language

magic python
verbal escarp
dusty osprey
#

Hi

verbal escarp
#

hi

grave jolt
#

it's a method call!

verbal escarp
#

i (ab)use this in fuzzylogic to wrap things on the fly for convenience, very useful

fossil blade
#

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):
   ...
flat gazelle
#

from . import smth as s

quick snow
#

I mean you can also do

from somewhere import Something

class Something(Something):
    ...

if you don't need the original class here anymore

fossil blade
fossil blade
#

How do I make an issue in python

#

I found an anti pattern

verbal escarp
fossil blade
#

Yes

#

I think it's an anti pattern

elder blade
#

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?

pliant tusk
fossil blade
verbal escarp
#

hu?

verbal escarp
#

and no, this isn't one

fossil blade
#

Inconsistency then?

verbal escarp
grave jolt
#

@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.

radiant garden
#

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?

paper echo
#

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"

radiant garden
#

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__)

rose schooner
fierce sleet
#

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 πŸ™

rose schooner
#

for me i just took some CPython code, started modifying, and learned from mistakes

fierce sleet
#

Do I have to have any knowledge of C?

rose schooner
#

probably

#

that's what python is implemented in

fierce sleet
#

=/

rose schooner
#

you can't know the internals of python without knowing C enough
unless you can understand from the API docs

fierce sleet
#

That sounds like a blocker to me...

#

Also, I have to buy it too

rose schooner
#

and that takes a few months to get right when you don't have knowledge about C

#

there's no easy way here

fierce sleet
fierce sleet
rose schooner
#

i didn't even know that existed

fierce sleet
#

Looks like a guide for contributors

#

@rose schooner mind if I PM you?

rose schooner
fierce sleet
#

I'd like to ask a question that I don't think is appropriate in a public chat