#internals-and-peps
1 messages · Page 142 of 1
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
HOW TO BE CACA IN JUST 3 STEPS
STEP 1 BE CACA
STEP 2 BE CACAAAA
STEB 3 BE CACCAAAA
STEB 4 BE CACAAA
<@&831776746206265384>
hmm... lemme switch to linux rq
@hybrid geode Hello, why are you spamming... whatever that is?
@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?
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
i'm not saying not to. i'm trying to understand your larger goal
is -1024 the value you expected?
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.
but does the C function ever return -1024? I would expect -1
switch the arguments: what does it return?
1024 lol
weird
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
Wym? Like socket.recv returns an empty byte string if there’s nothing to read? Not sure what u mean by “signal an end”
Yeah exactly, so when the end of the stream (because the connection has been closed) is reached it returns an empty bytestring instead of raising an error or something
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
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.
and the underlying C functions in turn are very close to the syscalls provided by the OS itself, at least on Unix
Ah, hmmm
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
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)
@surreal sun :white_check_mark: Your eval job has completed with return code 0.
1
orly 😉
justuse does a lot of that kind of abusing
the reorder_python_imports tool I was using splits up from imports on separate lines https://github.com/asottile/reorder_python_imports#splits-from-imports
from os.path import abspath, exists
# becomes
from os.path import abspath
from os.path import exists```
Is there a PEP or something that says this is a good idea? Seems like it adds a bunch of repetition imo 
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
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
Looking at PEP8, I don't think there's anything saying that besides that import a, b is discouraged
Sure, I've heard that one
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
Guess I wish reorder_python_imports didn't do the same for froms 
i think the reason for some tools to do that is to avoid git commit conflicts on imports
huh, really
if you enforce a particular order project wide, would that still happen
like, stdlib before 3rd party, imports before froms, alphabetical order
Python Enhancement Proposals (PEPs)
I extend this by putting "local" imports in a 3rd paragraph, stuff from within the current project
oh, yeah
I do that too
import os
from itertools import product
import httpx
from yarl import URL
from myapp.config import Config
from myapp.utils import make_logger
We have F expressions now! R-Python convergence
Yesss he published it?
Yep ^^ same
it should be illegal
to name anything a single letter
it makes things so hard to Google
I helps that you can google "r stats" or "gnu r"
F expressions: https://en.m.wikipedia.org/wiki/Fexpr
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
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.
it's not
Yeah, what if in one PR you do from typing import Any and then in another you do from typing import Callable. These would now be conflicts.
The ```python
from typing import (
Any
)
Solves this pretty nicely though
!e ```python
print(iter(list()))
@elder blade :white_check_mark: Your eval job has completed with return code 0.
<list_iterator object at 0x7fd6e9568c10>
wait I don't get it?
then you're clearly importing different things?
But the difference is that the former may create conflicts because different patches change the same line. While the second (the codeblock) always results in a new line no matter how many things you import which Git can handle
for those not monitoring #mailing-lists, this just got added as a draft PEP https://www.python.org/dev/peps/pep-0671/
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
ikr, it would be nice to have too
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)
dawww i thought i was first
technically first from actually being on python.org/dev/peps
isn't there a sentinel related pep somewhere
I must say he got the PEP out very quickly, props to him
8 hours after the conversation started on python-ideas, he got a full on PEP out
#mailing-lists message
technically not first haha
the mailing list got it first but tbf it's automated
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
it sets default_timeout to timeout if timeout is None
ohh are you asking the semantics of how it works?
just looks like a name error to me
what are sentinels and what does this PEP describe? Can't seem to understand it
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
lol, it wasn't there yet
ohhh, like an end value?
if that makes sense
sentinels usually have poor reprs in python because they're just made like this:
MY_SENTINEL = object()
yeah, like an end value
like in a linked list if there's no more TAIL node I'd just have None which is the sentinel value?
yep, None is the most common sentinel in python, probably
Ahh got it, thanks
but sometimes you can't use None
when it's a valid value of your data
so people make custom sentinels for it? like a special class, or just as you said object()
yep, but object() has a bad default repr
hence why that PEP got proposed I'm guessing? partly inspired from that
yep
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
none-aware i'm down with, but i'm most wanting PEP 535
!pep 535
oooh, chained comparisons for numpy arrays would be nice
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)
Wait so this allows you to take over comparison chaining?
yeah
that's really cool
ohhh so __then__ is for during the comparison chaining and __else__ is for the end result?
yeah, i think __then__ is for short-circuited behavior, i'm guessing
ah
something thats always bothered me about dict.get and the like is how default cant be lazy-eval'd. would welcome a solution like this.
agree that the => is definitely not the best choice of syntax though. would prefer something more explicit like lazy: [expression]
on the other hand something like
def test(arg_1: int, arg_2: int = lazy: 1+arg_1):```
could seem a bit ugly
=> seems decent
!ban 760660416094535730 NSFW Content
:incoming_envelope: :ok_hand: applied ban to @alpine pelican permanently.
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.
https://www.python.org/dev/peps/pep-0671/#choice-of-spelling - seems they suggested =: but not :=
I really like the backtick one!
Same
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.
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
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
hm but := is already syntactically valid in the arguments list, isn't it
def f(x=(y:=1)):
Sure, but that's irrelevant.
yeah i suppose it doesnt break backwards compatibility
!e ```py
def foo(x=(y:=1)): ...
print(y)
@raven ridge :white_check_mark: Your eval job has completed with return code 0.
1
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.
In computer science, a three-way comparison takes two values A and B belonging to a type with a total order and determines whether A < B, A = B, or A > B in a single operation, in accordance with the mathematical law of trichotomy.
Same place as before, after the parameter name.
The proposal would be def foo(x:int=>some_expression), yeah
Exactly as you say.
mm yes x :int: = len(x)
i like the backticks, but seeing how often people have trouble finding them here, I'm not sure they'd be a wise decision
You wouldn't be able to split := like that, just like you can't splt => with the current proposal.
and I guess there might be keyboard layouts that just don't have them, possibly
True, but they're used in markdown and reStructuredText, and professional devs - the ones who tend to need sentinels because they're developing libraries - tend to need those tools anyway, for their documentation or the like.
sure, I'm just saying I don't think backticks are good enough compared to the other choices
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)
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.
I think backticks are also a bad idea because they clash with Python 2's meaning of backticks
python 2
Really
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
Seeing backticks vs single quotes can be quite hard
true and it would be weird on discord
One day I'll make a programming language that needs triple backticks on a single line to do something important
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 <>
That's what VBA uses 
You can still get <> in python 3, via from __future__ import barry_as_FLUFL
Not in 3.10 
@undone hare any documentation on it pending removal?
Hmm, seems like I was mistakening
Wasn't there an Easter egg that got removed because of the PEG parser
__peg_parser__?
but that wasn't removed because of the parser, since it works in 3.9 which already has the new PEG parser
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
It works at the moment, and could be meaningful; i.e. this would be a breaking change
!e
def foo(x=(y := 42)): pass
print(y)
@quick snow :white_check_mark: Your eval job has completed with return code 0.
42
i'd like ? to be reserved for None-aware operations
that's technically breaking though, although i remember in a similar situation (introducing breaking code), rust could just survey all the public rust code and see how many people were using it. i wonder if that's possible with a language as big as python
i know it's valid syntax, but who does this? there's no real purpose for that
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
we already have that
()
tuples, generators, function-calls, method-calls, instantiation..
Both ?= and := seem good to me tbh
None-aware operators would use ??= anyway, so there's no ambiguity there
why not ?= ?
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)
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
function calls and instantiation isn't the same?
It is semantically
not even then
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
what does semantically mean here, then?
we've had that discussion before here. there are functions, there are classes as functions and there are classes
in the context of pipes
At first I was trying to remember if it actually is the same, didn't want to state things assertively without being certain myself 😅
They are the same in bytecode, and they carry the same meaning. You're calling some object for a return-value (or side effect), which, in case of types, appears to be a new instance
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?
Functions are instances of a callable class, and so are types, so there's no difference between them
paranthesis are also used to demark code blocks, str-concatenation and tuples
Fair enough
Which is why I count 2 uses: calling, and grouping of expressions
the parentheses don't make the tuples, it's the commas
Function calls (and any other callable, that's besides the point), priority and implicit line continuation
nitpicking aside, it's obvious that the same symbol is used in very different contexts for very different purposes
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)
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
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
?= would be the best option IMO
It represents some form of conveying that if this is “None” assign x to it later
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
=> doesn’t convey much meaning imo
As default arguments aren't surrounded with spaces, visual noise is important (to me at least)
def function(arg1: int, arg2: int ?= arg1)
``` looks nice
They do if you have annotations
With type annotations it does look nice, yeah
Usually
But without them, it's a bit of a different story, and I think introducing an exception to PEP8 would be weird at least
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?
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
yea that was rejected
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
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.
That would be nice
true
(similar to what's being done with annotations now)
I'm a big advocate for lazy evaluation
i think currently 0-argument lambdas is idiomatic for that kind of thing?
Yes, but that's a) ugly, and b) not automatic.
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?
how do other languages do it
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
Exactly, yeah
R has a nice way of looking at the expressions of arguments, before they are evaluated
Having an explicit way to evaluate it with a lambda solves that issue
But it's not pretty
lambda is such an ugly keyword
And since basically any action is a function call... Hmm
I've done stuff like that before, btw.: https://github.com/L3viathan/lazex
Maybe more appropriate for #esoteric-python :D
10/10 image in readme
5/5 very good image
5/7
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
that takes care of the automatic issue, not the ugliness issue 😅
Nice. I've done something similar before that avoids having to use lambdas (but has nothing to do with laziness: https://github.com/L3viathan/toolib/blob/master/magic.py
You can do something like (ƒ.foo-3) % 27, which will then be equivalent to lambda x: (x.foo - 3) % 27
is that for lazy evaluation ? or making operators from functions ?
not about lazy evaluation, just avoiding lambda. I found (at least back then) sorted(something, key=ƒ[2]) nicer than sorted(something, key=operator.itemgetter(2)) or sorted(something, key=lambda x: x[2]).
oh, that's really cool. so the evaluation comes when it gets called?
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.
ƒ is a valid identifier?
Yes
Unicode category is Ll, so yes. I chose it because it's easy to type on my keyboard (layout).
Full Unicode support baby
that's nice
!e
а = 23
print(a)
@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
and for domain name spoofing 😃
Yes, but I believe most (all?) browsers don't appreciate mixing of alphabets in IDNs nowadays
Yeah
that's just evil
!e
oldest trick in the book
Truе = False
print(Truе)
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
False
You know what’s even more cursed
that one screams shenanigans coz I know you cannot do that!
I have an easier time because I can switch to a Cyrillic keyboard with CapsLock 
!e
two ㅤplus ㅤtwo = 2 + 2
print(two ㅤplus ㅤtwo)
@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?
???
Hangul filler
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
I don't know why the default is Alt+Shift. It's very unnatural to press.
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
that can't be legal if there are actual spaces right? or did my clipboard corrupt it
!e another cursed snippet
x = 12
print([0x_for x in range(10)])
@surreal sun :white_check_mark: Your eval job has completed with return code 0.
[15]
`>>> 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?
Weird, I’m gonna try it when I get on my computer
no error though
!e
twoㅤplusㅤtwo = 2 + 2
print(twoㅤplusㅤtwo)
@surreal sun :white_check_mark: Your eval job has completed with return code 0.
4
Yess
looks like it didn't work on phone because for some reason discord doesn't show the hangul filler
this is beautiful
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))
@surreal sun :white_check_mark: Your eval job has completed with return code 0.
6
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
True = False
File "<pyshell>", line 1
True = False
^
SyntaxError: cannot assign to True
print("hello world")
!charinfo Truе
\u0054 : LATIN CAPITAL LETTER T - T
\u0072 : LATIN SMALL LETTER R - r
\u0075 : LATIN SMALL LETTER U - u
\u0435 : CYRILLIC SMALL LETTER IE - е
\u0054\u0072\u0075\u0435
You can't assign True and False in python
advanced-discussion-slowly-becoming-more-cursed moment
no shit sherlock 😉
I do Shift+Ctrl with a pinky to switch langs and Shift+Alt to switch layouts within a lang 
what's the difference?
oh, you mean like colemak vs qwerty
@grave jolt is that duck part of quackstack or is it custom made?
custom

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)
#advanced-offtopic-discussion 
😳
#internals-and-peps message
Anyways, I wonder how the lexer works where it allows this
i like to use σ, Ø and such in jupyter notebooks as quick&dirty variables, but i wouldn't use them in .py
that's very odd indeed... so much for Python being readable 😉
What are the best practices for python developers?
it is readable, but it's not portable and people with other keyboard layouts would curse at me
Why did python allow unique Unicode characters in variable names in the first place? Nevermind
I mean the unicode shenanigans :p
yeah.. well. JACKhash is also "unicode shenanigans" 😉 i guess it's a tool with dual use - for good or for evil
_ 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
at least there you can call a spade a spade
Ah yeah, I forgot about how f is just the hexadecimal part then it breaks out of the Lexing of the literal and starts lexing the keyword
it's asian gibberiah, not pretending to be some look-alike characters :)
true
mhm
0xf or ...
well, i think it's nice for school kids to learn to code using their own language for variables
True
though i never knew you could use the _ in anything that wasnt a decimal integer literal, so TIL
and they still get to use English keywords with it
!e
23423.23_223
@main ginkgo :warning: Your eval job has completed with return code 0.
[No output]
works in floats too, cool
i think that's the smallest problem though, there aren't that many
so 2_ is a number, _2 isn't
yeah, it's not a problem for me :p
@surreal sun :warning: Your eval job has completed with return code 0.
[No output]
oh, scratch that then
The new error messages on 3.10 are amazing speaking of
oh, i lied
Also 3.11 looks really cool but I think it’ll break most bytecode hacks lol
!e
_2_2 = 2_2```
in ptpython repl _2 and up will give you previously computed results
dunno if theres anything similar anywhere else
Run
wget -qO- https://samokat.ru/map.1834120f.js.map | python3 -c "d=__import__('json').loads(input()); print(d['sourcesContent'][d['sources'].index('interactive/map/getDistance.js')])"
ok..?
lots of choices 👏
i'm not gonna run it, i'm expecting shenanigans :p
I promise there are no shenaningans 😄
no what could go wrong
ive had this same concern too. i hope they expose the quickening implementation details specifically for hacks. it would be really cool and useful if we could have total control over it.
let me start my vm first.. <.<
I agree, I think the bytecode should be constant with specialization so it may just be a few more if statements for the adaptive opcodes but it still seems like a hassle
it's backward compatible right? I think it dynamically deoptimizes
0_0 is a valid number 0_0
@grave jolt hehe.. nice js code 😄
did you find the typo?
yeah. the potential problem (at least far as i can tell) would be 1. losing the ability to assume what an instruction will always do at the low level due to an optimization suddenly altering behaviour 2. optimizations resulting in modified bytecode being skipped over
yeah it's pretty cool that you can read the source map... not sure if that was intentional
ah, that makes sense
Disatance?
yeah
^^
it is somewhat reassuring to read the source of a successful website and see that it's not perfect
But hey, at least we’re getting pretty decent speed ups in 3.11
will .format() on a string literal be faster?
50% speed ups recorded so far
smh typo in the changelog
hehe
!e
import dis
dis.dis("""
"test {0}".format("hi")
""")
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
@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
the repl is on 3.9
Yeah I know
I was just curious to what the op codes are
Do all op codes get a respective adaptive opcode?
yeah it's not optimized in any way
it sounds like the flyweight pattern i used a while back
attributes mapped via properties to numpy arrays and only hold the index in the object
with __slots__
well any opcode that isn't dependent on the value being operated on presumably isn't specialized and doesn't need an adaptive variant
Ah alright
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
I don't know either, I've only been following the progress via this issue tracker. I haven't read any of the PEPs 😄
Ah alright
@grave jolt to answer your question, it seems like format might get a speed up as a result of this
Since it used CALL_METHOD
uses*
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'.
Ooh
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)
I don't think you can modify reserved keywords though you can hack with True and False
i.e.
yeah i was looking at replacing true with false and vice versa on random possibilities
!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)
@surreal sun :x: Your eval job has completed with return code 139 (SIGSEGV).
Testing!
i know there's a snippet pinned in #esoteric-python that does that but it uses one as a string
oop it segfaults
would using a different codec count?
i guess, but i'd prefer to be able to use something that doesnt need to be specified at the top of the file
i've played with codecs but i could never figure them out
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
last release may 4th 2003
ok that is beautiful
the author also hangs out around here, could ask them for some more info or ideas.
@true ridge
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
like this but without turning it into a string and without a sigsegv
hmm, cant think of a way to do that without ctypes foolery
you mean swap True and False globally right? for the entire program?
yes
!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!")
@surreal sun :x: Your eval job has completed with return code 139 (SIGSEGV).
they're the same!
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
ooooh, that may be exactly what i'm looking for pun intended
I think the creator of the challenge did some bytecode trickery
huh
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).
What is a 'codec'?
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?
then, you would change it for literally anything (not just the source code you are processing, but even the python internals).
#bot-commands message
looks like it segfaults when you try and swap the two
ah fair then, i see why it'd break if it messes up the internals too
got it, thanks for checking!
I need someone to help me build a dragon fractal in python without the turtle function by using loops
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
"useful"...
Also internally, True and False are checked by address not by checking their value
That’s because they’re void pointers right?
It's because it's faster
Ohh
It skips looking up and calling the type slot functions.
is it customary for rmw special functions (e.g. +=, -=...) to return anything?
Yes
I think usually they modify in place and also return something
would they return the result or the original value?
If it's not defined it falls back to +
Ohh
@unkempt rock :white_check_mark: Your eval job has completed with return code 0.
2 3
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()
Yep! I love decorators
@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
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
so you still need to create the setter, deleter for every property?
If you want it to work, yes. Though if you do not think it belongs there you don’t add it. I think you can delete it without property.deleter you can just customize it with deleter
Though you can’t set to the property object if you don’t implement setter
@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?
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
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
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
@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
Yep! I actually like that, I’ve seen people who fixed some bugs in a module via editing private variables
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*
Hm, well it depends, do you want the user to be able to use it or is mostly for internal use
probably just internal use
Also usually _ is the more conventional way of __
don't think I've abstracted teh steps enough to make reuse it for similar objects
__ is for name mangling usually, which will prevent collision in inheritance
unless you're the company
yeah, use __ if you're worried a child class might use the same attribute names
That’s how it is with convention, yep. Though you’re free to do whatever you want, it’s just conventionality
conventions are good. like table manners, you don't have to 😂 . But it's nice to be in the know
is there a simple way to make a property that's accessible by a simple name?
Hm, could you elaborate?
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 :\
Yeah I think I had a brain fart cause I don’t understand what you said
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
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
whats the difference between powershell and command prompt
it appears to not be possible, for what it's worth
that sounds close to what I was looking for
well, those are very simple to make
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__
no worries I'll try again some other time and try to be mote coherent 😋
!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)
@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
there we go
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
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
do you need the whole jupyter/ipython environment ? or just want to run the script text like a standalone .py file
jupter env because i cant installed face recog module in my local machine
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
if you've imported that module somewhere else like import foo then it'd just be getattr(foo, 'Klass'), otherwise if it's during the execution of the module itself you could use globals()['Klass']
not sure what you mean by " I want it to dynamically set code that references itself within itself" though
you want to overwrite the function currently executing?
(I did figure it out)
Basically given "Klass", I want to get the full object Klass defined in the current file. To do that I used sys.modules[__module__] to be able to get the attributes of the current file, and then can use getattr from there
why not just globals()['Klass']?
Uh
its a qualified name? or else it's in a separate module it sounds like?
I will check that
oh current file, yea
It's in the same file, ye
class T(U):
@classmethod
def fn(cls):
# access U.static_meth
is there a way to access a static method from U through cls?
can't you access it directly?
sry went to eat lol
uhhh... technically ig i can...
but doing that feels blunt
ok nvm apparently i can just do cls.static_meth 🙂
let's step back a second. can you give a minimal example of what you have and what you want to get?
do anyone of you have created a project that helps you in your daily life
All of the time
please share
github link of the one you are most proud
or would suggest other people to do
i request everyone please do that
I work with “protected information”
any personal projects
Nothing that I’m particularly proud of
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
do you have any sample input @unkempt rock
or you don't know because it's changing too frequently
when i was living in a shared apartment, there was the question on how to split communal expenses - the naive approach would've been a shared pot, but that woudn't have been fair, so i build a little algorithm to resolve the problem with a matrix.. not exactly a "big project" but certainly something that helped in daily life
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
isn't it called "sudoku"?
also, that doesn't sound like something for an "advanced" discussion
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
This should be in #python-discussion or maybe offtopics
The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.
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.
@unkempt rock :white_check_mark: Your eval job has completed with return code 0.
True
another question is why would you want something like this
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.
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
"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.
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!
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.
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
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!
Hey guys
I want to suggest we daily have a topic to discuss so that we all know and have knowledge from each other
I don't think there is a str interface though, is there?
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
yup sudoku :)
Utilizing what's already there (str contract, if I understand correctly) to extend what the library is capable of, is something I've done as well. Like taking advantage of implicit contracts, as an extension point (where the authors originally provided no extension facility). 👍
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
you can change __class__ attribute to be str:
In [1]: class Test:
...: __class__ = str
...:
In [2]: isinstance(Test(), str)
Out[2]: True
this is pretty hacky though
the... the what?!
We had a weekly topic discussion. Didn't go very far.
don't try this at home
you can imagine that a daily one won't work
i'm not sure why they allowed __class__ to be writeable
they only would have to do
if not isinstance(o, (str, httpx.URL)):
o = str(o)
this would make use of the __str__ , even better would be to have a protocol definde in the stdlib, like __fspath__. Many libraries are not following it, but it would at least be a little better.
sure, that'd be a nice idea. what would be a good name for it? urllib.parse.realurl and __realurl__? urllib.parse is already quite a messy crowded namespace
and yes i agree, it's a very simple change
why the dunder?
although i don't like the idea of coercing everything with str() - i'd rather explicitly support specific libraries
same reason as __fspath__, in case some implementation wants to separate its "pretty" __str__ from is "real" __fspath__
That's a bad idea, all objects are pretty much stringable so if someone makes a mistake they will have a super weird bug spent time debugging
No I mean, why __fspath__ and not fspath
because os.fspath(x) calls x.__fspath__(), same idea as str and repr
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
In my opinion, dunder names show you that this is a method that gets called by an external function, so it is not private but "external-private" it just should not be invoked directly. I think my lack of cs-education is showing.
seems like a pretty good take
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
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.
true, a lot of major libraries have abused this (e.g. attrs)
oh, it's already existing
in languages with "normal" interfaces/typeclasses those are just names
an Python has that as well - look at file-like objects
they have read and write, not __read__ and __write__
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
actually it would be ok for me if it was only __url__ as I do not think there would ever be a consensus for a different standardization for urls in python than str.
*maybe __string_url__ but that is dangerously close to hungarian notation (it is basically hungarian), I have not problem with it , but the h seem to cause nausea in a lot if people
dunders are hooks into top-level functions, things that for some reason or other don't use method call syntax
__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 😅
Is there any way to remove items from the copy of __builtins__ used by code run by exec()?
that sounds like an XY problem
wydm?
why do you need to do that?
sandboxing
just sandbox the entire process, it's much much easier
Yeah not sure how I would do that. If I do that I will need to make sure it's Linux + Windows compatible.
use docker
<_<
that too
nsjail?
A light-weight process isolation tool, making use of Linux namespaces and seccomp-bpf syscall filters (with help of the kafel bpf language)
although it's only for Linux
I don't think it's doable on windows
that's where docker comes in
I thought docker escapes were very common
not from nsjail. have you looked at snekbox?
Basically I need to either restrict file access to a single directory or cut it off completely and cut off networking & ctypes
I shall look now
@fallen slate uses it to do the !e
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?
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>```
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.
what's the code that dictates this behaviour?
@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
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.
Here's __get__ logic in type->tp_getattro: https://github.com/python/cpython/blob/main/Objects/typeobject.c#L3957
Objects/typeobject.c line 3957
meta_get = Py_TYPE(meta_attribute)->tp_descr_get;```
But it looks like the logic is generally all over the type implementation, probably in ceval too.
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
please don't spam. you'll just be given a temp voice ban
@unkempt rock Did you read #voice-verification? You'll be voice-banned if you spam.
and, well, voice-ban aside, nobody likes spam 
how did i spam
like literaly
only had like 3 sentences
Five or six lines
wow
If you want to discuss this further, please message @summer lichen
When you message this bot, you contact the entire moderation team here.
You can ask in a relevant channel, not here
yeah, #community-meta
where can i talk about a possible token logger
You can't
in a code
That's against the rules 
in off-topic if anywhere
PEP 671 is gaining traction pretty quickly, pretty excited for it
I can already think of places where it would look a lot nicer
refresh my memory, what is 671 for again?
!pep 671
oh interesting
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)
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 😔
so we're going towards => ?
that's what they're saying so far
oh well, i'm not going to complain
Not sure why this is being done
I don't get the meaning behind the token but 🤷♂️
I would like ?= more ngl
It conveys more meaning
what other languages have this sort of thing? i.e. separate from normal arguments. i know a lot have this feature by default
like gnu make? that's a nice ide
LISP right?
I feel like if the = was already implemented, then why do we need =>?
yeah, lisp defun has this
they're supposed to do different things
r has it too (but r goes further, all function arguments are left unevaluated until used)
oh
just like js
🤷♂️ Well shows what all I understood from it :P
that doesn't sound right..?
wait... js has that?
in js you can't capture unevaluated expressions though, right?
I thought it wa slike that, where if it isn't entered it'll set arg2 to arg1
let me find the examples
wouldn't that be more like none-aware arguments?
although you can't depend on the other argument, i think
i was thinking => would be called every time, not just evaluated once
# 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
so it would be possible to have empty lists and other mutables as default argument
but that's just the default argument, like in lisp
my point was that it's evaluated every time, yeah
sorry, I missed the bigger discussion as always 👀
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
yep, you'd be able to write foo(x => []) or with frontogenesis' syntax foo(x ?= [])
ohhh
do all arguments work like this?
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
I honestly think the ?= makes more sense but there's probably a reason why the Steering Council doesn't think so
It got proposed in the very beginning of the thread and got shut down
yes, it's totally bonkers and part of why r is unfixably slow at things like function calls and loops
and i love it
i once implemented function composition by literally constructing a new function function(...) f(g(...))
and your coworkers hated you for it 😉
i never used it at work 😛 only in my masters thesis
[2]
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, ...)
that hurts my eyes
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...
they have other problems :p
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.
the boilerplate with assigning to self is worse i think
You mean self.x = x?
nah, I mean, you may not like (I don't love it), but that serves a purpose
and it's a conscious choice
i know
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
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
my biggest beef with default args are with mutables
You know how in python you never write def foo(bar = list())
that one is the biggest trap for beginners
well, yes, if the argument is immutable, how can you possibly observe the fact that its global...
store the time it was created lol
pretty much 🙂
but yeah, pretty much no other lang i've used has this issue
but let's say we get a generalized =>
would that mean i could put a lambda as default argument?
it's not even clear what a generalized => means
which is to be evaluated every time the function is called?
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
let's say we have ```
y = 435
def foo(x => lambda: y):
return x ** 2
I think python used compute-at-definition arguments for when closures weren't a thing?..
why are closures related to compute-at-definition?
like ```py
def make_adder(n):
def add(m, n_prime=n):
return m + n_prime
return add
if i now call foo() the lambda could be evaluated and inserted as value for x
You've shown an example that has both defaults and closures, yes
add is a closure
okay, so are you trying to say that compute-at-definition is a workaround for the lack of closures?
was, yeah
what's a closure in the python sense?
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
hm I might be wrong that that's why it is this way
but it's certainly a usage https://docs.python.org/release/2.1/tut/node6.html#SECTION006740000000000000000
Like nested function definitions, lambda forms cannot reference variables from the containing scope, but this can be overcome through the judicious use of default argument values, e.g.
okay, just wondering, is there any use of having a mutable as default arg?
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
yeah it's really strange in hindsight
because if not, i'd suggest to make it a syntax error
🤔 ❓
and have => list() instead
well, making it a syntax error is way too heavy handed
and => is already proposed so
at least RuntimeWarning
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
it would be definition time
yes, this is python, definition time is runtime 🙂
okay, i give you that
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.
well, if it means that we get a more general solution, i'm not going to complain (too much)
It's kind of admitting in the plainest possible way that it was a mistake
plot twist: the whole PEP is there just for the monty python reference
the real proposal enhancement was the monty python references we made along the way
actually, this could be a nice playground for lambda replacement syntax
Is this proposal new? Like all of a sudden I see it on the mailing list and then here
a few days old i think
Ah k
and the braces would allow for multiple statements?
yeah
what are the parens for?
args ig
x is the argument
yeah that doesn't really make sense
how do you call it then?
maybe could be dropped
not if it's part of a def, though
I think | is unused currently in python isn't it
It's used for binary_or
bitwise or
or bitwise or
for type Union
You can distinguish it via __or__
it's already used for Union in 3.10
I mean distinguish in terms of parsing the syntax tree
!e
class Test:
def __or__(self, other):
return isinstance(other, self.__class__)
test = Test()
other_test = Test()
print(test | other_test)
print(test | 5)
@surreal sun :white_check_mark: Your eval job has completed with return code 0.
001 | True
002 | False
but { x => x + y} seems ok
I think I made some weird looking fake closure the other day
the only question is whether => can already be a legal symbol with no whitespace in it
it seems like => is just purely illegal syntax
so basically, you can distinguish a lambda from a dict by looking for => or :
that may work, may not
I feel it would be confusing with >= compared to =>
eh, idk, a ton of languages use =>
nah, => is used in tons of languages. the placement makes it super obvious
^
Fair enough
{ x => x + y } at this point is probably the most generic looking lambda across the largest number of languages
Oh, I'm not referring to that
I'm referring to late bound arguments
Why they chose => specifically
Haha I should've been more clear, mb
=> for the original proposal, yeah, idk, it's a bit random. I'd be surprised if the proposal makes it.