#internals-and-peps

1 messages · Page 142 of 1

spark magnet
#

you are making a good point, if your point is that the objects might have been reclaimed

red solar
#

it is

#
>>> ctypes.memcmp(p1, p2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'ctypes' has no attribute 'memcmp'

also lol

hybrid geode
#

HOW TO BE CACA IN JUST 3 STEPS

#

STEP 1 BE CACA

#

STEP 2 BE CACAAAA

#

STEB 3 BE CACCAAAA

#

STEB 4 BE CACAAA

astral gazelle
#

<@&831776746206265384>

red solar
#

hmm... lemme switch to linux rq

amber nexus
#

@hybrid geode Hello, why are you spamming... whatever that is?

hybrid geode
#

It was my brotgher

#

brother*

#

I was using the restroom

#

Sorry

spark magnet
#

@unkempt rock what was your goal in using memcmp on those byte strings?

#

The first bytes in a bytes object are not the characters

#

But why compare them with C code? Why not just use Python?

red solar
#
from ctypes import *


libc = cdll.LoadLibrary("libc.so.6")
libc.memcmp.argtypes = [c_void_p, c_void_p, c_size_t]
libc.memcmp.restype = c_int

b1 = b'hah'
b2 = b'heh'
p1 = c_char_p(b1)
p2 = c_char_p(b2)

print(int(libc.memcmp(p1, p2, 3)))

this works 🤷 gives me -1024

spark magnet
#

i'm not saying not to. i'm trying to understand your larger goal

spark magnet
red solar
#

yes - it's negative

#
res = libc.memcmp(c_char_p(b'hah'), c_char_p(b'heh'), 3)
print(int(res))

this also gives me a negative value

#

Negative value if the first differing byte (reinterpreted as unsigned char) in lhs is less than the corresponding byte in rhs.

​0​ if all count bytes of lhs and rhs are equal.

Positive value if the first differing byte in lhs is greater than the corresponding byte in rhs.

spark magnet
#

but does the C function ever return -1024? I would expect -1

red solar
#

it just says negative 🤷

#

i mean i would expect -1 too, but who knows

spark magnet
#

switch the arguments: what does it return?

red solar
#

1024 lol

spark magnet
#

weird

red solar
#

ah

#

i'm surprised it didn't crash

#

aww yours is -1 /1 😦

#

no 1024

elder blade
#

Is there a specific reason that socket uses an empty bytestring as a way to signal an end?

#

Python is so exception-oriented is nearly all other areas of the API

red solar
#

Wym? Like socket.recv returns an empty byte string if there’s nothing to read? Not sure what u mean by “signal an end”

elder blade
red solar
#

SO_LINGER Waits to complete the close function if data is present. When this option is enabled and there is unsent data present when the close function is called, the calling application is blocked during the close function until the data is transmitted or the connection has timed out. The close function returns without blocking the caller. This option has meaning only for stream sockets.

#

Apparently this is an option for sockets

#

So you could potentially read from a socket you have closed

raven ridge
#

the functions in os and socket are very close to what the underlying C routines give you. Which is actually great for developers, since you can very easily port code from C to Python or vice versa. And the underlying C routines don't return an error code for "remote disconnected", so Python doesn't raise an exception for it.

raven ridge
#

and the underlying C functions in turn are very close to the syscalls provided by the OS itself, at least on Unix

elder blade
#

Ah, hmmm

cobalt agate
#

Has anyone here used Processing 3.0 with Python?

#

I wish to use downhole data from oil wells and represent it visually as geological formation layers (an image). My data is like this:

HOLE:    402A
LEG:    48
TOP:    107.1000
BOTTOM:    437.9000
DEPTH_WMSF    DT    VP
m    us/ft    km/s
107.1000    146.4017    2.0804
107.2000    147.1032    2.0715
107.3000    148.0207    2.0590
107.4000    148.9655    2.0443
107.5000    150.6052    2.0238
107.6000    152.2933    2.0020
107.7000    153.7738    1.9819
107.8000    155.4267    1.9611
107.9000    157.1257    1.9376
108.0000    159.8593    1.9081
108.1000    162.0931    1.8820
108.2000    163.6698    1.8659
108.3000    163.6649    1.8654
108.4000    162.3990    1.8791
108.5000    160.2935    1.8998
108.6000    158.8602    1.9186
108.7000    157.4200    1.9350
108.8000    156.4614    1.9472
108.9000    155.7817    1.9570
109.0000    154.9389    1.9657
109.1000    154.6353    1.9733
109.2000    153.5717    1.9864
109.3000    152.0962    2.0026
surreal sun
#

You can abuse ModuleType quite a bit lol

#

!e

from sys import modules
from types import ModuleType

class Organize(ModuleType):
   hello_world = 1

modules["test"] = Organize

from test import hello_world
print(hello_world)
fallen slateBOT
#

@surreal sun :white_check_mark: Your eval job has completed with return code 0.

1
verbal escarp
#

justuse does a lot of that kind of abusing

unkempt rock
#

Is there a PEP or something that says this is a good idea? Seems like it adds a bunch of repetition imo pithink

#

especially when py from typing import Any from typing import Callable from typing import cast from typing import Collection from typing import Dict from typing import Iterable from typing import List from typing import Optional from typing import Sequence from typing import Tuple from typing import Union could be one line

spice pecan
#

from imports usually should be grouped up, yeah

#

Sometimes with parens for readability, like

from module import (
    A,
    B,
    C,
    ...
)
#

IIRC PEP-8 suggests you don't import different modules in one statement (import a, b is discouraged), but importing multiple things from one module should be done in one statement

surreal sun
unkempt rock
#

Sure, I've heard that one

surreal sun
#
Imports
Imports should usually be on separate lines, e.g.:

Yes:

import os
import sys
No:

import os, sys
It’s okay to say this though:

from subprocess import Popen, PIPE
unkempt rock
#

Guess I wish reorder_python_imports didn't do the same for froms lemon_warpaint

spice pecan
verbal escarp
gleaming rover
#

if you enforce a particular order project wide, would that still happen

#

like, stdlib before 3rd party, imports before froms, alphabetical order

dawn scarab
paper echo
paper echo
#
import os
from itertools import product

import httpx
from yarl import URL

from myapp.config import Config
from myapp.utils import make_logger
paper echo
surreal sun
#

Yep ^^ same

gleaming rover
#

to name anything a single letter

#

it makes things so hard to Google

paper echo
#

I helps that you can google "r stats" or "gnu r"

#

In Lisp programming languages, a fexpr is a function whose operands are passed to it without being evaluated. When a fexpr is called, only the body of the fexpr is evaluated; no other evaluations take place except when explicitly initiated by the fexpr. In contrast, when an ordinary Lisp function is called, the operands are evaluated automatical...

#

R is wild, you can literally access a function as a list of symbols including the function body, which you can modify freely and then call or pass around to higher order functions or whatever

#

You can implement a compose function for example by literally constructing nested function call objects and then casting that whole business to a function

#

You can write a function that inlines other functions dynamically at runtime

#

And people wonder why R is slow... but it is so fun to mess with stuff like that

#

Anyway late binding isn't exactly the same thing but it's a fun aspect of language design that's been kind of hiding quietly in a statistics DSL

boreal umbra
#

Why is it that you can echo "hello world" | python file.py but not echo "hello world" | python -i ?

#
$ echo "hello world" | py -i
...
Type "help", "copyright", "credits" or "license" for more information.
>>>   File "<stdin>", line 1
    hello world
          ^
SyntaxError: invalid syntax
>>>
#

I guess for the REPL, things that you type are stdin?

#

I guess I answered my own question.

rugged wedge
#

TypeError: 'list' object is not an iterator

#

ok

feral cedar
#

it's not

elder blade
elder blade
fallen slateBOT
#

@elder blade :white_check_mark: Your eval job has completed with return code 0.

<list_iterator object at 0x7fd6e9568c10>
gleaming rover
#

then you're clearly importing different things?

elder blade
worldly venture
#

proposes new syntax ```py
def bisect_right(a, x, lo=0, hi=>len(a), *, key=None):
def connect(timeout=>default_timeout):
def add_item(item, target=>[]):

#

anything following => is executed at function call time if no explicit argument is used, including referencing other args that are passed

#

I think this is super cool

#

not sure I'm entirely attached to the =>, but it's certainly a cool idea

dawn scarab
surreal sun
#

and guido seems for it, and so do quite a few core devs

#

might not get deferred like some other notable peps (cough 505 cough)

worldly venture
deft pagoda
#

isn't there a sentinel related pep somewhere

surreal sun
surreal sun
#

the mailing list got it first but tbf it's automated

worldly venture
deft pagoda
#

i wrote a sentinel library for myself that does this and more --- i think these are pretty useful to have

#

could just add a function in some stdlib

#

i still don't know how def connect(timeout=>default_timeout): works

surreal sun
#

ohh are you asking the semantics of how it works?

deft pagoda
#

just looks like a name error to me

surreal sun
deft pagoda
#

sentinels are used in a lot of algorithms to signal special cases

#

like in a linked list you might have a special sentinel block that is the HEAD or TAIL

dawn scarab
surreal sun
#

if that makes sense

deft pagoda
#

sentinels usually have poor reprs in python because they're just made like this:

MY_SENTINEL = object()

yeah, like an end value

surreal sun
#

like in a linked list if there's no more TAIL node I'd just have None which is the sentinel value?

deft pagoda
#

yep, None is the most common sentinel in python, probably

surreal sun
#

Ahh got it, thanks

deft pagoda
#

but sometimes you can't use None

feral cedar
#

when it's a valid value of your data

surreal sun
deft pagoda
#

yep, but object() has a bad default repr

surreal sun
deft pagoda
#

yep

surreal sun
#

that would actually be nice to have ngl

#

the PEP i'm most rooting for right now is PEP 505

#

I could really use those none aware operators

#

doesn't seem like they're very popular among the core devs tho

deft pagoda
#

none-aware i'm down with, but i'm most wanting PEP 535

feral cedar
#

!pep 535

fallen slateBOT
#
**PEP 535 - Rich comparison chaining**
Status

Deferred

Python-Version

3.8

Created

12-Nov-2016

Type

Standards Track

feral cedar
#

oooh, chained comparisons for numpy arrays would be nice

deft pagoda
#

yeah

#

there's actually other symbolic uses for it too

#

i have to do some hacks for this to work:

In [1]: from real_ranges import Var

In [2]: x = Var('x')

In [3]: 5 <= x < 10
Out[3]: Range(5, 10, start_inc=True, end_inc=False)
surreal sun
deft pagoda
#

yeah

surreal sun
#

ohhh so __then__ is for during the comparison chaining and __else__ is for the end result?

deft pagoda
#

yeah, i think __then__ is for short-circuited behavior, i'm guessing

surreal sun
#

ah

main ginkgo
#

on the other hand something like

def test(arg_1: int, arg_2: int = lazy: 1+arg_1):``` 
could seem a bit ugly
native flame
#

=> seems decent

unkempt rock
#

!ban 760660416094535730 NSFW Content

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied ban to @alpine pelican permanently.

raven ridge
# native flame `=>` seems decent

Hm. It'll be esoteric no matter what symbol is chosen. Maybe := would be a better choice, since that already refers to a "special" type of assignment in another context.

#

I really like the backtick one!

brave badger
#

Same

raven ridge
#

All of the bikeshedding over syntax aside, I really like the idea. I would use this much more often than the walrus operator or pattern matching. And it seems like this might subsume the sentinel proposal, since if we had this we'd need sentinels much, much less often.

brave badger
# brave badger Same

It's reminiscent of LISP-like quoting with the backticks and all; it's also certainly much better than just using strings again for it

raven ridge
#

And, we can't use strings. def foo(x="bar") already means something.

#

Though we could use our new "soft keyword" support to make it something like def foo(deferred x=[]) or something like that.

#

Or def foo(lazy x = [])
Or def foo(late x = [])

#

Sure. obj[index] has 2 arguments, obj and index

native flame
#

def f(x=(y:=1)):

raven ridge
#

Sure, but that's irrelevant.

native flame
#

yeah i suppose it doesnt break backwards compatibility

raven ridge
#

!e ```py
def foo(x=(y:=1)): ...
print(y)

fallen slateBOT
#

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

1
raven ridge
#

I'm genuinely surprised that works, though 😄

#

In other languages that's a "rich compare" operator. a<=>b returns -1, 0, or 1 depending on whether a is less than, equal to, or greater than b.

#

Same place as before, after the parameter name.

#

The proposal would be def foo(x:int=>some_expression), yeah

#

Exactly as you say.

native flame
#

mm yes x :int: = len(x)

sand python
#

i like the backticks, but seeing how often people have trouble finding them here, I'm not sure they'd be a wise decision

raven ridge
sand python
#

and I guess there might be keyboard layouts that just don't have them, possibly

raven ridge
sand python
#

sure, I'm just saying I don't think backticks are good enough compared to the other choices

raven ridge
#

simple, tp_richcompare doesn't have to call the dunders.

#

It's the other way around, a<b will try to call tp_richcompare(a, b, Py_LT)

prime estuary
#

If you override any of them at the Python level, it seems like it'll fallback only by looking up and calling the dunder method, which then goes and calls the c richcompare of the superclass.

quick snow
feral cedar
#

python 2

gleaming rover
#

I didn't even know backticks were a thing in Py2

#

TIL

nocturne delta
#

lmao

#

it was used for some string conversion ig

undone hare
#

Really

peak spoke
#

Backticks feel like an all around bad char to me, evidently hard to find for some people in and a tiny footprint on the code that makes them a bit harder to read compared to others

#

I don't think it was something that was actually used, at least in more recent years

undone hare
#

Seeing backticks vs single quotes can be quite hard

lusty scroll
#

true and it would be weird on discord

quick snow
#

One day I'll make a programming language that needs triple backticks on a single line to do something important

warm junco
#

It seems like an alias to repr

>>> class A(object):
...     def __str__(self): return "__str__ called"
...     def __repr__(self): return "__repr__ called"
... 
>>> a = A()
>>> `a`
'__repr__ called'
#

Oh cool/bit weird the inequality operator used to be <>

undone hare
#

That's what VBA uses pained_smile

quick snow
#

You can still get <> in python 3, via from __future__ import barry_as_FLUFL

undone hare
#

Not in 3.10 kek

quick snow
#

Whaat? It was removed? :,(

#

Still works for me on 3.10

undone hare
#

Really

#

Maybe it is in 3.11 then

quick snow
#

@undone hare any documentation on it pending removal?

undone hare
#

Hmm, seems like I was mistakening

#

Wasn't there an Easter egg that got removed because of the PEG parser

peak spoke
#

__peg_parser__?

quick snow
#

but that wasn't removed because of the parser, since it works in 3.9 which already has the new PEG parser

verbal escarp
#

i'd disallow walrus operation in def and use the syntax for late-bound arguments

#

i don't think walrus operation is meaningful in that place anyway

surreal sun
#

I honestly liked ?= the most for late bound arguments

#

It conveyed the most meaning

quick snow
#

!e

def foo(x=(y := 42)): pass
print(y)
fallen slateBOT
#

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

42
verbal escarp
#

i'd like ? to be reserved for None-aware operations

feral cedar
verbal escarp
quick snow
#

I guess I'm wrong, def foo(x:=42) doesn't work

#

but it's still confusing why the same syntax should have drastically different meaning there vs. in the rest of Python

verbal escarp
#

we already have that

#

()

#

tuples, generators, function-calls, method-calls, instantiation..

spice pecan
#

Both ?= and := seem good to me tbh

#

None-aware operators would use ??= anyway, so there's no ambiguity there

quick snow
#

method calls, function calls, and instantiation are the same. Tuples are not marked by parantheses, but by commas (except the empty tuple, I guess). So in total I count 2 uses: Calls, and grouping of expressions (including generator comprehensions)

spice pecan
#

That's what's proposed in the pep, and that's what would be obvious to people coming from other languages. Most of them use ?? for null-coalescence

verbal escarp
spice pecan
#

It is semantically

verbal escarp
#

not even then

spice pecan
#

Instantiation is not a separate procedure, it's calling an instance of type as any other callable object (including functions)

#

If it used a keyword, such as new in other languages, then it would be a separate concept, but currently it's the exact same operation

feral cedar
#

what does semantically mean here, then?

verbal escarp
#

we've had that discussion before here. there are functions, there are classes as functions and there are classes

#

in the context of pipes

spice pecan
spice pecan
quick snow
#

There are callables. They can be called. That is marked by parantheses. Or would you also say that calling something that is neither a class nor a function is an entirely different use of parantheses?

spice pecan
#

Functions are instances of a callable class, and so are types, so there's no difference between them

verbal escarp
surreal sun
quick snow
feral cedar
#

the parentheses don't make the tuples, it's the commas

spice pecan
#

Function calls (and any other callable, that's besides the point), priority and implicit line continuation

verbal escarp
spice pecan
#

Oh yeah, I do agree with that sentiment

#

There's nothing bad about giving the same symbol different meanings as long as context is easily distinguishable or meanings are similar enough

#

It's done constantly, such as the different meanings of *, or even _ for that matter

#

(I still think * would make a better wildcard :P)

verbal escarp
#

which is why i'd argue that having := for the purpose of late-bound arguments doesn't contradict the use for inline-assignment

#

if it's clear that they are very different contexts

quick snow
#

I don't find that clear. If I read def foo(x:=23): ... somewhere without knowing this, I'd just assume x would be assigned after the function definition as well

surreal sun
#

^

#

I feel like ?= would be the most fitting given its context

#

But 🤷‍♂️

spice pecan
#

?= would be the best option IMO

surreal sun
#

It represents some form of conveying that if this is “None” assign x to it later

spice pecan
#

It would be distinct from ??=, conveying that it's not just If not none, it's If not present

#

Though it will still convey that the purpose is similar

#

If the PEP goes through (and I hope it does), I'd vouch for ?= over =>

#

Although I can't skim past the fact that := seems to add the least visual noise, that's a big benefit in my eyes

surreal sun
#

=> doesn’t convey much meaning imo

spice pecan
#

As default arguments aren't surrounded with spaces, visual noise is important (to me at least)

surreal sun
#
def function(arg1: int, arg2: int ?= arg1)
``` looks nice
surreal sun
spice pecan
#

With type annotations it does look nice, yeah

surreal sun
#

Usually

spice pecan
#

But without them, it's a bit of a different story, and I think introducing an exception to PEP8 would be weird at least

native flame
#

i feel like using ? further leads to confusion between optional as in T | None and optional as in optional arguments
i think pyright(?) already shows Optional[T] as T?

spice pecan
#

Oh

#

That's a good point

#

I remember some discussion about having T? be syntactically equivalent to T | None, but IIRC the conclusion was that T | None is clear enough to avoid it

native flame
#

yea that was rejected

spice pecan
#

So while there wouldn't be syntactic ambiguity, it would be confusing for people coming from other languages with nullable types and pyright users

#

Hmm

#

Just reverse it, =? /s

quick snow
#

I'd love for there to be generic uses for this syntax, if it were to be introduced: mark an expression as lazy, to be evaluated on first use.

spice pecan
#

That would be nice

native flame
#

true

quick snow
#

(similar to what's being done with annotations now)

spice pecan
#

I'm a big advocate for lazy evaluation

native flame
#

i think currently 0-argument lambdas is idiomatic for that kind of thing?

spice pecan
#

Pretty sure, yeah

#

lambda: lazy_value

#

Having syntactic support would be very nice

quick snow
#

Yes, but that's a) ugly, and b) not automatic.

spice pecan
#

Although it does raise some questions

#

If you pass it to a function, should it be evaluated on call or on first usage in that function?

native flame
#

how do other languages do it

quick snow
#

Right. If done as I said above, I would say the first use of the expression evaluates it (i.e. on call), but the other way around would be more useful

spice pecan
#

Exactly, yeah

quick snow
spice pecan
#

Having an explicit way to evaluate it with a lambda solves that issue

#

But it's not pretty

native flame
#

lambda is such an ugly keyword

spice pecan
#

And since basically any action is a function call... Hmm

quick snow
native flame
#

10/10 image in readme

silk verge
#

5/5 very good image

spice pecan
#

5/7

verbal escarp
#

damn, need one of those for justuse

#

opens paint

lusty scroll
#

you could have a class called Lazy

#

that just eval's itself if you try to use any attribute of it

#

could even store the value so it's not computed multiple times

#
def myfunc():
    return Lazy("[5  + 8, len('blah'), z * z]")

a, b, c = myfunc()
#

it could also work with a lambda

#
from lazy import Lazy as L

def myfunc():
    return L @ lambda: [5+8, len('blah'), z * z]

a, b, c = myfunc()
``` @verbal escarp
#

L @ lambda: isn't nothing, but it seems like a pretty small inconvenience

lusty scroll
quick snow
lusty scroll
quick snow
lusty scroll
#

oh, that's really cool. so the evaluation comes when it gets called?

quick snow
#

yes, exactly. Although it would be nice to be able to do ƒ.foo(53) as well

#

But then you'd need some way to tell it "done", otherwise it won't behave well as a key function.

lusty scroll
#

ƒ is a valid identifier?

undone hare
#

Yes

quick snow
#

Unicode category is Ll, so yes. I chose it because it's easy to type on my keyboard (layout).

undone hare
#

Full Unicode support baby

lusty scroll
#

that's nice

quick snow
#

!e

а = 23
print(a)
fallen slateBOT
#

@quick snow :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 2, in <module>
003 | NameError: name 'a' is not defined
quick snow
#

:P

#

if you don't like your coworkers, you can use unicode support to your advantage ^

lusty scroll
#

and for domain name spoofing 😃

quick snow
#

Yes, but I believe most (all?) browsers don't appreciate mixing of alphabets in IDNs nowadays

undone hare
#

Yeah

lusty scroll
grave jolt
fallen slateBOT
#

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

False
surreal sun
#

You know what’s even more cursed

lusty scroll
grave jolt
#

I have an easier time because I can switch to a Cyrillic keyboard with CapsLock hyperlemon

surreal sun
#

!e

two ㅤplus ㅤtwo = 2 + 2
print(two ㅤplus ㅤtwo)
fallen slateBOT
#

@surreal sun :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 1
002 |     two ㅤplus ㅤtwo = 2 + 2
003 |         ^^^^^^^^^^
004 | SyntaxError: invalid syntax. Perhaps you forgot a comma?
surreal sun
#

Whattt

#

It worked in 3.9

grave jolt
#

???

surreal sun
#

Hangul filler

lusty scroll
#

b'two \xe3\x85\xa4plus \xe3\x85\xa4two = 2 + 2\nprint(two \xe3\x85\xa4plus \xe3\x85\xa4two)\xe2\x80\x8a\n\n'

#

haha, nice

#

still confused

grave jolt
#

and you have to move your entire hand, whereas with CapsLock I can just press it with my pinky

#

anyway, that's a bit off topic

lusty scroll
#

that can't be legal if there are actual spaces right? or did my clipboard corrupt it

surreal sun
#

!e another cursed snippet

x = 12
print([0x_for x in range(10)])
fallen slateBOT
#

@surreal sun :white_check_mark: Your eval job has completed with return code 0.

[15]
lusty scroll
#

`>>> exec(str(b'two \xe3\x85\xa4plus \xe3\x85\xa4two = 2 + 2\nprint(two \xe3\x85\xa4plus \xe3\x85\xa4two)\xe2\x80\x8a\n\n'))

dir()
['annotations', 'builtins', 'doc', 'loader', 'name', 'package', 'spec']`

#

nothing happened?

surreal sun
#

Weird, I’m gonna try it when I get on my computer

lusty scroll
#

no error though

surreal sun
#

!e

twoㅤplusㅤtwo = 2 + 2
print(twoㅤplusㅤtwo)
fallen slateBOT
#

@surreal sun :white_check_mark: Your eval job has completed with return code 0.

4
surreal sun
#

Yess

#

looks like it didn't work on phone because for some reason discord doesn't show the hangul filler

native flame
#

this is beautiful

surreal sun
#

I use it for some of the esoteric things I've done

#

found it

#

!e

from __future__ import annotations
from forbiddenfruit import curse


def __or__(self, other):
    if not isinstance(other, str):
        raise TypeError

    return ClosureFunction(self, other)


curse(list, "__or__", __or__)


class BlankSpace:
    """
    Used as a filler to make it seem not there.
    I got a blank space baby, and I'll write your name.
    """
    def __or__(self, other):
        """Allowing to look more like a closure"""
        return other


class ClosureFunction:
    def __init__(self, params, func):
        self.params, self.func = params, func

    def __call__(self, *args, **kwargs):
        assert len(self.params) == len(args) + len(kwargs)
        for value, name in zip(args, self.params):
            locals()[name] = value

        for param_name, param_value in kwargs.items():
            locals()[param_name] = param_value

        result = eval(self.func)
        return result



ㅤ= BlankSpace()
cool_func = ㅤ|['x', 'y', 'z']|"x + y + z"
print(cool_func(1, 2, 3))
fallen slateBOT
#

@surreal sun :white_check_mark: Your eval job has completed with return code 0.

6
surreal sun
#

As for this example, I wonder why this happens
#internals-and-peps message

I'd think Python wouldn't catch keywords while scanning a literal

verbal escarp
autumn zenith
#

print("hello world")

fallen slateBOT
autumn zenith
surreal sun
# grave jolt

advanced-discussion-slowly-becoming-more-cursed moment

verbal escarp
spice pecan
grave jolt
#

oh, you mean like colemak vs qwerty

surreal sun
#

@grave jolt is that duck part of quackstack or is it custom made?

surreal sun
#

Ah nice

#

Who made these

spice pecan
# grave jolt what's the difference?

I could use that for colemak vs qwerty, but I use it to switch between the american and european english layouts (so I can have easy access to things like ä when I need to)

grave jolt
#

#advanced-offtopic-discussion lemon_enraged

surreal sun
#

😳

verbal escarp
#

i like to use σ, Ø and such in jupyter notebooks as quick&dirty variables, but i wouldn't use them in .py

lusty scroll
#

that's very odd indeed... so much for Python being readable 😉

autumn zenith
#

What are the best practices for python developers?

verbal escarp
#

it is readable, but it's not portable and people with other keyboard layouts would curse at me

surreal sun
lusty scroll
verbal escarp
main ginkgo
#

_ can be used as a delimiter in number literals to add some space, so 0x_f is just being parsed as 0xf similar to how 1_000_000 is just 1000000

lusty scroll
#

at least there you can call a spade a spade

surreal sun
lusty scroll
#

it's asian gibberiah, not pretending to be some look-alike characters :)

verbal escarp
#

true

surreal sun
#

0xf or 0 which ll just return 15

#

since 0xf is 15

verbal escarp
#

well, i think it's nice for school kids to learn to code using their own language for variables

main ginkgo
#

though i never knew you could use the _ in anything that wasnt a decimal integer literal, so TIL

lusty scroll
main ginkgo
#

!e

23423.23_223
fallen slateBOT
#

@main ginkgo :warning: Your eval job has completed with return code 0.

[No output]
main ginkgo
#

works in floats too, cool

verbal escarp
lusty scroll
#

so 2_ is a number, _2 isn't

verbal escarp
#
  File "<stdin>", line 1
    2_
     ^
SyntaxError: invalid decimal literal```
#

neither

lusty scroll
surreal sun
#

I think you need something after the _

#

!e 2_5

fallen slateBOT
#

@surreal sun :warning: Your eval job has completed with return code 0.

[No output]
lusty scroll
#

oh, scratch that then

surreal sun
#

The new error messages on 3.10 are amazing speaking of

verbal escarp
#

oh, i lied

surreal sun
#

Also 3.11 looks really cool but I think it’ll break most bytecode hacks lol

verbal escarp
#
>>> _2 = 2 
#

works without complaint

lusty scroll
#

!e

_2_2 = 2_2```
main ginkgo
#

in ptpython repl _2 and up will give you previously computed results

#

dunno if theres anything similar anywhere else

grave jolt
lusty scroll
#

lots of choices 👏

verbal escarp
grave jolt
#

I promise there are no shenaningans 😄

lusty scroll
#

no what could go wrong

main ginkgo
verbal escarp
#

let me start my vm first.. <.<

surreal sun
lusty scroll
#

it's backward compatible right? I think it dynamically deoptimizes

grave jolt
verbal escarp
#

@grave jolt hehe.. nice js code 😄

grave jolt
#

did you find the typo?

main ginkgo
grave jolt
#

yeah it's pretty cool that you can read the source map... not sure if that was intentional

verbal escarp
grave jolt
#

yeah

verbal escarp
#

^^

grave jolt
#

it is somewhat reassuring to read the source of a successful website and see that it's not perfect

surreal sun
#

But hey, at least we’re getting pretty decent speed ups in 3.11

grave jolt
#

will .format() on a string literal be faster?

surreal sun
grave jolt
#

smh typo in the changelog

verbal escarp
#

hehe

surreal sun
#

!e

import dis

dis.dis("""
"test {0}".format("hi")
""")
grave jolt
#

Object attributes are held in an array instead of a dictionary. An object’s dictionary are created lazily, only when needed. Reduces the memory consumption of a typical Python object by about 30%. Patch by Mark Shannon.
huh that's interesting

fallen slateBOT
#

@surreal sun :white_check_mark: Your eval job has completed with return code 0.

001 |   2           0 LOAD_CONST               0 ('test {0}')
002 |               2 LOAD_METHOD              0 (format)
003 |               4 LOAD_CONST               1 ('hi')
004 |               6 CALL_METHOD              1
005 |               8 RETURN_VALUE
grave jolt
#

the repl is on 3.9

surreal sun
#

Yeah I know

#

I was just curious to what the op codes are

#

Do all op codes get a respective adaptive opcode?

grave jolt
#

yeah it's not optimized in any way

verbal escarp
#

attributes mapped via properties to numpy arrays and only hold the index in the object

#

with __slots__

naive saddle
surreal sun
#

I still don’t get how they’re gonna know when to call the adaptive opcode

#

I read the PEP but I still didn’t understand

naive saddle
#

I don't know either, I've only been following the progress via this issue tracker. I haven't read any of the PEPs 😄

surreal sun
#

Ah alright

surreal sun
#

Since it used CALL_METHOD

#

uses*

main ginkgo
#

iirc the bytecode is observed at runtime to see which instructions are hot and can be adapted (e.g. has this binary_and been called with two ints like 1000 times in a row? lets specialize this for ints). if so, some extra info is added separately from the original bytecode to say 'run this specialization instead of the instruction at position x'.

surreal sun
#

Ooh

silk pawn
#

is there any way to reassign reserved keywords in python (or using a c-extension) without modifying cpython itself

#

my guess is not because that could break the entire language but it doesnt seem impossible to me

#

(not sure if this is the right channel tbh, feel free to redirect me if it isnt)

surreal sun
#

i.e.

silk pawn
#

yeah i was looking at replacing true with false and vice versa on random possibilities

surreal sun
#

!e

from ctypes import c_void_p

class Test:
  def __str__(self):
    return "Testing!"
  
  __repr__ = __str__

c_void_p.from_address(id(True) + 8).value = id(Test)

test123 = test345 = object()
print(test123 is test345)
fallen slateBOT
#

@surreal sun :x: Your eval job has completed with return code 139 (SIGSEGV).

Testing!
silk pawn
#

i know there's a snippet pinned in #esoteric-python that does that but it uses one as a string

surreal sun
#

oop it segfaults

main ginkgo
silk pawn
#

i've played with codecs but i could never figure them out

main ginkgo
#

its pretty straightforward, you basically just have to register a function to convert bytes (as read from file) to text (which will then be passed to parser)

#

there's a module called bicyclerepairman or something like that which makes it easier iirc

#

has a full tokenizer and stuff built in

#

nah wait this isnt it

silk pawn
#

last release may 4th 2003

main ginkgo
silk pawn
#

ok that is beautiful

main ginkgo
#

the author also hangs out around here, could ask them for some more info or ideas.

#

@true ridge

silk pawn
#

yeah i've seen them around here before

#

is there a way to do it without a codec though, possibly with a function that swaps True and False every time it's called

silk pawn
main ginkgo
#

hmm, cant think of a way to do that without ctypes foolery

#

you mean swap True and False globally right? for the entire program?

silk pawn
#

yes

surreal sun
#

!e

from ctypes import c_void_p

class Test:
  def __str__(self):
    return "Testing!"
  
  def __bool__(self):
    return True
  
  __repr__ = __str__

c_void_p.from_address(id(True) + 8).value = id(Test)

test123 = test345 = object()
if test123 is test345:
  print("they're the same!")
fallen slateBOT
#

@surreal sun :x: Your eval job has completed with return code 139 (SIGSEGV).

they're the same!
surreal sun
#

I think there's a way you could make something walk and talk like a boolean

#

There was a challenge for it in esoteric-python a while back

silk pawn
#

ooooh, that may be exactly what i'm looking for pun intended

surreal sun
silk pawn
#

huh

true ridge
# silk pawn is there a way to do it without a codec though, possibly with a function that sw...

True and False keywords are directly converted to their actual objects during the parsing. So you can't actually get rid of it, unless you either modify something on the tokenizer or on the parser itself. The easier way is to just define a codec, or a custom importer which processes the source before passing it to the real python parser (possibly by changing each True/False to a something like __mylib_True/__mylib_False).

surreal sun
#

What is a 'codec'?

silk pawn
#

if they're converted to their actual objects during parsing, then shouldn't swapping the locations of true and false in memory with ctypes or something work just fine?

true ridge
surreal sun
silk pawn
lapis hare
#

I need someone to help me build a dragon fractal in python without the turtle function by using loops

quick snow
#

Again a useful feature we lost from Python 2 :(

Python 2.7.17 (default, Dec 23 2019, 21:25:33)
[GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.33.16)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> True, False = False, True
>>> True
False
red solar
#

"useful"...

pliant tusk
#

Also internally, True and False are checked by address not by checking their value

surreal sun
pliant tusk
#

It's because it's faster

surreal sun
#

Ohh

prime estuary
#

It skips looking up and calling the type slot functions.

red solar
#

is it customary for rmw special functions (e.g. +=, -=...) to return anything?

surreal sun
#

I think usually they modify in place and also return something

red solar
#

would they return the result or the original value?

surreal sun
#

result I think the former

#

nope

grave jolt
#

If it's not defined it falls back to +

surreal sun
#

Ohh

fallen slateBOT
#

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

2 3
red solar
#

lol

#

but ok, so return self

surreal sun
#

👀

#

This is pretty cool

fringe skiff
#

do you guys use decorators

#

import functools```python
def timer(func):
"""
Decorator Practice - Prints the runtime of the decorated function
* https://betterprogramming.pub/decorators-in-python-72a1d578eac4
* https://realpython.com/primer-on-python-decorators/#timing-functions
* https://realpython.com/primer-on-python-decorators/#decorators-with-arguments
"""
@functools.wraps(func)
def wrapper_timer():
start_time = time.perf_counter() # starts counting
func() # main
end_time = time.perf_counter() # ends counting
time_elapsed = end_time - start_time
logger.info(f"Main() completed in {time_elapsed:.4f}s.")
return wrapper_timer

#
@timer
def main():
  ...

if __name__ == '__main__':
  main()
surreal sun
fringe skiff
#

@surreal sun For some of the common ones, like @property I've been seeing ppl use it differently -- what's the correct way?

#
class object:
  def __init__(self, input_color):
    self._color = input_color # or can I do self.color?

  @property
  def color(self):
    return self._color
surreal sun
#

Well, it depends.

If you only want to have a way to get the value


class Test:
    @property
    def value(self) -> int:
        return 5

test = Test()
print(test.value)
>>> 5
test.value = 2
AttributeError: can’t set attribute value

If you want to be able to set it too, something like


class Test:
    def __init__(self):
        self._value = 5
    @property
    def value(self) -> int:
        return self._value
   
    @value.setter
    def value(self, value: int) -> None:
        self._value = value

test = Test()
print(test.value)
>>> 5
test.value = 2
print(test.value)
>>> 2

and if you wanna be able to delete it


class Test:
    def __init__(self):
        self._value = 5
    @property
    def value(self) -> int:
        return self._value
   
    @value.setter
    def value(self, value: int) -> None:
        self._value = value

   @value.deleter
   def value(self) -> None:
       print("value has been deleted!")
       del self._value

test = Test()
print(test.value)
>>> 5
test.value = 2
print(test.value)
>>> 2
del test.value
>>> "value has been deleted"
print(test.value)
>>> error about how it doesn’t exist (like AttributeError: "value" is not an attribute or something)
#

Sorry if anything is wrong, I’m on phone and can’t test it out

fringe skiff
#

so you still need to create the setter, deleter for every property?

surreal sun
#

Though you can’t set to the property object if you don’t implement setter

fringe skiff
#

@surreal sun Oh i see, you're very right.

#

so what if had saved color as self.color

#

could I just do y.color = 'red' then? Why not just make the attribute public?

#

Is it just for formality?

surreal sun
#

You could do that and remove property, usually people add property if they don’t want it to be changed due to abuse

#

Or for other reasons

#

Like datetime uses property for the datetime class

#

Because if you change the hour or day it could be wrong and cause the entire thing to mess up

#

So it doesn’t allow editing the public attribute

fringe skiff
#

Oh wow okay, very cool. So it's more about communicating with your end-user of your class, really in the sense of public vs. private variables

#

Ty, this was really enlightening, I appreciate it

surreal sun
# fringe skiff Ty, this was really enlightening, I appreciate it

No problem. Though, in python, nothing is truly a private variable. So if I wanted I could edit the internal, “private” attribute of the datetime class and make it go haywire but python has a “consenting adults” philosophy where you’re trusted not to do something like that

fringe skiff
#

@surreal sun That makes sense haha. You give the end-user more freedom, but if they want to mess things up they're allowed to do so

#

Okay, one more about just form of code

surreal sun
#

Yep! I actually like that, I’ve seen people who fixed some bugs in a module via editing private variables

fringe skiff
#

What do you think about auto-processing of data in an object?

#

initialize the object, it automates the process of what I wanted to do, returns a "cleaned" object. Makes sense that those methods are private, yeah?

#

functions*

surreal sun
#

Hm, well it depends, do you want the user to be able to use it or is mostly for internal use

fringe skiff
#

probably just internal use

surreal sun
#

Also usually _ is the more conventional way of __

fringe skiff
#

don't think I've abstracted teh steps enough to make reuse it for similar objects

surreal sun
#

__ is for name mangling usually, which will prevent collision in inheritance

deft pagoda
#

yeah, use __ if you're worried a child class might use the same attribute names

fringe skiff
#

@surreal sun so only use -- when you're working with inheritance?

#

__

surreal sun
#

That’s how it is with convention, yep. Though you’re free to do whatever you want, it’s just conventionality

fringe skiff
#

conventions are good. like table manners, you don't have to 😂 . But it's nice to be in the know

lusty scroll
surreal sun
#

Hm, could you elaborate?

lusty scroll
#

like, if you have a type that's defined in a module that's currently being imported, so you can't just import it at module scope, but you want later references to the simple name (like inside functions) to resolve it

#

my thought is basically to work around not being able to import names from a parent module that is importing the submodule itself

#

is that clear? o.O

#

if you try to import such a thing you get a "cannot import name X from partially initialized module 'parent'"

#

like parent module is ns and I'm talking about ns.tools module. ns first imports ns.tools then it defines a class that ns.tools needs

#

I thought having a lazy-like "property" at module scope of ns.tools might be a way to get away with it

#

the property could eventually fetch ns.ClassDefinedLater when it's actually needed by some function and your functions could contain unqualified references to ClassDefinedLater (without needing from ns import ClassDefinedLater (which would cause everything to come crashing down))

#

yeah, I knew it would be tricky to explain :\

surreal sun
#

Yeah I think I had a brain fart cause I don’t understand what you said

tired leaf
#

hey guys i am fascinated by the openai gpt3 and really want to make a cool project , how i am a beginner in python, how should i do it , please suggest something

deft pagoda
#

i don't know exactly what you're describing but beazley wrote these lazy methods that aren't even executed until someone pokes one with a __get__ for https://github.com/dabeaz/cluegen

#

they just exist as a string of code until then

unkempt rock
#

whats the difference between powershell and command prompt

lusty scroll
#

it appears to not be possible, for what it's worth

lusty scroll
deft pagoda
#

well, those are very simple to make

lusty scroll
#

like, suppose you have type hints that would be resolved to something lazy , which would then fetch the actual value later if someone reads __module__ or __bases__ , etc. sort of like a proxy, not just on function call. Would that work?

#

it's neat that 'cluegen' lets you return some code to get dynamically executed

#

trying to wrap my head around the example with __slots__

lusty scroll
deft pagoda
#

!e

from textwrap import dedent


class LazyMethod:
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, cls):
        if instance is None:
            return self

        func = self.func
        name = func.__name__

        code = func(cls)
        exec(code, loc := { })

        setattr(cls, name, loc[name])
        return getattr(instance, name)

class MyLazyClass:
    @LazyMethod
    def __add__(cls):
        return dedent(f"""
        def __add__(self, other):
            return other
        """)

print(MyLazyClass.__add__)
my_class = MyLazyClass()
print(my_class.__add__)
print(my_class + 5)
fallen slateBOT
#

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

001 | <__main__.LazyMethod object at 0x7f6f581abd90>
002 | <bound method __add__ of <__main__.MyLazyClass object at 0x7f6f581ab520>>
003 | 5
deft pagoda
#

there we go

light mesa
#

no idea where to ask this but anyone has any article, site, guide or etc that explains what is a TLS client and cache reduction and how bypasses work on like cloudflare or generally some bot protection

lusty scroll
#

maybe

potent schooner
#

is it possible to write a script to run a python script from jupyter notebook?

#

for example : execute the python script at local machine to ask jupyter note book to execute another py script

lusty scroll
potent schooner
white nexus
#

How can i get an attribute from a module file itself?
Eg I want it to dynamically set code that references itself within itself. So it has 'Klass' in a string and I want it to get its own object and return it of class Klass
if this isn't the right place to ask please let me know, this seems cursed enough to fit

unkempt rock
lusty scroll
#

you want to overwrite the function currently executing?

white nexus
unkempt rock
white nexus
#

Uh

lusty scroll
#

its a qualified name? or else it's in a separate module it sounds like?

white nexus
#

I will check that

lusty scroll
#

oh current file, yea

white nexus
red solar
#
class T(U):
    
    @classmethod
    def fn(cls):
        # access U.static_meth
#

is there a way to access a static method from U through cls?

peak spoke
red solar
#

sry went to eat lol

red solar
#

but doing that feels blunt

#

ok nvm apparently i can just do cls.static_meth 🙂

verbal escarp
#

let's step back a second. can you give a minimal example of what you have and what you want to get?

tired leaf
#

do anyone of you have created a project that helps you in your daily life

tired leaf
#

github link of the one you are most proud

#

or would suggest other people to do

#

i request everyone please do that

last panther
tired leaf
last panther
#

Kind of funny really. I can show my coworkers and nobody else… makes me feel kind of stuck.

#

I can explain one of my favorites though

#

I’ll Dm you

lusty scroll
#

do you have any sample input @unkempt rock

#

or you don't know because it's changing too frequently

verbal escarp
shadow lintel
#

I was again thinking about my python learning and i found that even though i learned OOP but i havent applied inheritance once so i challenged myself to use inheritance and reshape ur soduko program,...
.
So i started thinking deep on it that how i goona use it and implement it but still havent reached to a good soultion .
.
So if someone have any idea to find my way

#

.
My soduko app is just to make and solve soudko(mannual+automatic)

#

My mind gave me this map but when i am implying i am confused and entangled with the thoughts

verbal escarp
#

isn't it called "sudoku"?

#

also, that doesn't sound like something for an "advanced" discussion

shadow lintel
#

I wanted to have some discussions , career one dont suits, not the commu ity meta so i came here

#

Aah dont go on my spellings theya re like that

astral gazelle
unkempt rock
#

how to do python coding

#

plz help me

fallen slateBOT
#
Resources

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

unkempt rock
#

ya

#

thanks for

#

resource

#

thanks

vast saffron
#

Is there a way to make an instance of a custom class act like a string?

I do not mean __str__ but more so for interacting with libraries that will check isinstance(o, str). Just defining __str__ fails, using collections.UserString fails.

fallen slateBOT
#

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

True
cloud crypt
#

another question is why would you want something like this

vast saffron
#

to deal with libraries I am dependent on that want an url, but do not take any of the URL implementations, or want a path, but do not take any pathlib Path.

for example requests vs httpx.
requests.get can take an yarl..URL as first param
httpx.get can not it wants either its own URL implementation or an str.

as some other obscure libraries will dictate what I will use (webdav each implementation uses a different lib as engine) and I may want to easily switch them. I do not want to str(instance) in one and just instance in the other, but abstract it away.

visual shadow
#

Instead of making an object behave like that, instead make a middleman class that gives those libraries whatever datatype they need, and then just interact with this middman

halcyon trail
#

"middleman" is a bit of a weird way to put it, I guess you mean simply wrapping the library though

#

wrapping can be fine, really depends how many functions you have to wrap, compared to how complicated it is to make the datatypes work the way you want.

vast saffron
#

would be awesome if libraries would also accept the instances str implementation and not only a real string.

As far as I can tell for any use case, having it count as str via its str would solve it completely, I was just hoping to be able to modify the instance and not write a wrapper that is coupled to libraries.

thanks everyone for the answers though!

vast saffron
#

Just for completeness, this would not work in my case, as I would have to modify the parameter in the init. turn it to an URL and also adding a base url.

I accomplished it by

    def __new__(cls, href_path):
        return str.__new__(cls, cls.base_url.join(URL(href_path)))

    def __init__(self, href_path: str) -> None:
        self.url = self.base_url.join(URL(href_path))
        super().__init__()

It works but feels wrong.

halcyon trail
#

it's just kind of hard because ultimately str is not an interface. Anyone who's programming against str is programming against a concrete type, it's not really done in a way that is designed to allow using a different type

#

str doesn't even really provide, afaik, any obvious interface to program against instead. The way that say you have the concrete type list, but then you also have MutableSequence which is an interface

#

So, it seems to me like any real solution to your problem will feel at least somewhat wrong

grave jolt
#

Nice Monty Python reference

#

See the Spanish Inquisition sketch

vast saffron
# halcyon trail So, it seems to me like any real solution to your problem will feel at least som...

you are correct and I will most likely have to think about how I will go about it. postponing the decision though.

Still I am kind of annoyed for people to validate against a concrete string, or their own implementation instead of against the str interface. It feels like it is going against the intention of the language.

If someone knows the reason why it is done, I would really like to hear it!

tribal dirge
#

Hey guys
I want to suggest we daily have a topic to discuss so that we all know and have knowledge from each other

halcyon trail
#

If anything, it seems like the standard library's "fault" for not providing an interface separate of the concrete type?

#

But I could easily be wrong about that

lusty scroll
paper echo
#

it also kind of depends on what aspects of string-ness those libraries do actually depend on

#

without looking at their source code, it's hard to know what parts of the string interface they need

#

the best you can do is convert from path to string, although i agree it would be really nice if httpx directly supported hyperlink and yarl

deft pagoda
#

this is pretty hacky though

grave jolt
deft pagoda
#

don't try this at home

grave jolt
#

you can imagine that a daily one won't work

deft pagoda
#

i'm not sure why they allowed __class__ to be writeable

vast saffron
paper echo
#

and yes i agree, it's a very simple change

grave jolt
#

why the dunder?

paper echo
#

although i don't like the idea of coercing everything with str() - i'd rather explicitly support specific libraries

paper echo
# grave jolt why the dunder?

same reason as __fspath__, in case some implementation wants to separate its "pretty" __str__ from is "real" __fspath__

elder blade
grave jolt
paper echo
peak spoke
#

I don't really understand why some names chose the dunder naming, same with the pickling dunders, but in the case of fspath I think it mimics the usually expected interface

vast saffron
deft pagoda
#

seems like a pretty good take

paper echo
#

i think it's a good summary too

#

it's like a "hook" or otherwise overriding the behavior of some top-level function

#

kind of like an ad-hoc single dispatch mechanism for functions that are implemented as top-level functions and not as instance methods

vast saffron
#

also per definition dunder names are reserved for python itself. Nobody cares and everyone makes their own dunder(see richfor example) but there is no guarantee that a future python version will not define that specific dunder.

I would love to have a convention for user defined dunders, that show the same thing as in my previous comment, but make it clear that it is not from python itself, idk currently using "trunder" for it tripple underscore. it will make people even more mad that hate the underscores , but its just an experiment in my personal libraries.

paper echo
#

true, a lot of major libraries have abused this (e.g. attrs)

grave jolt
grave jolt
#

an Python has that as well - look at file-like objects

#

they have read and write, not __read__ and __write__

paper echo
#

but those are methods

#

in a language with UFCS the distinction melts away, but there you also typically have single dispatch on static types so it's not a fair comparison

vast saffron
paper echo
#

dunders are hooks into top-level functions, things that for some reason or other don't use method call syntax

vast saffron
# grave jolt they have `read` and `write`, not `__read__` and `__write__`

__iter__ is called when you do
~~```py
for i in o:

~~you should not call `__iter__`~~ 

~~same thing with `__len__`.~~

~~That there are actual functions (`iter()`, `len()`) that do nothing but call it, muddies the water, but I was unable to currently think of better examples.~~

EDIT: scratch that, bad examples, will hopefully post better ones when I am not in a hurry 😅
heady mauve
#

Is there any way to remove items from the copy of __builtins__ used by code run by exec()?

feral cedar
#

that sounds like an XY problem

heady mauve
#

wydm?

feral cedar
#

why do you need to do that?

heady mauve
#

sandboxing

feral cedar
#

just sandbox the entire process, it's much much easier

heady mauve
#

Yeah not sure how I would do that. If I do that I will need to make sure it's Linux + Windows compatible.

feral cedar
#

use docker

heady mauve
#

<_<

grave jolt
#

er

#

use nsjail

feral cedar
#

that too

heady mauve
#

nsjail?

grave jolt
#
#

although it's only for Linux

#

I don't think it's doable on windows

feral cedar
#

that's where docker comes in

heady mauve
#

I thought docker escapes were very common

feral cedar
#

not from nsjail. have you looked at snekbox?

heady mauve
#

Basically I need to either restrict file access to a single directory or cut it off completely and cut off networking & ctypes

heady mauve
feral cedar
#

@fallen slate uses it to do the !e

heady mauve
#

oh nice

#

nice nice nice

#

If I were to use snekbox, how would I communicate with the process while it's running?

#

and can snekbox be run without docker?

verbal escarp
#

i was just trying to reproduce how i think i set properties to instances of classes before, but i'm not sure what's going on

#
class Test:
    def __init__(self):
        self.a = 243
        self._b = 3
    
    @property
    def b(self):
        return self._b
    
    @b.setter
    def b_setter(self, x):
        self._b = x
    
test = Test()

def logged(func):
    def wrapper(*args, **kwargs):
        return func.fget(*args, **kwargs)
    return wrapper

setattr(test, "b", property(logged(test.__class__.b), test.__class__.b.fset))
#

gives AttributeError: can't set attribute

#

if i replace b_setter by b, it works doesn't raise an exception, but then

#
>>> test.b
<property object at 0x0000021AC7ACF9F0>```
prime estuary
#

Property objects need to be assigned on the class, it's only if they're accessed from there that they do their function-call behaviour.

verbal escarp
#

what's the code that dictates this behaviour?

grave jolt
#

@verbal escarp that's just how descriptors work AFAIK

#

just like what happens when you do foo.bar(): if bar is a function (which is a descriptor) on the class, foo.bar's descriptor magic will get called

prime estuary
#

Well, that's just how the descriptor protocol works. I think it's defined in the C equivalent of type.__getattribute__ / type.__setattr__.

#

"Where" might be hard to specify since it's likely special cased all over.

fallen slateBOT
#

Objects/typeobject.c line 3957

meta_get = Py_TYPE(meta_attribute)->tp_descr_get;```
prime estuary
#

But it looks like the logic is generally all over the type implementation, probably in ceval too.

verbal escarp
#

hmm..

#

could you elevate an instance of a class to be its own class?

#

then maybe you could manipulate its properties?

#

/* No data descriptor found on metatype. Look in tp_dict of this
* type and its bases */

#

that looks like the thing that controls this behaviour

feral cedar
#

please don't spam. you'll just be given a temp voice ban

grave jolt
#

and, well, voice-ban aside, nobody likes spam lemon_pensive

unkempt rock
#

like literaly

#

only had like 3 sentences

heady mauve
#

Five or six lines

unkempt rock
#

wow

grave jolt
#

If you want to discuss this further, please message @summer lichen

unkempt rock
#

lmow

#

lmao

#

thats a bot

#

idk how these things work

grave jolt
#

When you message this bot, you contact the entire moderation team here.

astral gazelle
#

You can ask in a relevant channel, not here

grave jolt
unkempt rock
#

where can i talk about a possible token logger

elder blade
#

You can't

unkempt rock
#

in a code

elder blade
#

That's against the rules pydis_nope_py

unkempt rock
#

ok

#

can i talk about how to get rid OF IT

heady mauve
#

in off-topic if anywhere

surreal sun
#

PEP 671 is gaining traction pretty quickly, pretty excited for it

#

I can already think of places where it would look a lot nicer

heady mauve
#

refresh my memory, what is 671 for again?

paper echo
#

!pep 671

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

Draft

Python-Version

3.11

Created

24-Oct-2021

Type

Standards Track

heady mauve
#

oh interesting

surreal sun
#

Example:
With a discord bot when you're getting the 'user' for a user-related command and the user doesn't provide a member
async def user_command(ctx: commands.Context, member: discord.Member => ctx.author)

surreal sun
# heady mauve oh interesting
def test(arg1: int, arg2: int => arg1):
  # code

would be the same as

def test(arg1: int, arg2: int = None):
  if arg2 is None:
    arg2 = arg1
#

with this PEP

#

I am more excited for PEP 505 (None aware operators) but it doesn't seem like that's coming anytime soon 😔

verbal escarp
#

so we're going towards => ?

surreal sun
#

that's what they're saying so far

verbal escarp
#

oh well, i'm not going to complain

heady mauve
#

Not sure why this is being done

surreal sun
#

I don't get the meaning behind the token but 🤷‍♂️

paper echo
#

i agree that => feels kind of arbitrary

surreal sun
#

It conveys more meaning

feral cedar
#

what other languages have this sort of thing? i.e. separate from normal arguments. i know a lot have this feature by default

paper echo
#

like gnu make? that's a nice ide

surreal sun
#

LISP right?

heady mauve
#

I feel like if the = was already implemented, then why do we need =>?

surreal sun
#

I heard LISP has it, and maybe Smalltalk, that was from the thread I think

#

OHh

paper echo
feral cedar
paper echo
#

r has it too (but r goes further, all function arguments are left unevaluated until used)

heady mauve
heady mauve
#

🤷‍♂️ Well shows what all I understood from it :P

verbal escarp
paper echo
#

in js you can't capture unevaluated expressions though, right?

surreal sun
#

let me find the examples

verbal escarp
#

wouldn't that be more like none-aware arguments?

grave jolt
#

although you can't depend on the other argument, i think

verbal escarp
#

i was thinking => would be called every time, not just evaluated once

surreal sun
#
# Very common: Use None and replace it in the function
def bisect_right(a, x, lo=0, hi=None, *, key=None):
    if hi is None:
        hi = len(a)

from the PEP itself, one of the examples

verbal escarp
#

so it would be possible to have empty lists and other mutables as default argument

paper echo
# grave jolt

but that's just the default argument, like in lisp

grave jolt
#

my point was that it's evaluated every time, yeah

#

sorry, I missed the bigger discussion as always 👀

paper echo
#

in r, if you write f(g(x + y - 10) * 10), f gets passed the expression g(x + y - 10) * 10, which is only evaluated the first argument is actually used in the body of f

#

and you can capture the unevaluated expression if you want to do meta-programming

paper echo
grave jolt
#

do all arguments work like this?

verbal escarp
#

hmm..

#

why not generalize that to all assignments?

#

if we had => as syntax for deferred evaluation

#

we could also make it a way to define properties

surreal sun
#

It got proposed in the very beginning of the thread and got shut down

paper echo
#

and i love it

#

i once implemented function composition by literally constructing a new function function(...) f(g(...))

verbal escarp
#

and your coworkers hated you for it 😉

paper echo
#

i never used it at work 😛 only in my masters thesis

paper echo
#

you can also implement partial application that way

#

as an infix operator

#

you can implement foo %$% _(a, b) which constructs and returns the function function(...) foo(a, b, ...)

verbal escarp
#

that hurts my eyes

halcyon trail
#

On the one hand, this => is helpful for saving boilerplate. On the other hand, you know you're an old language when you have to introduce stuff to fix problems that most languages, especially newer ones, just don't have...

halcyon trail
#

sure, it's not a competition

#

(well, maybe kinda)

#

but this problem is an eyesore and relatively unique to python (maybe also Ruby, idk)

#

this is probably the number one thing I see catch people who are learning python from other languages. One of the most unintuitive things you encounter the earliest on, and doesn't exist in most languages.

verbal escarp
#

the boilerplate with assigning to self is worse i think

halcyon trail
#

You mean self.x = x?

verbal escarp
#

yeah

#

but there are solutions for that at least by now

halcyon trail
#

nah, I mean, you may not like (I don't love it), but that serves a purpose

#

and it's a conscious choice

verbal escarp
#

i know

halcyon trail
#

python's default argument behavior is just bad

#

There's no reason why your function defaults should be forced to be globals

#

Nobody would ever consciously make this choice; it arises as a compromise

#

I doubt it

feral cedar
halcyon trail
#

the idea behind -> is when used for default arguments in functions, it causes it to be evaluted at function call time

#

not function definition time

verbal escarp
#

my biggest beef with default args are with mutables

halcyon trail
#

You know how in python you never write def foo(bar = list())

verbal escarp
#

that one is the biggest trap for beginners

halcyon trail
#

well, yes, if the argument is immutable, how can you possibly observe the fact that its global...

feral cedar
#

store the time it was created lol

halcyon trail
#

pretty much 🙂

feral cedar
#

but yeah, pretty much no other lang i've used has this issue

verbal escarp
#

but let's say we get a generalized =>

#

would that mean i could put a lambda as default argument?

halcyon trail
#

it's not even clear what a generalized => means

verbal escarp
#

which is to be evaluated every time the function is called?

halcyon trail
#

because the proposal here has to do with something very specific to function default arguments

#

?

#

everything that happens inside the body of a function happens every time its called, already

verbal escarp
#

let's say we have ```
y = 435
def foo(x => lambda: y):
return x ** 2

grave jolt
#

I think python used compute-at-definition arguments for when closures weren't a thing?..

halcyon trail
#

why are closures related to compute-at-definition?

grave jolt
verbal escarp
#

if i now call foo() the lambda could be evaluated and inserted as value for x

halcyon trail
#

You've shown an example that has both defaults and closures, yes

grave jolt
#

No, there's no closure.

#

At least in the Python sense

verbal escarp
#

add is a closure

halcyon trail
#

okay, so are you trying to say that compute-at-definition is a workaround for the lack of closures?

grave jolt
#

was, yeah

feral cedar
#

what's a closure in the python sense?

halcyon trail
#

I don't think that's the actual reason, but I could be wrong. let's see what google turns up.

#

I mean I really doubt that's the reason given Guido's views on this stuff

#

The main answers here suggest that basically either, it was a) for perf reasons, or b) easier to implement

grave jolt
#

hm I might be wrong that that's why it is this way

halcyon trail
#

actually maybe the main answer kind of supports what you're saying

#

I'm not sure

verbal escarp
#

okay, just wondering, is there any use of having a mutable as default arg?

halcyon trail
#

although, I definitely disagree with the framing 🙂

#

it's basically just making your default arg as a global

#

if there is a use, it's trivial to achieve without

#

*without it

grave jolt
#

yeah it's really strange in hindsight

verbal escarp
#

because if not, i'd suggest to make it a syntax error

grave jolt
#

🤔 ❓

verbal escarp
#

and have => list() instead

halcyon trail
#

well, making it a syntax error is way too heavy handed

#

and => is already proposed so

verbal escarp
#

at least RuntimeWarning

halcyon trail
#

linters ides etc the whole universe already warns about this

#

there's no reason to pay any interpreter cost at runtime for this

#

it can be checked and warned statically in 99% of important cases

verbal escarp
#

it would be definition time

halcyon trail
#

yes, this is python, definition time is runtime 🙂

verbal escarp
#

okay, i give you that

halcyon trail
#

it also just wouldn't be done for backwards compatibility reasons

#

yes it's a shitty way to write code but there's probably working code in the wild using it

#

Anyhow. It's just incredibly lame to have to introduce a magic operator to fix aproblem that shouldn't even exist to start with.

#

For basic reasons of human nature I think it will be hard for this proposal to be accepted, as a result.

verbal escarp
#

well, if it means that we get a more general solution, i'm not going to complain (too much)

halcyon trail
#

It's kind of admitting in the plainest possible way that it was a mistake

grave jolt
#

plot twist: the whole PEP is there just for the monty python reference

halcyon trail
#

lol

#

the real proposal was the monty python references we made along the way

grave jolt
#

the real proposal enhancement was the monty python references we made along the way

verbal escarp
#

actually, this could be a nice playground for lambda replacement syntax

red solar
#

Is this proposal new? Like all of a sudden I see it on the mailing list and then here

feral cedar
#

a few days old i think

red solar
#

Ah k

verbal escarp
#
y = 343
def foo(x => (){y +1}):
   return x ** 2
#

maybe?

feral cedar
#

and the braces would allow for multiple statements?

verbal escarp
#

yeah

halcyon trail
#

what are the parens for?

feral cedar
#

args ig

halcyon trail
#

x is the argument

verbal escarp
#

yeah

#

parameters for the lambda

halcyon trail
#

yeah that doesn't really make sense

feral cedar
#

how do you call it then?

verbal escarp
#

maybe could be dropped

surreal sun
#

I think
def (x, y): x + y looks nicer

#

add = def (x, y): x + y
add(2, 3)
>>> 5

verbal escarp
#

not if it's part of a def, though

surreal sun
#

ah true

#

def foo(test => def: 2)

halcyon trail
#

I think | is unused currently in python isn't it

surreal sun
#

It's used for binary_or

feral cedar
#

bitwise or

surreal sun
#

or bitwise or

verbal escarp
#

for type Union

halcyon trail
#

maybe those cases could be distinguished

#

hmm maybe not then

surreal sun
#

You can distinguish it via __or__

feral cedar
#

it's already used for Union in 3.10

halcyon trail
#

I mean distinguish in terms of parsing the syntax tree

surreal sun
#

!e

class Test:
  def __or__(self, other):
    return isinstance(other, self.__class__)

test = Test()
other_test = Test()

print(test | other_test)
print(test | 5)
fallen slateBOT
#

@surreal sun :white_check_mark: Your eval job has completed with return code 0.

001 | True
002 | False
surreal sun
#

Oh

#

you mean it that way

halcyon trail
#

but { x => x + y} seems ok

surreal sun
#

I think I made some weird looking fake closure the other day

halcyon trail
#

the only question is whether => can already be a legal symbol with no whitespace in it

#

it seems like => is just purely illegal syntax

surreal sun
halcyon trail
#

so basically, you can distinguish a lambda from a dict by looking for => or :

#

that may work, may not

surreal sun
#

I feel it would be confusing with >= compared to =>

halcyon trail
#

eh, idk, a ton of languages use =>

feral cedar
#

nah, => is used in tons of languages. the placement makes it super obvious

halcyon trail
#

^

surreal sun
#

Fair enough

halcyon trail
#

{ x => x + y } at this point is probably the most generic looking lambda across the largest number of languages

surreal sun
#

I feel like it's quite arbitrary for what it's doing but

#

🤷‍♂️

halcyon trail
#

well yes, syntax is arbitrary 🙂

#
  • is also arbitrary
surreal sun
#

I'm referring to late bound arguments

#

Why they chose => specifically

halcyon trail
#

ohhh

#

hah

#

at this point we have moved on to stealing => for lambdas

surreal sun
#

Haha I should've been more clear, mb

halcyon trail
#

=> for the original proposal, yeah, idk, it's a bit random. I'd be surprised if the proposal makes it.