#esoteric-python
1 messages · Page 107 of 1
The underlying data itself is discontiguous, which is what distinguishes it from a numpy.ndarray
Or, rather a non-dtype=object numpy.ndarray (which, examples like indexing on pandas.Interval-aside) is the only thing we should ever do.
oh well yea thats just due to how python handles objects in general
I was trying to do a comprehensive write-up on the idea of “restricted computation domains” and how they fit into a very set design in Python, which, as you note, is a direct consequence of the underlying design of the language (no-unboxed or primitive types, forcing built-in containers other than str or int to be contiguous containers of discontiguous references.)
I talked a little bit about this here: https://www.youtube.com/watch?v=Ix04KpZiUA8
PyData is excited to announce PyData Global, November 11th - 15th! Tickets are now available: https://global.pydata.org/pages/tickets.html#pricing-and-ticket-purchases
Part of an underrepresented group in tech? PyData Global is offering Diversity Scholarships. Applications close September 30th: https://docs.google.com/forms/d/e/1FAIpQLSfcFaTqVFj...
By the way, here is generator peek using only numpy: https://twitter.com/dontusethiscode/status/1251339365504221184?s=21
Okay, so this is genuinely quite clever…
I don't think anyone has written this before—peek(…) on arbitrary (e.g., non-materialised) iterables. https://t.co/H1Kx4tgRkM
@grand urchin you can write stuff like that without any imports
if you abuse LOAD_CONST you can load arbitrary py_objects
Of course, Joe Jevnik, and I did similar about three years ago with poisoned bytecode on LOAD_ATTR out-of-bounds
LOAD_ATTR has an out of bounds too?
We never got around to direct generation of poisoned bytecode with extended operands, but I thought his “splayed coroutine” approach was quite clever.
i actually did use extended operands when i messed with LOAD_CONST
Actually, that above was LOAD_FAST not LOAD_ATTR
!e ```py
def sizeof(obj):
return type(obj).sizeof(obj)
TUPLE_HEADER = sizeof(())
BYTES_HEADER = sizeof(b'') - 1
PTR_SIZE = sizeof((0,)) - TUPLE_HEADER
MAX_INT = (1 << PTR_SIZE * 8 - 1) - 1
def load_addr(addr):
magic = lambda:None # this functions bytecode gets patched
b_addr = addr.to_bytes(PTR_SIZE, 'little') # convert int to bytes (bytes values are held raw in memory)
offset = id(b_addr) + BYTES_HEADER # start of raw addr in memory
offset -= id(magic.code.co_consts) + TUPLE_HEADER # get distance from start of co_consts tuple
offset //= PTR_SIZE # offset has to be evenly dividable by PTR_SIZE as PyTuple_GET_ITEM indexes by PTR_SIZE
if offset < 0: # if address is located before the tuple overflow offset to convert to unsigned
# this works because opcode arguments are held in a signed int (4 bytes)
# EXTENDED_ARG does not check against signed overflow
offset += 0xffffffff + 1
co_code = bytes((0x64, offset & 0xff, 0x53, 0)) # LOAD_CONST, last byte of offset, RETURN_VALUE, 0
offset >>= 8 # shift offset by 8 to drop last byte
while offset > 0: # loop until offset is 0
co_code = bytes((0x90, offset & 0xff)) + co_code # EXTENDED_ARG, last byte of shifted offset
offset >>= 8 # shift offset by 8 to drop last byte
magic.code = magic.code.replace(
co_code=co_code # inject generated bytecode
)
return magic() # trigger the bug
print(load_addr(id(1)))```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
1
Yes, I’ve that approach as well.
Unfortunately, the core devs have threatened me more than once with changing id to a monotonic counter like IronPython, so a lot of these techniques could easily prove too narrow in practice.
And I’m not totally sure why .__code__.replace has to exist.
i believe because they wanted to encourage modification of code objects without requiring a full manual reconstruction
It is not actually for encouraging but rather not breaking whenever they add an attribute.
For whose purpose? The core devs (and GvR especially) think of stuff like quasiquotes and codetransformer as amusing, if not annoying, gimmicks. For anything real-like (like, e.g., Pyjion,) there’s PEP-523.
They added it literally because some code was broken after co_posonlyargs
By the way, if you’re not familiar with Joe Jevnik’s other work:
https://github.com/llllllllll/codetransformer
https://github.com/llllllllll/quasiquotes
@bitter iris is there dynamic code construction in the standard library via types.CodeType or similar patching?
An assembler? No
There is like bytecode library from victor stinner
Then whose use-case did they care about for this? You don’t know how many rolled-eyes we’d get from folks like Brett or Raymond or Guido with this stuff.
“A lot of applications break”—I’ll have to ask Victor or Matthieu about this. I think this slipped past, because, like, when I was trying to explain PEP-551 to Guido to help convince him to accept it, it was the same story I’ve gotten from every code dev that they understand and tolerate this kind of stuff, but they don’t feel any obligation to ever support or enable it.
PEP-551 was superseded, but import-free code replacement creates enormous surface area to attack the PEP-578, as well as the closed-source code signing stuff. Just fiddle some bits and disable it.
I wish like PEP 511 would have accepted :/
at least it would bring a bit of consistency around all these stuff, and actually let them become normal use cases instead of weird, esoteric hacks
You can already do a lot with PEP-523, which is basically a safe way to do the PyEval_EvalFrameEx trampolining that I wrote this silly libhook library to do.
if you need ast transformers (or even bytecode transformers) it is already possible to use import hooks / encoding hacks / startup stuff or like your libhook library though what I actually liked it for was it proposed a proper solution for all these stuff combined
are there any other users of PEP 523 beside pyjion?
I think making this too easy encourages people to use this stuff for library functionality, which means that we create en even further divide between CPython and alternate implementations. I think you’d see pushback from he EPython supporters (https://www.youtube.com/watch?v=Z8vsTxzmorE)
Keynote by Travis Oliphant
PyData is an educational program of NumFOCUS, a 501(c)3 non-profit organization in the United States. PyData provides a forum for the international community of users and developers of data analysis tools to share ideas and learn from each other. The global PyData network promotes discussion of best pr...
There is already a big division between CPython and alternate implementations. The ones that can catch up with CPython (Like PyPy, RustPython) uses the same AST (and even same bytecode [only PyPy I assume, not sure about RustPython])
I don’t think so, and the PEP-523 authors (Brett & Dino) were solely focused on JIT at the time. Both of them are fairly against these techniques for feature-level stuff.
because if they don't, they won't be supporting other cool stuff. For example mypy doesn't work under pypy because of the ast differences (currently being fixed...). Same goes for black (even though it only uses ast in very few places)
I don’t get it, either. I personally think that PyPy’s trajectory has already been set, and that, while it’s not the case that easy C-interface is the same draw as it was in the early days of PyData, it’s here to stay.
In fact, if you think about it, the biggest drawback to easy C-interface was deployment, which created a lot of complexity in numpy and pandas. But, with conda and conda-forge, that complaint seems to have been blunted, and you see pandas happily adding dependencies like numba for their GroupBy optimizations (https://www.youtube.com/watch?v=AQz9GmZrvD8)
Pandas has accrued a sizable debt in flexibility and maintainability to deliver excellent performance. This talk will show how Pandas maintainers and Two Sigma are using Numba to pay off some of this debt in one of the gnarliest parts of the code: window operations. If merged to mainstream Pandas, this work will deduplicate code, make it easier ...
And, on top of all of that, Python language adoption has been driven so heavily and disproportionately by the PyData (and PyTorch, and Tensorflow, &c.) user-bases—to the point where I suspect Python would have basically died out in the last five years if not for that surge of new users, new interest, and general energy.
So, like, CPython and the C-API and bytecode and such are pretty much here to stay.
But Travis, in the talk I linked, disagrees, and he’s been at all of this stuff longer than I have, so I could be wrong.
I just wanna create a list where one is len({id(x) for x in xs}) == len(xs) and where we’ve maximized over the sum(abs(id(x) - id(y)) for x, y in zip(xs, xs[1:])) and another that’s sorted(xs, key=id) and see a meaningful performance difference on some iteration operation!
That’s all I want in life right now.
Or maybe to hire someone to work on that for me.
If the new dicts remember the insertion order of their keys, and sets are based on dicts, is it too much to ask to have a list/set object that is guaranteed order stable, only allows one copy of a thing inserted, and membership tests as fast as dict/set?
the cpython implementation of sets is not related to the implementation of dicts
Oh, alright, well they used to be.
really?
but maybe it was generations ago.
I mean I think originally it was something like add means dict[thing]=0 and some functions to implement set math.
There are even still parts of old libraries that treat sets and dicts together as a special case, differently than all other sequences, when iterating because if they recognize each other they can grab stuff out of each other in a way that keeps from needing to recalculate all the hashes or whatever.
I think most recently I saw it in chainmap in the collections module.
@rugged sparrow Is there some way to abuse bytecode to "imply a lambda:"
inside a call
example:
switch, case, otherwise = Switch()
i = 4
switch(i)
case[1] (print("this is bad")
case[2] (exit(1))
case[4] (print("all good!"))
otherwise (print("switch communication error occurred"))
or ```py
switch, i = Switch(), 4
switch(i). case[1] (print("bad1")). case[2] (exit(1)). case[4] (print("good")). otherwise (print("bad2")or exit(2))
even better is if both of those worked
you know what I mean by implied lambda?
in esoteric python, implicit...
Yea I understand what you mean
You could mutate the bytecode to add jumps to convert the switch bytecode to what a sequence of ifs would be
That would be easier than reparsing the bytecode into a new code object
jumps?
Yea in bytecode (and assembly) there's a concept where you can jump to a new location of code
so case would access the switch object, whose value has been set to i and if the getitem doesn't match, it skips to the next line?
!e py from dis import dis dis("if(a):print(1)")
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | 1 0 LOAD_NAME 0 (a)
002 | 2 POP_JUMP_IF_FALSE 12
003 | 4 LOAD_NAME 1 (print)
004 | 6 LOAD_CONST 0 (1)
005 | 8 CALL_FUNCTION 1
006 | 10 POP_TOP
007 | >> 12 LOAD_CONST 1 (None)
008 | 14 RETURN_VALUE
@floral meteor yea
But messing with bytecode at runtime like that really isn't stable
stability isn't esoteric :>
You could make one of those site packages that parses Python in advance.
starting to sound like i should just throw a lambda in there...
print and input are lame when you have this
I'd use a generator expression
Imagine using the class keyword, eww
A while ago on here I saw a module that gave us label.goto() and label.set() implemented with a decorator that opened up the bytecode after it was compiled, and searched for load_global pointing to 'label' and load_attr and the load_const or load_local that happened next, and used it to figure out where to jump to, then replaced each with the correct jumps and nops.
Would this be easier to implement stacked on top of that? Or using the same techniques?
!e ```from dis import dis
dis("case i: if i==switch: x=lambda: n")
!e ```from dis import dis
dis("case i: if i==switch: x=lambda: n")
I don't think it parses.
Yeah I should have played with what I was trying to do on my own machine before attempting to demonstrate.
!e ```from dis import dis
dis("x=lambda: n")
dis("x1=lambda y: n")
dis("x2=lambda y, z: n")
dis("w1=lambda y=0: n")
dis("w2=lambda y=1, z=2: n")
@vague cairn :white_check_mark: Your eval job has completed with return code 0.
001 | 1 0 LOAD_CONST 0 (<code object <lambda> at 0x7f91a2e689d0, file "<dis>", line 1>)
002 | 2 LOAD_CONST 1 ('<lambda>')
003 | 4 MAKE_FUNCTION 0
004 | 6 STORE_NAME 0 (x)
005 | 8 LOAD_CONST 2 (None)
006 | 10 RETURN_VALUE
007 |
008 | Disassembly of <code object <lambda> at 0x7f91a2e689d0, file "<dis>", line 1>:
009 | 1 0 LOAD_GLOBAL 0 (n)
010 | 2 RETURN_VALUE
011 | 1 0 LOAD_CONST 0 (<code object <lambda> at 0x7f91a2e68a80, file "<dis>", line 1>)
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/yanoguvowo.txt
They're all compile to the same bytecode, the compilation of them happens in parallel and they're already packaged into lambdas before we get a chance to decorator them.
The code objects will have different co_args etc.
And it's never too late to decorate.
Either you'd need to muck with the AST or give up on the implied lambda: in cells.
unless the itself : already implies cool things, I haven't looked at the ast
AST? I'm not sure I see a need for that.
There's probably a pretty yet strange syntax for cases that Python compiled to recognisable bytecode.
you mean elif ?
Not in particular.
I have no syntax in mind.
I'd love to spitball, but I've got to go. I just think it is possible.
I've implemented case with with switch(n) as case: with case(a) as [_]: pass with case(b) as [_]: pass but I find the as [_] so unappealing that I didn't consider it a success and never used it for anything...
good news, in just a bit, there will be a python release with pattern matchign
just a bit?
why not just with case(a)
its implemented
it just needs a ton of testing and waiting for a release
but it doesn't let me inject Exceptions into the with block rather than in the case code.
Maybe... but it would still be less apealing than with case(a):
exec("Stack = type('Stack', (), {'__init__': %: & []$, 'isempty': %: len(self.l) == 0, 'push': %, value: & self.l + [value]$, 'pop': %: [self.l[-1], & self.l[:-1]$][0], 'top': %: self.l[-1]$".replace('%', "lambda self").replace('&', "self.__dict__.update({'l':").replace('$', "})"))```
what does esoteric mean?
The title of the room is: Golfing, Python VM languages, obfuscation, code gore and other general Python weirdness
Golfing: means make code as short as possible.
Python VM languages: making other languages compile to run in the python interpreter.
obfuscation: means code that is as unreadable as possible
code gore is ... all of the above but worse.
Nice
thanks
i come here everyday for my daily dose of insanity. i've had enough today 🙂
I made an obfuscated golfed python python vm
nods then I'm laying 9::1 odds that it qualifies as code gore. 😉
r/madlads
Is that [][9::1]
... Sure, If it makes you happy.
!e
Hey @sick hound!
Uh-oh! It looks like your message got zapped by our spam filter. We currently don't allow .txt attachments, so here are some tips to help you travel safely:
• If you attempted to send a message longer than 2000 characters, try shortening your message to fit within the character limit or use a pasting service (see below)
• If you tried to show someone your code, you can use codeblocks
(run !code-blocks in #bot-commands for more information) or use a pasting service like:
exec("exec('\x045[]\\nc\\x052\\n\\nwhile \x07t\x080\x07x04for\r\rn \x04\x0e7c%i =\x0f0\\x0\x0e0Fals\\x04\\x07\\r\t\\\x101n\x108\\x01\x11\\rt.append\\x08\x08e\x12c +\x0f1'.replace('\x12\x05\x03r\ns\x02c\x13\x01b\x0bi\x03t\x0c:\x028\x13(c)\x027\nf \x026\x13Tru\x025\x0b\x014\x0c\\n\x003\x13:\x06\x002\x13pri\x11ist\x021\x13\x06 pri\x020\x05 is\te = '))".replace('\x13', "', '").replace('\x12', '\\x0e').replace('\x11', 'me_l').replace('\x10', 't\\x0').replace('\x0f', '\\x0c').replace('\x0e', '3\\x0').replace('\r', '\\x0b').replace('\x0c', "', 'e").replace('\x0b', "', ' ").replace('\n', "', 'i").replace('\t', '_prim').replace('\x08', '\\n\\x0').replace('\x07', '\\x06\\').replace('\x06', '\\n ').replace('\x05', "', ' ").replace('\x04', '\\x02\\x0').replace('\x03', "').replace('\\").replace('\x02', "').replace('\\x0").replace('\x01', "= ').replace('\\x0").replace('\x00', " ').replace('\\x0"))```
ok I have another, better version
exec("exec('\\r\\x01\\r\\t\\r[\\r]\\x10c\\r\\t\\r2\\x10\\n\\rw\\rh\\ri\\rl\\x0e \\x12:\\x10\\x02\\x12\\x0c\\rf\\ro\\rr\\r\\x0b\\r\\x0b\\rn\\x0f\\x01\\r\\x03\\x11c\\r%\\ri\\x0f=\\r\\x06\\r0\\r\\x03\\r\\x02\\rF\\x13l\\rs\\x0e\\x0c\\x11i\\rs\\r_\\x14m\\x0e\\x03\\x14n\\rt\\r\\x04\\r\\x00\\r\\x01\\r.\\x13p\\rp\\x0en\\rd\\r\\x04\\rc\\x0f+\\r\\x06\\r1\\r'.replace('\\x14', '\\r\\x08\\r\x00x13', '\\ra\\r\x00x12', '\\r\\x05\\r\x00x11', '\\r\\x07\\r\x00x10', '\\r\\n\\r\x00x0f', '\\r \\r\x00x0e', '\\re\\r\x00r', '\x00x0c', '\\n\\x00\x00x0b', ' i\x00t', ' \\x06\x00x08', 'pri\x00x07', 'if \x00x06', '= \x00x05', 'True\x00x04', '(c)\\n\\x00\x00x03', ':\\n\\x00\\x00\x00x02', '\\x00is_prime = \x00x01', 'prime_list\x00x00', ' '))".replace('\x00', "').replace('\\"))```
ok so the last pieces of code were all the same program but expressed differently, this one is a different one and the algorithm seems to work really efficiently:
exec('exec("\\x10time\\tsleep\\n\\x10random\\trandint\\n\\nn\\x06196\\n\\x12\\x0615\\n\\x05\\x06119\\n\\x11\\x060.02\\n\\n\\x02\\x06[]\\n\\n\\rTrue:\\x0f\\x04\\x06[]\\x03if not \\x0c>\\x13i[1]):\\x0f\\x00\\x00\\x04\\x0bi)\\x0f\\x02\\x06\\x04\\x0f\\x0fif\\x13\\x02) < \\x12:\\n\\x01\\rnot all([(abs(\\x08 - i[0]) > 1) for i in \\x02]):\\x0f\\x01\\x02\\x0b[\\x08, \\x0e, 1])\\x0f\\x00n\\x06n + \\x14\\x0e[::-1])\\x07\\x06list(\' \' * \\x05)\\x03s[i[0] - 1]\\x06i[1][\\x0c- 1]\\x0fs\\x06\'\'.join(s)\\x0fpr\\x14\'\\\\n\' + s, end=\'\')\\n\\x03\\x0c+= 1\\x07leep(\\x11)".replace(\'\\x14\', \'int(\x00x13\', \' len(\x00x12\', \'max_\\x02\x00x11\', \'delay\x00x10\', \'from \x00x0f\', \'\\n\\x00\x00x0e\', \'str(n)\x00r\', \'while \x00x0c\', \'i[2] \x00x0b\', \'.append(\x00t\', \' import \x00x08\', \'new_width\x00x07\', \'\\n\\x00\\x00\\x00\\x00\\x00\\n\\x00s\x00x06\', \' = \x00x05\', \'screen_width\x00x04\', \'existing_\\x02\x00x03\', \'\\n\\x00for i in \\x02:\\n\\x00\\x00\x00x02\', \'streams\x00x01\', \'\\x00\\x00new_width = randint(1, screen_width)\\n\\x00\\x00\x00x00\', \' \'))'.replace('\x00', "').replace('\\"))```
E:\__py__\__modules__>py
Python 3.9.0 (tags/v3.9.0:9cf6752, Oct 5 2020, 15:34:40) [MSC v.1927 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from cursed import *
>>> switch,case,otherwise=Switch()
>>> i=2*2
>>> switch(i)
>>> case[0](print,"haha im dum")
>>> case[1](print,"divided?")
>>> case[2](print,"no op?")
>>> case[4](print,"this should print")
this should print
>>> case[5](print,"no printy")
>>> otherwise(print,"if this prints i will hang myself")
>>>
wait how do you make a context manager?
like
with thingy() as thing:
do_stuff(thing)
there's a pep-8 song? sounds like it would be heresy in this channel
the funny thing is I would actually use that switch case otherwise suite
for actual code
Not sure if this is the correct place to put this, but __import__ is used a lot in the esoteric world
Can someone explain why __import__("http.server") returns <module 'http' from '/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/__init__.py'> rather than the module http.server? How can I, in one line, access http.server?
try __import__('http.server').server
don't forget to specify from_list
E:\__py__\__modules__>py
Python 3.9.0 (tags/v3.9.0:9cf6752, Oct 5 2020, 15:34:40) [MSC v.1927 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from cursed import *
>>> case[7](print,"this should raise error")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "E:\__py__\__modules__\cursed.py", line 80, in __getitem__
if self.state<0:raise SyntaxError("Cannot find matching switch")
SyntaxError: Cannot find matching switch
>>> i=2*2
>>> otherwise(print)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "E:\__py__\__modules__\cursed.py", line 88, in otherwise
elif case.state<0:raise SyntaxError("Cannot find matching switch.")
SyntaxError: Cannot find matching switch.
>>> switch(i)
>>> case[0](print,'No printy')
>>> case[4](print,'yes printy')
yes printy
>>> case[5](print,'printy not')
>>> otherwise(print,'no print for u')
>>> otherwise(print)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "E:\__py__\__modules__\cursed.py", line 88, in otherwise
elif case.state<0:raise SyntaxError("Cannot find matching switch.")
SyntaxError: Cannot find matching switch.
>>>
exception raising
def Switch():
class Case:
def __init__(self):self.value,self.state=None,-1
def __getitem__(self, item):
if self.state<0:raise SyntaxError("Cannot find matching switch")
elif self.value==item:self.state+=1
else:return lambda*_,**__:None
return lambda f,*args,**kwargs:f(*args,**kwargs)
case=Case()
def switch(v):case.value,case.state=v,0
def otherwise(f,*args,**kwargs):
if not case.state:value=f(*args,**kwargs)
elif case.state<0:raise SyntaxError("Cannot find matching switch.")
else:value=None
case.state=-1;return value
return switch,case,otherwise
switch,case,otherwise=Switch()
yo what is my python professor doing?
That is highly inelegant
It does kind of look like a bunch of those for loops could be on the same line though...
For maximum beautiful code
ask him i really want to know
tell him use itertools or go home
na just make him use a oneliner
not just one line, one expression
ehh fuck it, this belongs here
oof
okay im gonna chuck off at that with an expanded form of 4D Conway's Game of Life
thanks
lol look at that looks like some ascii art
where?
bruh
!e ```py
def (,safe=[2,3],new=[3]):
=[];_=lambda :[-1]not in [:-1];=
try:
dims=[]
while True:dims+=[len()];=_[0]
except:r=[range(this)for this in dims]
while __():
for i in r[0]:
for j in r[1]:
for k in r[2]:
for l in r[3]:
count=0
for I in range(-1,2):
if i+I in r[0]:
for J in range(-1,2):
if j+J in r[1]:
for K in range(-1,2):
if k+K in r[2]:
for L in range(-1,2):
if l+L in r[3]:
try:
if __[i+I][j+J][k+K][l+L]:
count+=1
except IndexError:pass
if __[i][j][k][l] and count not in safe: __[i][j][k][l]=0
elif not [i][j][k][l] and count in new:[i][j][k][l]=1
return __
from random import randint
_r=[range(randint(2,10))for _ in range(4)]
_m=[[[[(randint(1,100)<50)-0 for _0 in _r[0]]for _1 in _r[1]]for _2 in _r[2]]for 3 in r[3]]
=(m)
print()
@floral meteor :x: Your eval job timed out or ran out of memory.
[4, 3, 2, 7]
...
aha my programmings is too powerful for ur bot
okay i run it locally it's still thonk
it much thonk
I just needed to make a new file...
hey i can just do +File(filename) to make a file :>
def gol_4D(__,safe=[2,3],new=[3]):
___=[__];_____=lambda _:_[-1]not in _[:-1];_=__
try:
dims=[]
while True:dims+=[len(_)];_=_[0]
except:r=[range(this)for this in dims]
_r=range(-1,2)
while _____(___):
for i in r[0]:
for j in r[1]:
for k in r[2]:
for l in r[3]:
count=0
for I in _r:
if i+I in r[0]:
for J in _r:
if j+J in r[1]:
for K in _r:
if k+K in r[2]:
for L in _r:
if l+L in r[3]:
try:
if __[i+I][j+J][k+K][l+L]:
count+=1
except IndexError:pass
if __[i][j][k][l] and count not in safe: __[i][j][k][l]=0
elif not __[i][j][k][l] and count in new:__[i][j][k][l]=1
return __
just make it a bit prettier, line up the rs ahahahaha
it takes a long time to work tho i'll have to optimise it
i could use itertools to make it less deceptive and possibly even more efficient...
I was about to say what on earth in this, but then I realized which channel I clicked on
import itertools
def gol_4D(__,safe=[2,3],new=[3]):
___=[__];_____=lambda _:_[-1]not in _[:-1];_=__;dims=[];_r=range(-1,2)
try:
while True:dims+=[len(_)];_=_[0]
except:r=[range(this)for this in dims]
while _____(___):
for i,j,k,l in itertools.product(*r):
count=0
for I,J,K,L in itertools.product(r,repeat=4):
if i+I in r[0]and j+J in r[1]and k+K in r[2]and l+L in r[3]:
try:
if __[i+I][j+J][k+K][l+L]:
count+=1
except IndexError:pass
if __[i][j][k][l] and count not in safe: __[i][j][k][l]=0
elif not __[i][j][k][l] and count in new:__[i][j][k][l]=1
return __
you see where I'm starting to get at?
I'm starting to get at NDIMENSIONAL AHAHAHA
alright i'll give y'all a break from my insanity sya tomorrow
Read the docs on import (built in functions page)
Trying to hurt you
That's boring
contextmanagers be like:
from contextlib import contextmanager
@contextmanager
def thing(arg):
#before stuff
try:
yield another_thing
finally:
#after stuff
pass
or ```py
class thing:
def init(self, arg):
pass
def enter(self):
#before stuff
return another_thing
def exit(self, e1, e2, e3):
#after stuff
Adding type hints to context managers can be tricky though
print('Console loaded successfully.\nVersion: 1.0\n'),[x for x in iter(lambda:(lambda o,s,n,h:(lambda d:(lambda i,*a:d.get(i)(*a)if i in d else print(f'Lambda: Command "{i}" Not Found.'))(*input(f"{n}@{h} $ ").split(' ')))({'':lambda:s.stdout.write(''),'clear':lambda:o.system('cls')if o.name=='nt'else o.system('clear'),'exit':lambda:s.exit('Process Killed Successfully.'),'echo':lambda *a:print(*a),'mkfile':lambda *a:print('Lambda: Please specify a file name to create.')if type(a)==tuple and len(a)==0 else open(a[0]if type(a)==tuple else a,'w').close(),'rmfile':lambda *a:print('Lambda: Please a file name to remove.')if type(a)==tuple and len(a)==0 else o.remove(a[0]if type(a)==tuple else a)if(o.path.exists(a[0])if type(a)==tuple else a)else print('Lambda: File does not exist.'),'man':lambda *a:(lambda k:k.get(a[0])()if a[0]in k else print(f'Lambda: No Manual Page Found For "{a[0]}"'))({'clear':lambda:print('Clears the screen.\nUsage: clear'),'exit':lambda:print('Exits the terminal.\nUsage: exit'),'echo':lambda:print('Echos the following message.\nUsage: echo (message)'),'mkfile':lambda:print('Creates the following file.\nUsage: mkfile (File Name)'),'rmfile':lambda:print('Removes the following file.\nUsage: rmfile (File Name)'),'man':lambda:print('Get the manual of the following command.\nUsage: man (Command)')})if len(a)!=0 else print('Lambda: Please supply a command to see the manual of.')}))(__import__('os'),__import__('sys'),(lambda _o:(_o.read(),_o.close())[0])(open('storage/user.txt')),(lambda _o:(_o.read(),_o.close())[0])(open('storage/host.txt'))),1)]
added manual command
recreating linux one command at a time
oh my god
What is worse: more unnecessary lines or everything on one or two lines?
the latter
The former
Ur in the wrong channel then, ahahahaha
too many lines can be quite esoteric
oneliners tend to quite boring
>>> from ctypes import c_void_p
>>> class NoMore:
... def __str__(self):
... return "baby don't hurt me"
... __repr__ = __str__
...
>>> c_void_p.from_address(id(True)+8).value = id(NoMore)
>>> what = love = object()
>>> what is love
baby don't hurt me
``` has unneeded lines, but is still awesome
.
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
<__main__.AwkwardSilence.f object at 0x7f7c9f261fd0>
Awww
replace __qualname__
!e ```py
class AwkwardSilence:
class f:name=".."
AwkwardSilence.f.qualname=".."
print(repr(AwkwardSilence.f()))
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
<__main__... object at 0x7fd7297f0fd0>
Awww
!e
__name__ = ''
class AwkwardSilence:
class f:__qualname__=".."
print(repr(AwkwardSilence.f()))
@proper vault :white_check_mark: Your eval job has completed with return code 0.
<... object at 0x7f6ad6020fd0>
!e
print(TOKEN)
@fluid maple :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | NameError: name 'TOKEN' is not defined

!e ```py
class AwkwardSilence:
class f:qualname=".."
AwkwardSilence.f.qualname=".."
print(repr(AwkwardSilence.f()))
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
<__main__... object at 0x7f71f0936fd0>
@fluid maple if you want try and break the sandbox, do so in #bot-commands
@fluid maple that is run in snekbox hence is not run in the same environment as the bot
ah
If ur gonna hack, do it good
Also it runs on Linux
:>
.
!e ```py
def call(self): print(self.name)
import main
try: main(main)
except: print(";-;")
main = type("module",(),globals())()
main()
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
001 | ;-;
002 | __main__
That's my latest python hackery I thought of while going to sleep.
Just because I didn't like how import main makes dunders impotent
Also, dunder methods outside of class ahahaha
Now you have me curious, what dunders do a module get?
If you were to define dunders in a module, they would be "impotent"
So if you imported my cursed dunder main script from the outside you wouldn't be able to call it directly
Even though the dunder is a valid attribute
Because the attributes of a module are hidden by overridden getattr and setattr methods
Which allows module.call to work but not module()
What the above does is a "potent" version of import main
You can't setattr a module that will likely also be overridden
Or read only
like py def __getattr__(self, attr): #bla bla _getattr = __getattr__ def please_call_after_import(): global __getattr__ __getattr__ = _getattr #etc
Why would you do that?
It's not the import that does it it's the module object
I'll show you how, hang on...
Ah!, alright got it.
You replace globals() in above script with this magic line:
{this:getattr(module, this) for this in dir(module)}
Replacing module with what you just imported
!e def __call__(self): print(self.__name__) import __main__ try: __main__(__main__) except: print(";-;") __main__ = type("module",(),{this:getattr(module, this) for this in dir(module)})() __main__()
@vague cairn :x: Your eval job has completed with return code 1.
001 | ;-;
002 | Traceback (most recent call last):
003 | File "<string>", line 5, in <module>
004 | NameError: name 'module' is not defined
You can define two dunders for a module dir and getattr
Although I don't think they take self
Emphasis on defining a variable in the first place duh
So that snippet posted might be valid
!e ```py
def call(self): print(self.name)
import main
try: main(main)
except: print(";-;")
del main
import main as module
main = type("module",(),{this:getattr(module, this) for this in dir(module)})()
main()
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
001 | ;-;
002 | __main__
I think I do.
!e py def __call__(self): print(self.__name__) def __str__(self): return 'foo' import __main__ try: str(__main__) except: print(";-;") del __main__ import __main__ as module __main__ = type("module",(),{this:getattr(module, this) for this in dir(module)})() print(str(__main__))
@vague cairn :white_check_mark: Your eval job has completed with return code 0.
foo
!e
The bit in the middle is just to show it doesn't work
print(str(__import__('__main__')))
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
<module '__main__' (built-in)>
Fair.
!e ```py
def gt(self,other): print(other)
import main as module
main = type("module",(),{this:getattr(module, this) for this in dir(module)})()
main > "Hello World!"
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
Hello World!
and generalized to: py def import_as_object(amodule_name): module = __import__(amodule_name) mod_obj = type("module", (), {this: getattr(module, this) for this in dir(module)} )() globals()[amodule_name] = mod_obj #or if it's more to your tastes: globals()[module.__name__] = mod_obj
Nice.
i=lambda n:(lambda m=__import__(n):(lambda o=type("module",(),{t:getattr(m,t)for t in dir(m)})():globals().__setitem__(n,o))())()```
@floral meteor Thank you for my evening dose of esoteric. I'll get lost now.
... is the new import
should make that a built-in hint hint nudge nudge pydevs
!e ```py
from ctypes import util
from ctypes import *
import atexit
base_size = sizeof(c_void_p)
libc = cdll.LoadLibrary(util.find_library('c'))
PAGE_SIZE = libc.getpagesize()
MEM_READ = 1
MEM_WRITE = 2
MEM_EXEC = 4
libc.mprotect.argtypes = (c_void_p, c_size_t, c_int)
libc.mprotect.restype = c_int
def mprotect(addr, size, flags):
addr_align = addr & ~(PAGE_SIZE - 1)
mem_end = (addr + size) & ~(PAGE_SIZE - 1)
if (addr + size) > mem_end:
mem_end += PAGE_SIZE
memlen = mem_end - addr_align
libc.mprotect(addr_align, memlen, flags)
def addr(cfunc):
ptr = c_void_p.from_address(addressof(cfunc))
return ptr.value
def hook(cfunc, restype=c_int, argtypes=()):
cfunctype = PYFUNCTYPE(restype, argtypes)
cfunc.restype, cfunc.argtypes = restype, argtypes
o_ptr = addr(cfunc)
mprotect(o_ptr, 5, MEM_READ | MEM_WRITE | MEM_EXEC)
mem = (c_ubyte5).from_address(o_ptr)
default = mem[:]
def wrapper(func):
@cfunctype
def injected(*args, **kwargs):
nonlocal mem, jmp, func
try:
mem[:] = default
return func(*args, **kwargs)
finally:
mem[:] = jmp
n_ptr = addr(injected)
offset = n_ptr - o_ptr - 5
jmp = b'\xe9' + (offset & ((1 << 32) - 1)).to_bytes(4, 'little')
mem[:] = jmp
@atexit.register
def unhook():
nonlocal mem
mem[:] = default
injected.unhook = unhook
return injected
return wrapper
@hook(pythonapi.PyDict_SetDefault, restype=py_object, argtypes=[py_object]*3)
def setdefault(self, key, value):
if key == 'MAGICVAL':
return self
return pythonapi.PyDict_SetDefault(self, key, value)
pythonapi.PyUnicode_InternFromString.restype = py_object
interned = pythonapi.PyUnicode_InternFromString(b'MAGICVAL')
setdefault.unhook()
print(interned)```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
{'__getattribute__': '__getattribute__', '__getattr__': '__getattr__', '__setattr__': '__setattr__', '__delattr__': '__delattr__', '__repr__': '__repr__', '__hash__': '__hash__', '__call__': '__call__', '__str__': '__str__', '__lt__': '__lt__', '__le__': '__le__', '__eq__': '__eq__', '__ne__': '__ne__', '__gt__': '__gt__', '__ge__': '__ge__', '__iter__': '__iter__', '__next__': '__next__', '__get__': '__get__', '__set__': '__set__', '__delete__': '__delete__', '__init__': '__init__', '__new__': '__new__', '__del__': '__del__', '__await__': '__await__', '__aiter__': '__aiter__', '__anext__': '__anext__', '__add__': '__add__', '__radd__': '__radd__', '__sub__': '__sub__', '__rsub__': '__rsub__', '__mul__': '__mul__', '__rmul__': '__rmul__', '__mod__': '__mod__', '__rmod__': '__rmod__', '__divmod__': '__divmod__', '__rdivmod__': '__rdivmod__', '__pow__': '__pow__', '__rpow__': '__rpow__', '__neg__': '__neg__', '__pos__': '__pos__', '__abs__': '__abs__', '__bool__': '__bool__', '__invert__
... (truncated - too long)
Full output: too long to upload
^ the internal interned string dictionary
in <lambda>
___=_prev if _prev is not None else[__.copy()];_____=lambda:___[-1]not in ___[:-1];dims=[len(__),len(__[0])];_r=range(-1,2);r=[range(_)for _ in dims]
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
whoever wrote numpy and made the bool method of array raise a valueerror, I will find them and make them suffer...
I will start by forcing them to watch this channel :>
@rugged sparrow :warning: Your eval job timed out or ran out of memory.
[No output]
👀 whoops
hehe u borke bot
okay i got an esoteric problem...
I've got a list of ndarrays called ___
and I want to test if the last element is equal to any of the other elements.
Now in what way shape or form does this:
lambda:___[-1]not in ___[:-1]
call the f***ked up bool method of ndarray which raises a ValueError cos they want you to compare all or any?
or do I have to compare the long way?
eh imma just hack the numpy module
stuff multi-device compatibility
!e print(import('sys').path)
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
['', '/snekbox/user_base/lib/python3.9/site-packages', '/usr/local/lib/python39.zip', '/usr/local/lib/python3.9', '/usr/local/lib/python3.9/lib-dynload']
def bad_idea(func):
def wrapper(*args, **kwargs):
while True:
try:
f = func(*args, **kwargs)
return f
except NameError as lol:
name = str(lol).split('\'')[1]
exec('global ' + name + '\n' + name + ' = None')
return wrapper
@bad_idea
def seriously_silly():
a
seriously_silly()
came up with this one a few days ago
decorator to handle NameErrors by defining name as None globally
then calling the function again
alright I tracked down the imports and arrived at a pyd
so I can't really hack numpy to allow bool() of an ndarray instance
so i'll have to throw it out window and make my own numpy module
can't you just subclass ndarray?
you rly should just make an array of True of the same size and check that they're the same assuming that's what you want the behavior to be haha
!e ```py
from numpy import ndarray
class UWU(ndarray):
bool=lambda s:len(s)>0
UWU([1,2,3,4]) and print('uwu')
UWU([])or print('owo')
@floral meteor :x: Your eval job has completed with return code 1.
001 | uwu
002 | Traceback (most recent call last):
003 | File "<string>", line 5, in <module>
004 | File "<string>", line 3, in <lambda>
005 | TypeError: len() of unsized object
def bool(self): in the esoteric python? r u less insane than me or something?
_multiarray_umath.cp39-win_amd64.pyd is the offensive file in this case
!e ```py
class w:
gt=print
str=lambda s:"Hello"
w() > "World!"
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
World!
interesting
!e
class w:
__gt__=print
__repr__=lambda s:"Hello"
w() > "World!"
@hard spoke :white_check_mark: Your eval job has completed with return code 0.
World!
hmm, I knew it uses repr for container classes, but not sure what happened here.
i think we borke it
Is there a way to make like a variable have a "whitespace" character in it?
sure...
like not a unicode space 32 like some other special character
one that looks like a space, but isn't
!e
class f:
__eq__ = lambda s, x: print(s, x)
g = f()
g == 'test'
@simple crystal :white_check_mark: Your eval job has completed with return code 0.
<__main__.f object at 0x7f9edd460fd0> test
Somewhere between chr(8190) and chr(8200)
!e ```py
globals().update({"a\tb":4})
print(globals()['a\tb'])
print(dir())
not like that though
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
001 | 4
002 | ['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a\tb']
that's a variable name with whitespace in it :>
!e py for i in range(8190, 8200): print(f"Special Character {i} : '{chr(i)}'")
@tribal moon :white_check_mark: Your eval job has completed with return code 0.
001 | Special Character 8190 : '῾'
002 | Special Character 8191 : ''
003 | Special Character 8192 : ' '
004 | Special Character 8193 : ' '
005 | Special Character 8194 : ' '
006 | Special Character 8195 : ' '
007 | Special Character 8196 : ' '
008 | Special Character 8197 : ' '
009 | Special Character 8198 : ' '
010 | Special Character 8199 : ' '
one that can be referenced without globals
it can be defined with globals, but it should be something like ```py
value```
something like that
!e ```py
class stdout:
eq=print
stdout() == "hehe Im dum"
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
hehe Im dum
somehow print doesn't take the first positional arg if it's self?
!e
def test(*args):
print(args)
class f:
__eq__ = test
g = f()
g == 'test'
@simple crystal :white_check_mark: Your eval job has completed with return code 0.
(<__main__.f object at 0x7faca57e1fd0>, 'test')
!e ```py
class MetaStupid:eq=lt=le=ne=gt=ge=add=sub=mul=matmul=or=and=call=new=print
class ImDum(metaclass=MetaStupid):pass
ImDum=="i am much stupid :>"
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
<class '__main__.MetaStupid'> ImDum () {'__module__': '__main__', '__qualname__': 'ImDum'}
there u go
lol typing p<object is way faster than print I might actually use this for debugging >_>
should use breakpoints and such ofc
I made a whole module to do
std << "some string"
std <= "Error"
std < File("filename")
exit << 0
etc...
haha nice
you can overload bitshift eh
never realized that
learning so many USEFUL FACTS today
:>
Chilaxan I have a few questions
with like this
remember: py if instructions[(idx//2)+1].opname == 'JUMP_FORWARD': if instructions[(idx//2)+2].opname == 'ROT_TWO': if instructions[(idx//2)+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, ])
I just wanna try to understand it
So like what does this mean?
What are you injecting?
What exactly did you change?
I can do this as well:
from cursed import *
switch(std<<"question? (yes/no)" and -std)
case['yes'](print,"you chose yes")
case['no'](print,"you chose no")
otherwise(print,"invalid option")
What do those bytecode things mean?
omg I could even have p<object print the name of the object variable if it doesn't exist so I could skip quotes
and why are you slicing instructions by half of index + 1
so ridiculous
basically Array.__lt__ is called when the interpreter hits Array<int
@simple crystal this is a peek of my cursed module
I only use def if i need to use try
that function changes the bytecode of the upper code object to remove the bytecode of >(1,2,3) and changes it to instead rearrange the stack to format the stack for a function call
then it uses CALL_FUNCTION 2 to call the function (Array) at stack[-3](stack[-2], stack[-1])
@tribal moon ^
And you learned how to do all of this in your free time?
@floral meteor what class do you need to shim __bool__?
yea
@simple crystal look up chilaxan/fishhook on github
Im walking to store rn but will when I'm back home
to make a file I can just execute
+File(filename)
to read a file
std < File(filename)
to test if file exists:
if File(filename): ...
try making Java in Python
@floral meteor what class was it that you wanted to shim bool on
numpy.ndarray
dope gimme a min
so like ```
public+static+void+"Main"+(String[]+args)+{
stufff
I feel inspired to make a testing module with a bunch of stupid things in it that can remove any traces of itself from a module when you're done using it
it'd be awesome
although the error is raised here:
lambda:___[-1]not in ___[:-1]
where ___ is a list of arrays
well, that's the only lambda in this line;
File "E:\__py__\__modules__\game_of_life.py", line 28, in <lambda>
___=_prev if _prev is not None else[__.copy()];_____=lambda:___[-1]not in ___[:-1];dims=[len(__),len(__[0])];_r=range(-1,2);r=[range(_)for _ in dims]
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
!e ```py
from forbiddenfruit import reverse
reverse(8,'invert')
@floral meteor :warning: Your eval job has completed with return code 139 (SIGSEGV).
[No output]
hehehehe
that crashed python on my pc
no error just exit
what is SIGSEGV?
that's not very verbose
segfault
patching things through cpython gets of rid of stability guarantees
i borke python :>
!e ```py
import ctypes
ctypes.string_at(0)
@earnest wing :warning: Your eval job has completed with return code 139 (SIGSEGV).
[No output]
pretty simple
!e ```py
from ctypes import c_void_p, c_ssize_t, py_object
import numpy as np
def get_bool_p(cls): # gets a pointer to cls.tp_as_number.nb_bool function pointer
return c_void_p.from_address(c_void_p.from_address(id(cls) + 96).value + 72)
class a: # create empty class with a.tp_as_number.nb_bool initialized
bool = None
get_bool_p(np.ndarray).value = get_bool_p(a).value # insert generic bool func pointer from a
mp = np.ndarray.dict # get mapping proxy (save reference)
py_object.from_address(id(mp) + 16).value['bool'] = lambda self:bool(len(self)) # insert new bool into mapping proxy
def PyType_Modified(cls): # tells the python runtime that the attribute cache for this class is invalid by toggling a flag
flags = c_ssize_t.from_address(id(cls) + 21 * 168)
if (flags.value & (1 << 19)) == 0:
return
for ref in cls.subclasses():
PyType_Modified(ref)
flags.value &= ~(1 << 19)
PyType_Modified(np.ndarray)
print(bool(np.array([[1, 2, 3], [4, 5, 6]], np.int32)))```
i borke python, u borke python, everyone broke python
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
True
@floral meteor ^ that swaps out the original __bool__
nice
noice...
does it return False when the array is "unsized"?
not currently
I've got some crazy ideas for this module now but I have to make dinner
but you can just modify the lambda to have the correct operation
then maybe i should just make it return True in all cases
now how do i test if the last element of a list is equal to any of the previous elements of a list
or...
test a list for duplicate values
that wouldn't necessarily pass the is test or in test
thats due to syntax errors being raised as code is compiled not as it is ran
but if I write a module that can wrap the whole program in exec......
it'd need to be executed before the rest of the code is compiled
or it can rewrite the module and then execute that maybe?
!e ```py
from numpy import array,ndarray
__m = array([[1,0],[0,1]])
try:__m and 1
except:print('.')
from forbiddenfruit import curse
curse(ndarray,"bool",lambda s:True)
print(bool(array([[0,1],[1,0]])))
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
001 | .
002 | True
:>
@floral meteor use fishhook its more stable
pip install fishhook?
ye
then just ```py
@hook(cls)
def method(self, *args **kwargs):
...
works for all dunders automatically
(if you find one that breaks it ping me)
!e import fishhook
@floral meteor :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | ModuleNotFoundError: No module named 'fishhook'
it shouldnt break
that's a lot of stuffs in fishhook
considering its only 5kb
>>> dir(fishhook)
['ARRAY', 'ArgumentError', 'Array', 'BigEndianStructure', 'CDLL', 'CFUNCTYPE', 'DEFAULT_MODE', 'DllCanUnloadNow', 'DllGetClassObject', 'FormatError', 'GetLastError', 'HRESULT', 'LibraryLoader', 'LittleEndianStructure', 'OleDLL', 'P', 'POINTER', 'PYFUNCTYPE', 'PyDLL', 'RTLD_GLOBAL', 'RTLD_LOCAL', 'SetPointerType', 'Structure', 'Union', 'WINFUNCTYPE', 'WinDLL', 'WinError', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_end', '_item', '_key', '_last', '_location', '_locs', '_name', '_offset', '_size', '_structs', '_subcls', '_val', '_wrapperbase', '_wrappers', 'addressof', 'alignment', 'base_size', 'byref', 'c_bool', 'c_buffer', 'c_byte', 'c_char', 'c_char_p', 'c_double', 'c_float', 'c_int', 'c_int16', 'c_int32', 'c_int64', 'c_int8', 'c_long', 'c_longdouble', 'c_longlong', 'c_short', 'c_size_t', 'c_ssize_t', 'c_ubyte', 'c_uint', 'c_uint16', 'c_uint32', 'c_uint64', 'c_uint8', 'c_ulong', 'c_ulonglong', 'c_ushort', 'c_void_p', 'c_voidp', 'c_wchar', 'c_wchar_p', 'cast', 'cdll', 'create_string_buffer', 'create_unicode_buffer', 'get_errno', 'get_last_error', 'getdict', 'getptrs', 'hook', 'hook_cls', 'hook_cls_from_cls', 'hooks', 'key_blacklist', 'memmove', 'memset', 'methods_cache', 'oledll', 'orig', 'pointer', 'py_object', 'pydll', 'pythonapi', 'resize', 'set_errno', 'set_last_error', 'sizeof', 'slotmap', 'string_at', 'sys', 'unhook', 'update_subcls', 'windll', 'wrapper_type', 'wstring_at']
it imports everything from ctypes
dam it works for objects already existing...
>>> import fishhook
>>> @fishhook.hook(fishhook.__class__)
... def __call__(s,f):print(s.__name__,':',f)
...
>>> fishhook("Yeet")
fishhook : Yeet
>>>
it should work for any class
and it transmits to all instances of that class already existing :O
i also wrote a function orig that calls the original implementation of the function automatically
sso far I like it
>>> @fishhook.hook(print.__class__)
... def __lshift__(s,f):s(f)
...
>>> print<<'yeet'
yeet
>>>
Not intended to be used outside hooked functions
you can also do py fishook.hook(print.__class__, name='__lshift__')(lambda s,f:s(f))
hehe you gave a clue how to borke it
did i?
uses orig outside hooked function
orig just wont do anything except raise an exception outside a hooked function
RuntimeError
ya
>>> @hook(int)
... def __matmul__(self, other):
... return self, other
...
>>> 1@2
(1, 2)
>>> ```
so I can do
@hook(....__class__.__class__)
def __lt__(s,o):do_one_thing(s,o)
@hook(int)
def __gt__(s,o):do_other_thing(s,o)
Array=type("array",(list,),{...}
var = Array<int>(1,2,3)
```instead of bytecode hackery?
show me :>
:<
Borke python?
the last line is technically var = Array<int and int>(1,2,3) and and has to return True or False
thats why i use bytecode hackery instead
The first half, at least.
Maybe with a global variable set when Array<int is called, that int>(1,2,3) reads?
and does not have to return a boolean
oh i was thinking about in
!e print(1 and "Hello World!")
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
Hello World!
bool is called on the first part.
@snow beacon is correct a global var would work
Or it could store data in the int class somehow.
however what will happen if i just did Array<int
then that would curse int
or just int>(1,2,3)
put the fishooks inside the methods
just int>(1,2,3) would not have been pre-hooked
Not supported.
thats why i prefer the bytecode version
!e ```python
print(int < (1, 2, 3))
@snow beacon :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | TypeError: '<' not supported between instances of 'type' and 'tuple'
As you can see, it's not normally supported.
true but what would it do after type.__gt__ is hooked?
I don't recall what sort of object Array<int> was meant to be.
its java-like template syntax
Then some representation of a template object applied to the argument.
i prefer my bytecode method cause it needs less boilerplate and it is easier to ensure that anything weird only happens when you want it to
from fishhook import hook
@hook(type)
def __lt__(s,o):return s().__lt__(o)
class Array:
def __lt__(s,cls):
@hook(cls)
def __gt__(_,args):
return s.__call__(*args)
return True
def __call__(s,*args):
return list(*args)
type.__class__ is type
then...
set type gt, and make it pass int
from fishhook import hook
@hook(type)
def __lt__(s,o):return s().__lt__(o)
class Array:
def __lt__(s,cls):
@hook(type)
def __gt__(_,args):
try:assert all([isinstance(this,cls)for this in args])
except AssertionError:raise ValueError(f"invalid type {this} for {cls}")
return s.__call__(*args)
return True
def __call__(s,*args):
return list(*args)
:>
@terse mortar
from fishhook import hook
@hook(type)
def __lt__(s, o):return s().__lt__(o)
class Array:
def __lt__(s, cls):
@hook(type(cls))
def __gt__(_, args):
return s.__call__(*args)
return True
def __call__(s, *args):
return list(args)
``` ```py
>>> Array<int>(1,2,3)
[1, 2, 3]
>>>
``` this works
But...
It doesn't assert
wont work for HashMap<(str, int)>{} tho
*it might work, but its a hack that it does
We cans make it works easy
the bytecode is more elegant then passing around random references inside function closures
imo
It's just that my laptop is about to die so I'm on phone now
ok done with dinner time to try some black magic
from fishhook import hook
@hook(type)
def __lt__(s,o):return s().__lt__(o)
class Array:
def __lt__(s,cls):
@hook(type)
def __gt__(_,args):
return s.__call__(args)
return True
def __call__(s,args):
return list(args)
it can dunderise the class class itself
:>
... return list(args)
File "<stdin>", line 8
return list(args)
^
SyntaxError: invalid non-printable character U+200A
characters
\u0022 : QUOTATION MARK - "
\u200a : HAIR SPACE -
\u0022 : QUOTATION MARK - "
\u0022\u200a\u0022
U+200x is used for all sorts of whitespace
as well as whitespace-esque non-whitespace chars
is there a better way to get the name of the file that is the module calling the module executing a statement than inspect.currentframe().f_back.f_globals['__file__']
The class or the function?
returns the function
So Class() = e.g. print?
Return return print from __new__?
ah i can return print from metaclass
metaclass __new__
!e
class SelfInit(type):
"""Metaclass that makes mesaclass a self-instantiated singleton"""
def __new__(cls, *args):
return print
class P(metaclass=SelfInit):
"""Prints with p>, """
def __new__(self, *args):
return print
P('test')
@simple crystal :white_check_mark: Your eval job has completed with return code 0.
test
Metaclass? You can do ```py
class MyClass:
def new(cls):
return print
let's try it
Oh, I see.
!e
class P():
"""Prints with p>, """
def __new__(self, *args):
return print
P('test')
@simple crystal :warning: Your eval job has completed with return code 0.
[No output]
__new__ is only called on instantiation
Yes, a metaclass looks like the way to go there, although the mesaclass shouldn't need any particular __new__.
yeah lots of fluff from other experiments
hmmm can I define __lt__ for the uninstantiated class?
Again, in the metaclass.
!e
class SelfInit(type):
"""Metaclass that makes mesaclass a self-instantiated singleton"""
def __lt__(cls):
return print
def __new__(cls, *args):
cls.__lt__ = print
return cls
def __lt__(cls):
return print
class P(metaclass=SelfInit):
"""Prints with p>, """
def __new__(self, *args):
return print
P() < 't'
@simple crystal :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 18, in <module>
003 | TypeError: '<' not supported between instances of 'type' and 'str'
tried a few things
That's the instantiated class.
doesn't work with uninstantiated either
hell this doesn't work
!e
class SelfInit(type):
"""Metaclass that makes mesaclass a self-instantiated singleton"""
def __lt__(cls):
return print
def __new__(cls, *args):
cls.__lt__ = print
return cls
def __lt__(cls):
return print
class P(metaclass=SelfInit):
"""Prints with p>, """
def __new__(self, *args):
return print
def __lt__(cls):
return print
P() < 't'
@simple crystal :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 20, in <module>
003 | TypeError: '<' not supported between instances of 'type' and 'str'
__lt__ should take two arguments.
oh and I have __new__ defined
That would be why, I forgot.
this is some esoteric stuff haha I'm pretty lost
I thought i kinda "got" metaclasses before
ooh I know I think
__new__ means "instead of whatever would be instantiated, return this thing instead". So P is print.
yeah I wanna redefine P as an instantiated class with its __lt__ being print
got it
!e
class SelfInit(type):
"""Metaclass that makes mesaclass a self-instantiated printer"""
def __new__(cls, *args):
printy = type('P', (object,), {})
printy.__lt__ = print
p = printy()
return p
class P(metaclass=SelfInit):
"""Prints with p<, """
P < 't'
@simple crystal :white_check_mark: Your eval job has completed with return code 0.
t
damn, can't catch NameError inside of __lt__, should have expected that
so my whole module editor needs to insert try except blocks around stuff
got it to execute the importing module after replacing stuff
!e ```python
class SelfInit(type):
def lt(self, other):
return print(other)
class P(metaclass=SelfInit):
pass
P < "t"
@snow beacon :white_check_mark: Your eval job has completed with return code 0.
t
ahhhh nice
ty
!e
class p(metaclass=type('p', (type,), {'__lt__':print})):
"""Prints with p<"""
p < 'test'
@simple crystal :white_check_mark: Your eval job has completed with return code 0.
test
yay 😄
also this abomination:
import inspect
def get_caller():
"""Returns module importing this module as string for function within this module calling this function..."""
return inspect.currentframe().f_back.f_back.f_globals['__file__']
def exec_self():
exec(open(get_caller()).read().replace('exec_self', 'nothing') + "\nimport sys\nsys.exit('EXECUTED')")
call exec_self from importing module and it executes itself with replacements and additions
p = type('p', (type,), {'__lt__':print})("p", (), {})
p < "test"
```?
!e
p = type('p', (type,), {'__lt__':print})("p", (), {})
p < "test"
@simple crystal :white_check_mark: Your eval job has completed with return code 0.
test
nice
because it is type haha wow neat
gonna leave mine cuz I do still want a docstring that actually looks like one but I appreciate the insight
Woah
I'm thinking it could like automatically add "breakpoints" and write tests
making it work for multi-module stuff and threading and so on would be intense of course
and maybe do a similar auto-doc module
^me writing up code for this channel ^
!e what i comes up with...
from forbiddenfruit import curse
from _sitebuiltins import Quitter
exit=Quitter('a,b','b,a')
curse(exit, '__repr__', lambda s:s())
repr(exit)
1/0
@floral meteor :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 'exit' is not defined
dam edit cooldown is quicker than my computer loading input from my keyboard
whoever made that rapid cooldown for rerun whe i find who it is i will ping them muchly until they fix >:>
!e ```py
from forbiddenfruit import curse
from _sitebuiltins import Quitter
exit=Quitter('a','b')
exit.repr=lambda s:str(s)
curse(exit, 'repr', lambda s:s())
repr(exit)
1/0
@floral meteor :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | File "/snekbox/user_base/lib/python3.9/site-packages/forbiddenfruit/__init__.py", line 425, in curse
004 | _curse_special(klass, attr, value)
005 | File "/snekbox/user_base/lib/python3.9/site-packages/forbiddenfruit/__init__.py", line 332, in _curse_special
006 | tp_as_name, impl_method = override_dict[attr]
007 | KeyError: '__repr__'
or has the rerun button gone?
notimplemented?
it will be considered nonexistent then
i wont be bothered removing the results or code block eitehr
I shouldn't have to rewrite the whole code blcok just to reevaluate it tho
!e ```py
from forbiddenfruit import curse
from _sitebuiltins import Quitter
curse(Quitter, 'repr', lambda s:s())
exit=Quitter(*'ab')
repr(exit)
1/0
@floral meteor :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 3, in <module>
003 | File "/snekbox/user_base/lib/python3.9/site-packages/forbiddenfruit/__init__.py", line 425, in curse
004 | _curse_special(klass, attr, value)
005 | File "/snekbox/user_base/lib/python3.9/site-packages/forbiddenfruit/__init__.py", line 332, in _curse_special
006 | tp_as_name, impl_method = override_dict[attr]
007 | KeyError: '__repr__'
whoever responsible for bot, pls fix rerun option. or i will find you and make your fingers feel the same pain mine do...
jk
but still fix bot
and my fingers do hurt
>>> class Array:
... def __lt__(s,cls):
... @hook(type)
... def __gt__(_,args):
... return s.__call__(args)
... return True
... def __call__(s,args):
... return list(args)
...
>>> Array<int>(1,2,3)
[1, 2, 3]
>>> from _sitebuiltins import Quitter
>>> @hook(Quitter)
... def __repr__(self):self()
...
>>> exit
C:\Users\%USERNAME%>
here's evidence the bot is gammin.
thats pretty neat
I have a weakness for avoiding libraries that aren't built in
it's stupid but I like stuff that runs without dependencies
that's the spirit
Oh my god
import inspect
import re
import sys
def get_caller():
"""Returns module importing this module as string for function within this module calling this function..."""
return inspect.currentframe().f_back.f_back.f_globals['__file__']
def p(p='p', replace=None, add=None, remove=False):
"""ONLY WORKS WHEN IMPORTING FROM THIS MODULE"""
pp = r'([\n;])?' + f'{p}' + ' *?< *(.*)?[\n;]?'
if remove: # DEFINE THIS BEHAVIOR TOO WITHOUT STRINGS OR KWARGS FOR SHITS
caller = open(get_caller())
f = caller.read()
caller.close()
f = re.sub(r'([\n;])*?from p import .*?[\n;]', '', f)
f = re.sub(r'([\n;])*?import p[\n;]', '', f)
f = re.sub(pp, r'\1', f)
f = re.sub(r'([\n;])*?[\.p]*?p\(.*?\)[\n;]', '', f)
with open(get_caller(), "w") as caller:
caller.write(f)
sys.exit()
py = open(get_caller()).read()
print(py)
py = re.sub(r'p\(.*?\)', r'nothing\(\)', py, 1)
if replace:
...
if add:
...
py = re.sub(pp, ' \n'
'while True: \n'
' try: \n'
' print(\\1) \n'
' break \n'
' except NameError as ne: \n'
' name = str(ne).split("\'")[1] \n'
' exec("global {}".format(name)) \n'
' exec(f"{name} = \'{name}\'")'
, py
)
exec(py + ' \n'
'import sys \n'
'sys.exit()'
)
def nothing():
...
allows for using p<anything to print anything in module this is imported into
if anything is undefined prints its name
can also redefine p print statement
and can clean this crap out of a module automatically too with kwarg remove=True
can you run a function from imported module in importing module in import statement?
No.
cuz then you wouldn't have to actually call or even specifically import p
damn thought so
Well, sort of.
You can't import the file while it's being run, but importing runs the file.
yeah it won't know the __file__ of the importing module though
right?
I added more f_backs to try to do that and they just called the p function and recursed
which makes sense
idk how one would access importing module from imported module
but from p import p; p() is pretty low effort
https://github.com/ajalt/fuckitpy @simple crystal take a look at this
couldn't you use << too?
!e
cout = type('p', (type,), {'__lshift__':print})("p", (), {})
cout << "test"
@toxic jewel :white_check_mark: Your eval job has completed with return code 0.
test
c++
yeah
I could use anything now because now the module rewrites and then execs the importing module because I wanted to be lazy and not put the print string in quotes...
working on making it print and add a breakpoint every time a name is created/changed too
ah nice, I've seem a JS version of this
pssh, amateur didn't set it up to run the importing module tho
called "fuck it" but only works on imports, as a decorator, and in context pssssh
you could use a file encodeing handler to run your code on the module before the module is compiled
https://pypi.org/project/brm/ like how this works
interesting
I'm already running my code on the module before it compiles tho
I have to because I want to insert stuff at every line and handle SyntaxErrors and NameErrors in place haha
but I like the way it uses tokens
!e py cout = type('p', (), {'__lshift__':print})() cout << "test"
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
test

...you can find the importing module without calling anything in it!
just gotta wade through the bootstrap modules
import inspect
def importer():
"""Returns module importing this module."""
depth = 0
while 'i' not in locals() or i == __file__ or '_bootstrap' in i:
depth += 1
i = eval(f'inspect.currentframe(){".f_back"*depth}.f_globals["__file__"]')
return i
when depth is 8 this returns importing module if run in body of imported module
so you could edit the functionality of a module just by importing another module
That's terrible code, if you aren't trying to make it eso
that's sort of the point of this channel
if you can do it better then show that you can
I made it better though
def importer():
"""Returns module importing this module."""
i = inspect.currentframe()
while (j := i.f_globals['__file__']) == __file__ or '_bootstrap' in j:
i = i.f_back
return j
import inspect
def importer():
"""Returns filename of outermost caller."""
frame = inspect.currentframe()
while frame is not None:
path = frame.f_globals['__file__']
frame = frame.f_back
return path
Now the function can be called from anywhere and always return outermost caller
cout = type('cout', (type,), {'__lshift__':print})("cout", (), {})
cin = type('cin', (type,), {'__rshit__':input})("cin", (), {})
cout << "test";
cin >> "test: "
not exactly like c++ but whatever
!!CEO had something going here, seems like the first pattern could be adapted to make it work like cout
I hate cout <_< prefer printf when I can get away with it
class MakeShitGoBrrrrr:
__shit__=print
def __rshit__(self, other):
return input(other)
a = MakeShitGoBrrrrr()
>>> a 💩 "Hello World!"
Hello World!
>>> "question? (Y/N)" 💩 a
question? (Y/N)Y
Y
lmfao
real shit
learning a language by figuring out how to make brainfuck...
after all, brainfuck is Turing Complete...
So if i can make brainfuck in a given language, i can code anything with that language :>
:D
am I wrong?
brainfuck=lambda c,i='',__=[[0],0,'',0]:(lambda a,j,o,z:[{
'+':lambda:a.__setitem__(j,(a[j]+1)%256),
'-':lambda:a.__setitem__(j,not a[j]and 256 or a[j]-1),
'<':lambda:(a:=[0]+a)if not j else (j:=j-1),
'>':lambda:[(j:=j+1),j==len(a)and a.append(0)],
'.':lambda:(o:=o+chr(a[j])),
',':lambda:[a.__setitem__(j,ord(i[0])),(i:=i[1:])if len(i)>1 else"\0"],
']':lambda:(s:=0),
'[':lambda:((o,c,i,s,j):=brainfuck(c,i,[a,j,o,1]))
}[_]()for _ in c if _ in'+-[],.<>']and(o,*(c,i,z,j)*z))(*__)
hangs on i'm thinkings...
mights this works?
no encoding to python and using exec like another one I've seen here
anyways, that's how you "switch" in python :>
and also I made a function that can technically do anything in python, therefore I have technically figured out how to do anything in python :>
is it rly brainfuck if you're just pretending to write data to memory with python sequences?
but write some tests haha
for ur brainfuck emulator
well if you wanted to get technical you'd specify a code!input file and output file and use file.write, and only use the namespace to emulate machinery, i.e. pointer position and file read/write position.
If you wanted to get really technical, you would also parse ANSI escape sequences, etc..
but I'm satisfied with it being more of a string processing function
also I haven't tested it or written it in an actual IDE i just vomited code into discord chat
brainfuck<-function(code,input="",byte.size=8)
{
#init
a=numeric(1)
i=1
# convert code to array of integers
chars=rawToChar(charToRaw(code),multiple=TRUE)
....<-rawToChar(charToRaw(input),multiple=TRUE)
..=numeric(0)
for(. in ....)(..[length(..)+1]=packBits(c(rawToBits(charToRaw(.)),rawToBits(raw(3))),"integer"))
.=numeric(0)
for(char in chars){
making it in r so far is looking like some more chunky code puke.
That would be fun lol
Now do it without lambda
I wonder if you can make -> in python...
would need to code it in C I think because it'll raise a SyntaxError on compile
:( surely there's some hack, maybe unicode invisible letter or fake dash
=>?
it looks like that doesn't work, the = needs to be second
you can use <= as another backwards arrow though 
you can have ー>
that is the most chad module I have ever seen
haha the tests for that https://github.com/ajalt/fuckitpy/blob/master/tests.py
At some point I'd like to use this trick to mislead readers :>
@callable
def foo(n: int) -> str:
return "foo" * n
I have an uncanny desire to steal that.
What?
I love their gh widget thingys
Random curiosity, is the pypi version number written on your native language?
nope
Versioning
The web devs tell me that fuckit's versioning scheme is confusing, and that I should use "Semitic Versioning" instead. So starting with fuckit version ה.ג.א, package versions will use Hebrew Numerals.
fuckitpy just uses that as the version
Hahaha, okay
also if their coverage is 110% and their downloads are 1.1M/month I don't expect the versioning to be real
...is that version 5.3.1 or version 1.3.5 
Theoretically if you modify pythons internal symbol table you can do anything with syntax
I'm still working on that tho
But it's no longer python
you can theoretically hijack the parser input function with an external module that initializes itself in the startup with @grand urchin 's libhook though there are a lot more easier ways to introduce / change syntax
@bitter iris can you point me in the direction of the easier ways?
Or is that stuff like brm?
It is not like brm in general, but all ways of pre-processing text and feeding the parser instead of changing the actual parser function (which is reaaally tricky)
Also I wrote something similar to that libhooker except in python ^ that can hook pythonapi functions (and technically more but those are easier to grab)
I tried to do it in the old parser, and had a successful demo though I won't recommend anyone doing that since there is no actual point.
If you want to generate bytecode from custom text, the easiest way is just pre-processing it and as a result constructing a source that looks like this;
_CODE = b'\x0\x0BLABLA'
_CO_NAMES = ('somestuff', 'etc')
...
exec(code(...))
Which python version introduced the new parser?
Is it possible to make something implicitly become lazy (genexpr or lambda or anything)
probably something along the lines of (lambda: "esoteric python")()
Lambdas are also always lazy
!e print(().__dir__())
@toxic jewel :white_check_mark: Your eval job has completed with return code 0.
['__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__len__', '__getitem__', '__add__', '__mul__', '__rmul__', '__contains__', '__new__', '__getnewargs__', 'index', 'count', '__class_getitem__', '__doc__', '__str__', '__setattr__', '__delattr__', '__init__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
My point is, i want to input normal code and get something lazy
my_function(print(123)) returns lamda that prints 124
what does getitem do?
()[0]
oh
@fluid tree that is more or less impossible without changing the python compiler
Thats what I thought
().__setattr__('__lt__', '__gt__')
What's the shortest way of doing it, then?
type('', (), {}) creates a class right
obvious:
lambda a: a
medium: (a for _ in _) [my code will deal with a value for _ and assigning to a, there is no problem here]
perfect: ???
_open = type('', (), {'__rshift__':open})()
_open >> ""
The closest things I can think of are function bodies, annotations and short circuiting operators
None of these work, nevermind
Hey, does anyone know a unban command for py? Everytime I do it there’s always a indent error and then I try to fix and that doesn’t work or an syntax error
You could do something with variable annotations under the __future__ import, but it's not exactly "first-class" lazy evaluation
for discord.py?
from __future__ import annotations # except py3.10
x: lazily_evaluated
get("x") # evaluates x, which in this case is a name error
Python yes
I’m née go coding
So I don’t know much
@tribal moon
Try using one of the help channels.
This channel is for doing Python in the worst way possible, as complicated as possible and as unreadable as possible.
Some would contend that this is the best way to do Python.
I can write it for you, thanks to this message that I'm replying to, It'll be easy! Try this: ```py
token = "put your token here"
(lambda c, a: [
f(c, a) for f in [
lambda c, a: [c.__setattr__(k, a.coroutine(v)) for k, v in {
"on_ready": lambda: print("Ready!"),
}.items()],
lambda c, a: [c.command(name = k)(a.coroutine(v)) for k, v in {
"unban": lambda ctx, member_id: c.loop.create_task(ctx.guild.unban(c.loop.create_task(c.fetch_user(member_id)))
}.items()],
lambda c, a: c.load_extension("jishaku"),
lambda c, a: c.run(token)
]
])(
import("importlib").import_module("discord.ext.commands").Bot(command_prefix = "lambda: "),
import("asyncio")
)
I think it will work
I used chilli grkans code lol and added the unban feature
you're welcome!
@floral meteor :warning: Your eval job has completed with return code 0.
[No output]
What's the float for?
Come to think of it, why the abs?
Actually, I don't think you need the ord either.
weight = lambda x: x
I do considered giving it a @callable decorator
That would break it.
@floral meteor keep in mind that discussing how to create a fork bomb, encouraging people to run one, or showing people where to find one, would all result in removal from the server.
I also don't really like this code sample. I would encourage you to re-read the #code-of-conduct
I'm heading out so DM @zinc aurora if you have a question about that.
@fluid tree Here's a quick example I made that lazily evaluates variables using variable annotations:
!e
from __future__ import annotations
import inspect, types
def get_frame(n: int) -> types.FrameType:
fr = inspect.currentframe()
for _ in range(n):
fr = fr.f_back
return fr
class Sentinel:
def __getattr__(self, name: str):
fr = get_frame(2)
try:
var = fr.f_globals["__annotations__"][name]
except KeyError:
raise NameError(f"Name {name} is not lazily defined")
value = eval(var, fr.f_globals, fr.f_locals)
fr.f_globals[name] = value
return value
_ = Sentinel()
x: 10
try:
print(x) # Fails
except NameError:
print("Not yet evaluated!")
print(_.x) # Succeeds, prints 10
print(x) # Subsequent accesses all succeed
@earnest wing :white_check_mark: Your eval job has completed with return code 0.
001 | Not yet evaluated!
002 | 10
003 | 10
instead of just using tokens I spent hours trying to write a regex that detects valid locations for ; in a python file
I don't think it's possible lol
....could just do the fuck it method and delete any that cause syntaxerrors until it runs...
coughs in ast module
yeah but that's not ridiculous enough
might run into the issue of changing program logic, lol
I think it'd be fine if it just deletes the semicolons and whatever is added with them
couldn't change anything
but I should work on extending pdb to do what I want instead of continuing to tinker with this hackjob...
Can you do that with getitem like
switch(i)
case[4]: print("wheeee")
otherwise: print("not four")
end()
Sure
Actually, probably not
case[4]: ... is a valid statement but doesn't get collected into __annotations__
.
;-;
cans it be hacked with bytecode or whatever?
since it doesn't raise syntaxerror?
or maybe...
can abuse frames to get line no. then read file?
:>:>:>:>:>:>
I think this would be a syntax error.
lol
from __future__ import annotations
case_found: False
class Case:
def __init__(s,__l):self.__l=__l
def __getitem__(s,v):
if __annotations__['switch']==v:
case_found: True
try:raise Exception
except Exception as e:
with open(__file__,'r') as file:
file.readlines(e.__traceback__.tb_frame.f_back.f_line_no)
line=file.readline()
doot=0;pos=line.find('[')
for char in line[pos:]:
pos+=1
if char=='[':doot+=1
elif char==']':doot-=1
if not doot:
while line[pos]!=':':pos+=1
pos+=1;break
statement=line[pos:]
exec(statement,s.__l,globals())
case=Case(globals())
def switchend():
if switch not in __annotations__:raise SyntaxError("no matching switch")
elif 'otherwise' in __annotations__ and not __annotations__['case_found']:
case[__annotations__['switch']]:__annotations__['otherwise']
case_found: True
i=4
switch: i
case[1]: print('wheee')
case[2]: print('whooo')
case[4]: print('hello world')
otherwise: print('dumm')
switchend()
very inelegant, and probably doesn't work :>
never rly understood the point of switch case it's just a cascading if statement that ppl always break anyway
very excited for match case tho
match case?
wait, that would work even if the annotation was an empty, string, i.e. execute blank....
It's slightly more concise, is all.
x: 10
try:
print(x) # Fails
except NameError:
print("Not yet evaluated!")
print(_.x) # Succeeds, prints 10
print(x) # Subsequent accesses all succeed
y = "foo"
_.y = lambda: "bar" # discards immediatly evaluated "foo"
try:
print(y)
except NameError:
print("Not evaluated!")
print(_.y) # prints "bar"
_.z = "2 ** 8" # Also supports using string literals in place of lambdas
print(_.z) # prints 256
Improved, now uses __setattr__ to replace immediately evaluated values with a lazy expression
sick typing btw 😎
def __setattr__(self, name: str, value: typing.Union[str, typing.Callable[[]]]) -> None:
Switch case is so much more elegant than either match case or cascading ifs
break statements are more elegant?
they aren't even more concise more of the time
I like the one obvious way to do it zen and switch leaves me wondering when there are enough cases to actually justify it
and using a dict is pretty much the same too, if you need lambdas in the dict to achieve what you want it's as clunky as breaks in a switch tree
I consider pattern matching plenty elegant (although I'm sure there will be ways to circumvent that in this channel).
C switch case is bad
I have yet to find a more elegant factorial than Haskell's recursive pattern matching:```hs
fact 0 = 1
fact n = n * fact (n - 1)
I should learn haskell
I was just wondering, what is the point of learning more than python, C and C++, SQL, and Javascript
other than needing to work on existing code or for fun
like what's useful about haskall?
I guess as far as c++ it's inseucre so you cand learn rust or some other fast secure language
Well JS is pretty useless without HTML and CSS 😉
true
Functional programming
yeah it has a style for sure but why is functional programming worth it?
s/w.+//
The right tool for the job, always.
It's better for mathematical fields. It gets in your way less.
ah makes sense
I'm interested in functional programming but mostly just to learn a new paradigm for fun
I'm working towards a math and cs major tho so maybe haskall will be something I get into for a reason
Haskell always strikes me as a beautiful (but often unfathomable) way to program, compared with Python. It's the same distinction between doing something for the maths and choosing it for the practicality.
yeah like I did a program that was basically functional today for a class but it still utilized a class with one shared attribute for convenience and utilized mutable types for the same reason
And there was probably no need to go fully functional. There often isn't.
A word of warning: after learning Haskell, every other language loses a little of its lustre. You might become one of those people who claim Haskell is better than every other language, and no one wants to be that.
We'll be here brandishing flaming swords made out of decorators and classmethods.
to welcome me into the esoteric hell lol
python looks simple but it doesn't wear kid gloves as far as what you can do with it
Not to mix too many biblical allusions, yes.
Python tries to accommodate everything (which makes esoteric programming easier), while other languages have opinions that some things should not be done.
in Python it's the programmers that have the opinions lol
Python says have at it just don't overload assignment of stuff that isn't class attributes
It pins you to its philosophy with peer pressure rather than compiler restrictions.
and it doesn't confuse you with the torrent of crap that's been glommed onto C++ >_>
you can import the stuff that's been glommed on and always have more to discover but none of it is essential
If you don't like things glommed on, then I can recommend learning Scheme. It's exceedingly minimalist, and a good stepping stone to functional programming.
I say learn. I always come back to Python if I need to do anything.
python seems like it only implements built-ins that actually make sense
and has little weird fluff
I'm super excited for match case because it actually seems like it can improve readability and simplicity
That's heresy in this channel.
lol true
at the same time I also love how you can do really stupid things in python
because of the level of introspection
but you need to dig for that instead of the whole c++ not knowing about vectors so you allocate memory for arrays garbage
aka might as well just use C
glad to hear you always return to python tho
Another comparison: C is to Rust what Python is to Haskell.
Well, no, not really.
okay what's the analogy?
I don't know it all that well. It seems to be C, except a lot safer.
Rust, that is.
I must say, we seem to be veering away from the topic of Esoteric Python.
#ot2-never-nester’s-nightmare looks free if there's much more to discuss.
def docstring_message(cls):
"""Decorates an exception to make its docstring its default message."""
cls_init = cls.__init__
@functools.wraps(cls_init)
def wrapped_init(self, *args, **kwargs):
if args:
cls_init(self, args[0], **kwargs)
else:
cls_init(self, cls.__doc__, **kwargs)
cls.__init__ = wrapped_init
return cls
neat little misguided decorator I wrote a while back
to get back on topic
Any args beyond the first are discarded? Why use *args at all rather than an argument with a default?
yeah I should fix that
I think though, whatever name you give your first parameter might shadow whatever would be passed to the exception, if that matters.
I just hacked away till it worked haha
gotta get around to actually reading the C to know how exceptions actually work
I did find out that the self parameter is required
and that this works for setting docstring as the default
def docstring_message(cls):
"""Decorates an exception to make its docstring its default message."""
cls_init = cls.__init__
@functools.wraps(cls_init)
def wrapped_init(self, msg=cls.__doc__, **kwargs):
cls_init(self, msg, **kwargs)
cls.__init__ = wrapped_init
return cls
fixed it to be nicer
appreciate the input @snow beacon
very interesting, care to elaborate?
!d super
on modules or something?
super([type[, object-or-type]])```
Return a proxy object that delegates method calls to a parent or sibling class of *type*. This is useful for accessing inherited methods that have been overridden in a class.
The *object-or-type* determines the [method resolution order](../glossary.html#term-method-resolution-order) to be searched. The search starts from the class right after the *type*.
For example, if [`__mro__`](stdtypes.html#class.__mro__ "class.__mro__") of *object-or-type* is `D -> B -> C -> A -> object` and the value of *type* is `B`, then [`super()`](#super "super") searches `C -> A -> object`.
The [`__mro__`](stdtypes.html#class.__mro__ "class.__mro__") attribute of the *object-or-type* lists the method resolution search order used by both [`getattr()`](#getattr "getattr") and [`super()`](#super "super"). The attribute is dynamic and can change whenever the inheritance hierarchy is updated.... [read more](https://docs.python.org/3/library/functions.html#super)
no you can use it with arguments
oh so just with classes defined in args
It fetches the first arg and uses that at the instance. Then it fetches the cellvar class and uses that as the class
makes sense
still not sure why i need to asign a name to cls.__init__ to avoid recursion in that deco
now I remember that's the weirdest part
after trying to remove it
cls_init is cls.__init__ is True
If you just use cls, then the closure will store cls in the closure, then access cls.__init__ whenever it needs. Because you edit that attribute, it's a recursion error. If you do cls_init, then cls_init is stored in the closure before it's edited, so it's saved for when it's needed without recursion errors.
You could store the old one in another attribute, but that seems equally indirect.
yeah I think this'll work
except adding back in *args just in case
I didn't consider attributes of parameters qualifying a closure but I guess that's why it's even a decorator
The attributes aren't stored in the closure, just the parameter.
It's a meaningless distinction, in a way.
yeah the parameter being the class so it is stored and therefore the parameter is stored and that is avoided by pointing to it with a name
if I'm grokkin
class Exception(Exception):
"""Exceptions defined in module use docstring as default message"""
def __init__(self, msg=None, *args):
super().__init__(msg or self.__doc__, *args)
another solution for doctsring default messages
"ls": lambda: (print('\n'.join((f"Directory: {u}"if o.path.isdir(u)else f"File: {u}") for u in o.listdir())), print(""))
ls command
That takes effect before the new class is defined, so if it has an __init__ it will overwrite the change.
Should've used a metaclass ™️
yeah ofc, its intended for exceotions defined like this```py
class MyException(Exception):
"""docstring"""
from where did you learn to do this weird stuff
books
Lol this chat's dead
@broken mesa look at this beautypy print("".join((f"(?:{char}|{'|'.join(dict(file)[char])})+" if char in (file := __import__('yaml').safe_load(open('./normalize/letters.yml', encoding='utf-8'))) else char) for char in __import__("re").sub(r'(.)\1+', r'\1', str(input("Enter string>")))))
this is abusing python internals so much that i even have to use dict(file) when file is already a dict
@steel siren you shouldnt have to do that
i know i dont have to do that
but im abusing the internals so much that it thinks file is a string literal when it isnt
what does the error look like?
Hey @snow beacon!
It looks like you tried to attach a Python file - please use a code-pasting service such as https://paste.pythondiscord.com
I wrote a converter for making arbitrary code use only ten distinct characters, \evaln(')%. https://paste.pythondiscord.com/ahitadomex.py However, it takes a long time and a lot of memory for programs with too many characters (more than 11 or 12).
I've done it in an atrocious way, by nesting evals inside each other and using a single % string format each level of nesting. I forgot that I could just escape the percentage signs and repeatedly string format, which would probably solve the exponential growth, but would be more work for me.
Hanging out in this room is the closest I purposely come to the aphorism about, "We do what we do as a warning to others." 😉
>>> eval(fix('lambda:1'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
File "<string>", line 1, in <module>
File "<string>", line 1, in <module>
[Previous line repeated 7 more times]
NameError: name 'lambdaǑ' is not defined``` @snow beacon 👀
It breaks for colons then. I haven't bothered to test it, given any test case longer than print("hi") is likely to fail.
based
what's fix?
In the haste bin link
ah
def fix(code):
return 'exec(' + '+'.join(['chr(len(\'' + 'l'*ord(c) + '\'))' for c in code]) + ')'
print(fix(input('Code? ')))```
Eleven characters or so? That is so much cleaner than my approach.
(Not meant as a bad thing.)
Lmao only in this channel is having cleaner code worse
sup fam'
you can tell i hang around here too much...
it's starting to affect my pc :>
Some letters aren't even printing anymore.
They've just had enough of the torture I'm putting them thru :/
>>> print('testing')
testing
>>> print('e')
e
>>> 'e'==' '
False
>>> print('\x1b[32mae')
ae
>>> print('\x1b[31m')
>>> MUCH ERROR
File "<stdin>", line 1
MUCH ERROR
^
SyntaxError: invalid syntax
>>>
KeyboardInterrupt
>>>
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
>>>
don't ask how I managed that. It's advanced python hackery.
~/brainfuck-bot$ python
Python 3.8.8 (default, Feb 20 2021, 21:09:14)
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.import os
os.system("\x1b[32m")
sh: 1: : not found
32512KeyboardInterrupt
if i mess with colouring enough i might even be able to get l447h4xx0r graphics
whos i ping for breakings of fishhook module?
was it chilaxin?
cos i did it :>
got a SEGFAULT from hooking __truediuv__ to type and then running an asynchronous event loop
exit code 139
iirc
https://github.com/chilaxan/fishhook You can put it in an issue.
I overwrote the code cos it no worky lol
But the thing I changed to prevent the segfault was removing the hook on type then not importing the module since I was no longer using it
And the segfault happened when I ran the event loop
I just realised ii don't need recursion to parse square brackets in brainfuck
foo=function(p,code){
._=1
while(._>0)if(is.na(code[(p=p+1)]))(stop("Invalid Syntax: ["))else if(code[p]=='[')(._=._+1)else if(code[p]==']')(._=._-1)
returnValue(p+1)
}
bar=function(p,code){
._=1
while(._>0)if(is.na(code[(p=p-1)]))(stop("Invalid Syntax: ]"))else if(code[p]==']')(._=._+1)else if(code[p]=='[')(._=._-1)
returnValue(p+1)
}
'['=if(a[i]==0){(pointer=foo(pointer,code))}
']'=if(a[i]!=0){(pointer=bar(pointer,code))}
isn't exactly python but it shows the algorithm :>
just wanna show off something ive been working on over the past week: this is my fork of the reloading library, which abuses ast to live-reload code while its running. At this point i've basically rewritten the whole thing.
https://github.com/laundmo/reloading/blob/master/reloading/reloading.py
there's a lot of function pairs in brainfuck
noice can i abuse it to make a switch case otherwise suite with annotations?
were you talking to me? not sure how thats related.
live reloading but editing the reloaded code so...
switch: value
is normal, sets annotations['switch'] to value which can be accessed...
but then i want to abuse frame code to make
case[a]: code
evaluate the code if value==a
and
otherwise: more_code
to execute more_code
i'm willing to use a switchend() which is what I've done so far
or i've done an expression version that inputs function handles or you can insert lambda: before the code
hmm, they way the library works is with parsing the source file as ast, stripping it of all unrelated ast branches and execing that
it works as a function decorator or loop wrapper
so i think what you would want inst really possible
You can use irrefutable patterns in matching but that's of course not very useful
