#esoteric-python
1 messages Β· Page 40 of 1
i followed the one on https://black.readthedocs.io/en/stable/
Try it out now using the Black Playground.
also like... as if formatting this would make it any better, lmao
idk since highlighting gave up on that code
Python bot doesn't evaluate due to user inputs
ok but what does this thing do?
It's a question I had to do for school, where we take user input and form a matrix and perform operations on them
You can run it and try it out
what language does linux/ubuntu use
Enter the numbers of the matrix seperated by a space, its a 2x2 matrix
while 1:(s:=str,r:=range,_:=s.join,print((lambda c,d:((d.update({'m1':[],'m2':[],'+':[[],[]],'-':[[],[]]})),[(d['m1'].append([int(i)for i in list(input(f"m1 line {i}:").replace(" ",''))]))for i in r(2)],[(d['m2'].append([int(i)for i in list(input(f"m2 line {i}:").replace(" ",''))]))for i in r(2)],([d['+'][i].extend([j+d['m2'][i][0],k+d['m2'][i][1]])for i,(j,k)in enumerate(d['m1'])]),([d['-'][i].extend([abs(j-d['m2'][i][0]),abs(k-d['m2'][i][1])])for i,(j,k)in enumerate(d['m1'])]),(_(_(_(_("Sum:\n"+" ",[s(i) for i in d['+'][0]])+'\n'+" ",[s(i) for i in d['+'][1]])+'\n' + 'Difference:\n'+" ",[s(i) for i in d['-'][0]])+"\n"+" ",[s(i)for i in d['-'][1]])))if c=='a'else(((d.update({'tm':[]})),[(d['tm'].append([int(i)for i in list(input(f"line {i}:").replace(" ",''))]))for i in r(2)],(d.update({'tf':[[d['tm'][j][i]for j in r(2)] for i in r(2)]})),(_(_(_(_("Original:\n"+" ",[s(i) for i in d['tm'][0]])+'\n'+" ",[s(i)for i in d['tm'][1]])+'\n'+'Transpose:\n'+" ",[s(i)for i in d['tf'][0]])+"\n"+" ",[s(i)for i in d['tf'][1]])))if c=='b'else(quit()if c=='q'else(None,'Invalid Input'))))(c=input("Enter Choice:\n(A)For Sum and Difference\n(B)For Transpose\n(Q)To Quit\n>>>").lower()[0],d={})[-1]))[:]
english?
what do you understand by "linux" and what do you mean by "language"
I mean the Ubuntu Operating System and I mean like which computer language was it originally programmed by
heh
most of the kernel is written in C
but there are a lot of other languages used in different parts of OS
Without execute the code, get the answer of the following code
class Base:
def __repr__(self):
return ''
class qmure(Base):
def __repr__(self):
return 'M' + super().__repr__()
class ko0r3(Base):
def __repr__(self):
return 'S' + super().__repr__()
class cumv6(Base):
def __repr__(self):
return 'E' + super().__repr__()
class stumv(cumv6):
def __repr__(self):
return 'A' + super().__repr__()
class rstuo(ko0r3):
def __repr__(self):
return 'I' + super().__repr__()
class umvs1(cumv6):
def __repr__(self):
return 'K' + super().__repr__()
class simpt(stumv, umvs1):
def __repr__(self):
return 'T' + super().__repr__()
class result(qmure, rstuo, simpt):
pass
print(result())
(Basic level MRO, Question 1: Beginner level)
Please use spoiler to say the answer
lol
||MISTAEK||
nope
the concept, if the 2 parent of the class have the same parent, it should execute after both parent execute
ah, im dumb
i confused the order at the end
oh lol
here is an inheritance tree: || ```py
Base
M
result
S
I
result
E
A
T
result
K
T
result
mhh, make you should make result on top
this look more confusing lol
||```
result
M
Base
I
S
Base
T
A
E
Base
K
E
Base
also do you mind spoil it
thx lol
object
BaseException
BaseExceptionGroup
ExceptionGroup(BaseExceptionGroup, Exception)
Exception
ArithmeticError
FloatingPointError
OverflowError
ZeroDivisionError
AssertionError
AttributeError
BufferError
EOFError
ImportError
ModuleNotFoundError
LookupError
IndexError
KeyError
MemoryError
NameError
UnboundLocalError
OSError
*snip* (there was too many to fit in one message)
ReferenceError
RuntimeError
NotImplementedError
RecursionError
StopAsyncIteration
StopIteration
SyntaxError
IndentationError
TabError
SystemError
TypeError
ValueError
UnicodeError
UnicodeDecodeError
UnicodeEncodeError
UnicodeTranslateError
Warning
BytesWarning
DeprecationWarning
EncodingWarning
FutureWarning
ImportWarning
PendingDeprecationWarning
ResourceWarning
RuntimeWarning
SyntaxWarning
UnicodeWarning
UserWarning
GeneratorExit
KeyboardInterrupt
SystemExit
lmao lol
this is the output from help(__builtins__)
it places base classes near the root, and subclasses are leafs
ok lol
Can you spoiler itπ
It is like literally telling the answer if you spend 3 more second reading the code
π
Also you are kindof cheating either
It suppose to test you, not the machine
Ok nvm me on this
I just realize probably my phone being weird on not spoiler it
Yeh. I mean I made it manually, so I don't understand "test you, not the machine"
Nope, I used app.diagrams.net
MRO level 2
:incoming_envelope: :ok_hand: applied timeout to @grave grail until <t:1708552339:f> (10 minutes) (reason: newlines spam - sent 104 newlines).
The <@&831776746206265384> have been alerted for review.
!untimeout 692957118592057386
:incoming_envelope: :ok_hand: pardoned infraction timeout for @grave grail.
I should have make a paste
thx π
Also remember to add spoiler to any form of answer
lol
or the permanent link of this challenge:
https://r.relay7f98.uk.to/pymro_ch2
you can also validate your answer by adding /answer/ then the answer to the url even tho you can just run it anyway
like this
||The graph was a bit bigger, so I used mermaid.live to partially autogenerate it after I formatted it into the correct syntax with PyCharm find+replace, then firealpaca for the actual mro lines.||
It wasn't took bad, there is almost a 1-1 mapping between the mermaid syntax and a python class statement, so it was just find and replace.
It makes the MRO rules really clear, at least to me
Yeah
||It might be better if I have more stuff point to n, Base instead of just Base||
My lord
Guys is there a way to make entire classes within one line?
yes
!d type
class type(object)``````py
class type(name, bases, dict, **kwds)```
With one argument, return the type of an *object*. The return value is a type object and generally the same object as returned by [`object.__class__`](https://docs.python.org/3/library/stdtypes.html#instance.__class__).
The [`isinstance()`](https://docs.python.org/3/library/functions.html#isinstance) built-in function is recommended for testing the type of an object, because it takes subclasses into account.
I missed some whitespaces in this
!d types.make_class
No documentation found for the requested symbol.
types.new_class(name, bases=(), kwds=None, exec_body=None)```
Creates a class object dynamically using the appropriate metaclass.
The first three arguments are the components that make up a class definition header: the class name, the base classes (in order), the keyword arguments (such as `metaclass`).
The *exec\_body* argument is a callback that is used to populate the freshly created class namespace. It should accept the class namespace as its sole argument and update the namespace directly with the class contents. If no callback is provided, it has the same effect as passing in `lambda ns: None`.
New in version 3.3.
Would you guys like to see me make a procedural terrain generator in one line?
Sound fun lol
https://redirect.relay7f98.uk.to/pymro_ch3
Try this @fleet lintel
Done, this time I manually applied the mro instead of using a graph || https://paste.pythondiscord.com/UAEA ||
lmao lol
How long does it took you
This took me 16mins to make it but I don't know the answer without running it + some trial and error to make it work
lol
Only like 10 mins. Here's it formatted better for maximum satisfction || https://paste.pythondiscord.com/2ENQ ||
VSCode highlighting all of the same letter when my cursor was on it made sure I didn't make any mistakes.
nice lol
What's the shortest expression you can come up with that evaluate to a recursive object? (of any type)
Best I have so far is (n:=[],n.append(n))
(n:=[]).append(n)
that evaluates to None
well, this technically evaluates to a non-recursive tuple that contains a recursive list
mmm, I disagree, if you did sth like (n:=[],n.append(n))[0], then that'd be a recursive object
well, my definition of the problem statement doesn't require the outer layer(s) to be part of the recursion
alright
can i use statements?
!e this is classic ```py
a=a[0]=[0]
print(a)
@fleet bridge :white_check_mark: Your 3.12 eval job has completed with return code 0.
[[...]]
technically 0 is a recursive object
i dont think you can make it any shorter
0 is recursive, because it contains reference to int, which contains reference to type, which contains reference to itself
lmao
HMMMMM I guess lol
fits the definition
nope, statements are cheating :P
and it also requires a "..." in the repr (and no cheating with that, either...)
if we dont allow objects that are not a part of reference cycle, then i guess the shortest one is type
x:=globals() fits all requirements
- it has
...in the repr - it references itself directly
>>> (x:=globals())
{ '__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': _frozen_importlib.BuiltinImporter,
'__spec__': None,
'__annotations__': {},
'__builtins__': builtins,
'x': {...}}
it is 12 or 14 chars (depending on if you count parens)
x:=locals() also fits and is shorter
i am a locals() hater
lol
what is the shortest code that makes an object that is an instance of itself?
statements are allowed
||type||
that looks like pure Python to me
||object|| technically also is an instance of itself
nah, it is implemented in C
||py class X(type):__instancecheck__=lambda s,o:1 class x(metaclass=X):1
Is it cheating? isinstance(x, x) is true, so at least by that metric it's the same as isinstance(type, type), and anything is an instance of x.||
how do we determine what's an instance of itself?
just
assert isinstance(obj, obj)
assert isinstance(obj(), obj)
?
do we also check this
assert obj() is not obj()
So far, my "solution" still checks all of these boxes.
Slight optimization ||py class X(type):__instancecheck__=slice class x(metaclass=X):1||
alr, here's mine
||
class M(type):
__instancecheck__=lambda*a:1
class T(metaclass=M):0
||
obj = T
assert isinstance(obj, obj)
assert isinstance(obj(), obj)
assert obj() is not obj()
||can use id instead of slice ||
I see, but I don't understand why.
me neither
I think this might be CPython specific. If it was implemented in just python, I don't think it would work. I also dont understand why cpython does it how it does, but it do. ||c PyObject *checker = _PyObject_LookupSpecial(cls, &_Py_ID(__instancecheck__)); ... PyObject *res = PyObject_CallOneArg(checker, inst);
It does a 1 arg call, so a 1 arg function works π€·. I guess it's whatever is magic about _PyObject_LookupSpecial.||
builtin functions aren't descriptors, so they don't bind self, if that's the point of confusion
Bruh, why are we going through C now lol
is every other function a descriptor then?
oh
!e
def foo(one): print(one)
foo.__get__(1)()
@proper vault :white_check_mark: Your 3.12 eval job has completed with return code 0.
1
i would prefer type(x) is x to be true
but good attempt anyway
!e
print(type(object) is object)
@torn cypress :white_check_mark: Your 3.12 eval job has completed with return code 0.
False
!e my way of doing it```py
class M(type):0
class X(M,metaclass=M):0
X.class=X
assert isinstance(X, X)
assert type(X) is X
@fleet bridge :warning: Your 3.12 eval job has completed with return code 0.
[No output]
for style points, you can also make X.__new__ return X, so X() is X is type(X) will be true
cursed
I suppose that means that you don't need functools.partial to partial almost any function, as long as it isn't builtin/constructed weirdly.
we can use it instead of functools.partial for binding only one positional argument
>>> from functools import partial
>>> def f(x, y): return x+y
...
>>> partial(f,1)(2)
3
>>> f.__get__(1)(2)
3
you are faster than me π
:). Sadly only for one though, since after one __get__ it becomes a method, not a function.
>>> m = f.__get__(1)
>>> m.__get__ # attribute access is forwarded to underlying function
f.__get__
>>> f.__get__?
Help on method-wrapper:
__get__(instance, owner=None, /)
Return an attribute of instance, which is of type owner.
>>> f.__get__(1,int)
<bound method f of 1>
>>> f.__get__(1,str) # no checks
<bound method f of 1>
>>> f.__get__(None,...) # literally no checks
f
>>> f.__get__(1,2) # second arg is discarded completely
<bound method f of 1>
>>> f.__get__(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected at most 2 arguments, got 3
>>> f.__get__(None,...)
f
>>> f.__get__(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __get__(None, None) is invalid
``` i just noticed that you cant bind `None` using that approach
does it mean that NoneType cant have working pure-python methods? π€
import fishhook
@fishhook.hook(str)
@fishhook.hook(type(None))
def foo(self, *a):
print(f'{self!r}.foo(*{a}) was called')
``` ```py
# works fine for strings:
>>> ''.foo
<bound method foo of ''>
>>> ''.foo()
''.foo(*()) was called
# this is weird:
>>> None.foo
foo
# this is ok:
>>> None.foo()
None.foo(*()) was called
# but if we call it in other way, then it breaks:
>>> x = None.foo; x()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() missing 1 required positional argument: 'self'
>>> dis('None.foo()')
0 0 RESUME 0
1 2 LOAD_CONST 0 (None)
4 LOAD_ATTR 1 (NULL|self + foo)
24 CALL 0
32 RETURN_VALUE
``` this must be happening because of optimizations on bytecode level
whats up
LOAD_ATTR(namei)
If the low bit of namei is not set, this replaces STACK[-1] with getattr(STACK[-1], co_names[namei>>1]).If the low bit of namei is set, this will attempt to load a method named co_names[namei>>1] from the STACK[-1] object. STACK[-1] is popped. This bytecode distinguishes two cases: if STACK[-1] has a method with the correct name, the bytecode pushes the unbound method and STACK[-1]. STACK[-1] will be used as the first argument (self) by CALL when calling the unbound method. Otherwise, NULL and the object returned by the attribute lookup are pushed.
Changed in version 3.12: If the low bit of namei is set, then a NULL or self is pushed to the stack before the attribute or unbound method respectively.
??????
i believe in None.foo case descriptor protocol failed to execute, so normal lookup was peroformed, so foo was returned
!e
print(dis.dis("x = None.foo; x()"))```
!e
print(dis.dis("x = None.foo; x()"))```
@unique heath :x: Your 3.12 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 1, in <module>
003 | print(dis.dis("x = None.foo; x()"))
004 | ^^^
005 | NameError: name 'dis' is not defined. Did you mean: 'dir'? Or did you forget to import 'dis'?
!e
import dis
print(dis.dis("x = None.foo; x()"))```
@unique heath :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | 0 0 RESUME 0
002 |
003 | 1 2 LOAD_CONST 0 (None)
004 | 4 LOAD_ATTR 0 (foo)
005 | 24 STORE_NAME 1 (x)
006 | 26 PUSH_NULL
007 | 28 LOAD_NAME 1 (x)
008 | 30 CALL 0
009 | 38 POP_TOP
010 | 40 RETURN_CONST 0 (None)
011 | None
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/5HNCCGESB3NEQJHAETNL6PY27Q
ah yeah probably
it works but you need to hook a data descriptor onto NoneType as well as a regular descriptor onto None
that's how my custom-literals library works
STACK[-1]has a method with the correct name...
if objectSTACK[-1]has an attribute with a name that matches that method, that is
>>> dis("a.foo()") # different LOAD_ATTR argument opcode because `a` and `foo` are both part of `.co_names`, but they're relatively the same
0 0 RESUME 0
1 2 LOAD_NAME 0 (a)
4 LOAD_ATTR 3 (NULL|self + foo)
24 CALL 0
32 RETURN_VALUE
>>> dis("None.foo()")
0 0 RESUME 0
1 2 LOAD_CONST 0 (None)
4 LOAD_ATTR 1 (NULL|self + foo)
24 CALL 0
32 RETURN_VALUE
.topic I wonder what topics it will have for here
Suggest more topics here!
this one is actually nice
understanding code
is_odd=lambda _:bool(_&1)
is_odd=1 .__and__
that will not return bool
is_odd=lambda _:_&1>0
``` hapy?
Suggest more topics here!
yes
i would like return to be usable in expressions
imagine @return decorator: ```py
def deco(f):
@return
def wrapper(*args, **kwargs):
...
res = f(*args, **kwargs)
...
return res
Ruby's unless
well, we could just raise a PEP and hope it gets accepted...
if not ...:?
no no
raise Exception
unless everything_is_fine:
or
print("hello world")
print("the quick brown fox jumps over the fence")
unless not True:
is that a reverse statement
maybe, idk, apparently Ruby has this
well, not exactly this syntax ig, but close enough
although i feel like the : placement is odd
yeah
Being able to treat strings as variables or executable code blocks without having to resort to eval or ast.literal. I find this really handy. But, I don't think there could be changes in Python to do that.
eval() is already the most compact way to do that
Yeah, but I mean it in built-in matter. No eval needed. I'll show example in a few.
i'll just not have it
what could be the worst thing that could happen
JSFuck, not sort of a feature but can be considered
Here, this is what I mean: ``` # G'MIC example
list_of_strings=a,b,c,d,e
$list_of_strings={expr('x',narg($list_of_strings))}
a,b,c,d,e becomes 0,1,2,3,4 and their value can be retrieved by typing in $a or $b and so forth
In Python, you have to use eval or ast.literal to do that. There's also being able to execute a command there and the string is treated as a call to a command.
just placed it at the top ```pycon
:
... b = 2
... c = 4
... unless False
b
2
c
4
The example is to demonstrates treating strings as variables. of course, it can be simplified to that in this case.
objects dont have any idea about variables they are stored in
hehe it works!!!!!! ```py
: b = 2 unless False
b
2
nvm :( ```pycon
while True:
... :break unless True
File "<stdin>", line 2
:break unless True
^
SyntaxError: invalid syntax
yeah i know. I use it to be able to retrieve the value of string without having to know the number of arguments they have, and I can also retrieve them from using $$string. If string is c, then this becomes $c, then I get 2. This is weird, yes, but I find it powerful.
but back to Python anyway
czy ktos z tad jest w stanie wyslac kod do jakiejs gry w pythonie? mega potrzebuje z gory dzieki
i don't know what language is this
polish
Can anyone send me the code for a python game? I really need it, thanks in advance
this is wrong channel for that, unless you want a very obscure code
whats the channel i can ask for it?
you can search for github to find existing Python game code
thanks
@open pulsar ```py
from pygame import*
init()
d=display
c=draw.rect
x=t=l=j=0
while not event.get(256):
s=d.set_mode((500,300));k=key.get_pressed()
if l:
if t%66<1:o+=[m:=Rect(550,p.y%9*-25,50,200),m.move(0,300)]
j=[j+1,-8][k[32]];p.y+=min(j,9);c(s,-1,p);t+=1;l=p.collidelist(o+[(0,0,70,300)])==len(o);x=t
for a in o:a.x-=3;c(s,-1,a)
else:s.blit(Font().render(str(x),0,"red"),p:=Rect(40,90,10,10));o=[];t=l=k[13]
d.flip();time.wait(33)
(not my code)
I have seen this somehwere
it is on gh btw https://github.com/Matiiss/FlpyBrd
(speaking of recent events on reddit, there's an exe file
)
similarly, i would like break, continue, yield, and raise to be useable in expressions
how would you use break and continue as expressions? like in list comps or sth?
speaking of break, if we could have named loops and break out of one by that assigned name (I think Rust has sth like this), that'd be great as well
it would be useful for comprehensions and generators, but i just meant in general
e.g.,
for i in something:
x = a if something() else break
interesting idea
i specifically want raise to be useable in return statements (or return expressions, hypothetically):
e.g.,
def check_validity (something):
# ...
if some_condition:
return raise TypeError("foobar is unable to be frobnicated")
and then this would forward the error to the callsite of the function, so that the traceback shows that instead of showing whatever validity checks you have
funny thing, this is how you could do it using the C API return RAISE(PyExc_TypeError, "foobar is unable to be frobnicated");
Hello
Idont have the mic permissions
!voice
Canβt talk in voice chat? Check out #voice-verification to get access. The criteria for verifying are specified there.
class a:
def __add__ (self, other):
raise TypeError()
a() + a()
# Traceback (most recent call last):
# File "somefile", line lineno, in <somemodule>
# File "somefile", line lineno, in __add__
# TypeError
as opposed to
1 + ""
# Traceback (most recent call last):
# File "somefile", line lineno, in <somemodule>
# TypeError: unsupported operand type(s) for +: 'int' and 'str'
the error message for the first one includes the function in the traceback, and for complicated code it can be several layers deep before the error checking happens
it would be nice if the callsite could be the top of the traceback
you can do that now using other stuffs
mhm
sure, but it would be nice if it was return raise SomeError imo
perhaps perhaps
i think a python goto would be nice as well, although im sure many would disagree lol
that is if RAISE() is defined
PyErr_Format() returns NULL which means it can be used with return, but PyErr_SetString() (most likely to be used here) does not return anything
and i don't know how returning a void would make sense
oop, that's an internal pygame-ce macro 
I'm just so used to it, I thought it was part of the C API
right, makes sense, welp
or follows the general format of PySpecifier_SCREAMING_SNAKE_CASE_NAME
just use goto lol
in fairness, it will most certainly exit the loop
by means of a NameError, but if it works, it works π€·ββοΈ /s
imo, raise exc from -2 (where -2 is a number of frames to go back) would be nicer
that's... obscure
but actually, going back a frame would be pretty neat so that it doesn't show the raise line (is there like a super simple solution to that rn? ik you can do sth, sth around excepthooks and such, but like, I have to configure that and such)
you can manually construct the exception object with proper traceback and stuff, and then raise it
(and hope that its traceback remains untouched)
i believe it can be boiled down to raise f(MyException(blah, blah), 1)
f takes an exception you wanna raise, mutates its traceback removing specified amount of frames from it, and returns it
ooh, neat
oooh i like that
but it wouldnt mesh with the modern raise exc from otherexc thing (which imo really shouldnt have become a thing in the first place but whatever)
good idea, had it implemented in my local copy ```pycon
def a():
... raise ValueError
...
def b():
... raise ValueError from -1
...
a()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in a
ValueError
b()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError
time for a PEP π
<3
love that so much
minified python
ok wait...
Hi, I had a a esoteric number generator
(1).__lshift__(1).__lshift__(1).__add__(1).__pow__(((1).__lshift__(1).__mul__((1).__lshift__(1).__add__(1))).__mul__((1).__add__((1).__lshift__(1).__add__(1).__pow__((1).__lshift__(1))).__pow__((1).__lshift__(1))).__sub__((1).__lshift__(1).__lshift__(1).__add__(1).__pow__((1).__lshift__(1)).__add__((1).__lshift__(1).__lshift__(1).__lshift__(1).__sub__(1).__pow__((1).__lshift__(1).__add__(1))))
I think I was dumb-dumb-stupid-head when I made that comment in pydiscussion
you can only do what I said for literally the first (1)
oh wait π€
lol
I see now that you have some nesting
oh yeah
found it
on preset on number 6
I forgot to remove the bracket at the front when copying
please send updated expression
(1).__lshift__(1).__lshift__(1).__add__(1).__pow__((1).__lshift__(1).__mul__((1).__lshift__(1).__add__(1))).__mul__((1).__add__((1).__lshift__(1).__add__(1).__pow__((1).__lshift__(1))).__pow__((1).__lshift__(1))).__sub__((1).__lshift__(1).__lshift__(1).__add__(1).__pow__((1).__lshift__(1)).__add__((1).__lshift__(1).__lshift__(1).__lshift__(1).__sub__(1).__pow__((1).__lshift__(1).__add__(1))))
Was re-generating
lol
(1
.__lshift__(1)
.__lshift__(1)
.__add__(1)
.__pow__(1
.__lshift__(1)
.__mul__(1
.__lshift__(1)
.__add__(1)))
.__mul__(1
.__add__(1
.__lshift__(1)
.__add__(1)
.__pow__(1
.__lshift__(1)))
.__pow__(1
.__lshift__(1)))
.__sub__(1
.__lshift__(1)
.__lshift__(1)
.__add__(1)
.__pow__(1
.__lshift__(1))
.__add__(1
.__lshift__(1)
.__lshift__(1)
.__lshift__(1)
.__sub__(1)
.__pow__(1
.__lshift__(1)
.__add__(1)))))
1.__add__(1)
Cell In[11], line 1
1.__add__(1)
^
SyntaxError: invalid decimal literal
umm, I doubt that would work
you need to put a space, as I said earlier in pydiscussion
well I didn't say it, but I wrote code like that ig
fairnuff
oh ok, it is simple then
now to make it more cursed
1 .__lshift__(1).__lshift__(1).__add__(1).__pow__(1 .__lshift__(1).__mul__(1 .__lshift__(1).__add__(1))).__mul__(1 .__add__((1).__lshift__(1).__add__(1).__pow__(1 .__lshift__(1))).__pow__(1 .__lshift__(1))).__sub__(1 .__lshift__(1).__lshift__(1).__add__(1).__pow__(1 .__lshift__(1)).__add__(1 .__lshift__(1).__lshift__(1).__lshift__(1).__sub__(1).__pow__(1 .__lshift__(1).__add__(1))))
!e
print( (1
.__lshift__ (1)
.__lshift__ (1)
.__add__ (1)
.__pow__ (1
.__lshift__ (1)
.__mul__ (1
.__lshift__ (1)
.__add__ (1)))
.__mul__ (1
.__add__ (1
.__lshift__ (1)
.__add__ (1)
.__pow__ (1
.__lshift__ (1)))
.__pow__ (1
.__lshift__ (1)))
.__sub__ (1
.__lshift__ (1)
.__lshift__ (1)
.__add__ (1)
.__pow__ (1
.__lshift__ (1))
.__add__ (1
.__lshift__ (1)
.__lshift__ (1)
.__lshift__ (1)
.__sub__ (1)
.__pow__ (1
.__lshift__ (1)
.__add__ (1))))))
@digital mesa :white_check_mark: Your 3.12 eval job has completed with return code 0.
1562132
lmao lol
time to make it even better
( print( (1
. __lshift__ (1)
. __lshift__ (1)
. __add__ (1)
. __pow__ (1
. __lshift__ (1)
. __mul__ (1
. __lshift__ (1)
. __add__ (1) ) )
. __mul__ (1
. __add__ (1
. __lshift__ (1)
. __add__ (1)
. __pow__ (1
. __lshift__ (1) ) )
. __pow__ (1
. __lshift__ (1) ) )
. __sub__ (1
. __lshift__ (1)
. __lshift__ (1)
. __add__ (1)
. __pow__ (1
. __lshift__ (1) )
. __add__ (1
. __lshift__ (1)
. __lshift__ (1)
. __lshift__ (1)
. __sub__ (1)
. __pow__ (1
. __lshift__ (1)
. __add__ (1) ) ) ) ) ) )
π€£
t a b u l a r
ok now I'm bored bye
Ok lol
def f(a,b):
# this code is executed when the function is running:
print(a, b, a + b)
return a + b
else:
# this code is executed when the function is not running:
print('f() is not running :-(')
print(f(1,2))
``` expected output: ```py
f() is not running :-(
f() is not running :-(
f() is not running :-(
f() is not running :-(
*snip*
f() is not running :-(
f() is not running :-(
f() is not running :-(
1 2 3
3
f() is not running :-(
f() is not running :-(
f() is not running :-(
...
lol
def f ():
...
else:
f()
while True: loop
:3
asynchronous while True loop!
def f():
print('foo')
else:
f()
def g():
print('bar')
else:
g()
``` this will print a lot of foos and bars
simultaneously
that would be an error of some sort
unless the functions are declared with async def
hm
what are the semantics of this?
def f ():
def g ():
...
else:
...
else:
...
f()
and what about this
def f ():
def g ():
...
else:
...
return g
else:
...
a = f()
do the else blocks live for the objects whole lifetime, or just until the definition goes out of scope?
&& is there a specified order for when else blocks execute (maybe from innermost scope outwards, in order or definition in case of a tie?)
Command "&" is not found
an interesting thing to do would be to have functions which dont execute a return just continue execution at the point after the definition, a la old C
e.g.,
_ = 0
def a ():
global _
_ = 1
print("a")
print("here")
if 1-_: # so it doesnt loop forever
a()
prints
here
a
here
I gone insane on my esoteric number generator and type a random large number
and then I got this
((((1<<1<<1<<1)-1)*((((1+(1+((1+(1<<1))**(1<<1))))*(((1<<1<<1)+1)+(1+((1+(1<<1))**(1<<1)))))<<1)+((((1+(1<<1))**(1<<1))+(1+((1+(1<<1))**(1<<1))))**(1<<1))))+(((((1<<1)*(((1+(1<<1))+(1+((1+(1<<1))**(1<<1))))**(1<<1)))+((((1+(1<<1))**(1<<1))+(1+((1+(1<<1))**(1<<1))))*((1+((1+(1<<1))**(1<<1)))+(1+((1+(1<<1))**(1<<1))))))**(1<<1))*((((1+(1<<1))+(1+((1+(1<<1))**(1<<1))))*((1<<1<<1<<1)+(1+((1+(1<<1))**(1<<1)))))+((1+(1+((1+(1<<1))**(1<<1))))*(((1<<1)*((1<<1)+1))**(1<<1))))))
using numbers to make numbers feels like cheating
consider replacing 1 with (()==())
what about using True
True is an integer
the reason I use 1 is you can use any number to represent 1
0==0 -> 1
1 -> 1
n//n -> 1
amd it is up to you on how you replacing it
lol
what about using (~~(([])>([]))^(()==()))
and, I make a way to make you customize how you represent 1
just, it have no validation
mhhh
give me a relatively large number
7865148676348646855753486648653636
too large π
you know it use bruteforce right lol
basically 5**5**5**5**5**5
my computer is having fun calculating that
basically 1.911012597945477520356404559704e+2184
ok how about 5**5**5
jk it won't be what you want to be
1
I only allow it do do to the power of 10
Nope, wayyyyyyyyyy bigger than that
5**(5**5) is already 5**3125
π€―
so (5**5)**5?
This one should be possible
By change some settings
Jk I just crashed PyCharm so relaunching
Even my system monitor with trustinstaller perm get terminated
anyway
(((~~(([])>([]))^(()==()))>>(~~(([])>([]))^(()==())))+(((((~~(([])>([]))^(()==()))<<(~~(([])>([]))^(()==()))<<(~~(([])>([]))^(()==())))+(~~(([])>([]))^(()==())))**(((~~(([])>([]))^(()==()))+(((~~(([])>([]))^(()==()))+((~~(([])>([]))^(()==()))<<(~~(([])>([]))^(()==()))))**((~~(([])>([]))^(()==()))<<(~~(([])>([]))^(()==())))))+((~~(([])>([]))^(()==()))+(((~~(([])>([]))^(()==()))+((~~(([])>([]))^(()==()))<<(~~(([])>([]))^(()==()))))**((~~(([])>([]))^(()==()))<<(~~(([])>([]))^(()==())))))))*((((~~(([])>([]))^(()==()))<<(~~(([])>([]))^(()==()))<<(~~(([])>([]))^(()==())))+(~~(([])>([]))^(()==())))**(((~~(([])>([]))^(()==()))<<(~~(([])>([]))^(()==()))<<(~~(([])>([]))^(()==())))+(~~(([])>([]))^(()==()))))))
for (5**5)**5
and you 2 disappear
lol
400=
((((~~(([])>([]))^(()>=()))+(((~~(([])>([]))^(()>=()))+((~~(([])>([]))^(()>=()))<<(~~(([])>([]))^(()>=()))))**((~~(([])>([]))^(()>=()))<<(~~(([])>([]))^(()>=())))))+((~~(([])>([]))^(()>=()))+(((~~(([])>([]))^(()>=()))+((~~(([])>([]))^(()>=()))<<(~~(([])>([]))^(()>=()))))**((~~(([])>([]))^(()>=()))<<(~~(([])>([]))^(()>=()))))))**((~~(([])>([]))^(()>=()))<<(~~(([])>([]))^(()>=()))))
it's as much an integer as ()==()
()is not an integer, it is a tuple==is not an integer, it is an operator()is a tuple too
you are mistaken
True is a boolean value
I said "as much an integer as" because in this context, evalutation both True and ()==() would yield an integer, well, ig, the latter is gonna yield a boolean first, but like... why does it have to be 2 layers of abstraction and why is 1 not enough 
why not (troll
also ability to represent an integer with only syntax is funny
-~(()<())
better
look at this amazing thing
lol
just don't work on chaining
How to get globals (globals dict) with just 0123456789!"#$%&\'()*+,-./:;<=>?@[\\]^_{|}~ `
can other non-letter characters be used?
yeah
although you did say syntax and numbers
I just pick printable and remove the \t, \r...
ok
let's discuss all the possible values you could get out of say two characters of that set (or more, if you can describe it well)
_0
of course you can have any integer or float
yes
also any string containing those characters
list, tuple, set, dict, containing any valid value
yes
I think that's gotta be all
yeah, and you cannot use dunder since it is character
I thought of that and realize it don't work
any operator used on numbers or string is gonna give you bool, number or string
I mean, we could also try to get exec or eval
but the diffculty is probably the same
but that can only execute code which we can write
we don't have a way to make arbitrary characters in a string, do we?
oh wait yeah, we would need chr
oops, I realize to do what I want, we also need chr
since to get anything from globals we need the name
constructing a string with number would require chr
I have an idea
what idea
!e
print([*globals()][0])
@digital mesa :white_check_mark: Your 3.12 eval job has completed with return code 0.
__name__
if you can get globals, then you can extract names positionally
because you can convert to list like that
oh ok, then we can extract chr from there
at that point you don't need to
because you can access everything by position
ye fair
Yeah, dunder won't work
?
operators call dunders
is what I mean
there is no operation on int that will help get globals directly
Wait what's that
I don't know you can call dunder with operator
that's the main use of them
Oh, you mean that lol
1 + 2 == (1).__add__(2)
Yeah, ik that
ok so what's the issue smh
OK
I had a really good idea
using % with strings
because that lets us use format codes
But that won't be executable tho
?
Like you cannot execute to get globals dict
the short-term idea here is to make an arbitrary string
because at least it's a fun mini-project
Ok
!e print("%c" % 68)
@digital mesa :white_check_mark: Your 3.12 eval job has completed with return code 0.
D
if we can get the letter c then we can get any letter
Mhh
ok I got bored
Ok
ez: just type ? and then _
proof:
???what python was that
since when is a question mark doing stuff in the repl?
Or he just trolling
no, I saw it used the other day
When did it even exist
Really?
you can read this message (and a little bit above about weird emojis)
scam
Scamming
I cannot write a letter so I cannot define a function until I have access to globals()
And I probably still couldn't after I have
Haven't investiate that part
i dont think this is possible
is there a way to get some alphabet characters as string values?
if so, and if only one exception to the rules is allowed: _=str.format, then i can perform attribute lookups and get results formatted to strings
>>> _=str.format
>>> _('{0.__class__.__base__}',())
'object'
>>> _('{0.__class__.__class__}',())
'type'
>>> _('{0.__class__.__dict__}',())
("{'__new__': tuple.__new__, '__repr__': tuple.__repr__, '__hash__': tuple.__hash__, '__getattribute__': "
"tuple.__getattribute__, '__lt__': tuple.__lt__, '__le__': tuple.__le__, '__eq__': tuple.__eq__, '__ne__': "
"tuple.__ne__, '__gt__': tuple.__gt__, '__ge__': tuple.__ge__, '__iter__': tuple.__iter__, '__len__': "
"tuple.__len__, '__getitem__': tuple.__getitem__, '__add__': tuple.__add__, '__mul__': tuple.__mul__, '__rmul__': "
"tuple.__rmul__, '__contains__': tuple.__contains__, '__getnewargs__': tuple.__getnewargs__, 'index': tuple.index, "
'\'count\': tuple.count, \'__class_getitem__\': tuple.__class_getitem__, \'__doc__\': "Built-in immutable '
'sequence.\\n\\nIf no argument is given, the constructor returns an empty tuple.\\nIf iterable is specified the '
"tuple is initialized from iterable's items.\\n\\nIf the argument is a tuple, the return value is the same "
'object.", \'__invert__\': <function sc._@__invert__ UnpackedArgs=<class \'sc._.<locals>.UnpackedArgs\'>>}')
https://paste.pythondiscord.com/5O53WU7RCOJ2ZF36JFCMPTGNAM
I wrote this with just 5 a-z character and a bunch of syntax which can basically run anything
And file that print Hello
https://paste.pythondiscord.com/IABE6VQOFCE7AMC5IUC6IB255I
you can get rid of c
just use ||oct escaped strings||
>>> code = 'print(123)'
>>> eval(eval('"'+''.join(f'\\{oct(ord(c))[2:]}' for c in code)+'"'))
123
>>> print('"'+''.join(f'\\{oct(ord(c))[2:]}' for c in code)+'"')
"\160\162\151\156\164\50\61\62\63\51"
# ^^^ this is code generation
# vvv this is what actually will be executed
>>> eval("\160\162\151\156\164\50\61\62\63\51")
123
Ok
(but issue is I have to use syntax to represent the number
which still either require f-string or modula format
!e
a = 1 == 1.0 == True == bool(...) == type("", (), {"__eq__": bool})() == (not None) == all([]) == (() == ())
print(a)
@torn cypress :white_check_mark: Your 3.12 eval job has completed with return code 0.
True
I mean pretty more all of them are having 0-9a-zA-Z character
except last one
I mean using this btw
!e
print(-~(()<()))
@grave grail :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | /home/main.py:1: DeprecationWarning: Bitwise inversion '~' on bool is deprecated. This returns the bitwise inversion of the underlying int object and is usually not what you expect from negating a bool. Use the 'not' operator for boolean negation or ~int(x) if you really want the bitwise inversion of the underlying int.
002 | print(-~(()<()))
003 | 1
what I sent is completely unrelated
oh lol
#esoteric-python messageI thought you are continuing from here but apparently you ain't and I misunderstood lol
Discord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.
sorry
-~+(()<())
wait til pithon comes out
(unlikely chance of removal)
lol
The fact that they just deprecated on 3.12, I would believe it would only be removed like 3.14+, and it is just a small fun project that probably only last a few day
Would be funny decades later someone complain it doesn't work lol
can someone make this shitcode even more shitcode
def floor(n: float) -> int:
return int(str(n).split(".")[0])
has to be in 1 line no ;
golf or gore?
gore
floor=lambda*_:eval(('%r'%(_,)).replace(*'.,'))[0]
*_ huh?
figure it out :3
!e
a=lambda*_:print(_)
a()```
@bright valve :white_check_mark: Your 3.12 eval job has completed with return code 0.
()
@bright valve :white_check_mark: Your 3.12 eval job has completed with return code 0.
()
floor=lambda*n:compile((_:=(_:='_=%r'%(n,)).translate(_.maketrans(*'.,',_.__class__((n*0))))+',')[:_.find(',')],_,'exec').co_consts[0]
fun fact: removing n*0 will do the same thing
gotta learn how to code those
it looks kind of dark magic to me
That doesnt work for negative numbers
Same way how converting (int)double just discards the decimal component
-5.5 gets int-ed into -5 rather than -6
lets add a little bit more fun
https://paste.pythondiscord.com/CCIGN6NHXKKQPNNFNDVUFVZ3B4
Yes
Using strange Python to remove the nth element of a list with the .remove function.
my_list = [1, 2]*10
class RemoveObj():
def __init__(self, x):
self.x = x
def __eq__(self, x):
self.x -= 1
return self.x < 0
my_list.remove(RemoveObj(15))
kinda cursed if you ask me
no need to ask you, it is
eval('exec')("floor=lambda*n:compile((_:=(_:='_=%r'%(n,)).translate(_.maketran" + "s(*'.,',_.__class__((n*0))))+',')[:_.find(',')],_,'exec').co_con" + 'sts[0]')
why's the string split up
eval("exev")(...) bruh
into 64-character chunks
They are also split in 32,16,8,4,2...
It was used to prevent recurrsion error
When I throw a 7kb file to obfuscate
And when it run, it say recursion error on compilation
Which was fixed by bracket them reasonably so they ain't doing a single chain of process
In this size, it is not necessary but way too lazy to code it to handle differently
Because I have to also evaluate chr
So it make more sense to use eval instead of exec
eval('exec') is evil
Nah
upcoming french python```
dΓ©f fizzbuzz(n):
pour i en sΓ©rie(1, n+1):
si i % 15 == 0:
imprimer(Β«fizzbuzzΒ»)
sinonsi i % 5 == 0:
imprimer(Β«buzzΒ»)
sinonsi i % 3 == 0:
imprimer(Β«fizzΒ»)
sinon:
imprimer(i)
fizzbuzz(100)
what tool is this generated with?
looks hilarious
:incoming_envelope: :ok_hand: applied timeout to @azure trellis until <t:1709354394:f> (10 minutes) (reason: duplicates spam - sent 4 duplicate messages).
The <@&831776746206265384> have been alerted for review.
My obfuscate tool
An incomplete version of the same tool is on my GitHub gist
Gl finding it
lol
i can see that
these parentheses are grouped in a particular order
Because it's continuously group by 2
okay i'm gonna try completing it then
Well, do anything without uploading it on my gist lol
does it expand into higher powers than 64?
Yes
It should have been 128 from the code, but guess you accidentally ignored it
1: 1
2: 1+1
3: (1+1)+1
4: (1+1)+(1+1)
5: ((1+1)+(1+1))+1
6: ((1+1)+(1+1))+(1+1)
...
it looks more like
1: 1
2: 1+1
3: 1+1+1
4: 1+1+(1+1)
8: 1+1+(1+1)+(1+1+(1+1))
is it?
yeah
it shouldn't be checking from my code
FSP? so like the opposite of PSF
holy shit i didnt think of that
FSP FTW
well maybe not i wouldnt want to subject anyone except my worst enemy to that
i managed to remake the logic but in a sloppy way that only equals when totally evaluated
do you have test inputs anywhere
!e who still covers their numbers in brackets?
print(0 .__class__ is int)
print(0..__class__ is float)
@floral meteor :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | True
002 | True
!e or even worse, a dot with no purpose
print(
69..__int__() is 69 .__int__()
)
@floral meteor :white_check_mark: Your 3.12 eval job has completed with return code 0.
True
!e is this... getting the right answer by threatening a list comprehension into submission?
fifteen ,= [0x00for hello in world]
print(fifteen)
@floral meteor :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | /home/main.py:1: SyntaxWarning: invalid hexadecimal literal
002 | fifteen ,= [0x00for hello in world]
003 | 15
oh come on is this warning a new thing?
3.10 onwards is starting to look like a killjoy
C:\Users\denba>py -3.10 -c "fifteen ,= [0x00for hello in world]"
C:\Users\denba>py -3.11 -c "fifteen ,= [0x00for hello in world]"
<string>:1: SyntaxWarning: invalid hexadecimal literal
C:\Users\denba>py -3.12 -c "fifteen ,= [0x00for hello in world]"
<string>:1: SyntaxWarning: invalid hexadecimal literal
@unique heath :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | /home/main.py:1: SyntaxWarning: invalid hexadecimal literal
002 | fifteen ,= [0x00for hello in world]
003 | 15
@unique heath :white_check_mark: Your 3.12 eval job has completed with return code 0.
bananas
oh
starting to look like a killjoy
its done more than start to look like a killjoy
!e ```py
fifteen ,= [0x00for hello in world]
print(hello world!)```
@thorny falcon :x: Your 3.12 eval job has completed with return code 1.
001 | /home/main.py:1: SyntaxWarning: invalid hexadecimal literal
002 | fifteen ,= [0x00for hello in world]
003 | File "/home/main.py", line 2
004 | print(hello world!)
005 | ^^^^^^^^^^^
006 | SyntaxError: invalid syntax. Perhaps you forgot a comma?
!e ```py
fifteen = [0x00for hello in world]
print(hello_world!)```
@thorny falcon :x: Your 3.12 eval job has completed with return code 1.
001 | /home/main.py:1: SyntaxWarning: invalid hexadecimal literal
002 | fifteen = [0x00for hello in world]
003 | File "/home/main.py", line 2
004 | print(hello_world!)
005 | ^
006 | SyntaxError: invalid syntax
!e ```py
fifteen = [0x00for hello in world]
print(hello_python)```
!e ```py
fifteen = [0x00for hello in world]
print(hellopython)```
@thorny falcon :x: Your 3.12 eval job has completed with return code 1.
001 | /home/main.py:1: SyntaxWarning: invalid hexadecimal literal
002 | fifteen = [0x00for hello in world]
003 | Traceback (most recent call last):
004 | File "/home/main.py", line 2, in <module>
005 | print(hellopython)
006 | ^^^^^^^^^^^
007 | NameError: name 'hellopython' is not defined
!e ```py
fifteen = [0x00for hello in world]
print(helloworld)```
@thorny falcon :x: Your 3.12 eval job has completed with return code 1.
001 | /home/main.py:1: SyntaxWarning: invalid hexadecimal literal
002 | fifteen = [0x00for hello in world]
003 | Traceback (most recent call last):
004 | File "/home/main.py", line 2, in <module>
005 | print(helloworld)
006 | ^^^^^^^^^^
007 | NameError: name 'helloworld' is not defined
!e ```py
fifteen = [0x00for hello in world]
print(hello_world)```
!e ```py
print("X.Y")(z. B. 3.8, 3.9)
@thorny falcon :x: Your 3.12 eval job has completed with return code 1.
001 | File "/home/main.py", line 1
002 | print("X.Y")(z. B. 3.8, 3.9)
003 | ^^^
004 | SyntaxError: invalid syntax
Please use #bot-commands for trying things out
guys can someone hop on a call w/ me so they can help me with why my pygame images are not blitting to the screen
just dm me so we can call, would really appreciate it.
this channel is not for game dev, you should probably ask in #game-development
ok
@sick hound :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | /home/main.py:1: SyntaxWarning: invalid hexadecimal literal
002 | print(0x0for truly_cursed)
003 | 15
!e
__0xff__=lambda:__builtins__.__import__("sys").stdout.write(__builtins__.__dir__()[0x01c-(1-~~-1)][1>>1]+__builtins__.__dir__()[--1^++1**1][0x08-0x03]+__build_class__.__dir__()[(0x0f-0x08>>++1*1)-1][(0x0a>>1)-1]*(0x0ff-0x0fd)+chr(int("++-++++".replace(*"-0").replace(*"+1"),2))+chr(int("{}".format(int("08",16)-0x02*0x02<<0x06-0x03)))+__annotations__.__dir__()[0x02*0x04-0x06>>2][(0x0b>>2)*2]+str(dir().__dir__()[(0x3d>>1)-1][0x03-0x02]+dir().__dir__().__dir__()[(0x62>>0x02)+0x0a][0x06//0x03])+__build_class__.__dir__()[(0x0f-0x08>>++1*1)-1][(0x0a>>1)-1]+dir().__dir__().__dir__()[0x0b6-0x088][0x0a>>2])
if ((__name__:=__name__) == '__main__'):__0xff__()```
@fluid pumice :white_check_mark: Your 3.12 eval job has completed with return code 0.
hello world
!e ```python
(lambda _, , , ____, , , ______, ________:
getattr(
import(True.class.name[] + [].class.name[]),
().class.eq.class.name[:] +
().iter().class.name[:][:__]
)(
_, (lambda _, __, ___: (, __, ___))(
lambda _, __, :
bytes([ % __]) + (, __, ___ // __) if ___ else
(lambda: _).code.co_lnotab,
_ << ___,
((( << __) + ) << (( << ____) - )) + ((((( << )
- ) << ) + ) << (( << ) + ( << ))) + ((( <<
_) - ) << ((((( << ) + )) << ) + ( << ))) + (((
<< ) + ) << (( << ) + )) + ((( << ) - ) <<
(( << ))) + ((( << ) - ) << (((( << ) + ) <<
) - )) - ( << (((( << ) - ) << ) + )) + (
<< ((((( << ___) + _)) << _))) - (((((( << ) + )) << ) +
) << (((( << ) + ) << ))) + ((( << ) - ) <<
((((( << ) + )) << ))) + ((( << ) + ) << (( <<
))) + ( << _____) + ( << ___)
)
)
)(
*(lambda _, __, ___: (, __, ___))(
(lambda _, , :
[([(lambda: _).code.co_nlocals])] +
(, __, ___[(lambda _: _).code.co_nlocals:]) if ___ else []
),
lambda _: _.code.co_argcount,
(
lambda _: _,
lambda _, __: _,
lambda _, __, ___: _,
lambda _, __, ___, ____: _,
lambda _, __, ___, ____, _____: _,
lambda _, __, ___, ____, _____, ______: _,
lambda _, __, ___, ____, _____, ______, _______: _,
lambda _, __, ___, ____, _____, ______, _______, ________: _
)
)
)
@sick hound :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | /home/main.py:10: DeprecationWarning: co_lnotab is deprecated, use co_lines instead.
002 | (lambda: _).__code__.co_lnotab,
003 | Hello world!
!e
print(~0o0or truly @ cursed)
@sick hound :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | /home/main.py:1: SyntaxWarning: invalid octal literal
002 | print(~0o0or truly @ cursed)
003 | -1
cursed
cursed
truly
how is it cursed
its just <truthy expr> or <expr> returning <truthy expr>
is there a simple way to reassembly the parser/ast in runtime to do some preprocessing in tokens/ast?
custom encodings might be able to do something
or fork cpython, but that's not very simple
would a parsinghook do?
I haven't heard of that before, TIL
this better
cursed
#esoteric-python python users rewriting cpython from scratch & modifying cpu logic gates to print hello world
!e ```py
print(+())
@gleaming timber :x: Your 3.12 eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/home/main.py", line 1, in <module>
003 | print(+())
004 | ^^^
005 | TypeError: bad operand type for unary +: 'tuple'
>>> ''+()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "tuple") to str
>>> 1+[]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'list'
weird
error messages are different
does it mean that str.__add__ raises TypeError instead of returning NotImplemented?
>>> ''.__add__(())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "tuple") to str
>>> 1 .__add__([])
NotImplemented
``` yeah
i consider this a bug
thats weird, report it on github
Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 .__add__([])
NotImplemented
>>> 1+[]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'list'
>>>
```its been like that for long time
I don't have older versions to test on
this is not a bug, this is completely normal
and why?
why would it be a bug?
.__op__ should not raise an exception, they should return NotImplemented
this is a documented behaviour
then why ```py
''.add([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'list' object to str implicitly
[].add('')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
read this again
you just used dunder method on strings and lists in your example
what is __op__
any binary dunder method
a dunder method that implements some binary operator
>>> ''.__add__(b'')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "bytes") to str
>>> b'' + ''
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't concat str to bytes
``` this is also weird, i would expect these errors to be the same
i also have a suspicion that all these inconsistencies are caused by some common code that is shared across all sequence-like types (list/tuple/str/...)
it might be related to the fact that there are two slots that implement `+`, and the one that is related to sequences is not implemented properly
ok
what does a for look for to stop when a StopIteration is thrown, besides the exception? e.g. you can't simply do a raise StopIteration within the for's body itself or use .throw taken from a generator:
throw = (lambda: (yield))().throw
class Iterator:
def __init__(self):
self.i = 0
self.limit = 4
def __next__(self):
if self.i < self.limit:
self.i += 1
return self.i
# works with `raise`, not with `throw(...)`
raise StopIteration
# throw(StopIteration)
Iterable = type(
'',
(),
{
'__iter__': lambda self: Iterator()
})
for n in Iterable():
print(n)```I assume it has something to do with the way the tracing works
- it only looks for exceptions when calling
.__next__(). This is why exceptions in the loop body are not caught - not sure why
throw(...)is ignored
In [17]: throw = (lambda: (yield))().throw
In [18]: throw(StopIteration)
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
Cell In[17], line 1, in <lambda>()
----> 1 throw = (lambda: (yield))().throw
StopIteration:
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
Cell In[18], line 1
----> 1 throw(StopIteration)
RuntimeError: generator raised StopIteration
```generators aren't allowed to raise StopIteration other than by being exhausted - `next((lambda:1 or (yield))())` for example.
ah, that explains the message... explaining it
lololol
thanks, is there any other way to raise an exception with an expression? without using exec
maybe
(lambda threading=__import__('threading'):[setattr(threading, 'ValueError', YourError), threading.Semaphore(-1)])()
```or with any similar standard function that can be used like this.
cursed
that's what I'm here for
Hi
n2s=lambda n,b:[s:='',[(s:=s+'0123456789ABCDEF'[n%b],n:=n//b)for _ in iter(lambda:n>0,False)],s[::-1]][-1]
number n -> string in base b
assert b in range(1, 16+1)
assert b in range(2, 16+1)
doesn't work with b = 1
tbf neither does int
int converts from base to int not the other way around like n2s above and also denball specified that b in range(1, 16 + 1) which includes 1, so, uhhh
i always await seeing new wizard spells to gaze upon in esoteric python channel
same
im guessing it was a mistake
yeah, it was a typo
also this function produces empty string for 0, and will produce some nonsense for negative numbers
if you're golfing, you can replace False with 0
(I mean... kinda obvious that you are golfing)
Nvm
n2s=lambda n,b:[s:='',[(s:='0123456789ABCDEF'[n%b]+s,n:=n//b)for _ in iter(lambda:n>0,0)]]and s
there is an other way tp golf it further
i can swap the order in s:=... and get rid of [::-1] at the end
n2s=lambda n,b:"".join('0123456789ABCDEF'[n-(n:=n//b)*b]for _ in iter(lambda:n>0,0))[::-1]
much shorter when recursive but that doesn't work for lengths greater than 999
also shorter when using a normal function
i made wordle in 1 line but it can probably be shorter
idk
a:[((g:=(gf:=lambda:(((i,print(a[0]-c-1,a[4](i,a[1])))[0] if(i!=a[1])else(print(1),__import__('sys').exit()))if len((i:=input().strip().upper()))==5 and i not in a[3]and i in a[2]else gf()))()),a[3].append(g))for c in range(a[0])]+[print(0,a[1])]=[9-2*(df:=lambda:int(r)if(r:=input().strip()).isdigit()and 0<int(r)<=3 else df())(),__import__('random').choice(open('answers.txt','r').readlines()[0].strip().split()),open('valid_guesses.txt','r').readlines()[0].strip().split(),[],(lambda g,r:(c:=__import__('colorama'),u:=[],m:=[f"{c.Back.GREEN}{c.Fore.BLACK}",f"{c.Back.YELLOW}{c.Fore.BLACK}"],''.join((f"{m[0]}{l}{c.Style.RESET_ALL}"if l==r[i]else(f'{m[1]}{l}{c.Style.RESET_ALL}'if l in r and u.count(l)+1<=r.count(l)else l),u.append(l))[0]for i,l in enumerate(g)))[3])]
and what are answers.txt and valid_guess.txt?
also you don't need to pass 'r'
by default it opens in r mode
!d open
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)```
Open *file* and return a corresponding [file object](https://docs.python.org/3/glossary.html#term-file-object). If the file cannot be opened, an [`OSError`](https://docs.python.org/3/library/exceptions.html#OSError) is raised. See [Reading and Writing Files](https://docs.python.org/3/tutorial/inputoutput.html#tut-files) for more examples of how to use this function.
*file* is a [path-like object](https://docs.python.org/3/glossary.html#term-path-like-object) giving the pathname (absolute or relative to the current working directory) of the file to be opened or an integer file descriptor of the file to be wrapped. (If a file descriptor is given, it is closed when the returned I/O object is closed unless *closefd* is set to `False`.)
theyre files with the possible answers and acceptable guesses respectively
you were supposed to send format for them
r = lambda a,b: str(random.randint(a,b))
c = lambda s: random.choice(s)
comp = c([f"Lenovo ","Windows "])+r(10,50)+" "
calling upon the grand wizards
how do i make this more
to make this more?
You can import randint and choice (maybe with aliases) to remove random., you can make a an iterable argument so you dont need the brackets around Lenovo or Windows, remove the broken f
Could do maths on 10, 50 i guess
Hash lenovo and windows
Could not make a variable for comp and just concatenate where its used
This isnt really the right channel though
Not sure what you're after - shorter and messier are two completely separate things - It looks like you want messier code? Which can be done in a million ways with like str.__call__ or calling __add__ instead of +, using ridiculous ternaries, adding redundancy, to just name a few
import random
r = lambda a,b: str(random.randint(a,b))
c = lambda s: random.choice(s)
while True:
hubris = "Why yes, I quite enjoy playing DOOM on my "+c(["Lenovo ","Windows ","Atari ","Dell ","Raspberry Pi ","HP ","Alienware ","Acer ","Toshiba ","IBM ","Panasonic "])+r(10,9001)+c([" Deluxe "," Extreme ",("-"+r(1,99)+" "),"-X ","-I4 "," 99 "," "])+c(["AMD Ryzen ", "Intel ", "Cortex-A7 ","AMD Phenom ","AMD K6-III+ ","GTIA ","Motorola 68k ","Zilog Z80 ","MOS 6502 "])+r(3,124)+"ghz "+c(["DRAM ",("DDR"+r(2,19)+" "),"SRAM "])+r(1,140)+c(["GB ","MB ","KB "])
print(hubris)
this is what i ended up with
i play doom on my neighbours 12th microwave
adding microwave to the list
I play doom on my calculator
texas instruments calculator
when there are 0 ti calculators where i am π
you can also play doom on bacteria
you can also play doom on this guy
omg
i think my framerate would be higher than gut bacteria
i just need to bust out hella calculators
Potatoes().play_doom()
no thats the wrong way
imagine a competition where competitors need to play doom with a piece of paper and calculators
Potatoes(doom)
when we revert back to esotericism
you dopy @Potatoes().doom def play(): return self.status.playing play()
what is @
decorator
decorator
it decorates the function so you can invite your little pet ant to it
what
when you add a decorator to a function it sneakily adds a π to the byte code
i'm in the wrong channel to ask questions, i'm gonna get some enchantment table moon rune type stuff
I didn't expect this
nah cuz it cant be that hard to modify the c code for python to change the notation for decorators from @ to π right
"am i pregnant?"
"hold on let me finish this level"
babe look at the new gaming pregnancy tests π£οΈ
@quartz wave
he will do it in his python 4
mad
"Ok, you look very qualified for the job! Just one last thing, what version of python are you most comfortable with?"
"Oh, mostly Python 4"
"bro what"
4
I don't think interviewer would use the word "bro" unless its gen alpha or pure gen Z
no way
Suggest more topics here!
make a print function without using the print function
print=lambda*a,s=' ',e='\n',_=__import__('sys').stdout,f=0:(_.write(s.join([*map(str,[*a,e])])),_.flush()if f else...)[0]```
here you go
print function without using print
with all functionality
wh
????
how do you use it
print=lambda*a,sep=' ',end='\n',file=__import__('sys').stdout,flush=0:(file.write(sep.join([*map(str,[*a,end])])),file.flush()if flush else...)[0]```
forgot I can't just change name of kwargs
!e```py
print=lambda*a,sep=' ',end='\n',file=import('sys').stdout,flush=0:(file.write(sep.join([*map(str,[*a,end])])),file.flush()if flush else...)[0]
print('hello world')
print('1,2,', 1,4, sep=',', end='5')
print('f.f', file=open('file.txt','w'))
print('flush', flush=True)```
@arctic skiff :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | hello world
002 | 1,2,,1,4,5flush
file.txt
f.f
@left hinge
it's not supposed to spit out a 7
it is insane to me that you can just. redefine a built in function
print=lambda*a,sep=' ',end='\n',file=__import__('sys').stdout,flush=0:(file.write(sep.join([*map(str,a)])+end),file.flush()if flush else...,None)[2]```fixed
its also not supposed to put , at the end
!e
print=lambda*a,sep=' ',end='\n',file=__import__('sys').stdout,flush=0:(file.write(sep.join([*map(str,a)])+end),file.flush()if flush else...,None)[2]
print('hello')
@left hinge :white_check_mark: Your 3.12 eval job has completed with return code 0.
hello
does it just function the exact same as the built in one, or is it better
wait I can make it shorterpy print=lambda*a,sep=' ',end='\n',file=__import__('sys').stdout,flush=0:(file.write(sep.join(map(str,a))+end),file.flush()if flush else None)[1]I don't need to unpack map in a list
the latter one because it the previous one had bug
this is 141 bytes, let see if anyone can make it shorter
I don't see anyway to make it shorter
i dont think you got the sarcasm on that
you can be point-free and use c = random.choice
(or you could even use import aliases!)
dynamic namespaces are cool, yeah
def print(*a,sep=' ',end='\n',file=__import__('sys').stdout,flush=0):file.write(sep.join(map(str,a))+end);flush and file.flush()
from sys import*
def print(*a,sep=' ',end='\n',file=stdout,flush=0):file.write(sep.join(map(str,a))+end);flush and file.flush()
number of bytes?
!e```py
print(len("""
from sys import*
def print(*a,sep=' ',end='\n',file=stdout,flush=0):file.write(sep.join(map(str,a))+end);flush and file.flush()"""))
@arctic skiff :white_check_mark: Your 3.12 eval job has completed with return code 0.
127
this can be shorter
import sys
def print(*a,sep=' ',end='\n',file=sys.stdout,flush=0):file.write(sep.join(map(str,a))+end);flush and file.flush()
!e```py
print(len("""
import sys
def print(*a,sep=' ',end='\n',file=sys.stdout,flush=0):file.write(sep.join(map(str,a))+end);flush and file.flush()"""))
@arctic skiff :white_check_mark: Your 3.12 eval job has completed with return code 0.
125
noted!
that looks cursed lmao
idk why I felt it looked like gradle at first glance
UTF-8 in python's ascii source code handling?
i don't think so
I have a challenge for y'all. Given only control over the inputs to this function: ```py
def challenge(data, stacksize=0, variables=0):
func = lambda:None
func.code = func.code.replace(
co_stacksize=stacksize,
co_nlocals=variables,
co_varnames= ('',) * variables,
co_code=data
)
return func()
@quartz wave you might like this ^
Probably not that esoteric, but is there a way to programmatically update the locals of a function while within the function?
For context, I'm trying to iterate through the locals and update them based on some conditions.
def test(
a: int = 2,
b: float = 1.0,
/,
ex: str = "hello",
*,
c: list[object] = defer(lambda *_: ["Preceding args", *_]),
d: bool = False,
e: int = defer(lambda _, __, ___, c, ____: len(c))
) -> tuple[object, ...]:
for arg_name, arg_val in locals().copy().items():
if isinstance(arg_val, defer):
result = arg_val(*itertools.takewhile(lambda arg: not isinstance(arg, defer), locals().values()))
exec(f"{arg_name} = result") # Doesn't seem to work.
sys._getframe(0).f_locals.update({arg_name: result}) # Doesn't seem to work.
you will need use the pythonapi to tell python the locals are updated
specific python version?
Na whatever python version you want
this works on python 3.11.7 https://gist.github.com/TheBlupper/ff7f0faafc5e55be4c997d5bf78893f7
Very cool, nice trick with the exec offset
Oh, so either the C api or ctypes would be needed?
Yea barring some very odd technique's involving tracing
opinion from the wizards:
is it better to use lambdas or defs
defs are always going to be more readable and clear
so if thats your goal, go with that ig
leak_address = bytes([
*op('BUILD_LIST', 0),
*op('STORE_FAST', 0),
*op('STORE_DEREF', 0),
*op('LOAD_FAST', 0),
*op('GET_LEN'),
*op('DELETE_DEREF', 0)
])
``` I am working on my version, trying to avoid the need for a magic offset
^ this makes an empty list, then treats it as a cell and stores an object at its addr + (3 * 8), then uses GET_LEN to dump the address
the inverse to load an object from an address is trickier, requires floats
pfffffffffff. that's what a paragraph of comment is for
lambdas are the obvious choice, you can pretty much use them as defs anyway
in code thats actually meant to be used for anything ever:
for very (very!) trivial functions that are only used once, and are passed as arguments to other functions (e.g. map), lambdas are better because they're more concise, but for anything else, normal function definitions are more readable, maintainable, and a bunch of other positive adjectives that i cant be bothered to type out
for doing esoteric nonsense:
lambda is so silly, you should use it 100% of the time :3:3
lambdas for anything short, def for anything that can't be golfed enough
applies to both esoteric and readable purposes
oh wow, thatβs very interesting I havenβt seen that before. how are floats used to write?
Floats are structured with their 3rd element being a double, and CellTypes are structured with their 3rd element being a pointer. So you can take an address, convert it to its ieee float representation, then load that floats double as an address of a object
aah very neat
private variables using closures```py
class ObjWithPrivate:
def init(self):
int_only = 0
def get_int_only(self):
return int_only
def set_int_only(self, v):
if not isinstance(v, int):
raise ValueError
int_only = v
self.x = property(get_int_only, set_int_only)
o = ObjWithPrivate()
o.x = 42
print(o.x) # 42
o.x = 'hello' # error```
!e
class ObjWithPrivate:
def __init__(self):
int_only = 0
def get_int_only(self):
return int_only
def set_int_only(self, v):
if not isinstance(v, int):
raise ValueError
int_only = v
self.x = property(get_int_only, set_int_only)
o = ObjWithPrivate()
o.x = 42
print(o.x) # 42
o.x = 'hello' # error
print(o.x)
@restive void :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | 42
002 | hello
Nope, doesn't error.
Descriptors don't work on the instance.
class ObjWithPrivate:
def setup():
int_only = 0
def get_int_only(self):
return int_only
def set_int_only(self, v):
if not isinstance(v, int):
raise ValueError
nonlocal int_only
int_only = v
return get_int_only, set_int_only
x = property(*setup())
o = ObjWithPrivate()
o.x = 42
o.x = 'hi' # error
this works ^
(Although you can still do type(o).x.fset.__closure__[0].cell_contents = 'hi')
nothing can escape python's reflection 
@lunar marsh || this still uses a magic offset (id(0) - id(breakpoint)) but it demo's leaking and loading arbitrary addresses: https://paste.pythondiscord.com/W2SA ||
this has instances sharing the attribute right?
like all problems, this can be fixed by using more indirection
class with_int_only:
def _setup (self):
int_only = 0
def get ():
return int_only
def set (v):
if not isinstance(v, int):
raise ValueError
nonlocal int_only
int_only = v
self._get, self._set = get, set
def _get_wrapper (s):
return s._get()
def _set_wrapper (s, v):
return s._set(v)
x = property(_get_wrapper, _set_wrapper)
def __init__ (self):
self._setup()
o = with_int_only()
o.x = 43
O = with_int_only()
print(O.x == o.x) # False
O.x = "hello" # errors
(but now it's easier to change the value, o._get.__closure__[0].cell_contents = 'hi')
rewrite it as a C extension
very nice! would be interesting to try and find a more offset-agnostic payload
yea thats my goal now that I have the primitives laid out. It will still only work on 3.11 because of the opcodes used, but thats a bit harder to make agnostic
little bit, yeah
but if someone is going around modifying closure cells, a few extra attribute accesses probably wont stop them
import dis
import opcode
def generate_extended_args(argval):
if argval < 0:
argval += 0xffffffff + 1
args = []
while argval > 0:
args = [argval & 0xff] + args
argval >>= 8
return args
def op(opname, arg=0):
arg &= 0xffffffff
if (arg > 255) or (arg < 0):
args = generate_extended_args(arg)
else:
args = [arg]
for i, arg in enumerate(args):
if i == len(args) - 1:
yield (opn := dis.opmap[opname])
yield arg
yield from [0] * 2 * opcode._inline_cache_entries[opn]
return
yield dis.opmap['EXTENDED_ARG']
yield arg
def push_number(n):
return bytes([
*op('LOAD_CONST', 0), # None
*op('UNARY_NOT'), # True
*op('UNARY_POSITIVE'), # 1
*op('COPY', 1),
*op('COPY', 1),
*op('BINARY_OP', 10), # 1-1=0
]) + b''.join(
bytes([
*([
*op('COPY', 2),
*op('BINARY_OP', 0), # +
] if n & (1 << i) else []),
*op('SWAP', 2),
*op('COPY', 1),
*op('BINARY_OP', 0), # +
*op('SWAP', 2)
])
for i in range(n.bit_length())
) + bytes([
*op('SWAP', 2),
*op('POP_TOP'),
])
def position_independent_code(payload):
# Here, you can implement logic to generate position-independent code
# that adapts to different memory layouts and offsets
# For simplicity, let's assume the payload doesn't rely on fixed addresses
return payload
def generate_payload():
# Example payload generation
payload = b'' # Replace this with your actual payload bytecode
return position_independent_code(payload)
# Generate and print the payload
print(generate_payload())```
this is an example of a more offset-agnostic payload generator using Python bytecode manipulation. This payload dynamically calculates memory addresses and utilizes position-independent code to adapt to different memory layouts.
please don't test your chatGPT skills on code in this channel, I guarantee it will rarely understand it.
actually chatGPT 4
and they made some errors
in which I fixed so it isnt all chat gpt
the code you sent does not do anything
I guess this can be considered esoteric
maybe
korn shell wrapper that outputs python code: you write shell > out comes the snake
@lunar marsh https://paste.pythondiscord.com/URFA using EXTENDED_ARG you can overflow the offset used by LOAD_FAST to pull items out of the frame
so you can grab the __builtins__ dictionary
and you can grab the code object (and use the letter c from it for format spec to generate strings)
is that at a predictable offset from the frame?
dope
its -7 for __builtins__ and -5 for code
Why is it always at -7?
What's the idea behind storing builtins behind every frame
because reference to builtins can be different
its to do with _PyInterpreterFrame https://github.com/python/cpython/blob/3.11/Include/internal/pycore_frame.h
f_builtins is 8*7 bytes behind localsplus
so not really outside the frame, just another place inside it
Like I said itβs an example I donβt have the time to implement it into ur code
I was more trying to say that what you sent was just a regurgitation of what I wrote, and it didn't add anything to the conversation. In the future, please avoid putting my code into the plagiarism machine.
yo uhm guys I need help with a little script
is it possible to monkeypatch __getitem__ on the globals dict?
yea, there are a few ways to do that
you can change the globals instance for a frame, or you can swap out the base type using ctypes/memory corruption
!e ```py
def example():
print(non_existent)
class MyDict(dict):
def getitem(self, key):
print('Looking up:', key)
return super().getitem(key)
example = type(example)(example.code, MyDict())
example()```
@rugged sparrow :x: Your 3.12 eval job has completed with return code 1.
001 | Looking up: print
002 | Looking up: non_existent
003 | Traceback (most recent call last):
004 | File "/home/main.py", line 10, in <module>
005 | example()
006 | File "/home/main.py", line 2, in example
007 | print(non_existent)
008 | ^^^^^^^^^^^^
009 | NameError: name 'non_existent' is not defined
@elfin ether ^
this is much less stable however
Thanks, and lol that you have this bookmarked
I'm looking at this thread and wondering if there's a somewhat less brittle solution: https://discuss.python.org/t/when-might-f-globals-and-f-builtins-not-be-a-dict/22071
The CPython bytecode interpreter takes the trouble to check that f_globals and f_builtins are both dictionaries here: https://github.com/python/cpython/blob/ba8e30c56ba4833f572318e1cf4108d9f206d1a0/Python/ceval.c#L2996-L3004 It takes a slow path if they are not. In 3.11 these fields are behind the macros GLOBALS() and BUILTINS(). Under what ...
you could in theory replace the builtins module globally, but that is tricky, and it won't behave consistently
@elfin ether take a look at this https://chilaxan.github.io/python/2023/12/01/symbolic-numbers-in-python-part-1.html
A while ago I wanted to see if I could add symbolic numbers to Python. This would mean that something like one would equal 1 and two_hundred_and_five would equal 205.
i am still working on the second part (which will accomplish global name lookup hooks)
Will do, thanks.
I'm trying to modify the code you shared, adding __getitem__ to the missing_hook class, but everything i've tried results in endless recursion
I'm not actually trying to resolve names that don't exist in scope. I'm trying to "decorate" everything
ah that is much more fragile, and won't work for local name look ups
those use LOAD_FAST at the bytecode level, and just indexing a C level array of pointers
that's unfortunate
Weren't you saying there's a way to replace the globals dict in a frame; does the same approach not work for the locals dict?
In the future π I can do what I want dawg ur struggling to code in basic python for someoneβs homework ππ
I think u might need to do your homework first
π
@elfin ether you could use a tracing function that runs on every bytecode access, but that would likely be really slow
I'm trying to think of a way to modify the bytecode of a function so that it executes in the global frame, forcing resolution with the globals dict; obviously care would need to be taken to avoid collisions
the issue isn't where the bytecode runs, its the actual instructions used
!e py import dis x = lambda a:a dis.dis(x)
@rugged sparrow :white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | 2 0 RESUME 0
002 | 2 LOAD_FAST 0 (a)
003 | 4 RETURN_VALUE
^ inside the function, LOAD_FAST is used to load local variables
even if the bytecode is moved outside the frame, it will still be a load fast
you could in theory use a tracing function, watch for LOAD_FAST ops and replace them with LOAD_GLOBAL of some custom name that your global hook sees and uses to resolve the value
Understood, I guess what I meant was possibly creating new frame from the code of the function, except replacing the function declaration with a set of dummy initializations (or real initializations in the case of optional args), then compiling this to bytecode and executing it. Obviously there are tons of potential issues
ah yea patching bytecode and recompiling is going to be very tricky
I did that a while back when I implemented Tail Call Optimization into python
there are a lot of edge cases
Do you have a blog post on that? I've read a few blog posts on tail call optimization in python awhile back.
also with bytecode specialization, it may not be consistent
i never wrote a post on it (although I really should)
let me find the implementation
Is it possible to force the load_fast to look at a different memory location?
LOAD_FAST indexes just after the frame object
since there isnt any indirection, you would need to swap out the entire frame i think
https://paste.pythondiscord.com/LJBA @elfin ether
thats from 3.10, it does not optimize on 3.12
it looks for CALL_FUNCTION which was replaced with PRECALL and CALL in 3.11
been awhile since i looked into the details of python bytecode, so I can't really digest this quickly
all good, feel free to ping with any questions
!rule 10
Unrelated to everything we've been talking about, but may be of interest to some: here's a fragile way to create "custom operators" possibly with modifiers:
def reshape(mat, r, c, fill=np.nan):
newmat = np.empty((r, c))
newmat.fill(np.nan)
rr, cc = mat.shape
rr = min(r, rr)
cc = min(c, cc)
newmat[:rr, :cc] = mat[:rr, :cc]
return newmat
class Block:
def __init__(self, mat: np.array):
self.mat = mat
self.mod = None
def __invert__(self):
self.mod = 1
return self
def a(self, other):
r1, c1 = self.mat.shape
r2, c2 = other.mat.shape
if other.mod == 1:
mat = np.hstack([reshape(self.mat, r2, c1), other.mat])
else:
mat = np.hstack([self.mat, reshape(other.mat, r1, c2)])
return Block(mat)
class A:
def __init__(self):
self.args = []
def __gt__(self, other):
if not self.args:
self.args.append(other)
return True
else:
return self.args.pop().a(other)
a = A()
block1 = Block(np.arange(4).reshape((2,2)))
block2 = Block(5 + np.arange(9).reshape((3,3)))
(block1 <a> block2).mat, (block1 <a>~ block2).mat
oh thats sick
reminds of my weird typing code i wrote to emulate generics from java.
it would let this Type<int>(1) work
but it involved some weird bytecode reordering shenanigans
basically would rearrange the bytecode once the first < executed to be shaped like Type(int, (1))
interesting
class Tmeta(type):
def __lt__(cls, ocls):
frame = sys._getframe(1)
mem = getmem(id(frame.f_code.co_code) + bytes.__basicsize__ - 1, len(frame.f_code.co_code))
instructions = [*dis.get_instructions(frame.f_code)]
for idx, instruction in enumerate(instructions):
if idx * 2 < frame.f_lasti:
continue
if instruction.opname == 'COMPARE_OP' and instruction.argval == '>':
if instructions[idx+1].opname == 'JUMP_FORWARD':
if instructions[idx+2].opname == 'ROT_TWO':
if instructions[idx+3].opname == 'POP_TOP':
inj_code = bytes([
dis.opmap['ROT_TWO'], 0,
dis.opmap['ROT_THREE'], 0,
dis.opmap['CALL_FUNCTION'], 2,
dis.opmap['NOP'], 0,
])
mem[frame.f_lasti] = dis.opmap['POP_TOP']
mem[frame.f_lasti + 2] = dis.opmap['NOP']
mem[idx * 2:idx * 2 + len(inj_code)] = inj_code
return cls
class Array(metaclass=Tmeta):
def __init__(self, T, args):
self.T = T
self.args = args
def __repr__(self):
return f'{type(self).__name__}<{self.T.__name__}>{self.args}'
class HashMap(metaclass=Tmeta):
def __init__(self, T, args):
self.T = T
self.args = args
def __repr__(self):
return f'{type(self).__name__}<({", ".join(t.__name__ for t in self.T)})>{self.args}'
a = Array<int>(1,2,3)
b = HashMap<(str, int)>{
'a': 0,
'b': 1
}
def f():
v = Array<int>(1,2,3)
print(v)```
it def does not work on anything above 3.9
i would have treated it like a metaclass
stuff<thing>(123) -> stuff(thing)(123)
ah that would have been good too
and in hindsite, actually easier lol
by a decent amount
actually because of the shortcircuting it would still be difficult
just for different reasons
A<B>C turns into A<B and B>C, (and B is copied)
right
so in theory could replace B on the stack with the a wrapped return value that calls its input when > against another argument
tricky part is grabbing the address to the stack of a currently evaluating frame
i also would have done it with codecs instead of with a bytecode hook
because then you can do things like stuff<>(123) or stuff<thing<thing2>>(123)
very fair, I like to do things in bytecode specifically because I was once told "that would never work without a codec"
ah
(in refence to fishhook but i extended it to most of my weird hacks)
the second example (stuff<thing<thing2>>(123)) probably actually could be done with bytecode hacking
because it is valid syntax
and with barry as flufl the first one could also be done..
i was about to say that lol
in a perfect world tho, if its being treated as a meta class i would want X = thing<thing2> to work, but thats not valid
true
though, such things aren't allowed with Java generics afaik
since they're based on C++ templates
hmm fair
Would love to know how I can write x<>y in python without throwing a syntax error.
,
!e ```py
from future import barry_as_FLUFL
print(1 <> 2) # same as 1 != 2
@versed eagle :x: Your 3.12 eval job has completed with return code 1.
001 | File "/home/main.py", line 2
002 | print(1 <> 2) # same as 1 != 2
003 | ^^
004 | SyntaxError: invalid syntax
first i'm hearing of barry_as_FLUFL
!e py from __future__ import barry_as_FLUFL print(1 <> 2)
@rugged sparrow :x: Your 3.12 eval job has completed with return code 1.
001 | File "/home/main.py", line 2
002 | print(1 <> 2)
003 | ^^
004 | SyntaxError: invalid syntax
might not work with the bot