#internals-and-peps

1 messages · Page 41 of 1

wide shuttle
#

You're making a function anyway, one that's 3-5 lines. In one instance you just use lambda to make it, in the other def

#

The latter has readability and gets debugging information, such as the function name bound the __repr__

rich wharf
#

if I made a def for each of these, I'd have to scroll up constantly

#

and I've still kept them readable

wide shuttle
#

They both result in a callable object in memory with compiled code, and if you're making a 5 line lambda, a 5 line def at more or less the same place would be okay.

#

Since it apparently doesn't matter if the function object goes out of scope.

rich wharf
#

the problem is I have a continuous list with each of those

raven ridge
#

you don't need to scroll up - you can def a new function right where you are lambda'ing a new function.

rich wharf
#

no I can't, not in the middle of a list

#

defs aren't expressions

#

these lists usually have a couple dozen lambdas in one place with simple logic

wide shuttle
#

I guess to each their preference. I just really hate the look of long expressions that have multiple lambda subexpressions in them

rich wharf
#
Statement(
            'builtins_forever',
            'Repeat the code forever',
            ['forever'],
            lt.function('frame, exprs', lambda v: (
                (yield from lt.during(lambda v: True, lambda v: (
                    yield from v.frame.execute(v.exprs[0])
                )))
            ))
        )```
#

these lambdas are simple logic in a continuous list with items just like that

#

so it's organized to have all of this data in one place for me

#

this use case is rare but it does exactly what my needs are

#

and this is a language that has code meant to be as easy as pseudo-code for basic scripting purposes that I'm making

#

but it's convenient to have this all in one place with the function right there

wide shuttle
#

This less readable for me, as there is less information. I have to parse your expression to see what it does. To me, this is the kind of thing I don't like reading.

north root
#

i'm gonna be honest, that looks kind of horrifying to me in python. although, i guess it's just preference

rich wharf
#

to me it's just fine

wide shuttle
#

Having a function with an actual descriptive name and then using that descriptive name just looks so much better to me

rich wharf
#

then it'll be hundreds of lines above where that statement object is

#

maybe it is preference, but I think I'm going to be keeping lambdas like that

wide shuttle
#

Yeah, maybe. I'm not saying that you shouldn't; I'm just saying that I've personally not reviewed a lot of code where more complicated lambda would have increased readability.

rich wharf
#

I only have a few functions that aren't anonymous like those ones, and those are for complex logic

#

And you're right

#

A somewhat logical lambda is uncommon but this is a use case for it

#

And even though it's less readable then a regular function, it's still readable enough, and it's convenient because all of the expression is in one place

#

And it means adding new statements is easy too

#

All I have to do is add a statement in one place with one function attached

#

And editing these statements is convenient too

wide shuttle
#

But you're calling for multi-expression lambdas, right? The ones that would take 3-5 statements.

rich wharf
#

Yes, but this is a good use case for me

#

Usually I can use a regular function if it's only a few lines away

#

In this case, it will never be a few lines away because of the sheer size of this

#

This use case is very uncommon, but that's my point of view

primal girder
#

With a meaningful function name it doesn't matter how far away it is

rich wharf
#

The expression already has a name

#

If it is this hard to debug, I can just attach the expression name to the lambda can't I?

#

And it does matter how far away it is

#

It's much harder to maintain when it's not all in one place

#

If I wanted to translate all of the code with messages in it, I wouldn't have to go to two places to do this

primal girder
#

That's where good editors come in.

ionic void
#

Why does Python have so many ways to format strings? Doesn't Python try to do similar things in one way?

primal girder
#

They can take you directly to the implementation and back

wide shuttle
rich wharf
#

Honestly, this is just a matter of preference, but even then I like having it all in one spot.

#

And having to constantly switch places even with an IDE doesn't seem like the solution I want

#

I think that's enough explaining my case for now.

#

Thanks for taking the time to make your counterarguments and reasoning.

north root
#

string concatenation and f-strings are pretty standard in many languages. str.format is there for backwards compatibility and is useful for templating strings. i think printf style is also for backwards compatibility.

rich wharf
#

my preference is the fstring

north root
#

yeah, i agree in that it's a matter of preference

wide shuttle
#

I think that having reasonable limitations on what you can and can't do is what has created a very readable language. It may be that those decisions are not the best for every case, but I think picking different defaults would lead to a less readable language in general, maybe just not in this particular use case.

ionic void
#

But why don't they remove the old ones?

#

It's slower than f-strings.

#

Is backwards compatibility the only reason?

rich wharf
#

Because it would break backwards compatibility

#

If people update to the new version, they would have to rewrite plenty of code

ionic void
#

Oh, hm.

wide shuttle
#

Not entirely, you can do things with str.format that are not possible f-strings, such as formatting a string at a later point in time.

rich wharf
#

A lot of times that isn't worth it

#

And that's true too

wide shuttle
#

But, it would break a lot and it's probably not worth it.

ionic void
#

Oh really!?

rich wharf
#

Actually yes, I use that too

#

I have a list of template strings and I format them

#

When is Python 4 coming, if it comes, out of curiousity?

ionic void
#

There's a Python 4 planned?

rich wharf
#

I don't think so yet

ionic void
#

Didn't Python 3 take like 10 years.

rich wharf
#

But I'm wondering if and when it will

ionic void
#

To fully roll out.

rich wharf
#

I'm not sure

#

What was Python 1 like?

wide shuttle
#

There was a plan to just go to Python 4 after Python 3.9, but that has been abandoned a few years ago. The idea was to keep the transition small to avoid the Py2-Py3 controversy.

#

However, there are sometimes some breaking changes that you do want to make and reserving a major version change for those kind of changes has its purpose as well

rich wharf
#

What would a Python 4 have that would break Python 3 compatibility?

wide shuttle
#

One change that was planned for a Py4 release was the new annotations behavior. I'm actually not sure when they want do that now. I think they may still wait for Py4 with that.

#

It's what you get now if you do the from __future__ import annotations import

#

I haven't kept up with that PEP, though, so maybe the planned release version has changed. (That PEP was released when Py4 was still planned as the version after P3.9)

rich wharf
#

If Python did add better lambdas, I'd propose syntax like this maybe (even though it has its downsides), but I don't think good lambdas are easy with Python's whitespace system

#
doStuffWith(
  lambda: (
    if True:
      print(3)
    else:
      for i in range(3):
        print(i)
  ), lambda: (
    for i in range(3):
      if i == 2:
        print(i)
  )
)
ionic void
#

I never really understood how dunder name == dunder main helps check if a module is imported or not, does Python just magically add something?

rich wharf
#

__name__ is basically what is calling it

#

if it's "__main__", it's the actual package and module

ionic void
#

But isn't Python a functional language?

rich wharf
#

if it's something else, like "mymod", I think that's the module importing it

#

What do you mean?

north root
#

python is multi-paradigm

ionic void
#

and main is kind of like a method which is part of a class?

#

Oh why did Discord do that.

rich wharf
#

__main__ is a builtin variable that gets set

#

and it's markdown

ionic void
#

Oh so it is built-in

rich wharf
#

any variables starting with __ and ending with __ are python builtin variables and are reserved for internal use

#

you can set them, but you shouldn't

#

it's like how list = [1, 2, 3] is bad practice

ionic void
#

I'm always confused about what is or is not builtin to Python

#

Got it

#

Python has a lot more built-in functions

raven ridge
#

__all__ is an exception to that rule, at least - it's meant to be set by package owners

ionic void
#

that could be used without even importing libraries.

unkempt rock
#

its what makes python easier than everything else

#

besides scratch

#

hehe

ionic void
#

Oh haha

rich wharf
#

Python is literally psuedocode

unkempt rock
#

fr

ionic void
#

Does Java have an equivalent to Python dunder?

#

Or is this purely a unique Python feature?

rich wharf
#

Maybe constructors

#

But I'm not sure much else

ionic void
#

Hm possibly, I tried to compare those two as well.

#

But dunder doesn't even create an object.

#

It's just ...there.

wide shuttle
#

That dunder is a name assigned to some object in memory

#

The biggest concentration of dunders you'll find in the Python datamodel

rich wharf
#

Oh, I thought you were talking about dunder/magic methods

ionic void
#

They aren't the same?

wide shuttle
#

They're the hooks you can use to make your classes behave as built-in Python objects and to hook into various parts in an object's lifetime

unkempt rock
#

ye

#

wait

#

does java not have it

ionic void
#

Not that I know of.

raven ridge
#

Most of the dunder methods are essentially for operator overloading, which Java doesn't generally support.

unkempt rock
#

i dont think so

#

i think just python

#

how tho

ionic void
#

When I learn Python I try to match everything to java haha

unkempt rock
#

like isnt java supposed to have more capabilities than python

ionic void
#

No.

unkempt rock
#

o

ionic void
#

They have different strengths.

raven ridge
#

C++ has pretty close analogues to some Python dunders, with things like operator+ and operator<<

ionic void
#

The biggest difference is probably that Java is statically typed.

#

So it's faster.

#

hm oh

unkempt rock
#

is it really necessary tho

#

to have dunder

#

like

ionic void
#

I guess.

unkempt rock
#

what makes it different from dictionary

#

except that its hundred times more organized

ionic void
#

But the tutorial that I did talked about it, and I was confused.

primal girder
#

If you're looking for speed, then c++ is what you're after

unkempt rock
#

yes c++ does all the stuff

primal girder
#

Java isn't particularly useful

raven ridge
#

Java isn't just faster because of static typing (though that does make it do less work). The fact that it compiles to bytecode with a JIT is its biggest performance advantage over Python.

unkempt rock
#

did my PhD in quantum computing where nothing but speed is important

#

actually almost all the stuff was written in C or Fortran

ionic void
#

Yes that's true.

unkempt rock
#

but you can always go a step further and write assembler

ionic void
#

But then Python is more human readable than those languages.

#

That's also a strength.

#

It's easier to learn.

primal girder
#

Python and c++ work quite well together

#

Libraries like pybind11 are awesome

raven ridge
#

Dunder isn't necessary. Python chooses to pass self explicitly, unlike Java passing this implicitly. So, one could imagine an alternative to dunders where instead of specially named methods, you call a method anything you want, and then call a function or use a decorator to register it to the object model.

primal girder
#

You can do the performance critical stuff in c++ and expose that to python easily

unkempt rock
#

or just use Numpy instead of basic python

#

and you get very close

#

without having to write any C++

raven ridge
#

That is, you can see dunders as a way to do something implicitly (with magic methods with known names) that could instead be done explicitly (with explicit registration to make non-magic methods magic)

ionic void
#

ah ok, but do you create the "known names" or are they premade?

unkempt rock
#

there's something i never tried doing before

#

how do i list all the words from a file

#

like

#

slap it into a list

raven ridge
#

With Python's data model the known names are things like __init__ and __add__ - the interpreter knows them and looks for them.

ionic void
#

Use a for loop? and append each word into the list from your file?

#

I've done it with an URL before, I haven't gotten to Python I/O yet.

uncut sage
#
  1. read each line
  2. split each line into words
  3. add each word to a set so there are no duplicates
ionic void
#

Oh that's good

uncut sage
#

@unkempt rock

unkempt rock
#

uh

#

how do i determine line

uncut sage
#

When you read from a text file Python automatically reads a line at a time unless you specify otherwise

ionic void
#

^ you just need to open the file and put it in read mode

#

well the default is read.

unkempt rock
#

Well, there are countless tutorials on how to read a file in python

#

just look into one of those

#

oh wait nvm

#

im actually braindead

#

smhmyhead

#

didnt even need to split into a list lmao

wide shuttle
#

With Python's data model the known names are things like __init__ and __add__ - the interpreter knows them and looks for them.
@raven ridge

I really like this way of doing it, as it means that I know what to look for as well. It should also set apart the functions/names that have a special meaning in the data model.

raven ridge
#

Oh, I agree that it's more elegant than the alternatives - I was just saying that there definitely are alternatives that could have worked.

wide shuttle
#

Yeah, I wasn't trying to argue that point, more trying to add that I like the decision that was made

#

but, there are alternatives

raven ridge
#

It's also better than C++'s approach - that also has magic names, but a) some of those magic functions can be defined outside the class, which is madness when it comes to tracking down how things will behave, and b) they choose operator$OP as the function name, which is ambiguous for things like pre- vs post- increment and requires a whole ugly hack to fix

#

If I recall correctly, some operator overloads must be defined as free functions in C++, in fact...

wide shuttle
#

I was just looking at it; I haven't touched C++ in a long time

#

The current page I'm looking at has it the other way around, that some overloadings cannot be a non-member

raven ridge
#

Stream extraction and insertion

The overloads of operator>> and operator<< that take a std::istream& or std::ostream& as the left hand argument are known as insertion and extraction operators. Since they take the user-defined type as the right argument (b in a@b), they must be implemented as non-members.

#

I was double checking myself on that same page 😀

wide shuttle
#

Ah, nice. I should have read more

raven ridge
#

It's kinda the same problem as Python solves with the reflected dunders, come to think of it

undone hare
#

3.9 has some cool features so far

fossil pumice
#

@undone hare what are you favorite ones?

undone hare
fossil pumice
#

hell yeah, that's a nice change

#

such a tiny change but very appreciated

undone hare
#

Yup

wide shuttle
#

I'm excited about PEG and what it will hold for the future

#

It's the new parser

undone hare
#

Yup, that's quite interesting too

#

The new parser also has a wonderful +27,058 additions, −147 deletions haha

deft pagoda
#

new parser is a PEG?

undone hare
#

Yup

deft pagoda
#

nice, i wanted to implement my own toy peg a few months ago, but moved past it

#
Dictionary Merge & Update Operators¶
Merge (|) and update (|=) operators have been added to the built-in dict class. See PEP 584 for a full description. (Contributed by Brandt Bucher in bpo-36144.)
wide shuttle
#

That is pretty cool

deft pagoda
#

i'm gonna guess this is what i'll be using the most

#

would be cool if it added things to a ChainMap too

#

maybe ChainMap already has it, i've never looked

#

it doesn't 😦

#

oh i actually wanted this not that long ago:

PEP 616: New removeprefix() and removesuffix() string methods¶
str.removeprefix(prefix) and str.removesuffix(suffix) have been added to easily remove an unneeded prefix or a suffix from a string. Corresponding bytes, bytearray, and collections.UserString methods have also been added. See PEP 616 for a full description. (Contributed by Dennis Sweeney in bpo-18939.)
#

now i have to find out where it was

ruby spruce
#

Is next Python 3.10 or 4?

gray mirage
#

3.10

ruby spruce
#

😭

#

I hope we get Py4 in one day

unkempt rock
#

true

jovial pagoda
#

I have 64-bit processor, so it is better to have 64-bit python or 32-bit python?

undone hare
#
Dictionary Merge & Update Operators¶
Merge (|) and update (|=) operators have been added to the built-in dict class. See PEP 584 for a full description. (Contributed by Brandt Bucher in bpo-36144.)

@deft pagoda well, you could already do {**dict1, **dict2}, but not a lot of people know about it apparently, according to the PEP

#

@jovial pagoda 64bits for sure

jovial pagoda
#

but, it will work same, right?

deft pagoda
#

that just doesn't look pretty

wide shuttle
#

The PEP says this:

{**d1, **d2}

Dict unpacking looks ugly and is not easily discoverable. Few people would be able to guess what it means the first time they see it, or think of it as the "obvious way" to merge two dicts.

undone hare
#

@jovial pagoda yup, but the 64bits is faster and can use more than 4Gb of memory

#

I don't think it looks that ugly, but that's isn't the most obvious thing ever yeah

deft pagoda
#

ha, agree with PEP

undone hare
#

Unpacking inside constructors works for lists and sets too, and has its use cases

oblique crystal
#

that just doesn't look pretty
or how to say "looks ugly" not using word "ugly"

deft pagoda
#

i'm a glass twice as big as it needs to be kind of guy

oblique crystal
#

having those dict operators is cool really, should make codes quite nicer

raven pike
#

I never get zipping and unpacking man. I just don't get it. I don't remember c++ had this one, that's the only languages I am familiar with except python

peak spoke
#

I think without knowing it beforehand, the unpacking is a bit clearer than update imo

raven pike
#

Guys can't we decleare a variable without assigning anything to it? Just decleare an address for example

flat gazelle
#

not really

dreamy tartan
#

Why would you need to do that in python?

flat gazelle
#

there is no reason to

undone hare
#

Nope you can't, and there's no so much point in doing so, because of Python's nature

dreamy tartan
#

That's more of a C thing to do, because you have to keep variables a certain type.

You do not have to do this in python.

flat gazelle
#

only functions have their own scope, and in those you can use global to make a variable global even if there is no outer variable

#
if a:
    b = 7
else:
    b = 6
print(b)
```this works
deft pagoda
#

you can do it in classes

raven pike
#

you can do it in classes
@deft pagoda like how?

flat gazelle
#

just

class U:
    name
``` afaik
deft pagoda
#

by __prepare__ passing a default dict

flat gazelle
#

optionally with a type hint

raven pike
#

Oh, this sounds interesting. İs I'll dig into that

deft pagoda
#

!e

from itertools import count

class IncrDict(dict):
    def __init__(self, start=0, step=1):
        self.counter = count(start, step)

    def __missing__(self, key):
        if key.startswith('__'):
            raise KeyError(key)

        self[key] = next(self.counter)
        return self[key]

class EnumMetaclass(type):
    def __prepare__(*args, **kwargs):
        start = kwargs.get('start', 0)
        step = kwargs.get('step', 1)
        return IncrDict(start, step)

class Enum(metaclass=EnumMetaclass):
    def __init_subclass__(cls, **kwargs):
        """Pull kwargs from class def"""

class Fruit(Enum, start=10, step=15):
    APPLE
    BANANA
    KIWI

print(Fruit.APPLE, Fruit.BANANA, Fruit.KIWI)
fallen slateBOT
#

@deft pagoda :white_check_mark: Your eval job has completed with return code 0.

10 25 40
deft pagoda
#

APPLE, BANANA, and KIWI weren't defined!

raven pike
#

Interesting. Thanks for sharing

peak spoke
#

Not really something I'd want to see in real code

deft pagoda
#

this is real code

#

this is the best Enum class i've ever seen

undone hare
#

All of that just because salt is too lazy to type 6 digits

deft pagoda
#

pff, i've done worse things

flat gazelle
#

I mean, how often do you really care about what exactly the ordinals in an enum are. You just need them distinct, and sometimes on distinct bits too

deft pagoda
#

i hacked kivy's widget.py to ChainMap kivy Properties in the Widget class defs

#

for convenience

raven pike
#

One of you said 64 bit version of python could eat much more ram, so if I replace mine with 32 bit, the ram usage would decreased? I'm having trouble working in vscode, and out of my 8 GB ram using chrome for problem solving etc I left with only 400 mb so many times. Although I'm using vs code's interactive python screen as well

flat gazelle
#

not really, it is more that the 32bit will not drain all your ram if you overallocate

undone hare
#

Well, python will use the same amount of bits to represent a value, even if you use a 32bits version or a 64bits

visual shadow
#

dont use 32bit python, the headaches associated are a lot greater

raven pike
#

Oh ok. Just thought do that and boom. Free ram 😄

visual shadow
#

haha. if you need more ram, just download more ram online! (ps, that was a joke!)

flat gazelle
visual shadow
#

i knew it was coming too haha!

undone hare
#

I was going to do that >.>

visual shadow
#

But yeah, stick with 64bit python, and dont worry about looking at the ram your system is using. your system tries it best to allocate and deallocate memory as necessary

#

if you dont have a lot of applications open at the same time, you should be fine for normal use. if you load something that's too big to fit in memory, then the "application" isnt the problem, the volume of data is.

flat gazelle
#

I have pushed chrome with ~100 tabs to 200MB of RAM

peak spoke
#

@deft pagoda well in general people should stay away from metaclasses imo, or use the builtin simple ones like Enum which don't do that much black magic

visual shadow
#

in that case, you use other techniques to work with the data

undone hare
#

The 32 bits version might even have more overhead than the 64bits

flat gazelle
#

the OS is pretty good at managing memory

peak spoke
#

Explicit is better than implicit and all

deft pagoda
#

i think in general people should use meta classes more often to produce more interesting libraries with simpler interfaces

visual shadow
#

iirc the 32bit python has a hardcap on using only 2gb ram for python. it's a horrid environment to work in, very starved for resources

flat gazelle
#

sometimes, that is nice

#

when doing which, if you screw up, would use a lot ram

#

can be hard to shut it down in time

undone hare
#

Meta classes are here to provide more DSL, and that's something I think we should have more in python

peak spoke
#

metaclasses usually lead to dynamic code which just gets more confusing for tools and people

visual shadow
#

what's dsl?

peak spoke
#

if I saw

class Fruit(Enum, start=10, step=15):
    APPLE
    BANANA
    KIWI

as a random snippet in a lib I'd have to guess what it does

flat gazelle
#

personally, I prefer DSLs in separate files, rather than strapped onto existing syntax

#

like kvlang

#

Domain Specific Language

undone hare
#

^

visual shadow
#

i see. that phrase doesnt mean much to me atm, so i'd have to look into it

flat gazelle
#

well, there are some languages where DSLs are convenient, like FORTH, LISP, kotlin and such

#

but in python, it does not work all that well imo

deft pagoda
#

i'm not such a stickler for conformity -- if you can make a simple to use interface with a metaclass, i think you should do it -- it's not like you can't document what you're doing

molten onyx
#

I don't like this "hack" but I do think that enum.auto should definitely be a descriptor

deft pagoda
#

pythons enums look awful

wide shuttle
#

I think there's a lot of value in having things behave in a predictable way

deft pagoda
#

i bet that Enum class behaves the same way every time, thats predictable!

wide shuttle
#

Very. But you know what I mean.

deft pagoda
#

the sly parser uses the magic @_ decorator in class defs

wide shuttle
#

@wide moss This channel is specifically meant to discuss the Python programming language itself, from a higher perspective. You could try one of our off-topic channels, but we're a Python-specific server. This is a C/C++ Discord server: https://discord.gg/vnyVmAE.

sacred tinsel
#

is there a style guide for method definition order, i.e. dunder property static abstract.. ?

#

looks like PEP8 doesn't mention that

#

also, in the case of an abstract property, I'm not sure whether to group it with properties or abstract methods

grave jolt
#

I think it's reasonable to define __init__, __repl__ and __str__ on top

sacred tinsel
#

yeah, I do dunders at the top, but for the rest, I'm not sure

#

I think in Java the convention is to do static at the very top

#

I don't do staticmethods much - if it's a non-bound helper accessed from within only I put it as a module-level func

wide shuttle
#

That's what I recently started doing more and more as well

sacred tinsel
#

it's so nice

grave jolt
peak spoke
#

I usually lean towards putting not that functional things like str towards the end, along with classmethod constructors and function helpers

sacred tinsel
#

it's interesting because I remember chatting to the professor who led my bsc dissertation about this (in relation to C++), he said it should tell a story and the interface should be at the bottom, not the top

peak spoke
#

the others mostly grouped by functionality between that (and of course init on top if there is one)

grave jolt
#

I think consistency is more important than a particular choice here. If a class has 100 methods, maybe there's something wrong with it

peak spoke
#

the main constructor/initialization method should be at the top imo but beyond that it's preference

grave jolt
#

True

sacred tinsel
#

I think the reasoning there was that if you read the class top to bottom, you shouldn't come across references to things that you haven't seen defined yet

#

but overall I believe the opposite is preferred by many

#

i.e. interface at the top

#

which makes sense too

wide shuttle
#

I struggle with the question as well

#

I'm not always sure what the best option is

#

Too bad there's no black for method definition order

sacred tinsel
#

with this abstract property, I'm tempted to put it above the __init__

#

ahh, it's so difficult

#

I wish there was a way to have an abstract attribute

grave jolt
#

Maybe someone could make a metaclass for that🧂

wide shuttle
#

With a bit of magic, you could do head surgery on the child class (as Beazley calls it) and make it raise an error when you try to intantiate it if it does not define certain attributes at class definition time

#

It's just "custom", so you may upset people

sacred tinsel
#

yeah, I don't like that

#

I'm aware that it's possible, what I mean is "I wish abc supported it"

molten onyx
#

There's no real way to know what attributes a child defines as __init__ is only called after the instance exists

grave jolt
#

Only if it's required to be a property for some weird reason.

#

Maybe you can redefine __init__ on instance creation. That will show the contract breaching in a test case.

sacred tinsel
#

I wouldn't mind enforcing it via tests, but that's pretty difficult, too

#

the ABC will give you its subclasses, but only if their definitions had run at that point

grave jolt
#

Maybe you can look for both properties and annotations.

#

But that would create some ugly redundant annotations.

#
class Point:
    x: float
    y: float
    def __init__(self, x: float, y: float):
        """Constructor takes two floating-point numbers and creates a 2D point"""
        if not isinstance(x, float):
            print(f"Invalid argument: {x=}")
        if not isinstance(y, float):
            print(f"Invalid argument: {y=}")
        self.x, self.y = x, y
wide shuttle
#

I honestly thought you meant a class attribute

#

Not an instance attribute

sacred tinsel
#

I meant class attrs

grave jolt
#

oh

#

Then you can detect them on class defintion, right?

sacred tinsel
#

yeah, but it's still "custom"

#

I wouldn't consider that out of the box functionality

grave jolt
#

true

#

But maybe it will be obvious if you call it my_property: AbstractProperty

#

or something like that

#

Can't you just say my_property = abc.abstractproperty()?

#

Oh, it won't be enforced.

sacred tinsel
#

ideally, I'd want this:

class MyABC(ABC):
  attr: some_type  # Somehow express that this must be provided by the child

class Implementation(MyABC):
  ...  # This fails on class creation because attr isn't defined
#

afaik, the only way this is supported by abc is having a property decorated as abc.abstractmethod

grave jolt
#

!e

from abc import abstractproperty

class AbstractPropertyEnforcer(type):
    def __new__(cls, name, bases, newattrs):
        if len(bases) > 0:
            base = bases[0]
            for prop_name, prop_value in base.__dict__.items():
                if (
                    isinstance(prop_value, abstractproperty)
                    and prop_name not in newattrs
                ):
                    raise TypeError(
                        f"Child class {name} must implement the abstract "\
                        f"property '{prop_name}'."
                    )
        return super().__new__(cls, name, bases, newattrs)

class Base(metaclass=AbstractPropertyEnforcer):
    x = abstractproperty()

class Child1(Base):
    x = 42

class Child2(Base):
    y = 42
fallen slateBOT
#

@grave jolt :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 24, in <module>
003 |   File "<string>", line 12, in __new__
004 | TypeError: Child class Child2 must implement the abstract property 'x'.
wide shuttle
#

You could also do this with __init_subclass__

grave jolt
#

oh

#

True, that's much better

lost nexus
#

Is there any advantage to defining a sequence with its respective literal rather than calling it? For example [] over list()

grave jolt
#

well

wide moss
#

what is a great randamizer function

grave jolt
#

maybe dict() might give some advantage over {} if you're working with sets a lot in a module

lost nexus
#

So, is it a visual preference or does it play any role in how efficient the code is?

grave jolt
#

probably ```py
In [25]: %timeit x = []
25.5 ns ± 0.142 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [26]: %timeit x = list()
68.7 ns ± 0.683 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

wide shuttle
#

It does make a difference, yeah

lost nexus
#

I see

wide shuttle
#

For the list() variant, you load a name and call a function

undone hare
#

Yup, list() is a function

grave jolt
#

!e

__import__("dis").dis(lambda: list())
print()
__import__("dis").dis(lambda: [])
fallen slateBOT
#

@grave jolt :white_check_mark: Your eval job has completed with return code 0.

001 |   1           0 LOAD_GLOBAL              0 (list)
002 |               2 CALL_FUNCTION            0
003 |               4 RETURN_VALUE
004 | 
005 |   3           0 BUILD_LIST               0
006 |               2 RETURN_VALUE
undone hare
#

As [] is directly BUILD_LIST

grave jolt
#

well, technically it's a class, but it's still some object you have to call.

#

And BUILD_LIST just allocates some memory and copies some stuff into there.

undone hare
#

Well, that's a bound function :>

grave jolt
#

(probably)

wide shuttle
#

I call it a function because it's listed in the documentation as a built-in function

#

I'm not actually sure how it's implemented.

grave jolt
wide shuttle
#

I've not checked

#

haha

#

that's interesting

grave jolt
#

Maybe they did that so that beginners aren't confused too much while reading the docs.

undone hare
#

Well, that's the python docs haha

wide shuttle
#

I think the Python docs are excellent for language docs

undone hare
#

or just two different people wrote it

wide shuttle
#

They're not perfect, sure

undone hare
#

They are really good yeah

#

But that's funny to see all the issues about docs on bpo

lost nexus
#

I learned 75% of what I know of Python off the offline docs I randomly found on my drive

sacred tinsel
#

I hate that the docs never show up at the top of my google searches

#

it's always some magicalpythonsnakegrandmasters.org tutorial

wide shuttle
#

I've added a custom shortcut to my firefox for that

sacred tinsel
#

and when I actually find the doc link, it's 2.7

wide shuttle
#

p3doc <search term>

undone hare
#

Tbh I don't google anymore, I !d-ing

zenith topaz
#

Python 2 is often the first one.
Python 3 the seond for me

wide shuttle
#

and p3doc searches the docs specifically

undone hare
#

Well, there is a big red warning now on the py2 docs

#

Docstrings are also useful

wide shuttle
#

That's what I did

undone hare
#

That's pretty cool

wide shuttle
#

It's just a firefox feature

wide moss
#

how do you make text bubble to show code ?

wide shuttle
#

Try the !codeblock tag in #bot-commands

peak spoke
#

making google search the good docs without writing out the url at the start can sometimes be a tad hard

#

for some things I tend to get docs from 15 years ago

undone hare
#

It looks like BUILD_STRING is a wrapper around the PyObject* STRINGLIB_NEW(STRINGLIB_CHAR*, Py_ssize_t) function, I'm looking for the list

wide shuttle
#

Python 2 docs have really good SEO and I don't think it helps that you can change the version in the bar at the top

#

If you do that, Google assumes you've found what you're looking for with that Py2 docs link

peak spoke
#

at least they're better than the ones which pop up first but are missing the selector (or completely different structure)

grave jolt
#

Or maybe that's just a mypy bug?

undone hare
grave jolt
#

and loading a global name

undone hare
#

Yup

#

Would someone here already set up PyCharm to dev CPython directly? I'm having a really hard time to make it find modules and such, and I can't find anything online

true ridge
#

I dont know if pycharm supports it but for finding functions definitions etc, we have a build target that outputs tags file (make tags)

undone hare
#

Oh hey, I remember seeing your name on bpo haha

deft pagoda
#

i actually implemented that thing for someone in a help channel --- the init_subclass enforcing attributes of the children

undone hare
#

I'll try geany thanks!

deft pagoda
#

need a ipython line magic for opening pydocs

#
# -----------------------------------------
# ---------- Quick Pydocs %docs -----------
# -----------------------------------------

import webbrowser

@register_line_magic
def docs(line):
    webbrowser.open(f'https://docs.python.org/3/search.html?q={line}')

del docs
peak spoke
#

Could download the inventory and search like !d does

undone hare
#

The first beta of Py3.9 should be out today apparently

peak spoke
#

the pep for the new release cycle has a nice chart for the periods

#

!pep 602

fallen slateBOT
#
**PEP 602 - Annual Release Cycle for Python**
Status

Accepted

Python-Version

3.9

Created

04-Jun-2019

Type

Informational

true ridge
#

Oh hey, I remember seeing your name on bpo haha
@undone hare haha, nice. I just learnt that discord can automatically match ascii characters with different styles (such as s in my surname), so I switched back to my original name.

grizzled vigil
#

@wide shuttle

I call it a function because it's listed in the documentation as a built-in function
Simply calling list() a function is accurate enough for 99% of use cases, at least IMO. I suspect that's why it's grouped as a built-in function, even if it may technically not be.

@grave jolt

Maybe they did that so that beginners aren't confused too much while reading the docs.
Most of the Python docs tend to lean in the direction of focusing on being "practically accurate" rather than being 100% semantically accurate. I'd consider it to be a case of practicality > purity.

undone hare
#

One thing that I'd like to see on the docs is a link to the source code though, to check the implementation quickly, but the docs have a pretty good balance between correctness and readability imo

deft pagoda
#

docs have a link to source

undone hare
#

Yes there's a per module link, but not a per element link to the right line, and some doesn't even have a link, like the built in

prime estuary
#

One difficulty is that that would need to be somehow dynamic so it updates every time someone commits to the file.

wide shuttle
#

Yeah, cool, I was just reading that

molten onyx
#

Does this mean 3.9 is on feature freeze

#

oh hey

#

This seems to be the same memory leak I never reported yert

true ridge
#

Does this mean 3.9 is on feature freeze
@molten onyx yep, no new features to 3.9 (unless RM decides otherwise)

undone hare
#

It looks like all major 3.9 features have already been merged anyway

#

Are you hyped about the new parser @true ridge ? lemon_pika

true ridge
#

Very much

#

The only thing I'm sad about is deprecation of lib2to3 :(

#

That was a must, since the parser generator inside of it was LL(1) and in the future won't be able to parse new python code, though it was nice to have a CST implementation on the stdlib

undone hare
#

Oh, that’s a bit sad that they deprecated 2to3

#

The new parser looks pretty cool

#

Oh well, hello news

#

I’m really wondering why posting the download link twice though, it seems like that’s the case for every annoucement, that’s pretty weird

boreal umbra
#

does datetime.timedelta not support formatting their duration as a string in a custom format?

shy vine
#

Nope

boreal umbra
#

This is very upsetting for me.

#

I might have to look into what it would take to implement that.

tame bay
#

Yo, is there anyway I can remove blank lines while reading my text?

peak spoke
#

ought to have a lib, but the format it does is pretty neat imo; not sure if weeks could be included without getting into time weirdness

sturdy timber
tame bay
#

Haha, my bad, it's just I'm in a hurry, and the channel is closed

#

So, what do you guys usually talk about in here?

north root
#

it's in the channel topic

Discussion on the use cases, implementation and future of the Python programming language including PEPs, new releases, the standard library and the overall design of the language.

tame bay
#

Oh, interesting!

vale bolt
#

can anyone explain why python cant be used on client side the same way javascript is?

flat gazelle
#

because browsers run javascript. Anything that wants to run client side has to be javascript

unkempt rock
#

the browser can't run it

flat gazelle
#

everything else just compiles to javascript. (well there is also WASM)

#

python actually does have a runtime for JS (brython), but it is not really production ready

vale bolt
#

Oh ok, then why dont browsers allow more languages?

flat gazelle
#

because all of them would have to agree on one

#

and implement it

#

according to a very strict standard

lost nexus
#

Why does Python allocate so much memory to dictionaries?

flat gazelle
#

they are hashtables, and they need quite a bit of space because of that

#

and also, it overallocates in case the dict grows

vale bolt
#

ok thanks man

lost nexus
#

Don't all sequences over-allocate to pre-allocate?

gray mirage
#

tuples and other fixed-size ones don't

flat gazelle
#

ye, frozenset does not either.

#

neither do strings

lost nexus
#

I see

gray mirage
#

yeah, they're immutable so there's no point

inner edge
#

What's more efficient, .endswith("baz") or string[-n:]?

deft pagoda
#

use the more explicit one and don't worry about anything else

peak spoke
#

readability first, speed last or when it becomes a bottleneck

boreal umbra
#

I think it would be pretty simple to implement custom duration formatting with datetime.timedelta in a datetime.datetime.strftime like way using regular expressions. Do you think that would get immediately shot down?

peak spoke
#

I don't think there's as much utility for it with deltas compared to datetimes, and those just call the C function

boreal umbra
#

deltas?

#

oh, timedeltas. I thought maybe "delta" was a separate thing.

#

But I was just looking at the implementation for strftime and it looks like it's written in Python

peak spoke
#

Like, I don't want to represent a difference in units that are variable like months and years

boreal umbra
#

ah good point

#

though the hypothetical strfdelta method would just be for outputting a visual representation; the timedelta itself would be precise.

peak spoke
#

datetime's strftime should end up going to time's strftime

#

and I don't believe there's a python implementation for time

boreal umbra
#

You're right, the strftime method written in pure Python is actually just preparing an input for _time

peak spoke
#

reminded me of an issue that points to how horrible the docstring on strftime is - "Format using strftime()."

boreal umbra
#

I don't envy whoever was put in charge of that

#

The people on the various Python podcasts have remarked a few times that they always have to look up the syntax for datetime formatting.

peak spoke
#

datetime could use a redo with how it's structured, but that would break a lot of things

#

Guessing it's one of the old libs

flat gazelle
#

make datelib maybe, like pathlib

peak spoke
#

well the first commit on gh is 30 years old

boreal umbra
#

gh?

peak spoke
#

github, sorry

#

ah, looked at the wrong module because an issue mislead me; the first commit there is 18 years old and looks like it was somewhere before

boreal umbra
#

I should have been able to infer that you were talking about github

undone hare
#

They weren't even using git at this time hehe

grave jolt
#

wikipedia says that git was released in 2005, so...

#

So they probably weren't using it 18 years ago.

peak spoke
#

Could've used something else for version control before, they didn't just make up the dates of the commits

true ridge
#

before git, there was mercurial (before 2015~)

undone hare
#

There's still a mercurial mirroir, if you're still living in the 90s too 😄

grizzled vigil
#

Yep, for version control systems I believe CPython's history has been CVS -> SVN -> Mercurial -> Git

lost nexus
#

Does python support pattern binding in variables? For example:

overwrites.send_messages, overwrites.add_reactions = False, False
flat gazelle
#

Ye, that will work

#

We call it unpacking

lost nexus
#

I see, alr.

rich wharf
#
x = y => (
  if True:
    print(y)
)```
#

Example syntax for my concept of better python lambdas

#

It's unlikely for this to ever be added though

flat gazelle
#

How do you deal with indentation within indented blocks?

rich wharf
#

The syntax is as follows

#

( your block )

#

the inner block inside of indented blocks can be ignored up until the first statement

#

and the new lines after parentheses are encouraged

#

if not required

#
=> (
if True:
  print(5)
)
=> (
  if False:
    print(2)
)
=> (
      if False:
        print(3)
)
#

these are all valued

#

the second one is preferred

flat gazelle
#
if True:
    x = y => (
if True:
    return False
)
```this is valid then?
rich wharf
#

technically

#

but it's not preferred syntax

#
if True:
    x = y => (
      if True:
        return False
    )
#

My concept is that this is best practice

#

With the lambda indented one more then the outer layer

#

The good thing with surrounding this with parantheses means your example can also be parsed though

flat gazelle
#

So this would be valid then

x = y => (
    6
)
#

You would probably want -> to avoid ambiguity with the => operator

slim island
#

Some people are very opposed to pretty lambdas in Python

rich wharf
#

Huh, sure -> works too

#

@flat gazelle For multi-line expressions, that syntax is valid

#

But for single expressions, just do

#

x = y -> 6

flat gazelle
#

Actually NVM, the operator is >= and <=, not =>

#

Am doing a silly

rich wharf
#

Well -> could be confused

#

=> could be confused with them

#

So -> is equally fine

rich wharf
#

Also, we could keep existing lambdas for backwards compatibility

#

lambda: 5 <-- Still valid

#

-> 5 <-- Better practice

slim island
#

or just introduce them in Python 4 and ditch the old way

lost nexus
#

Which sequences in Python are fixed-size?

true ridge
#

builtins: frozenset, tuple

peak spoke
#

(byte)strings, range

true ridge
#

mapping proxies are also frozen

magic python
#

we're using R syntax in python now? 🤔

peak spoke
#

are those builtin @true ridge ?

#

never really saw them beyond __dict__

true ridge
#

well, technically yes type(type.__dict__) can give you access, but it isn't in the builtins module

peak spoke
#

Guess they have a similiar use to a memoryview?

#

Haven't found a use for those yet, but neither did I exactly consider them

true ridge
#

Also there is a named-tuple like sequence called PyStructSequence, that enpoweres sys.version_info etc. It is also embedded to language, but not accessible from the python level

peak spoke
#

Oh is that what sys.flags uses? It claims to be a namedtuple in the docs but the features don't agree

true ridge
#

from read-only proxy point of view, yea they both are similiar

#

yup @peak spoke

peak spoke
#

that got me confused for a bit

true ridge
#

it isn't efficient to use namedtuple in the C level, so this is kind a replacement to it but a bit different

peak spoke
#

Does it have some normal documentation or only as a part of the c api docs?

#

If it's there at all

boreal umbra
#

Which file in the cpython repo parses command line arguments given to python?

true ridge
#

It is a multi-layered process, but it startswith Modules/main.c:pymain_init

#

then you need to follow through the function calls, there are plenty of them

boreal umbra
#

Thanks for letting me know!

#

Out of curiosity, how did you get the community role?

true ridge
#

Out of curiosity, how did you get the community role?

I work on CPython on regular basis

boreal umbra
#

That's pretty cool. My friend who hates Python was complaining to me that his code that would refuse to compile in Java runs in Python and gives him an attribute error, whereas he'd prefer to know at compile time where he messed up.

#

I was going to see what it would take to add a flag that runs the mypy linter and refuse to run if there's an issue there, with no pretense that it would get added to the language.

true ridge
#

That is a cool idea, I just started like this. Thinked about a feature I would want, and implemented it while I was learning the internals

#

FWIW, it was a new conversion for f-strings for path expensions, f"{a!p}" => f"{os.fspath(a)}"

boreal umbra
#

A few weeks ago I implemented my own variation on defaultdict, but I mostly copied the defaultdict implementation and made I think one notable change.

true ridge
boreal umbra
#

Sorry, I'm not sure what you're referring to about f-strings? That's something that you implemented?

true ridge
#

that is what I thought would be cool to have, and implemented just for fun

boreal umbra
#

But it got integrated? That's great!

true ridge
#

no, it didn't

boreal umbra
#

oh 😛

true ridge
#

hahaha

boreal umbra
#

I know how you feel.

true ridge
#

but on the good side, it led me to contributing

boreal umbra
#

By the way, I want to add my dict thing to pypi. I didn't see anything similar there when I looked. Should I explicitly state in the source code that I mostly copied it from the stdlib? I'm not trying to keep it a secret that I wrote almost none of it, but I don't know what the procedure is there.

true ridge
#

By the way, I want to add my dict thing to pypi. I didn't see anything similar there when I looked. Should I explicitly state in the source code that I mostly copied it from the stdlib? I'm not trying to keep it a secret that I wrote almost none of it, but I don't know what the procedure is there.
@boreal umbra well, you can if you want, but for something like that there are no restrictions.

boreal umbra
#

hmm I see

true ridge
#

For an example, in the past, there was a tool in cpython repo itself (but not exposed in the stdlib) for unparsing an AST back to the source (and we've exposed it with 3.9 btw, ast.unparse) and someone directly took the source code and published on PyPI. For situations like that, you need to include PSFL in your license statement: https://github.com/simonpercivall/astunparse

boreal umbra
#

One of the things I never learned in my one C class is where import statements are getting things from.

#

I guess "include statements" is more accurate in the context of C.

#

not sure though

prime estuary
#

There's an "include path", which is a list of folders it searches through. <> means to use these system locations. "" means to search relative to the current folder.

boreal umbra
#

aha

prime estuary
#

Python has a similar system - sys.path.

boreal umbra
#

I just tried that in a repl I happened to have running. I guess that's a list of directories it tries to import from in a __mro__ type way?

deft pagoda
#

importing specific files in python is annoying

#

i don't know what the "right" way is, but i usually os.chdir for it

trail willow
#

I am importing for example txt files pdf and excel with this f = open("demofile.txt", "r")

wide shuttle
#

Hello @trail willow, this channel is for discussing the Python programming language itself, but we do have many other channels where you can ask a question.

undone hare
#

i don't know what the "right" way is, but i usually os.chdir for it
@deft pagoda the right way :

p = '/home/usr/myfile.py'
with open(p) as f:
    exec(f.read())```works like a charm haha
deft pagoda
#

i've thought about adding a similar function to ipython

dusty haven
#

Importlib can do that no?

gray mirage
#

Well there's execfile

deft pagoda
#

there's reload from importlib which i use often, but it won't work if you just import specific objects

sacred tinsel
#

I use reload when testing modules in a jupyter session

#

works great for me

deft pagoda
#

try it when doing from x import y

sacred tinsel
#

yeah you have to get it from the module

#

but it's not difficult to account for, right?

#

you can do

#

reload(x); y = x.y

deft pagoda
#

you can do that

#

it's annoying though, i should just overload reload

true ridge
#

@dusty haven yep, you can create a spec from the path and then execute that spec to get a module object.

deft pagoda
#

does this look right:

def reload(obj):
    if hasattr(obj, '__spec__'): return importlib.reload(obj)

    try:
        module = importlib.reload(globals()[obj.__module__])
    except KeyError:
        module = importlib.import_module(obj.__module__)

    globals()[obj.__name__] = getattr(module, obj.__name__)

unkempt rock
#

OK

dire hull
#

Petition to change loop to using index instead of iter in python4

deft pagoda
#

👎

dire hull
#

Why can't it be like normal langs

deft pagoda
#

because then people wouldn't use it

dire hull
#

Wat why

wide shuttle
#

A foreach-style loop isn't that uncommon and Python isn't the first to use this direct iteration style

#

I don't really see the advantage in iterating over integers if I want the elements of something

undone hare
#

That would be just too much verbose

dire hull
#

Can you gib example of another language that has this?

deft pagoda
#

the boilerplate setup of for-loops in c is so much worse

wide shuttle
#

"Hey, let's iterate over those integer range here. Why? Well, I want the elements of that other thing, but I decided to strip out the feature that allows me to do that, so let's do it in this roundabout way"

dire hull
#

Yes cuz index are somewhat independent of the content of the collection of things

#

And if I want to skip something I could just set it to skip

#

That's great I think

wide shuttle
#

A more fundamental restriction is that most iterables in Python don't even have an index

deft pagoda
dire hull
#

Hum

#

I see

#

I ve only used list matrix and nested lists and dict so far lol

wide shuttle
#

Yes cuz index are somewhat independent of the content of the collection of things
@dire hull

No, you're making your iteration depend on more context and be more restrictive as well

deft pagoda
#

dicts don't have an index

dire hull
#

Yes

deft pagoda
#

if you're iterating over a dict, an index does not help

dire hull
#

They fast I liek that

#

So basically python loop is better than C loop?

deft pagoda
#

it's different

wide shuttle
#

It's different

deft pagoda
#

ginx

dire hull
#

So which is better then

wide shuttle
#

I like Python-style iteration, but it fits the philosophy of abstraction

#

I want to iterate over the items of this list, so let's iterate over the items of this list

#

The index of the items has nothing to do with it

dire hull
#

I see

#

What I meant by they are somewhat independent is that you could make them dependant or if you need them to be separate you could do that as well

#

So essentially you could alter the loop search method somehow

wide shuttle
#

I don't know what you mean by that, but if you want to enumerate your iterable as you get elements from it, you can do that already

dire hull
#

Yeah salt die showed me

wide shuttle
#

And, the upshot is, enumerate works with iterables that don't allow indexing with an integer

deft pagoda
#

you can make wacky iterables in python where indices won't really help you:

In [21]: class MyIter: 
    ...:     def __iter__(self): 
    ...:         yield 'this' 
    ...:         yield 'is' 
    ...:         yield 'insane' 
    ...:                                                                                                                            

In [22]: for i in MyIter(): 
    ...:     print(i) 
    ...:                                                                                                                            
this
is
insane
flat gazelle
#

C style for loops do have their merits, but not in the pure for(int i = 0; i < 20; i++) form

dire hull
#

So what they good at ?

flat gazelle
#

they are neat when you put something else into those conditions, for example

#
for(int i = 1; i < num; i *= 2) {}
#

in python, you would need a while loop

dire hull
#

Maybe I'm just used to change index in loops lol

#

Honestly I ve been using python for a while and never realized that for loops don't work like I thought

#

Tis kinda scary

flat gazelle
#

another neat one is

for (int i = 0; i[some_string]; i++) {}
```to iterate over all indicies within a string
deft pagoda
#

i feel like that should alias for with foreach or for each

dire hull
#

Yes maybe stress it a bit

deft pagoda
#

maybe that violates the there should be only one way

dire hull
#

So that lazy peeps like me would know lol

flat gazelle
#

but foreach loops are in pretty much in every modern language, though most also keep the C style for loops as an alternative

wide shuttle
#

Iteration, iterables, and iterators are core concepts in Python and quite fundamental to how a lot of things work in the language

dire hull
#

I'ma read on that lol

wide shuttle
#

I don't think just changing the name would work, although it may help

#

At the same time, learning about the concepts is important on your way to reaching an intermediate level

dire hull
#

Ye

#

I m still reluctant to read on high level funcs lol too much work it feels like

grave jolt
peak spoke
true ridge
#

well, probably a regex bug

mellow rapids
#

how would i know what module to import for each project

#

thats smth i struggle with

#

and what happens if you dont import any module and just start coding

#

and how does the code know how to do each function

#

like do i just write them out in english in the correct template

#

like bird.move(cdvevee)

#

thx

dire hull
#

You need to know what function you are using I think

flat gazelle
#

you only import things once you discover you need sth from the given module

dire hull
#

I didn't quite understand the question tbh

gloomy rain
#

@mellow rapids The language has certain constructs and functions built into it, which you can use without importing anything.

#

There is also a standard module library that is bundled with Python, which can let you do a lot of things. If you need your program to do something that's not supported by the standard module library, you might be able to find third-party libraries online instead. In either case, you can usually find which module (whether it's bundled with Python or not) does what you want by googling.

#

@mellow rapids As for your bird.move() example, unless they happen to be built into the language, Python won't know what you mean by "bird" and "move" unless you define those names.

#

That could either mean typing out the definitions in your own code, or importing the names from a module (standard library or otherwise).

mellow rapids
#

ohh okay
you can always google what module to use i guess
thank you

gloomy rain
#

Yeah, I mean, if you need to, say, load a csv file from your computer, you could google "how to load csv in python"

#

And you will probably find a result that tells you about the csv module.

mellow rapids
#

oki

true ridge
#

@grave jolt would you open an issue?

#

that looks like a bug

wide shuttle
#

Hey @fossil charm, this is not a help channel, but rather a channel to discuss the Python programming language itself. We do have a lot of help channels and you can claim one from the Python Help: Available category just above the category this channel is in. See #❓|how-to-get-help for more details.

undone hare
radiant fulcrum
#

If you switch using the toggle to 3.9 it dissapears

#

which then goes to 3.8

#

then you go back to 3.9, and get 3.10

#

lol

grave jolt
#

They used 1-indexed lists

true ridge
#

It is a bug, and should be reported

red solar
#

@wide shuttle wait you can enumerate over sequences that don't have an integer index? so enumerate(dict) is basically for key, value in dict.items()?

flat gazelle
#

no, enumerate gives any iterable sequential integer keys

red solar
#

oh :/

wide shuttle
#

It will enumerate the elements that come out

red solar
#

eh ig that's cool too

full jay
#

Saves you from having to implement it yourself

#

Which is always nice

lusty bramble
#

i have a question about inheritance on immutable class, where can i ask it ?

full jay
#

You can ask here if you like, since it's about a broad concept in Python

lusty bramble
#

ok

oblique crystal
#

hey @covert rain perhaps it beeter fits here, as it is no longer about a "how to achieve" but about what we actually achieve with python there

covert rain
#

I believe it is already answered?

lusty bramble
#

i want to make an inheritance class on numpy.ndarray. it does’nt work with init and i dont know enough about new to do it

red solar
oblique crystal
#

like I said, we have found the solutions, but are they equivalent? @covert rain

lusty bramble
#

@red solar thanks !

#

i dont understand the .view(cls) but it works

covert rain
#

"equivalent" is a loose term

peak spoke
#

the partial calls it as a normal function with the instance passed while the get binds it normally

covert rain
#

they are equivalent in the sense that they will do the same thing

#

in my opinion the functools.partial version is better because it is more readable

#

in the company I work for, we flag invocation of dunder methods for further code review

red solar
#

what are dunder methods again?

#

__ stuff?

covert rain
#

methods that start and end with two underscores

#

dunder - double under

red solar
#

ah k

oblique crystal
#

indeed. Or at least they seem to do the same thing.

peak spoke
#

Yeah dunders should usually stay hidden behind some normal funcs that have the same behaviour or access them; but while I don't know the original issue, adding methods to instances after they were created doesn't sound very nice

oblique crystal
#

but can partial lead to some side effects?

#

in a more complex case

covert rain
#

yeah, suppose you have to pass this method to another code that inspects the method itself to find which class it is bound to

oblique crystal
#

adding methods to instances after they were created doesn't sound very nice
we this is not for production or anything, it's for quick test/prtotypye

covert rain
#

but that is evil over evil chain

deft pagoda
#

am reminded of a beazley talk:

def __iter__(self):
    if not self.done():
        yield self
    return self.result()

Future.__iter__ = __iter__
flat gazelle
#

you can trivially assign to the class, but here they are assigning to instances

covert rain
#

they want it only in one instance

#

it doesn't make sense to want it to be a method

#

because it is not in the class anyway

#

so it can be a normal function

flat gazelle
#

yeah, dont do poor style

#

inherit if you must

oblique crystal
#

in short: I have a class in the module that I don't want to touch explicitly now and a code that works that uses it.
I want to replace one specific method with the other one that is in development. So rather than change the module every time and reload jupyter/ipython kernel etc (or redo the import) or to subclass I want just to change the specific method

covert rain
#

yeah, so you're monkeypatching an instance

deft pagoda
#

inheritance

covert rain
#

just use partial

oblique crystal
#

yes

deft pagoda
#

just subclass it

covert rain
#

it is a one-off thing

#

not a project

oblique crystal
#

I don't want subclass it

covert rain
#

you can just use whatever

oblique crystal
#

because it is a big class and in init and later it needs to do the claculations

deft pagoda
#

then monkey patch it, i don't know what your original ask was

flat gazelle
#

just do

class InDevThing(Thing):
    def my_indev_method():...
```and just replace the instantiation
unkempt rock
#

monkey patching sounds like the best option to me

flat gazelle
#

ye, patching is also an option

red solar
#

@lusty bramble __new__ creates an instance of your class - so when you call __new__, whatever it returns is now what you're referencing with self (i think). So then in updateNumpyArrayWithValues, self is obj that's returned by new - which is the array view

oblique crystal
#

yeah I did not know the term monkey patching when I was asking

#

also I did not know how to monkey patch it better

covert rain
#

they are monkey patching - the question is whether to monkey patch with functools.partial or with MyClass.__get__

#

I'd go with functools.partial all day

unkempt rock
#

partial

lusty bramble
#

@lusty bramble __new__ creates an instance of your class - so when you call __new__, whatever it returns is now what you're referencing with self (i think). So then in updateNumpyArrayWithValues, self is obj that's returned by new - which is the array view
@red solar ok

red solar
#

why functools over get?

#

dislike dunder methods?

covert rain
#

dunder methods are not meant to be called

wide shuttle
#

You could use types.MethodType to create a bound method

covert rain
#

you should only call them when you subclassed and you are calling the overriden method

#

otherwise, let python call them for you

wide shuttle
#

!e

import types

def monkey_patch(self):
    print(self)

bound_method = types.MethodType(monkey_patch, "hello, there")
print(bound_method)
bound_method()
fallen slateBOT
#

@wide shuttle :white_check_mark: Your eval job has completed with return code 0.

001 | <bound method monkey_patch of 'hello, there'>
002 | hello, there
oblique crystal
#

oh

#

ok so types.MethodType is equivalent to dunder get basically?

covert rain
#

default dunder get implementation calls types.MethodType

#

but you could have a metaclass that does something else

oblique crystal
#

no metaclasses here (don't even know what are those 😁 )

#

Ves, where is the instance in your example btw? 🙂

deft pagoda
#

the string

wide shuttle
#

It's the string, yes

covert rain
#

types.MethodType does roughly the same as functools.partial

#

I would still go with functools.partial

oblique crystal
#

I see. So with types in my example it would be

#

!e

import types
class A:
    def __init__(self,b):
        self.b = b
    def print_b(self):
        print(self.b)
a=A(5)
a.print_b()
def print_b_2(self):

    print(self.b**2)
a.print_b_2 = types.MethodType(print_b_2,a)
a.print_b_2()
print(a.print_b_2)
dis.dis('a.print_b_2()')```
fallen slateBOT
#

You are not allowed to use that command here. Please use the #bot-commands channel instead.

oblique crystal
#

oh crap, I forgot I can't do it here

deft pagoda
#

yeah, that will work i think

#
In [2]: import types 
   ...:  
   ...: def monkey_patch(self): 
   ...:     print('hi') 
   ...:  
   ...: class Test: ... 
   ...:  
   ...: test = Test() 
   ...: test.say_hi = types.MethodType(monkey_patch, test) 
   ...: test.say_hi()                                                                                                               
hi
oblique crystal
#

yeah just tested.
Btw if you do dis.dis on the monkey patching line the dunder method has one less call

unkempt rock
#

oh, check it out, the functools.partial signature is using a positional only parameter. that's actually a good example for its use-case

functools.partial(func, /, *args, **keywords)

deft pagoda
#
In [7]: ThreadPoolExecutor.submit?                                                                                                  
Signature: ThreadPoolExecutor.submit(self, fn, /, *args, **kwargs)
#

same deal

oblique crystal
#

ok thanks everyone for suggestion on monkey patching 🙂 now time to actually use it

grave jolt
#

@unkempt rock yes, that's a very good example, because a function can have a func kwarg

full jay
#

I feel like I relearn about functools almost daily

deft pagoda
#

did yall know about re.Scanner

#
In [51]: tokens = ['(?P<NUMBER>\d+)', 
    ...:           '(?P<PLUS>\+)', 
    ...:           '(?P<MINUS>-)', 
    ...:           '(?P<WS>\s+)'] 
    ...: m = re.compile('|'.join(tokens)) 
    ...: s = m.scanner('1 + 2 - 3') 
    ...: list(iter(s.match, None))                                                                                                  
Out[51]: 
[<re.Match object; span=(0, 1), match='1'>,
 <re.Match object; span=(1, 2), match=' '>,
 <re.Match object; span=(2, 3), match='+'>,
 <re.Match object; span=(3, 4), match=' '>,
 <re.Match object; span=(4, 5), match='2'>,
 <re.Match object; span=(5, 6), match=' '>,
 <re.Match object; span=(6, 7), match='-'>,
 <re.Match object; span=(7, 8), match=' '>,
 <re.Match object; span=(8, 9), match='3'>]
cloud crypt
#

@deft pagoda looks like finditer to me

hasty thistle
#

that seems really similar to re.finditer...
I like some other examples I found though, with converting int/float and recognizing simple operators for example

>>> scanner.scan("sum = 3*foo + 312.50 + bar")
(['sum', "<OPCODE>'='", 3, "<OPCODE>'*'", 'foo', "<OPCODE>'+'", 312.5, "<OPCODE>'+'", 'bar'], '')
cloud crypt
#

seems interesting

grave jolt
#

!e

import re

def tokenize(tokens, string):
    matches = iter(re.compile("|".join(tokens)).scanner(string).match, None)
    tokens = ((k := next(filter(m.group, m.groupdict())), m.group(k)) for m in matches)
    return tokens

for token in tokenize(['(?P<NUMBER>\d+)', '(?P<PLUS>\+)'], "1+42+3"):
    print(token)
fallen slateBOT
#

@grave jolt :white_check_mark: Your eval job has completed with return code 0.

001 | ('NUMBER', '1')
002 | ('PLUS', '+')
003 | ('NUMBER', '42')
004 | ('PLUS', '+')
005 | ('NUMBER', '3')
hasty thistle
#

don't see why you'd use scanner there, when re.finditer does the job as well (this has the exact same output for me)

def tokenize(tokens, string):
    matches = re.finditer('|'.join(tokens), string)
    tokens = ((k, m.group()) for m in matches for k, v in m.groupdict().items() if v)
    return tokens
unkempt rock
#

the future ~

#

this goes a step beyond normal code completion, it generates snippets based on comments

inland acorn
#

first we made code to steal others jobs, now we are writting code to steal our own job?!

flat gazelle
#

type driven development, but the types are just english text

torn yacht
#

@inland acorn haha

inland acorn
#

the next step is writting code, that writes ai that writes code

boreal umbra
#

@deft pagoda is re.Scanner supposed to emulate Java.util.Scanner?

#

Because the Java scanner is my least favorite OOP solution that's ever been invented.

deft pagoda
#

i doin't know what that is

#

all i know is that re.scanner is undocumented

#

it's a re secret

torn yacht
#

the next step is writting code, that writes ai that writes code
@inland acorn Then writing code that writes code that writes code

unkempt rock
#

a code that writes itself
hmm

unkempt rock
#

hmm.....

dusty haven
#

That's just a compiler

unkempt rock
#

no an ai that writes itself over and over again i think

unkempt rock
#

How about an ai that creates an ai to then have them work on eachother to improve constantly

dire hull
#

So GAN

unkempt rock
#

Basically

limpid umbra
#

height = no.round(np.random.normal(1.75, 0.20, 5000), 2)

What does the last 2 stand for?
What's is the function of the "2" here?

unkempt rock
#

wrong channel but it's to round up to 2 decimals

limpid umbra
#

Oh, Thanks

shy vine
#

@glad goblet This is a channel for the discussion of the python language

glad goblet
#

oh ok

unkempt rock
#

what is b-string ?

deft pagoda
#

a byte string

unkempt rock
#

and what is libpython3.7m.so.1.0 ?

deft pagoda
#

looks like some shared object file

unkempt rock
#

seems like a library to me

#

library "libpython3.7m.so.1.0" not found

deft pagoda
#

.so is shared object extension

#

it's a c-extension for something

gentle lodge
#

yeah on windows they call them "DLLs"

round nexus
#

did anyone have a problem with python-dotenv where some env var names could not be fetched? like the word DEBUG is not being fetched for some reason, but if I rename it to say HELLO, then i get an output

unkempt rock
#

the word debug might be a reserved name for something

round nexus
#

oh

unkempt rock
#

i don't know.

#

i'm just guessing

round nexus
#

could be

unkempt rock
#

is it possible there is a global variable DEBUG it is fetching?

#

but it's empty or something?

round nexus
#

nop

#

empty

unkempt rock
#

external system variable i mean

#

environment variable

#

or maybe the software was started with a flag DEBUG

#

those could be some of the reasons why it's not letting you override it?

shy vine
#

This would probably be better in a help channel, this is a channel for Python language discussion

round nexus
#

I mean its a general discussion, not a question

shy vine
#

This isn’t a general discussion channel

round nexus
#

okay

unkempt rock
#

general is getting raided

tough moat
#

rip

#

I was having a nice discussion

uncut sage
#

@tough moat in re your question, the most common thing to do is include a requirements.txt file with the repo, or a proper setup.py

molten onyx
#

You also have the option of pyproject.toml now

unkempt rock
#

so ik this isnt the place to ask this but general is locked soo yeah,Im still gonna ask,Does anyone know a server like this one just for java script

surreal fern
#

Hello guys need help regarding setting environment variable in virutalenv on windows machine I tried set PYTHONPATH="TESTSTRING" but when I print(os.environ["PYTHONPATH"]) It give raise KeyError(key) from None

gray mirage
#

The general channel was locked while staff deal with a raid

modern frigate
#

Oh

gray mirage
crystal quarry
#

@unkempt rock Sorry, no, I don't, but it's JavaScript, one word.

gray mirage
#

If you want to discuss something off topic,

modern frigate
#

What happened?

gray mirage
#

!off-topic

fallen slateBOT
modern frigate
#

kk

crystal quarry
#

@unkempt rock And it's completely unrelated to Java FYI

gray mirage
crystal quarry
#

Someone wrote some bot to spam general. That is what happened.

gray mirage
#

Let's get back on topic.

unkempt rock
sudden briar
#

It's awesome!

obsidian prawn
#

what non-library features of python would people consider required for it to be useable?

flat gazelle
#

nothing really. You can do a lot in python with just vim and the basic install

#

for larger projects, you do want some linter, code formatter and type checker

worldly venture
#

a

deft pagoda
#

i have none of those things! i consider numpy essential though

#

and networkx

obsidian prawn
#

i guess what i should say is what functions of base python are considered essential, stuff like functions, imports, etc.

flat gazelle
#

All of it except like... The walrus operator, filter, map.

deft pagoda
#

map is offended

pliant tusk
#

map = lambda f,l,*i:(f(*q) for q in zip(l,*i)) map is trivial to re-implement

inland acorn
#

map might be one of my favorite functions xD

deft pagoda
#

i think you implemented starmap

pliant tusk
#

that up there works the same as map

#

filter = lambda f, i:(q for q in i if (f or (lambda q:q))(q)) filter was a bit weirder to do in oneline

flat gazelle
#

To be nitpicky, map(f) is an error with python and an empty iterator with your version.

pliant tusk
#

fixed it

inland acorn
#

you are right! we dont need any functions, all we need are lambdas and generator expressions!

pliant tusk
#

imo most builtins are rewritable with listcomps and lambdas

deft pagoda
#
map = lambda f, i:(f(q) for q in i) 

does this not work

pliant tusk
#

map can take multiple iterables for funcs that take more than one argument

#

map(lambda a,b:a+b, [1,2,3], [3,2,1])

deft pagoda
#

oh, i always use starmap over a zip

#

figures

pliant tusk
#

lol starmap(f, i) == map(f, *i)

deft pagoda
#

isn't it beautiful

pliant tusk
#

map is always beautiful

#

also i didnt realize until now that filter(None, iterable) was a thing

#

it just checks the truthiness of each element in the iterable in that case

deft pagoda
#

it's (x for x in iterable if x)?

pliant tusk
#

yea

deft pagoda
#

can you just pass in one argument in that case

#

like filter(iterable)

pliant tusk
#

no

#

it needs None or a func

deft pagoda
#

isn't there a itertools function that does that

pliant tusk
#

probably

deft pagoda
#

oh, i was thinking of compress, but then you'd need compress(iterable, iterable)

inland acorn
#

I give you abs with no function calls (returns a string)```py
abs = lambda n: (o:="",x:=True, [o:=o+i for i in f"{n}" if ("0"<=i<="9" and x,(x:=False) if i=="."else None)[0]],o)[-1]

#

and there is the mathy version xD ```py
abs = lambda n: (n*n)**.5 // 1

deft pagoda
#

can you use max

inland acorn
#

that would work max(n, n*-1)

pliant tusk
#

abs = lambda n:f'{n:+}'[1:]

deft pagoda
#

max(n, -n)

pliant tusk
#

you can always abuse fstrings

inland acorn
#

what does the + option do?

pliant tusk
#

always shows +n or -n

inland acorn
#

ah

#

would still need to remove the part after . tho

pliant tusk
#

nah

deft pagoda
#

next(next({n, -n})) if sets are ordered for ints

pliant tusk
#

that option works with floats

deft pagoda
#

shit, i'm calling next on an int

inland acorn
#
In [3]: abs = lambda n:f'{n:+}'[1:]            

In [4]: abs(-5.5)      
Out[4]: '5.5'``` well `abs` should return `5` on that right?
#

wait no

#

what am I thinking

#

my brain just went to a completly wrong place xD

#

for some reason I tought abs always returned a int 🙃

modern night
#

i mean its not as elegant but u can just do python abs = lambda x: x if x > 0 else -x

pliant tusk
#

wow we are dumb

modern night
#

also preserves type

pliant tusk
#

youre right

#

abs = lambda x:(x,-x)[x<0]

inland acorn
#
abs = lambda x:[x,-x][x<0]```
deft pagoda
#

use a tuple

unkempt rock
#

Hmm, this is new to me

#

this is using an Array?

deft pagoda
#

yep

unkempt rock
#

I see, that looks really weird

grave jolt
#

!e

abs = lambda x:[*{x,-x}][0]
print(abs(3.14))
print(abs(-3.14))
print(abs(0))
fallen slateBOT
#

@grave jolt :white_check_mark: Your eval job has completed with return code 0.

001 | 3.14
002 | 3.14
003 | 0
inland acorn
#

it is not something you would use in real code

unkempt rock
#

Sorry mate, i tend to be a java guy than a python lol

#

or C++

grave jolt
#

oh, salt-die already had a setful solution

inland acorn
deft pagoda
#

yeah, this is getting esoteric

pliant tusk
#

a bit

unkempt rock
#

is it as same as adding the variable into an Arraylist?

inland acorn
#

what other functions can we make without using function calls?

deft pagoda
#

probably all of them

#

lambdas are universal by themselves

grave jolt
#

Except for map, maybe

pliant tusk
#

at least all of the logical ones

inland acorn
pliant tusk
#

@grave jolt we already recreated map

grave jolt
#

Well, it still has function calls, doesn't it?

#

Maybe vivax meant without build-in functions

rich wharf
#

Suggestion: Python type annotation for loops

#
for (x: int) in [1, 2, 3]:
  ...
#

Suggestion: Python type annotation for assignment expressions