#internals-and-peps

1 messages · Page 71 of 1

peak pollen
#

I know I probably should be looking at the source, but I bodged some %timeit stuff together and it seems to suggest linear time

feral cedar
#

it looks to be

grave jolt
#

yes, it's totally O(n)

unkempt rock
#

from asdf.zxcv.something import whatever as _ -- is this a python convention or is someone being lazy? Ive never seen this until now. Ive only seen _ used to mark a throwaway name.

grave jolt
#

I have read that it's used as a shorthand for some internationalization stuff

unkempt rock
#

yeah, I figured that out after a bit.

livid mason
#
@commands.command()
    @commands.has_guild_permissions(administrator=True)
    async def SetPingToTag(self,ctx, boolean_value=None):
        print("command recognized.")
        c.execute("""SELECT include_ping_in_tags
                    FROM guildstats
                    WHERE guildid = ?""", (ctx.guild.id))
        print("values selected")```
this isnt getting executed. I wanted to select certain values from a database
#

welp?

boreal umbra
#

@peak pollen tbh I'm pretty impressed that you took the time to use timeit. I could have done that but I decided to just bring it up on here.

rain lotus
#

hello guys i need help if somebody help me out i'm stuck at gen assigment i don't know nothing about python

boreal umbra
#

@rain lotus this server is definitely a place where you can get help (as long as you're not asking people to do an assignment for you), but this is specifically a discussion channel; take a look at #❓|how-to-get-help

winged ridge
#

hi, I have a doubt regarding including a custom version of a library in python

I am using ssl library of python to do some certificate related stuff. However the library lacks a certain functionality i require. With further research i found that the functionality has already been added as a patch, and a pull request is available. But it is still under review and it has not been added to python. The functionality was added by making additional implementation in ssl.py and ssl.c files.
Now my question is this: Will it be possible to add this version of ssl to my program without completely replacing my python.

undone hare
#

You can always package the modified ssl library with your app and use it instead of the stdlib one

winged ridge
#

how do i do that?

prime estuary
#

site-packages, and the path where your code is is deliberately higher priority than builtin stuff, so by creating a module with the same name you can override them.

#

What exactly is the patch?

#

If it's an additional function, perhaps you could get away with ctypes.

winged ridge
#

the patch was a method to get entire certificate chain

#

@prime estuary . so i import the c file with ctypes? and then use the .py file?

prime estuary
#

Ok, you should probably be able to compile the SSL module, it looks like it's not builtin to the interpreter. Probably the easiest way would be to compile the whole thing?

winged ridge
#

okay i will try that. thanks @prime estuary

narrow mango
#

python advanced

runic musk
#

@winged ridge are you using an older version of python?

#

We ran into that issue at work, we couldn't upgrade to a new version of python so I think we just swapped the _ssl.so from a newer version that implemented the TLS that was required

#

super hacky but it worked

worn scroll
#

It's okay to scrap data about products from amazon?

radiant fulcrum
#

no

boreal umbra
#

@worn scroll that would be a good question for #web-development, but I would always look at the terms of service of a given website and search for the word "scrape" or "automated" to find what it says about that.

half wolf
#

Scrap data yes. Scrape data? Maybe.

forest kindle
#

How can I make my script continue on a PermissionError: [WinError 5] Access is Denied? It's trying to grab a file, but sometimes another process (which I don't have control over) deletes it before my script can grab it. I'd like it to just return a value instead of straight up crashing on me (there's already a Try that's being invoked, do I just add another Except?)

haughty birch
cyan fable
#

Can I ask help for a python keylogger ( not for breaking the law ) ? It's for one of my project.

boreal umbra
#

Has anyone had large scale maintainability issues because of python's approach to typing?

#

I haven't had that issue, even in a library I worked on that doesn't use type annotations

peak spoke
#

Missing annotations would be a pretty big annoyance, but still just an annoyance. I haven't worked on anything big but never had problems with it as documentation (be it docstrings or annotations) usually includes the intended types/interfaces

boreal umbra
#

A pretty common criticism is that Python shouldn't even be considered for large projects for no reason other than the dynamic typing (though some critics throw in the performance issues)

#

But at the same time, I've never encountered someone asking about a typing related issue that wasn't easily solved.

sacred tinsel
#

I work on some fairly large projects at work, it only becomes a problem when there are no type annotations and the documentation lies, which sadly happens

#

it's pretty easy to make a change and forget to update the docstring

#

with annotations, the problem basically goes away

#

your IDE or a reviewer will probably scream at you if you lie about types

paper echo
#

@boreal umbra at a previous job we actually used annotations to significantly improve the maintainability of the code base

#

Developer velocity increased and we were able to do big important refactors that would have been nearly impossible otherwise

flat gazelle
#

The problem of dynamic typing generally comes up when you change something and do not know what places depend on it working the old way. But even then I can generally do fine

spark magnet
#

automated testing can help with this (as well as a lot of other things)

manic token
#

Hi! I wonder, is there any good article about underlying libraries of various http clients? For example, which native library used by requests, urllib, httpx and so on. Does anybody can share this knowledge?

radiant fulcrum
#

almost everything is based on urllib which is the std lib

#

Requests is built on urllib, httpx is built ontop of requests, aiohttp is its own custom system from the ground up

spark magnet
#

i don't think httpx uses requests?

radiant fulcrum
#

@spark magnet it was built off of requests iirc not directly wrapping it

#

Bad choice of wording

spark magnet
#

i see what you mean

radiant fulcrum
grand loom
#

httpx seems to be built off of httpcore - no mention of requests

Package    Version
---------- ---------
certifi    2020.6.20
chardet    3.0.4
h11        0.9.0
httpcore   0.10.2
httpx      0.14.3
idna       2.10
pip        20.1.1
rfc3986    1.4.0
setuptools 49.6.0
sniffio    1.1.0
wheel      0.35.1
#

When running on a fresh virtual environment

manic token
#

What I found about httpx just now:

  • httpx uses httpcore
  • httpcore uses socket from standard python bundle
grand loom
#

👍

manic token
#

I believe lower than socket is only OS kernel implementation

spark magnet
#

the python socket module is a light wrapper around the OS socket library

grand loom
#

I imagine that's why httpx is modern - in that it can probably power ASGI and WSGI servers alike

boreal umbra
#

The problem of dynamic typing generally comes up when you change something and do not know what places depend on it working the old way. But even then I can generally do fine
@flat gazelle isn't that a problem regardless? I typically use the pycharm "find uses" tool so I can know how impactful a change to an existing system is.

winged ridge
#

We ran into that issue at work, we couldn't upgrade to a new version of python so I think we just swapped the _ssl.so from a newer version that implemented the TLS that was required
@runic musk that is an excellent idea. so do i have to compile the entire python c code and then replace the .so file or just compile the library i require and replace the .so file in my python distribution?

and i am not using an older version of python. the functionality i require has not been added to python yet. its under review and a pull request is available

modern frigate
#

httpx seems to be built off of httpcore - no mention of requests
@grand loom interesting, i love httpx, but have never been sure what it was built on

rich wharf
#

Ok

#

I added then and catch to asyncio functions

#

I found out that asyncio.Tasks have the add_done_callback function

#

You can even chain them

heady siren
#

What are the real world uses for pypy?

keen prism
#

if you're not going to a bootcamp or university for computer science what are the most essential parts of computer science to study for lets say a web dev who uses javascript python html css sql?

charred wagon
left bronze
swift imp
#

class A is a base class to class B,C,D . Is there a way to monkey patch A, like say alter the __init__ and add some attributes to it such that the monkey patch will take effect to B,C,D?

flat gazelle
#

isn't that a problem regardless? I typically use the pycharm "find uses" tool so I can know how impactful a change to an existing system is.
@boreal umbra
Find uses often cannot catch some of them, due to the halting problem pretty much. But in languages with stricter type systems (elm, haskell, Ada and probably C++, D and other languages without runtime reflection) it can be entirely deterministic and the compiler will not let you accidentally skip a change as long as it is tied to type.

runic musk
#

@winged ridge
In our case we just found the earliest version with the change that we required and pulled the files directly from the new version. ssl.py from lib/version and _ssl.so from lib/version/lib-dynload . You just need to swap them for your files, no need to build anything.

#

If you're using windows, I think the _ssl.so is replaced by _ssl.pyd in the DLLs directory

winged ridge
#

@runic musk can i dm you?

runic musk
#

@winged ridge sure

austere vigil
#

map object gets flushed after using it once?

#
i = map(lambda x: x**2, [i for i in range(10)])
list(i)
tuple(i)
flat gazelle
#

yes, map returns a generator

austere vigil
#

yeah, but the generator object shouldn't be flushed after using once right?

#

seems like the map object gets flushed after using it once.

flat gazelle
#

that is how all generators work

austere vigil
#

wait, generators don't get flushed right?

cloud crypt
#

wym flushed

flat gazelle
#
s = iter('abc')
list(s)
tuple(s)
def gen():
    yield 1
    yield 2
s = gen()
list(s)
tuple(s)
#

they are all single use

cloud crypt
#

they get exhausted

#

or consumed

pearl river
#

@austere vigil Iterators in general are objects which have __next__, which returns an element and changes the state of the iterator, until it raises StopIteration when it's empty. So yeah, most iterators are single-use, you can't peek (check the next element without changing the state) into them without itertools's tools for it.

#
import itertools
i = map(lambda x: x**2, [i for i in range(10)])
i1, i2 = itertools.tee(i)
list(i1)
tuple(i2)

would work - tee splits an iterator into two.

#

(also, [i for i in range(10)] can just be range(10) here)

grand crag
#

(and has an optional parameter to split it in more than in two iterators)

cloud crypt
#

note that it's not thread-safe though

left bronze
#

Anyone have used decorator? I think it's one of the under-utilized features in Python 🙄

grand crag
#

it is widely used

left bronze
#

Apart from the widely used packages like scikit-learn or tensorflow, have rarely seen it being implemented properly. 🤕

undone hare
#

How do you define a decorator "implemented properly"?

#

There's like, no proper implementation for a decorator, you can do whatever you want with it

grand crag
#

definition : "a decorator is a function taking another function and extending the behavior of this function"
It is so large that quite anything can be a decorator

brave badger
#

I mean decorators can be used much more than that to be fair

#

They're not restricted to extending the behaviour of a function, some are just there for conveniece e.g. a register decorator that adds a function to a global function store

undone hare
#

^ I did that in an old game engine project

#

You could register event listeners using decorators

#

It is a really cool use of the decorator, even if it isn't its main purpose

flat gazelle
#

I mean, a decorator is just a special syntax for a function call

lost sequoia
#

Hi guys, just a quick question; should threads be closed ?

undone hare
#

They sure do

#

Leaving hanging resources is never a good thing

lost sequoia
#

😦 thanks

cloud crypt
#

@undone hare hanging resources be like: hippedy hoppedy your RAM is now my property lemon_pleased

undone hare
#

Wut haha

peak spoke
#

The os will clean up everything that python couldn't, but it won't run any handlers

lost sequoia
#

how do you stop an infinite thread ? looks like .join(0) is not enough

#

by infinite thread I mean

def f():
    while True:
        do_stuff()

p = Thread(target=f)
undone hare
#

You kill them ¯\_(ツ)_/¯

lost sequoia
#

hum after digging a little more, I found out that I had a waiting Queue q.get(). I think that is why the program is not closing

peak spoke
#

The thread has to handle its own quitting

lost sequoia
#

Yes, I was missing that point 🙂

boreal umbra
#

What are the real world uses for pypy?
@heady siren it's just another implementation of the interpreter, so the uses are the same as cpython. I think it's faster than cpython but is less portable, or something like that.

#

Looks like pypy is just in time compiled rather than interpreted

covert saddle
#

hey guys what sorting algorithm does python use when I do mylist.sort()? mylist is list here.

#

Please ping me when you reply

peak spoke
#

cpython uses timsort for its sorting

#

pypy is more performant given enough time and assuming you're not relying on c extensions too much; but it has its own tradeoffs to get that

covert saddle
#

so you mean different implementations have different sorting algorithms used? @peak spoke

peak spoke
#

The second message was for the discussion above; I don't know what sorting algorithm pypy uses but I don't think they have to use timsort

swift imp
#

class A is a base class to class B,C,D . Is there a way to monkey patch A, like say alter the init and add some attributes to it such that the monkey patch will take effect to B,C,D?

boreal umbra
#

@swift imp so you want subclasses of A to all have a set of attributes not had by A?

#

because if you need all the subclasses to have some common attributes, I would make one subclass of A that's an abstract base class, and then subclass that one

#

though the class method __init_sublcass__ might afford you the functionality you're looking for.

swift imp
#

Ok caveat, A, B, C, D are all already defined

#

Basically they're coming out of a module, and I need to tweek them ever so slightly but don't want to full on subclass them all

peak spoke
#

What do you want to achieve?

swift imp
#

I was wondering if I could monkey patch them somehow

#

At work we use pandas extensively, and for every plot we generate, we need to frame it in a black box and add a security classication marking to the bottom right corner. I just want to add that functionality to the pandas plotting class so that whenever someone makes the plots they never forget to do it and get in trouble

#

Like if I added __init_subclass__ to it as a monkey patch, would that work?

undone hare
#

Why not subclassing it and using this new subclass?

brave badger
#

Not quite sure what's happening here, was there some implementation detail that happened between 3.7 and 3.8?

>>> def foo():
...   return 1, *(2, 3)  # Illegal on 3.7, valid on 3.8
  File "<stdin>", line 2
    return 1, *(2, 3)
              ^
SyntaxError: invalid syntax
swift imp
#

Why not subclassing it and using this new subclass?
@undone hare

Bc I don't want to go through the process of re registering the backend and stuff

icy furnace
#

Hallo bois

#

Can y'all halp me with something?

#

I need a program

#

which will help me ace my maths exam

#

it is ISC 12th

feral cedar
#

no

spice pecan
#

Not the right channel for that

feral cedar
#

also just not allowed

spice pecan
#

Also true

digital tundra
#

hello I am a noob

#

I can calculate area of a triangle

#

um

icy furnace
#

I can calculate area of a triangle
@digital tundra I can calculate the number of dads you have .

digital tundra
#

ok

#

I have 1

#

lol

icy furnace
#

...

#

noob

digital tundra
#

Yes

#
n = int(input("Enter the Base in cm: "))

n * num / 2 

print (n * num / 2)
print ("This is the area of a triangle in cm square. ")```
#

that's one of the code I did

feral cedar
#

@digital tundra this isn't on topic for this channel, probably better for #python-discussion

digital tundra
#

ok

hasty turtle
#

will regex of pypi replace re one day?

spice pecan
hasty turtle
#

You were already told that it probably won't in #python-discussion
@spice pecan I dont know that he/she is replying me....

unkempt rock
#

How does python’s interpreter deduce types? I did a few searches, nothing meaningful came up. Maybe I just wrote the wrong things

lost sequoia
#

if it quacks, then its a duck

feral cedar
#

if it acts like a duck, looks like a duck, etc it's probably a duck

peak spoke
#

If it doesn't go into C, then it doesn't do much with types

flat gazelle
#

it doesn't deduce types

#

every value knows its type

boreal umbra
#

@unkempt rock every value knows its type, but some operations don't require knowing the type

#

if you have an object named foo and you look up foo.bar, either you get that value because it happens to have a bar attribute, or you get an AttributeError. If it turns out that foo.bar isn't compatible with what you wanted to use it for, you'd get some other error.

rich wharf
#

Oh well

#

At least I got promises to work

#
async def returnFive():
    return 5

async def other():
    return await returnFive().then(lambda i: i + 3)

def main():
    return other().then(print)
#

Essentially I used the gc module to add then and catch to python objects

radiant fulcrum
#

yikes

sharp fog
#

👀

#

i should be here...

#

im a noob

rich wharf
#
def returnFive():
    return Promise.resolve(5)

def other():
    def callback(resolve, reject):
        returnFive().then(lambda i: resolve(i + 3))
    return Promise(callback)

def main():
    return other().then(print)
#

You can actually use a non-async solution

#

It should work just fine

#

main() will still output an asyncio.Task

#

Which can be awaited

radiant fulcrum
#

but why...

rich wharf
#
def other():
    def callback(resolve, reject):
        returnFive().then(lambda i: resolve(i + 3))
    return Promise(callback)

Could be changed to

def other():
  return returnFive().then(lambda i: i + 3)
#

Why not? It's nice to abuse Python

#

If you really wanted you could shorten it more

#
returnFive = lambda: Promise.resolve(5)
other = lambda: returnFive().then(lambda i: i + 3)
main = lambda: other().then(print)
#

Unfortunately, I couldn't implement running promises without await

#

But you could probably just do loop.create_task for that

#

You might be asking what Promise is

#

Promise is just a function with a few attributes

#

It isn't a class

#

Promise.then and Promise.catch are the same methods as the two added to both objects with the gc module

#

Promise.resolve is this helper function

def resolve(obj):
    if inspect.iscoroutine(obj):
        return obj
    async def coro():
        return obj
    return coro()
#

Promise.all is asyncio.gather

radiant fulcrum
#

I mean JS still has await and async as syntax sugar methods

rich wharf
#

Python technically does too

#

await and async are just low level wrappers for futures

radiant fulcrum
#

yeah

rich wharf
#

Which is what this whole thing is based on

#

A asyncio.Future is awaited

#

When you set its result or exception, the async functions will return it

radiant fulcrum
#

before 3.5.5 it used to be @asyncio.coroutine as a decor and then everything was yeild from essentially

#

Python's entire async system is based of generators

rich wharf
#

All this does is it wraps coroutines with asyncio.Task

#

And adds a done callback

raven ridge
#

How does python’s interpreter deduce types? I did a few searches, nothing meaningful came up. Maybe I just wrote the wrong things
@unkempt rock As others said, every value knows its type. When you do x + y, the interpreter asks x's type to add y to x. That operation can either succeed (in which case the new value is returned), or fail (in which case an exception is raised), or signal that x's type doesn't know how to handle adding y's type, which case the reverse operation is performed: the interpreter asks y's type to add x to y. This time around, if y's type says that it doesn't know how to handle adding x's type, an exception is raised up to the user. And, because operators are designed to be able to handle arbitrary types, even user-defined ones, user code generally doesn't have to worry about types at all; it just defines the operations that it wants to perform, and they'll succeed if objects are passed to it that work for the operations that it does.

radiant fulcrum
#

The interpreter has a weird system

#

There's a talk somewhere which goes on about how it works and why the system is alot weirder than people think

rich wharf
#

So tbh

#

Coroutines are just like JS coros at the low level

#

Python tries to abstract away the low level though

radiant fulcrum
#

Js doesnt have coros

rich wharf
#

JS has promises

radiant fulcrum
#

JS's system is entirely promise based yh

rich wharf
#

Python's is too

#

You just don't normally see it

#

loop.create_task(coro).add_done_callback(lambda fut: fut.result())

#

Boom

radiant fulcrum
#

technically futures are slightly diffrent from promises in places

#

Not sure if Python actually applies these diffrences tho

rich wharf
#

maybe slightly different

#

but at the low level they're similar to promises

#

You have a promise/coroutine

#

You wait for a value

#

Then you run a callback

#

When you use an async function

#

awaiting a promise will resolve to a callback that sort of does next(asyncGen)

#

It's the same concept

radiant fulcrum
#

yeah ik

rich wharf
#

Python is horrible at good callbacks though

#

You have to use a decorator

#

Or pass in another function

#

Time to add finally

#

Finally

#

The JS-promise collection in Python is done

#
async def done(res):
    print('Done', res)
    if res == 5: raise Exception()
    print('Hi')
    return res + 1

async def handler(e):
    print('ERROR!')
    print('It had an error', e)

async def complete():
    print('Well I did it.')

task = (
    foo()
    .then(done)
    .then(done)
    .catch(handler)
    .finish(complete)
)
#

.finish is the same as .finally in JS

#

All three methods have been added to coros

#

And you can make your own futures too

flat gazelle
#

isn't this an inconvenient async with?

#

actually, not really

rich wharf
#

Not really

#

This is more like abusing Python to make promises

#

JS-type promises

#

By using asyncio.Task.add_done_callback

grave jolt
#

Do you even need async functions for that?

#

I mean, in the user code

unkempt rock
#

Can requests directly write to disk without placing the file object in ram first ?

flat gazelle
#

you always need parts in RAM, but you can do it in chunks, rather than the whole file at once. This is more suited for a help channel though

unkempt rock
#

Okay i'll ask thanks

rich wharf
#

@grave jolt Actually no

#

You just need coroutines

#

Or futures/tasks

cloud crypt
#

Not really advanced python, I guess, but has anyone ever come across a rich iterator library? Something similar to what rust has.

spark magnet
#

@cloud crypt what would it do?

cloud crypt
#

I’d describe it like itertools but OOP in a nutshell

#

so you have an Iterator that implements things like group, map, filter, and so on as its method

grand crag
#

that would be great

#

chaining iterators like in rust ❤️

cloud crypt
#

Yeah, rust takes it to the next level with IntoIterator and other traits, allowing you to effectively chain operations in a nice way

grave jolt
#

Can you add >> operator to object by hacking into ctypes?

cloud crypt
#

yeah but why haha

#

forbiddenfruit can surely do that

grave jolt
#

yeah but why haha
to make iterator chaining!

cloud crypt
#

I’d rather have it object styled

#

well I have written a thing once but it kinda failed

#
from iter import enable_std_iter
enable_std_iter()

numbers = [1, 2, 3, 4, 5]

squared_odds = numbers.into_iter().filter(lambda n: n % 2).map(lambda n: n * n).collect(list)```
grave jolt
#

Yes, that would make sense

#

but sadly, that's impossible in python

grand crag
#

let's hack python :p

#

anyway, that is still way more readable than nested function calls

grave jolt
#

On the other hand, you could do iter(numbers).filter(...).map(...), not a big deal

cloud crypt
#

the code I sent runs on CPython 👀

grave jolt
#

oh

cloud crypt
#

doesn't even use ctypes, hehe

grand crag
#

the into_iter is not that interessant, I think, in your code. Simply using iter is great.

grave jolt
#

so it messes with object?

cloud crypt
#

yeah, object.__dict__ specifically

grave jolt
#

that's a thing?

cloud crypt
#

it's a mappingproxy

#

and apparently it refers to a mutable dictionary which you can find by tracing alive objects

grave jolt
#

how do you do that?

grand crag
#

right, how ?

#

it is interesting

#

mappingproxy doesn't define any setter, and you cannot access the inner dict

grave jolt
#

gc.get_objects?

grand crag
#

it is hard to find the right one, isn't it ?

cloud crypt
#
>>> import gc
>>> type(object.__dict__)
<class 'mappingproxy'>
>>> referents = gc.get_referents(object.__dict__)
>>> len(referents)
1
>>> mutable_dict = referents[0]
>>> mutable_dict["test"] = "nekit"
>>> (13).test
"nekit"```
grand crag
#

oh !

#

I forgot this method

grave jolt
#

huh

grand crag
#

and why the hell is it does it give a mutable dict ?

grave jolt
#

I guess it's just implemented as a dict, why invent a new thing?

cloud crypt
#

ah nice I segfaulted already

#

lol

#

well all classes have their class dictionary mutable on creation

#

which then gets frozen into cls.__dict__

grand crag
#

it is a descriptor ?

#

making it read-only ?

cloud crypt
#

so I suppose that's how you have object.__dict__ refer to a mutable dictionary

#

no it’s more like

#

cls.__dict__ is in a nutshell just mappingproxy of class's inner namespace

grand crag
#

I thought that object and type were real "non-python" object, if you see what I mean

#

I didn't know they had a mutable dict, too. I thought there inner C implementation made them fixed

cloud crypt
#

well ideally it does

#

PyPy actually raises an error if you attempt to do what I did here

#

anyways, I like how we went from a simple question to python's internals, haha

grand crag
#

I love it too :p

#

What is great with python, is that is seems simple

#

And it is actually so deep... 😄 There is always something new to learn !

grave jolt
#

TIL JavaScript has an esoteric mechanic that python doesn't

#
Object.defineProperty(window, 'answer', {
  get: () => {
    return 42
  }
});
#

In JS, global variables are just properties of the window object, so every time you access answer you get 42

grand crag
#

you define a getter in that way ?

spice pecan
#

I mean, you can kinda do that with builtins

#
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import builtins
>>> builtins.a = 10
>>> a
10```
grave jolt
#

Maybe this is possible by substituting globals()'s type with a subclass of dict?

grand crag
#

that could be cool

#

having the same as in lua 🤮 (returning None without throwing error in case the attribute is not found)

grave jolt
#

same in JS

#

(undefined)

#

Or you can mess with dict.__getitem__ but that will absolutely obliterate performance, I guess?

spice pecan
#

Most likely

grand crag
#

right, there is so many possibilities... definitely, I love python

spice pecan
#

A lot of the stuff is just mind-boggling

#

Like the goto-statement library

paper echo
pseudo cradle
#

wait what

#

we have a goto-statement library?

north root
#

!e

from goto import goto, label

def even_or_odd(num):
  if num % 2 == 0:
    goto even
  else:
    goto odd

  label even:
    print(f'{num} is even')
  label odd:
    print(f'{num} is odd')

even_or_odd(7)
fallen slateBOT
#

@north root :white_check_mark: Your eval job has completed with return code 0.

7 is odd
spark magnet
#

it's a massive hack

pseudo cradle
#

Interesting

#

How does it...?

#

work?

spark parcel
#

That is the most wonderful thing I've seen

#

I've wanted to use something like that many times after looking at assembly. Nice to see it in python

spark magnet
north root
#

lol

pseudo cradle
#

Assembly is a blast

spark magnet
tawdry gulch
#

Whoever made that goto statement library must be taking this piss

#

lmfao

inland oxide
#

does anyone know how to install smtplib because when i do it comes up with these 2 errors ERROR: Could not find a version that satisfies the requirement smtplib (from versions: none) ERROR: No matching distribution found for smtplib

runic musk
#

the builtin?

#

you should just be able to import smtplib

eternal shale
#

I don't personally mind. But it is generally considered bad style to use GOTO if can be avoided. And... It always can be avoided. There's no real benefit in puting the body of the If/else anywhere else. BUT! I agree that it is very very interesting for educative purposees. For loops are so much easier understand if you know goto statements beforehand.

sacred yew
#

personally i think you should first learn while loops, then for loops

#

then after that the gotos behind both

#

also goto is used in c for error handling

raven ridge
#

Indeed it's nothing that couldn't be avoided, but judicious use of goto in C can make code much more readable than it would otherwise be.

hexed maple
#

agreed

sacred yew
#

poor man's try except

raven ridge
#

The alternative is early returns with a bunch of duplicated code.
Allocate foo, if it fails return. Allocate bar, if it fails free foo and return. Allocate baz, if it fails free foo and bar and return. The goto in this case is a common pattern for removing that duplication.

flat gazelle
#

which is why most languages that try to replace C introduce defer

raven ridge
#

C++ uses RAII instead. Terrible name, that...

hollow garden
#

what the fuck is guido doing

grand crag
#

pattern matching

#

one of the best thing if the world !

amber nexus
#

Yeah i'm a fan of that pep

#

Only thing i would change would be the end case that acts as an else

#

instead of case _ i feel like it should just be else

grand crag
#

agreed

#

it would be better with an else

amber nexus
#

Yeah just for consistency

unkempt rock
#

Any where to look on this server cause I am here to learn about python

#

and more about it

amber nexus
#

Every other situation in python where you want to run something if everything else isn't true, else is used

grand crag
#

but case _ must be a correct thing too

amber nexus
unkempt rock
#

Thanks

amber nexus
#

Why did they decide on case _ anyway

#

I think i read it in there when i first read it

grand crag
#

because of case (x, _) maybe ?

spice pecan
#

probably, yeah

amber nexus
#

Yeah i think thats why looking at it

spice pecan
#

else would fit well in line with things like try/except/else/finally, for/else and while/else

amber nexus
#

Its for consistency in the match basically

#

Since it can be used elsewhere in other cases as the wildcard

#

So the case _ just captures anything

spice pecan
#

I'm not a big fan of giving _ special treatment tbh

#

Or rather I'm rooting for it to be a true wildcard/throwaway in every context and not just pattern matching

grand crag
#

I used to think that _ was a real wildcard. Then I discovered it was just a variable.

amber nexus
#

Yeah its just used as one

#

Rather than actually being one

spice pecan
#

It's technically a regular identifier, just like a

#

Which is... meh?

amber nexus
#

Yeah i wouldn't mind if it was a throwaway everywhere

spice pecan
#

There are cases where it would break backwards compatibility, but I'm all in favor of making _ a throwaway

grand crag
#

breaking compability ? Are there people actually using it as a variable, without consedering it as a throwaway ?

spice pecan
#

I've seen it used for localization/internationalization functions quite a lot tbh

grand crag
#

oh !

peak spoke
#

I'd rather leave it as it is than reserve the char for the special behaviour, having it for i18n is quite helpful as it adds the least visual noise

#

The change would also have to be eased into python, putting the pattern matching in later versions if it ends up getting accepted

grand crag
#

a python4 version ? with that big changes ?

deft pagoda
#

also used as a decorator in sly

spice pecan
#

What about keeping _ and using __ as a throwaway? Or would that be a bit too iffy

grand crag
#

my obfuscated code would not work, then 😢 (just kidding)

spice pecan
#

probably too iffy

deft pagoda
#

maybe they could use ellipsis instead for matching anything

#
case ...:
#

though I also like the else suggestion

worn scroll
#

Can i say a variable it's an integer or a specific string?

#

ex. def myfunction(x: (int, 'mystring'))

spice pecan
#

I'd go with Union[int, Literal['mystring']]

#

I don't remember the specifics of Literal though

worn scroll
#

i will take a look, thanks

spice pecan
barren aurora
#

at what level do you get eligible for this channel..

deft pagoda
#

any level as long as you remain on topic

spice pecan
#

There's no "You must be this tall to come here" restriction, as long as you're following the topic you're fine

barren aurora
#

kk

#

whats the topic

spice pecan
barren aurora
#

ow

#

bye bye

spice pecan
#

As stated in the, well, channel topic in discord

barren aurora
#

i will come here after a few years

hollow garden
#

pattern matching is something not okay for a language supposed to be simple and explicit

#

Especially considering he didn’t want to add functional programming features this is the worst pep ever

#

Guido fucked up the language

cloud crypt
#

that is a rather debatable statement of yours

peak spoke
#

I'm not a huge fan of the pep, but it is still just a draft

cloud crypt
#

same here, it is large and brings more questions than answers to problems

hollow garden
#

That’s the problem

#

Guido keeps doing that

half wolf
#

@hollow garden you know Guido created python right?

hollow garden
#

This doesn’t mean he is always does the correct thing.

flat gazelle
#

Pattern matching gives a better way to express the extremely common

if is_something:
    unpack_the_something
``` pattern
grave jolt
#

right, we have iterable unpacking like a, b, c = xs, is it somehow less explicit than a = xs[0]; b = xs[1]; c = xs[2]?

half wolf
#

It seems to me that dict unpacking would be like 100x more useful than this pattern matching thing.

grave jolt
#

it's possible with a hack 🙂

mint forge
#

can anyone give me some questions that i can ask a guuy who is saying that he has 4 years of experience and he is telling me to (take his course and stuff like that)

magic python
#

I'm interested in what do do when the following sort of pattern appears:

def _h(a, b, c):
    <do stuff>

def _g(a, b, c, d):
    ret = _h(a, b, c)
    <do stuff>

def f(a, b, c, d, e):
    ret = _g(a, b, c, d)
    <do stuff>

so, there are a few functions, f is called, but in turn calls others, with shared arguments. Here it seems that documenting a, b, c in three places is pretty silly, I'm not sure what's usually done though (or - perhaps this is a code smell right off the bat). I was thinking that perhaps in this scenario one would either create a dictionary for the values and document that, or and attrs object or something

half wolf
#

@mint forge "experience" in what? Full time? What company? And there are lots of free resources online so....

#

@magic python two of the functions look like they're private so don't document them, just the public one maybe. Seems a good choice.

#

You can also do some custom tooling to "inherit" doc strings I guess.

magic python
#

@half wolf right - so if the call is just f then there's no real need to re-document those which are called by it.

#

custom tooling - i think pandas and stuff uses some decorators to wrap docstrings around things or something 🤔

#

what i said about attrs objects - this seems off I assume?

half wolf
#

Yea, it's quite easy.

magic python
#

my thinking was I'd have some

@attr.s
class D:
    a = attr.ib()
    b = attr.ib()
    c = attr.ib()

or something, and pass f( attr_thing, d, e)

half wolf
#

Attrs is mostly obsolete now with data classes. But yea, could do that. Not sure it's better. Hard to tell without the real code.

#

Simple > complex though.

magic python
#

for sure - with these kinda design decisions simple isn't obvious to me still

half wolf
#

It's too context dependendant.

magic python
#

I mean - it's not obvious to me that wrapping functions with decorators is simpler than using an attrs obj because I've not done enough design (assuming that I read your previous messages correctly)

half wolf
#

I normally do keyword arguments for everything except functions with one or maybe 2 arguments and that helps a bit.

magic python
#

for everything except functions with one or maybe 2 arguments and that helps a bit
hrm ok, interesting

half wolf
#

It's annoyingly redundant but pass through is super clear when it's a bunch of a=a, b=b etc at the end.

magic python
#

It's annoyingly redundant but pass through is super clear when it's a bunch of a=a, b=b etc at the end.

are you referring to the original layout that I had here?

half wolf
#

(Another reason I would like short hand syntax =a, =b)

#

Yes

magic python
#

fair... yeah - it feels wrong, but I'm not sure whether other things are necessarily better (where better means simpler here), esp if there's a sort of nested structure as I outlined.

half wolf
#

5 arguments with no keyword arguments? That's not really usable imo.

magic python
#

it's quite common with some plotting libraries and stuff as a lot are flags sometimes

#

( to have > 5 args )

half wolf
#

Kwarg only ftw.

magic python
#

where do you document the kwargs?

half wolf
#

I usually joke that python has an ugly way of defining functions def f(*, a, b). The * is totally meaningless! :)

magic python
#

I use that a lot 😅

half wolf
#

Good

magic python
#

oh ok, phew

#

I'm still a bit unsure where one would document the kwargs though, where's typical for that

#

sometimes when using matplotlib I've found it a bit annoying that there are a lot of kwargs, and they're not defined within the function so it's hard to know what things are

#

perhaps there's a convention to that which I'm unfamiliar with though

half wolf
#

We have custom tooling there too for documentation. Since we do some magic with the Refinable/RefinableObject stuff.

magic python
#

fair - generating documentation isn't as much of a concern for me atm, just writing it well and where to put it. I guess here they have the kwargs within the function docstring, which in my example would have been f(), then _h, _g refer to that 🤔

half wolf
#

I would prefer the docs to be closer to the parameter. But that's not how python does it.

magic python
#
def _h(**kwargs):
    """
    Args:
        see f
    """
    <do stuff>

def _g(**kwargs):
    """
    Args:
        see f
    """
    ret = _h(a, b, c)
    <do stuff>

def f(*, **kwargs):
    """
    Args:
        a ...
        b ...
        c ...
        d ...
        e ...
    """
    ret = _g(a, b, c, d)
    <do stuff>
half wolf
#

Yea it depends on why you're documenting a lot too. Like for iommi this is a public facing lib we want random strangers to use. Very different from internal stuff.

#

Yea that's very reasonable.

magic python
#

I would prefer the docs to be closer to the parameter
me too - this is what confuses me with kwargs when using other tooling sometimes (that they're no where near the usage)

#

so understanding what's possible parameter wise and what they all do can be tricky if it's not made clear 🤔

half wolf
#

Yea I would like to be able to say "the **kwargs here go straight into f() so make the auto complete handle that"

#

Or even "the kwargs here can be auto completed by actually calling this function b() that returns the possible stuff."

magic python
#

maybe I should check how pandas does it properly - having some

@doc_if_kwarg_passed
def function ... 

which automatically injected into documentation might be nice

#

tho now i've written that it sounds too complicated lol

half wolf
#

In iommi we can pass stuff like columns__foo__field__display_name='hello there' which is dispatched into columns.foo.field.display_name

#

It's a bit special but super powerful once you get the hang of it. But auto complete for it isn't really a thing :(

magic python
#

is that referred to as anything?

#

i mean - is that a particular pattern

#

or just something within iommi

half wolf
#

We've stolen the idea from djabgo query sets. We call it "transparent APIs".

magic python
#
./endpoint__tests.py:44:            columns__foo=dict(
./endpoint__tests.py:54:            columns__foo=dict(
./table__tests.py:152:    table = MyTable(rows=[], columns__foo__extra__stuff="baz")
./table__tests.py:159:        Table(rows=[], columns__foo=Column(), foo=None)
./table__tests.py:828:        columns__foo__bulk__include=True,
./table__tests.py:1905:        columns__foo={},
./table__tests.py:1921:    table = MyTable(columns__foo__include=False, rows=[])
./table__tests.py:1930:    table = MyTable(columns__foo__include=False, rows=[])
./table__tests.py:1948:        return Table(auto__model=TBar, columns__foo__filter=dict(include=True, field__include=True))

I see it's in the tests

half wolf
#

Django doesn't have a name for it and uses it super narrowly. We use it for eeeeeeverything

#

Yea there too sort of. Another case of things being next to the thing they are about.

#

This coupling makes testing faster too, with hammett (which I also wrote).

magic python
#

seems interesting, I'm not sure i'm comfortable enough with the basic usage at the moment :/

half wolf
#

Transparent APIs makes it possible to have a() call b() call c() and expose the full api of c to calls of a without destroying the function signature of a.

magic python
#

oh ok, i think that makes sense

half wolf
#

It's a bit niche, but for GUI programming it's life altering.

magic python
#

really, never had to do gui, but was asked about it on friday 😬

half wolf
#

You always have deep hierarchies of stuff and it's super annoying and hard to change even small things deep down that tree.

#

With iommi it's super simple. Add a css class to the filter field lable for the column a: columns__a__filter__field__label__attrs__class__my_class=True

#

In other systems you'd have to subclass everything down that path. That's 5 or 7 classes or something.

#

The problem for us is that this is borderline a new paradigm and that's hard to teach because it's super new.

magic python
#

It's referred to as "Transparent API's" though?

half wolf
#

Well by me. I invented the term and I've told it to maybe like... 40 or 50 people?

magic python
#

😄 maybe it'll spread

#

hopefully before i have to do any gui stuff

half wolf
#

Crap. Haven't even written it up on my blog I realized. Gotta do that. I have a presentation I've given.

#

Maybe I should record a video too. People nowadays want video I've understood. Kids these days eh? ;)

magic python
#

ha, yeah - why have a 1 minute readme when a 10 minute vid will do?

half wolf
#

Exactly. God help you if you want to Google it later.

magic python
#

although sometimes seeing is beliving, it can be nice

feral cedar
#

could add a transcript for googling purposes

half wolf
#

Yea it's good for like vague overviews and sales :)

magic python
#
def inherit_names(names: List[str], delegate, cache: bool = False, wrap: bool = False):
    """
    Class decorator to pin attributes from an ExtensionArray to a Index subclass.

    Parameters
    ----------
    names : List[str]
    delegate : class
    cache : bool, default False
    wrap : bool, default False
        Whether to wrap the inherited result in an Index.
    """

    def wrapper(cls):
        for name in names:
            meth = inherit_from_data(name, delegate, cache=cache, wrap=wrap)
            setattr(cls, name, meth)

        return cls

    return wrapper
#

is there a name for making decorators to wrap docstrings in things?

#

@feral cedar yea - wonder when we'll be able to search through captions too

half wolf
#

@feral cedar yea for some stuff I have blog posts too. But I've forgot for this thing. And I don't have one for my mutation testing talk. Should do that too.

grave jolt
#

Automated captions have gotten better on youtube, maybe it's possible to build on them?

half wolf
#

Don't know of a specific name for that. Doesn't seem common enough to have a name.

#

My last video I put up i couldn't get youtube to make captions for it. I had to do it manually.

#

Don't understand what went wrong.

#

Their GUI is atrocious imo.

magic python
half wolf
#

There are two guis so I guess they're in the process of a big rewrite.

grave jolt
#

also, isn't youtube removing the community-added captions/caption translation?

half wolf
#

I heard that too. Seems stupid. Why not just have it be that the channel have to approve them?

grave jolt
#

The channel already has to approve them

half wolf
#

Well then I don't get it.

feral cedar
#

seems like an only good outcome thing

grave jolt
#

alright, this is turning off topic here

#

@feral cedar They were concerned about adding inappropriate translation. i.e. if I translate captions of a creator from UK into Russian, they won't be able to check that I didn't put anything silly in there.

half wolf
#

Hmm. Sad.

unkempt rock
#

I have access to an A.I with an IQ of 180, you can ask it a question if u guys want

amber nexus
#

Not the channel for that

half wolf
#

Maybe try #claimyournobelprize

#

Maybe fields medal to be fair.

feral cedar
#

probably both

half wolf
#

Yea.. Probably fields plus biology nobel.

magic python
#
def f(*, x, y):
    """f is a function.
    Args:
        x (int): some int
        y (str): some string
    """
    return _g(x=x) + 1


def _g(*, x):
    return x + 1

# nope
_g.__doc__ = f.__doc__

ok i just confused myself and that was about it...

maybe it's best to just have see f() in the docstring of _g

#
def f(*, x, y):
    """f is a function.
    Args:
        x (int): some int
        y (str): some string
    """
    return _g(x=x) + 1


def _g(*, x):
    """Another function.
    Args:
        x (int): see f()
    """
    return x + 1

as so 🤔

half wolf
#

Yea. If it's private absolutely.

magic python
#

i think that makes most sense, certainly the most simple

magic python
feral cedar
#

the braces and the tilde make it look like a bacteria, sorta

magic python
#

😄 would save .apply(lambda g: <do stuff>) perhaps

#

.apply( ~g: ...), hrm, idk

pallid meteor
#

i prefer () -> {} tbh

brave badger
#

What would better, actually usuable lambdas look like in Python?

magic python
#

I'm just thinking of saving having to type lambda to be honest

brave badger
#

I'm thinking utilizing => but it would look to much like JS at that point

pallid meteor
#

honestly i hate lambdas, wish we had something like closures in rust

magic python
#

I think that could be nice, like df.apply( g => <do stuff>)

pallid meteor
#

-> over =>

magic python
#

df.apply(g -> <do_stuff>) then, instead of df.apply(lambda g: <do stuff>)

brave badger
#

Looks odd in-line though

xs = [...]
xs.sort(key=g => g[0])
pallid meteor
#

yes pls, someone submit a pep for that

#

for the love of god

spice pecan
#

I like ->

feral cedar
#

^ the equals sign looks too thick

pallid meteor
#

how do i even submit a PEP

swift imp
#

You should search for an existing pep that was already rejected and see why

#

All you can do is make a post on mail-in python ideas

#

Then if a council member wants to support it, a pep is made

magic python
#

-> is very R, but if it works it works

pallid meteor
#

its beautiful and its insane how they went with lambda : over literally anything else

boreal umbra
#

@pallid meteor you can subscribe to the python ideas email list. it's basically a forum.

#

though most ideas are rejected pretty quickly

#

mine was 😢

#

that being said, you don't need to use lambda for that either

#

you can use operator.itemgetter

#

!e

from operator import itemgetter

stuff = [(1, 2), (5, 6), (3, 4)]
stuff.sort(key=itemgetter(1))
print(stuff)
fallen slateBOT
#

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

[(1, 2), (3, 4), (5, 6)]
deft pagoda
#

that's the same as sorting default!

boreal umbra
#

itemgetter(n) creates a function that returns thing[n] for whatever thing you pass to it.

#

it's just an example 😢

deft pagoda
#

i still like the generator syntax for anonymous functions

boreal umbra
#

is that a thing that exists or an idea?

deft pagoda
#

it's an idea

boreal umbra
#

show

deft pagoda
#

on python ideas

boreal umbra
#

oh it's active?

#

I guess I'll take a look

deft pagoda
#

i dunno

boreal umbra
#

I'm still just really mad that they won't give us func composition

deft pagoda
#

i can make an example:

sorted(my_list, key=(x[0] from x))
boreal umbra
#

hmm that's pretty good

#

it's certainly not worse than lambda because lambda certainly requires you to know what lambda means

deft pagoda
#

i think it's too alien for most people, but i think it fits python

boreal umbra
#

from x has a slight chance that you'd know what it is intuitively

deft pagoda
#

you could also use for x

boreal umbra
#

I might like from better because for has a very strong association with iteration

deft pagoda
#

same

boreal umbra
#

there was also someone who tried to revive discussion about inline exception handling

#

they suggested my_list[6] eor "hello" where my_list[6] causes index error

#

and eor would be a new keyword

#

apparently the past proposal was for my_list[6] except IndexError: "hello"

#

I would prefer my_list[6] except IndexError with "hello"

#

because except-with is more similar to if-else

#

but apparently there was tons of bikeshedding the first time around

deft pagoda
#

i'd rather none-aware first

boreal umbra
#

none-aware?

spice pecan
#

unless-then sounds nice in my head, but is definitely not going to be a thing

deft pagoda
spice pecan
#

null-coalescence, a ?? b == a if a is not None else b and similar

boreal umbra
#

@spice pecan in theory they shouldn't even consider making a new keyword without going up to 4.x

#

but we all saw what happened with async

spice pecan
#

true

boreal umbra
#

hmm, would ?? be overloadable?

deft pagoda
#

i don't think it's in the pep

spice pecan
#

I'd rather not, IMO it's on the same level as is - it's something you really don't want to overload

#

even if it would be nice in some niche cases

boreal umbra
#

I don't really want to add more symbols to the language that only do one thing

deft pagoda
#

oh there is a proposal at the end for a dunder

#
def __has_value__(self):
    return True
boreal umbra
#

also will there be ??=?

spice pecan
#

It's in the pep iirc

#

??=, ?., ?[], maybe ?(), not sure

deft pagoda
#

there would be chaining

#

my_class?.my_attr?.sub_attr

spice pecan
#

^ those are very nice to have

boreal umbra
#

my "python is not perl" sense is tingling

spice pecan
#

I found out about null-coalescence when I was learning C#, it's extremely convenient at times

visual shadow
#

One of the biggest lures of Python for me was how English like it reads at times.

#

I feel like most of these suggestions go against that.

deft pagoda
#

Well, I would think the same if I hadn't seen the idiom of checking for attrs in long if-chains constantly

spice pecan
#

that is true, a if a is not None else b is significantly more explicit and english-like

boreal umbra
#

I don't think staying English-like should be a goal. we shouldn't be favoring English speakers

visual shadow
#

The ones that introduce brevity by use of a symbol for the sake of brevity don't sit well with me if the original version is clear.

boreal umbra
#

and there's also cobol

#

if you really want executable English

spice pecan
#

There are cases where chaining makes it extremely verbose, so I think in case of null-coalescence it's a necessary evil

visual shadow
#

I don't think staying English-like should be a goal. we shouldn't be favoring English speakers
@boreal umbra I'd flip that argument. It's not that I'm saying push stuff that isn't English like to make it English. More so that there needs to be an identifiable pain point with the existing approach to consider a new symbol

paper echo
#

@boreal umbra i don't think anyone is that attached to the ? syntax, i'd be hard pressed to think of an alternative that is also chainable

#

and the alternative is a gnarly mess of nested conditional expressions

deft pagoda
paper echo
#

i dont think we are headed down the path of perl

#

perl 5's soup of sigils, or raku's soup of cryptic binary infix operators

visual shadow
#

Well, I would think the same if I hadn't seen the idiom of checking for attrs in long if-chains constantly
@deft pagoda this seems like something worth considering if enough projects have this.

boreal umbra
#

I've never written anything where I needed to check if something wasn't null that many levels down

#

so I guess the value is lost on me

visual shadow
#

Like that's something I can put my finger on and say, OK that makes sense.

#

I've never written anything where I needed to check if something wasn't null that many levels down
@boreal umbra same.

deft pagoda
#

I mean the pattern matching pep also addresses similar issues

boreal umbra
#

is that pep still active?

deft pagoda
#

but none-aware is just used all the time

visual shadow
#

To be fair though, I haven't written a lot of code outside data wrangling so it doesn't come up as often in my applications.

spice pecan
#

Last time I checked it was still marked as a draft (pattern matching)

boreal umbra
#

I was hoping it had been rejected tbh

paper echo
#

@boreal umbra even 2 levels saves a lot

#

there is a 3rd party library for this, glom

visual shadow
#

Haha. There's a strong push in favour of it from rust community.

paper echo
#

i actually do have this case somewhat frequently

#

you're more likely to need it if you use a lot of attrs/dataclasses

visual shadow
#

I'm a bit more open to it now than I was at first.

paper echo
#

with lots of nullable data (which i have all the time)

boreal umbra
#

Haha. There's a strong push in favour of it from rust community.
@visual shadow for pattern matching?

visual shadow
#

Yep, as far as I understood

paper echo
#

oh pattern matching

#

yeah im not a fan of that

#

none-aware operators, yes. pattern matching, needs a lot more work and maybe just shouldn't exist.

boreal umbra
#

why do we care what those iron oxide people want?

visual shadow
#

Apparently rust has it

paper echo
#

but rust is a strictly statically typed language

visual shadow
#

And people who like rust and python want to see it brought over

paper echo
#

the python devs want pattern matching on literals, types, and structural properties

#

and the resulting syntax is a mess

boreal umbra
#

I might actually learn rust if I ever want to write an extension

visual shadow
#

Ha

paper echo
#

maybe if matching were on types only i'd be OK

#

but with support for Literal and Protocol

#

oh yeah they want destructuring too...

#

so destructuring, structural, types, and literals

#

its just too much

visual shadow
#

I just don't like the cognitive load it brings.

paper echo
#

i want all of those features, but exactly

deft pagoda
#

it's awesome

paper echo
#

cognitive load too high and syntax becomes a mess

#

if someone can think of sane syntax to cover all 4 of those cases i'm in favor

#

but the current syntax is NOT sane to me

visual shadow
#

However their examples are pretty nice. It's just I wish there was a happy medium

#

Yep.

pearl river
#

after actually learning some Rust, I'm liking the proposal less because I feel like the main advantage of match in Rust is compile-time checking that the match arms together are exhaustive, which makes it very hard to forget a case. Without said checking, it will possibly introduce weird mistakes.

visual shadow
#

Oh. Interesting

pearl river
#

basically, if you do

match (a,b){
}

where a and b are both Option (which the compiler knows is a enum that can be either Some(_) or None) , then the compiler will make you handle all 4 cases:

(Some(x), Some(y)) => ...
(Some(x), None) => ...
(None, Some(y)) => ...
(None, None) => ...
paper echo
#

which we already have with type annotation syntax, kinda

#

with @overload

boreal umbra
#

can't overload only account for the length of the signature?

modern frigate
#

How do computers generate random numbers? I've heard that CloudFlare literally uses Lava Lamps because computers aren't the best at generating random things.

unkempt rock
#

dose python hate java???

peak spoke
#

For usual pseudo randomness just some math, python uses the Mersenne twister algorithm in the random module

modern frigate
#

interesting

paper echo
#

@modern frigate this is a good question for #algos-and-data-structs , but computers use something called "pseudo-random numbers", which you can generate using several different algorithms. the mersenne twister is one very common example. but yes, this isn't "truly" random, and you can also "run out of" randomness with these methods. so you can get the randomness directly from a random (and unpredictable) physical process, or you can use that physical process to randomly seed a random number generator

#

no @unkempt rock

modern frigate
#

ah ok, that sounds cool!

#

thanks

pseudo cradle
#

Sometimes what they do is go off of your cpu clock as your random seed

#

Best I've seen is a site that uses atmospheric noise to generate random numbers

modern frigate
#

damn thats sick

runic musk
#

here's one based on one from SGI

seed = 0
def usi_rand(seed):
    n = seed

    n *= 1103515245
    n += 12345
    result = (n // 65536) % 256

    n *= 1103515245
    n += 12345
    result <<= 7
    result ^= (n // 65536) % 256
    return result

modern frigate
#

what <<= @runic musk ?

runic musk
#

like +=

#

but <<

peak spoke
#

left bitwise shift

modern frigate
#

what does that do?

peak spoke
#

it shifts all the bits in the number to the left by the specified amount

In [6]: format(1, "b")
Out[6]: '1'
In [7]: format(1 << 3, "b")
Out[7]: '1000'

In [8]: format(5, "b")
Out[8]: '101'
In [9]: format(5 << 3, "b")
Out[9]: '101000'
modern frigate
#

oh thats awesome

#

One more thing

#

how does python generate the seed @runic musk

peak spoke
#

Seeds are mostly time based

modern frigate
#

ah that makes sense

runic musk
#

I have no idea what python doesn for rng

modern frigate
#

yeah it could just take get the current epoch time in ms and take the last digit or something

#

you would have to be extremely precise to be able to get the same number everytime

#

so i guess that makes it decently random?

pearl river
#

so to conclude, it's a Mersenne Twister initialized from the system's randomness source. I think.

paper echo
#

@modern frigate in statistics and machine learning, it's actually very important that the user be able to set the seed manually, so that their results can be reproduced

potent frigate
#

has there been any recent talk about type hinting being used to speed up code?

uncut sage
#

@potent frigate there are several projects that already do this but they are not part of mainline Python. Cython has done this for a long time, and there's now mypyc

paper echo
#

it would be interesting if there were a pypy variant that could do this

#

take advantage of the fact that it's JIT compiled

uncut sage
#

there's some reasons why pypy's JIT can't really be repurposed in that way, apparently

potent frigate
#

interesting. I feel like it being implemented in mainline in a way that isn't mandatory would be a massive boost

uncut sage
#

one thing that could be useful in time, IMO, is having PyPy generate profile information from runtime that could be in time used to compile a standalone binary

#

but that's a fairly major undertaking, I think

raven ridge
#

Remember that type hints aren't required to be accurate, because they're never used at runtime, but the only way to get performance improvements from them is if they can be trusted. If pypy started assuming that any type annotations are correct and complete, it would no longer be possible to use most libraries.

#

Even libraries that are annotated often have bugs or white lies in their annotations, and the annotation language is insufficiently flexible to describe all possible Python code.

deft pagoda
#

maybe a decorator or shebang like thing next to functions that are correctly typed

pseudo cradle
#

I just learned about fsum, and it's so cool

#
>>> sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
0.9999999999999999
>>> fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
1.0
true ibex
#

Why does sum() not return 1.0?

signal tide
#

Because while 0.99..=1, the system doesn’t know that and will return the literal sum

#

Or smthing like that

spice pecan
#

precision loss because floats are wack

pearl river
#

nah, it's just floating-point errors. this

spice pecan
#

multiple operations make it worse, fsum takes that into account and reduces the effect

pearl river
#

0.1 cannot be exactly represented as a finite base-two decimal.

true ibex
#

I see. Thanks, everyone!

pearl river
#

it's 0.00011(0011), I think

spice pecan
#

something like that, yeah

signal tide
#

Nvm then

spice pecan
#

a classic demonstration is .1 + .2 == .3

#
>>> .1 + .2
0.30000000000000004
>>> _ == .3
False```
#

And that's why all float (equality) comparison should be wrapped into something like math.isclose or abs(a - b) < tolerance

faint trout
#

And even then, chasing precision can be a bit of a nightmare.

paper echo
#

@raven ridge yeah i wasnt suggesting that pypy itself should use type annotations. i was wondering about something analogous to mypyc, but JIT compiled based on pypy's internals

#

for example knowing types ahead of time could make a lot of operations more efficient

magic python
#

@paper echo have you made much use of glom?

paper echo
#

not all the time but i use it now and then

#

e.g. i've had stuff like business.address_info.street_lines[0] and all of those lookups could fail

magic python
#

I only bumped into it the other day for the first time

#

Hmm ok, so you used it for saner error messages?

paper echo
#

no, to avoid large nested if/else or try/except checks

magic python
#

I'm guessing business is a class there?

paper echo
#

instance of a class defined with attrs, yes

magic python
#

the glom here would be glom( business , "address_info.street_lines") i think?

paper echo
#
import glom as G
from glom import glom

...

addr1 = glom(business, G.T.address_info.street_lines[0], default=None)
#

hm, might need skip_exc= too, can't remember right now

wary kestrel
#

disqualifications: [Disqualification] = []
Is this not possible in a dataclasss

paper echo
#

@wary kestrel disqualifications: typing.List[Disqualification] maybe? im not sure if you can pass a callable as a default

#

in attrs it would be disqualifications: typing.List[Disqualification] = attr.ib(factory=list)

#

i think they have to be literal defaults

#

in which case you might want to write

disqualifications: typing.Sequence[Disqualification] = ()

i.e. use a tuple instead of a list, to avoid the "mutable default argument" trap -- but then you might be depending on the mutability of the list

#
disqualifications: typing.List[Disqualification] = dataclasses.field(default_factory=list)
wary kestrel
#

ahhh

#

ty

paper echo
#

so dataclasses.field is analogous to attr.ib

#

(for my own future reference)

#

and the dataclasses.dataclass decorator is analogous to attr.s

paper echo
magic python
#

thanks salt 🙂

red solar
#

what's a glom?

grave jolt
#

Before you have an operation, you take a glom test

#

To, you know, see if you have any gloms around you

raven ridge
grave jolt
#

or that, yes

paper echo
rocky patio
#

omg lol

unkempt rock
#

ok so i have a py file and a config.json file the config has stuff i dont want the user to see can i pack the config with the pyfile and make a exe so like they open a exe and the py file and the config are like packed so they cant change the config how would i do this

honest blade
#

I recently found about PyPDF2. A module for PDFs.I wanted to know about some interesting modules like this

clear mantle
#

Oh, there's one called

runic musk
#

I've used ReportLab before. its solid

boreal umbra
#

Every python pdf library I've attempted to use has failed to extract any text at all from any pdf I've tried it with

red solar
#

but have you tried ReportLab?

half wolf
paper echo
#

interesting

#

id rather use sansio

#

but this could be useful for writing an "avec io" wrapper layer

#

and the damn async "color problem" still remains a problem

#

this is what people mean when they talk about "dependency injection" right?

half wolf
#

It's related but distinct I would say. DI usually involves some kind of dependency bucket, from where stuff is located and then inserted.

#

But I've had a colleague once state that DI is to have a function that takes arguments.

#

Which is imo stupid.

#

I don't see how sansio is related.

sacred tinsel
#

I'm not entirely sure what dependency injection really is, but I've once come across an article that was supposed to explain it and then the author just spoke about functions that take parameters, as if that was some novel unorthodox new concept

half wolf
#

To me it's a function that takes a bunch of things by some selection criteria (usually name) and then some other piece of code which has some way to find a thing by that name and then call it with those arguments.

sacred tinsel
#

The image makes sense to me, but I wasn't able to understand much from your explanation

half wolf
#

DI is the child. The arguments are the blocks. The box is the function. The shape is the lookup criteria (normally a name).

sacred tinsel
#

Ah right

#

The shape is the lookup criteria
this is the analogy I needed

half wolf
#

So yea, it's similar to just a function call, but in a normal situation you have "the child" being just one line in your source code.

#

(and everything being positional arguments often ugggghhhhh)

#

Maybe I should write a blog post.. feels stupid to write it :P

sacred tinsel
#

Maybe you should, I liked the articles that I read in your blog

half wolf
#

wow, you've read more than one?! :P

sacred tinsel
#

I liked "The Else Statement Smell" a lot

half wolf
#

Thanks. Truly.

#

oh.. that's an old one too

sacred tinsel
#

The problem with that is having the extra else clause everywhere seems noisy to me

#

ideally there would be a better way to express that

#

I think I abuse dict sometimes to get around the problem

half wolf
#

pattern matching.. -_-;

sacred tinsel
#

yees

half wolf
#

I am not a fan of the PEP

#

I'd prefer a simple switch honestly, seems more useful

#

with an implicit error default it could be quite nice

sacred tinsel
#

I find myself doing e.g. this fairly often:

cases = {
    x: func_1,
    y: func_2,
}

if something not in cases:
    raise

cases[something]()
half wolf
#

yea I've seen that.. I would probably prefer the long if else chain

#

KISS and all that

sacred tinsel
#

my issue with elif chains is that I just find them ugly

#

but that's mostly a me problem

half wolf
#

Anyway, gotta run. Time to pick up the kids from school/preschool. Nice again to hear someone actually reads my stuff :P

#

they are ugly. 100% agree. That's why I'd want a switch.

sacred tinsel
#

👍 see you around

mystic cargo
#

hope this question isn't too noobish,
How does python use infix and postfix expressions?
if I have an expression x+y*z in the script, will it convert to postfix and then evaluate it?Like it still has to deal with precedence to create the postix expression.

half wolf
mystic cargo
#

I'm asking just for knowledge, I don't have any application right now. But I appreciate the link

half wolf
#

Should be able to answer the question for yourself with it.

mystic cargo
#

sure, I'll check it out

paper echo
#

@mystic cargo python doesnt have any kind of formal intermediate representation of expressions, if that's what you're asking

#

I don't know exactly how expression parsing is implemented in cpython but it should be considered an implementation detail (and they are rolling out a new parser anyway)

half wolf
#

The generated byte code should be stable though.

unkempt rock
#

If i put the kwarg as __method it gives me this error TypeError: _unpack() got an unexpected keyword argument '__method'

spark magnet
#

the generated bytecode will not be stable. they add/remove/change the bytecode opcodes in each release.

unkempt rock
#

But if i put it as some other variable without the __ it works fine

spark magnet
#

@unkempt rock why are you using double-underscore argument names?

unkempt rock
#

Is it illegal?

spark magnet
#

there's no point, and it's causing your problem.

unkempt rock
spark magnet
#

(i think: not sure)

radiant fulcrum
#

ned will be able to explain why better than me^^

spark magnet
#

@unkempt rock double-underscore names are mangled inside classes.

radiant fulcrum
#

we established the issue was the __ but i cant explain why it happens exactly with the __ system other than its a internal thing

wide shuttle
#

It's because this indeed triggers name mangling if applied within a class

spark magnet
#

@half wolf bytecode is definitely not stable

wide shuttle
#

!e

import inspect

class Spam:
    def eggs(self, __kwarg=None):
        pass

print(inspect.signature(Spam.eggs))
fallen slateBOT
#

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

(self, _Spam__kwarg=None)
teal yacht
#

That's actually interesting, it shows the name mangling algorithm is much more naive than I thought

unkempt rock
#

Oh

teal yacht
#

I'm pretty sure that is never specified anywhere

spark magnet
#

@unkempt rock what did you want the double-underscore to do? Why use them?

wide shuttle
#

That's actually interesting, it shows the name mangling algorithm is much more naive than I thought
@teal yacht

The docs mention this:

Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.

spark magnet
#

@wide shuttle i guess it doesn't apply to the keyword names when calling a function with keyword arguments.

teal yacht
#

Ah I guess it does then

unkempt rock
#

Because i already have a singe underscore variable names and its eassy to copypaste and just add another _ (ee if i wud have known dis wud happen i wudnt be so lazy) 😪

#

@teal yacht

The docs mention this:
@wide shuttle Thanks a lot atleast i learnt something out of this

wide shuttle
#

@spark magnet Apparently. I'm not aware of any more details beyond observing the effect and reading this just now in the docs.

spark magnet
#

me too

unkempt rock
#

any number of leading _ if its > 1 then the class name will come?

spark magnet
#

a name with three underscores starts with two underscores 🙂

pseudo cradle
#

That's so weird I had no idea

unkempt rock
#

Oh damn😅

half wolf
#

@spark magnet in general no but I think he was asking about stuff like a+b vs -a which is simple enough to be stable.

spark magnet
#

i guess the question is: stable in the face of what changing?

half wolf
#

Stable for super trivial question exploration :)

spark magnet
#

i see: because it's such a simple expression.

half wolf
#

But yes, I made a bunch of implicit assumptions.

spark magnet
#

@half wolf mostly i was worried about the difference between JVM and Python.

paper echo
#

i think it sounded more like they learned about some parsing technique and were wondering if python used it

half wolf
#

Ah

swift mortar
#

anyone know how to switch the systems audio output to a different device aka from like headset to speakers using python?

lavish coral
#

Why I don't like Python: (this is my opinion, make additions/adjustments)

Indentation as syntax:

- inconsistent use of tabs and spaces in indentation
- Multiple devs working with different formatter (2 spaces, 4 spaces, tabs), if they open a file from another dev and save it, it'll break the code
- Copy paste from web (needs manuel adjustments)

File System:
- no compatibility layer between windows and linux file (endings)

Multiple Python Versions, with lack of backwards compatibility

Very old, unclear documentation (compared to other docs)

Pip packages, no easy generation of requirements.txt (pipenv required)

Many, many compatibilty problems, between Windows, Linux, Mac

Python begginers, who want to program website, will use template static html sites, which often leads to a bad UX, instead they should be making a HTTP API and a separate Single Page Application (SPA)

rugged fractal
#

ok

#

when did anyone ask GWchadThonkery

peak spoke
#

What do you mean with the compatibility problems?

rugged fractal
#

What do you mean with the compatibility problems?
@peak spoke he props means like paths with windows

#

and linux file endings

lavish coral
#

In comparison to JS or Java native libaries, that (mostly) just work out of the box without hustle

peak spoke
#

I'm not aware of any non os specific libs that don't just work

brazen jacinth
#

Pythhon packaging definitely leaves something to be desired, but preety much every other argument i disagree with in some way

lavish coral
#

I had many bad experiences switching from windows to mac

#

@brazen jacinth what exactly do you disagree with (and why)?

brazen jacinth
#

Indentation as syntax, you get used to it, .editorconfig, ehh, no experience with that one, isnt async built into the stdlib?, docs are really clean to me honestly, packaging i agree with

#

To be brief as im typing on the phone guido

lavish coral
#

no problem xD

rugged fractal
#

docs are hard to understand for me

#

except django

#

i think most docs are a mess

#

compared to most js docs

lavish coral
#

I though you can only use asynchronous with asyncio?

peak spoke
#

asyncio is stdlib

lavish coral
#

yeah since version 3.4

peak spoke
#

none of the versions before that are relevant anymore

sacred tinsel
#

hard to claim "no native support" with the async and await keywords existing

lavish coral
#

right 👍

#

Python begginers, who want to program website, will use template static html sites, which often leads to a bad UX, instead they should be making a HTTP API and a separate Single Page Application (SPA)
I find that very annoying, that many Websites are still use static site generators, the web is moving on to SPA

sacred tinsel
#

eh, I don't think you can realistically claim that we should be ditching non-SPA websites

#

but I don't see how it's relevant

peak spoke
#

Most of the indentation issue are from people not being consistent which is mostly their problem, not python's; perhaps not allowing tabs for indentation would've helped there. Can't say I agree with docs as the python docs are fine imo. What issues did you have with line endings? Python handles all of them with \n in text encodings

sacred tinsel
#

you can still build APIs with Python and query them from e.g. Angular right?

#

I don't see how that's a limitation of the language

lavish coral
#

yeah, but the sadly many beginners are learning the Static Site generation not SPA

sacred tinsel
#

why is that a bad thing?

lavish coral
#

which leads to bad UX websites

flat gazelle
#

Static sites are perfectly fine for a lot of things.

lavish coral
#

yes for little websites ok, but if the projects growths, it'll be a mess. The main Problem with static sites, that the site refreshes for every action. I wouldn't enjoy using discord this way

flat gazelle
#

Youtube is not an SPA

#

It is a multipage responsive website

lavish coral
#

sorry i meant discord

frank siren
zenith topaz
#

There's multiple pages on youtube?

flat gazelle
#

Discord is a web app, not a website

#

I think so

zenith topaz
#

To me it seems like they just use the history api to change the url, but dont' actually load in a new page

lavish coral
#

To me it seems like they just use the history api to change the url, but dont' actually load in a new page
@zenith topaz yeah they only fetch the html/js/css assets once

grave jolt
#

I am making an app with FastAPI and Vue, I don't see how Python prevents you from making an SPA.

#

(yes, there is native support of asynchronous programming -- asyncio is stdlib)

lavish coral
#

many beginners tend to use static site generation

peak spoke
#

python itself doesn't influence that much

lavish coral
#

although its not a problem with python

#

yeah

flat gazelle
#

That is still a web app. Though I guess the difference between a web app and a website is hard to define. But yes, discord should absolutely work the way it does. But should there is nothing wrong with having multiple pages that redirect to each other.

#

Static sites are easier when you do not know JS

lavish coral
#

thats the problem/point, that they don't want to learn Js I think?

sacred tinsel
#

I think it's probably better for beginners to start with static websites than go straight to SPA frameworks while still learning how to build a Python backend

lavish coral
#

yeah, I would agree on this, sadly some aren't bothered to learn new technologies and get stuck using the familiar one they know. (no problem with python)

grave jolt
#

Once every few weeks people come here just to present their list of Python's fatal flaws, most of which stem from not being familiar with the language (or are very subjective).

lavish coral
#

lol, really? 😂

grave jolt
#

I disliked JS in a similar way until I started using it in a real project. I'm kind of starting to get it.

peak spoke
#

To me, indentation syntax seems like the biggest non issue that's always brought up

lavish coral
#

yeah syntax is very subjective

grave jolt
#

Some person listed join being a method of strings instead of lists as a separate point in the fatal flaws list 👀

spice pecan
#

I actually consider that a benefit

sacred tinsel
#

I'm curious, do serious projects in languages where indentation plays no role not enforce consistent depth and spaces/tabs?

peak spoke
#

I believe that's even in the faq in the docs, but python isn't big on implementing method on all objects to be compatible

sacred tinsel
#

It's mentioned as if you could literally ignore that aspect elsewhere, but I don't think that's the case

flat gazelle
#

The argument against indentation is that braces are easier to move around

lavish coral
#

I'm curious, do serious projects in languages where indentation plays no role not enforce consistent depth and spaces/tabs?
@sacred tinsel it wouldn't break the code

flat gazelle
#

Which I never really faced

grave jolt
lavish coral
#

no, its the inconsistency

flat gazelle
#

Misbalanced brackets break code, as do misplaced. And misplaced do not error out.

#

Having braces forces an autoformatter

#

Which is fine

grave jolt
#

I think we're literally spiraling into an indentation debate, so let's move to off-topic

gleaming rover
#

the best thing about JS that Python doesn't have is nice lambdas

frank siren
#

that and unpacking for function arguments

peak spoke
#

Param unpacking was in python but was removed

frank siren
#
Scalar = TypeVar("Scalar")
class Vector3(NamedTuple, Generic[Scalar]):
    x: Scalar
    y: Scalar
    z: Scalar
    def __add__(self, other: "Vector3[Scalar]") -> "Vector3[Scalar]":
        if not isinstance(other, type(self)):
            raise OperandError("+", self, other)
        return Vector3(*(a + b for a, b in zip(self, other)))
    
    def __xor__(self, other: "Vector3[Scalar]") -> "Vector3[Scalar]":
        if not isinstance(other, type(self)):
            raise OperandError("^", self, other)
        return Vector3(self.y*other.z-self.z*other.y,
                       self.z*other.x-self.x*other.z,
                       self.x*other.y-self.y*other.x)

    @overload
    def __mul__(self, scalar: Scalar) -> "Vector3[Scalar]": ...
    @overload
    def __mul__(self, other: "Vector3[Scalar]") -> Scalar: ...

    def __mul__(self, other: Union["Vector3[Scalar]", Scalar]
    ) -> Union[Scalar, "Vector3[Scalar]"]:
        if isinstance(other, type(self.x)):
            return Vector3(*(comp * other for comp in iter(self)))
        if isinstance(other, type(self)):
            return sum((a * b for a, b in zip(self, other)))
        raise OperandError("*", self, other)

I get "type is not subscriptable" when I use brackets on that generic

#
Scalar = TypeVar("Scalar")
class Vector3(NamedTuple, Generic[Scalar]):
    x: Scalar
    y: Scalar
    z: Scalar
    def __add__(self, other: "Vector3[Scalar]") -> "Vector3[Scalar]":
        if not isinstance(other, type(self)):
            raise OperandError("+", self, other)
        return Vector3(*(a + b for a, b in zip(self, other)))
    
    def __xor__(self, other: "Vector3[Scalar]") -> "Vector3[Scalar]":
        if not isinstance(other, type(self)):
            raise OperandError("^", self, other)
        return Vector3(self.y*other.z-self.z*other.y,
                       self.z*other.x-self.x*other.z,
                       self.x*other.y-self.y*other.x)

    @overload
    def __mul__(self, scalar: Scalar) -> "Vector3[Scalar]": ...
    @overload
    def __mul__(self, other: "Vector3[Scalar]") -> Scalar: ...

    def __mul__(self, other: Union["Vector3[Scalar]", Scalar]
    ) -> Union[Scalar, "Vector3[Scalar]"]:
        if isinstance(other, type(self.x)):
            return Vector3(*(comp * other for comp in iter(self)))
        if isinstance(other, type(self)):
            return sum((a * b for a, b in zip(self, other)))
        raise OperandError("*", self, other)

I get "type is not subscriptable" when I use brackets on that generic

#

afaik generics should still work fine for multiple inheritance

#

any ideas of what I could be doing wrong

#

also, I thought I'd ask here since I don't usually get help with 484 stuff in the help channels

swift imp
#

A = TypeVar('A', str, bytes)

#

ehh

#

no

#

hmm

#

You need to define Vector3 such that it has __getitem__ defined

#
class Vector3():
  def __getitem__(): ...
gleaming rover
#

You need to define Vector3 such that it has __getitem__ defined
@swift imp nope, __getitem__ has to be defined on its metaclass

#

(which is what Generic does)

#

@frank siren IIRC you can't do that with NamedTuple

#

it overrides the other bases

#
>>> from typing import NamedTuple, Generic, TypeVar
>>> T = TypeVar('T')
>>> class Test(NamedTuple, Generic[T]):
...     a: int
...     b: int
... 
>>> Test.__bases__
(<class 'tuple'>,)
frank siren
#

Rip

#

So no generics with named tuples?

gleaming rover
#

yeah.

#

at least, AFAIK

frank siren
#

That sucks

gleaming rover
#

I wanted to do that too

#

😢

#

but well

#

typing just isn't the same as in a functional language