#esoteric-python

1 messages · Page 107 of 1

rugged sparrow
#

the structure looks like this -> py typedef struct { Py_ssize_t ob_refcnt; PyObject *ob_base; Py_ssize_t ob_size PyObject **ob_item; Py_ssize_t allocated; } PyListObject; where ob_item is actually a pointer to a py_object array (like how tuples are implemented) that is allocated items long

grand urchin
#

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.

rugged sparrow
#

oh well yea thats just due to how python handles objects in general

grand urchin
#

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...

▶ Play video
rugged sparrow
#

@grand urchin you can write stuff like that without any imports

#

if you abuse LOAD_CONST you can load arbitrary py_objects

grand urchin
#

Of course, Joe Jevnik, and I did similar about three years ago with poisoned bytecode on LOAD_ATTR out-of-bounds

rugged sparrow
#

LOAD_ATTR has an out of bounds too?

grand urchin
#

We never got around to direct generation of poisoned bytecode with extended operands, but I thought his “splayed coroutine” approach was quite clever.

rugged sparrow
#

i actually did use extended operands when i messed with LOAD_CONST

grand urchin
#

Actually, that above was LOAD_FAST not LOAD_ATTR

rugged sparrow
#

!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)))```

night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

1
grand urchin
#

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.

rugged sparrow
#

i believe because they wanted to encourage modification of code objects without requiring a full manual reconstruction

bitter iris
#

It is not actually for encouraging but rather not breaking whenever they add an attribute.

grand urchin
#

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.

bitter iris
#

They added it literally because some code was broken after co_posonlyargs

grand urchin
#

@bitter iris is there dynamic code construction in the standard library via types.CodeType or similar patching?

bitter iris
#

An assembler? No

#

There is like bytecode library from victor stinner

grand urchin
#

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.

bitter iris
#

let me find the issue, one min

grand urchin
#

“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.

bitter iris
#

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

grand urchin
#

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.

bitter iris
#

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?

grand urchin
#

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

www.pydata.org

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...

▶ Play video
bitter iris
#

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])

grand urchin
bitter iris
#

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)

grand urchin
# bitter iris There is already a big division between CPython and alternate implementations. T...

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 ...

▶ Play video
grand urchin
grand urchin
#

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.

vague cairn
#

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?

twilit grotto
#

the cpython implementation of sets is not related to the implementation of dicts

vague cairn
#

Oh, alright, well they used to be.

twilit grotto
#

really?

vague cairn
#

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.

floral meteor
#

@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...

rugged sparrow
#

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

floral meteor
#

jumps?

rugged sparrow
#

Yea in bytecode (and assembly) there's a concept where you can jump to a new location of code

floral meteor
#

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?

rugged sparrow
#

!e py from dis import dis dis("if(a):print(1)")

night quarryBOT
#

@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
rugged sparrow
#

@floral meteor yea

#

But messing with bytecode at runtime like that really isn't stable

floral meteor
#

stability isn't esoteric :>

snow beacon
#

You could make one of those site packages that parses Python in advance.

floral meteor
#

starting to sound like i should just throw a lambda in there...

#

print and input are lame when you have this

fluid tree
vague cairn
#

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")

snow beacon
#

I don't think it parses.

vague cairn
#

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")

night quarryBOT
#

@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

vague cairn
#

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.

snow beacon
#

The code objects will have different co_args etc.

#

And it's never too late to decorate.

vague cairn
#

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

snow beacon
#

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.

vague cairn
#

you mean elif ?

snow beacon
#

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.

vague cairn
#

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...

proper vault
#

good news, in just a bit, there will be a python release with pattern matchign

twilit grotto
#

just a bit?

proper vault
#

why not just with case(a)

#

its implemented

#

it just needs a ton of testing and waiting for a release

vague cairn
#

but it doesn't let me inject Exceptions into the with block rather than in the case code.

proper vault
#

ah

#

could do as []

vague cairn
#

Maybe... but it would still be less apealing than with case(a):

sick hound
#
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?

vague cairn
#

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.

sick hound
#

thanks

dire yew
fluid tree
vague cairn
#

nods then I'm laying 9::1 odds that it qualifies as code gore. 😉

dire yew
vague cairn
#

... Sure, If it makes you happy.

sick hound
#

!e

night quarryBOT
#

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:

https://paste.pythondiscord.com

sick hound
#

bruh cringe

#

idk here

sick hound
#
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"))```
sick hound
#

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('\\"))```
sick hound
#

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('\\"))```
floral meteor
#
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

cloud garden
#

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?

tribal moon
floral meteor
#

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()
dreamy spire
#

yo what is my python professor doing?

floral meteor
#

That is highly inelegant

drifting grove
#

It does kind of look like a bunch of those for loops could be on the same line though...

For maximum beautiful code

steep mural
floral meteor
#

tell him use itertools or go home

terse mortar
#

na just make him use a oneliner

floral meteor
#

not just one line, one expression

terse mortar
#

ehh fuck it, this belongs here

jaunty creek
#

oof

floral meteor
#

okay im gonna chuck off at that with an expanded form of 4D Conway's Game of Life

cloud garden
fading monolith
#

lol look at that looks like some ascii art

floral meteor
#

where?

floral meteor
#

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(
)

night quarryBOT
#

@floral meteor :x: Your eval job timed out or ran out of memory.

[4, 3, 2, 7]
floral meteor
#

...

#

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...

thin trout
#

I was about to say what on earth in this, but then I realized which channel I clicked on

floral meteor
#
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

fluid tree
fluid tree
idle island
fluid tree
idle island
#

oh

#

have javascript instead-

hollow kiln
#

Lots of esoteric ppl here

#

👀

vague cairn
# floral meteor wait how do you make a context manager?

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

late burrow
#

Adding type hints to context managers can be tricky though

toxic jewel
#
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

austere surge
#

oh my god

verbal totem
#

What is worse: more unnecessary lines or everything on one or two lines?

proper vault
#

the latter

floral meteor
#

The former

floral meteor
proper vault
#

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
#

.

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

<__main__.AwkwardSilence.f object at 0x7f7c9f261fd0>
floral meteor
#

Awww

proper vault
#

replace __qualname__

floral meteor
#

!e ```py
class AwkwardSilence:
class f:name=".."
AwkwardSilence.f.qualname=".."
print(repr(AwkwardSilence.f()))

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

<__main__... object at 0x7fd7297f0fd0>
floral meteor
#

Awww

proper vault
#

!e

__name__ = ''
class AwkwardSilence:
   class f:__qualname__=".."
print(repr(AwkwardSilence.f()))
night quarryBOT
#

@proper vault :white_check_mark: Your eval job has completed with return code 0.

<... object at 0x7f6ad6020fd0>
fluid maple
#

!e
print(TOKEN)

night quarryBOT
#

@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
fluid maple
floral meteor
#

!e ```py
class AwkwardSilence:
class f:qualname=".."
AwkwardSilence.f.qualname=".."
print(repr(AwkwardSilence.f()))

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

<__main__... object at 0x7f71f0936fd0>
proper vault
#

@fluid maple if you want try and break the sandbox, do so in #bot-commands

floral meteor
#

@fluid maple that is run in snekbox hence is not run in the same environment as the bot

fluid maple
#

ah

floral meteor
#

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()

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

001 | ;-;
002 | __main__
floral meteor
#

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

vague cairn
#

Now you have me curious, what dunders do a module get?

floral meteor
#

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()

vague cairn
#

got it.

#

So can they be replaced back?

floral meteor
#

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

vague cairn
#

like py def __getattr__(self, attr): #bla bla _getattr = __getattr__ def please_call_after_import(): global __getattr__ __getattr__ = _getattr #etc

floral meteor
#

Why would you do that?

vague cairn
#

To undo the replacing of __getattr__ that import does?

#

to re-enable everything...

floral meteor
#

It's not the import that does it it's the module object

#

I'll show you how, hang on...

vague cairn
#

Ah!, alright got it.

floral meteor
#

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

vague cairn
#

!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__()

night quarryBOT
#

@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
astral rover
#

You can define two dunders for a module dir and getattr

#

Although I don't think they take self

floral meteor
astral rover
#

So that snippet posted might be valid

floral meteor
#

!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()

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

001 | ;-;
002 | __main__
floral meteor
#

You see?

#

That'll now work for any import that has dunders in globals

vague cairn
#

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__))

night quarryBOT
#

@vague cairn :white_check_mark: Your eval job has completed with return code 0.

foo
vague cairn
#

Yup

#

Nice one.

#

Now we just need.

floral meteor
#

!e
The bit in the middle is just to show it doesn't work

print(str(__import__('__main__')))
night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

<module '__main__' (built-in)>
floral meteor
#

Instead of foo in your case

#

Doesn't raise any error it's just wrong

vague cairn
#

Fair.

floral meteor
#

!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!"

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

Hello World!
vague cairn
#

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.

floral meteor
#

should make that a built-in hint hint nudge nudge pydevs

rugged sparrow
#

!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_ubyte
5).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)```

night quarryBOT
#

@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

rugged sparrow
#

^ the internal interned string dictionary

floral meteor
#
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 :>

night quarryBOT
#

@rugged sparrow :warning: Your eval job timed out or ran out of memory.

[No output]
rugged sparrow
#

👀 whoops

floral meteor
#

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)

night quarryBOT
#

@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']
simple crystal
#
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

floral meteor
#

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

simple crystal
#

can't you just subclass ndarray?

floral meteor
#

huh tru

#

im

#

dum

simple crystal
#

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

floral meteor
#

!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')

night quarryBOT
#

@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
simple crystal
#

gotta def __bool__(self): no?

#

idk maybe a lambda works

floral meteor
#

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

simple crystal
#

I just don't k ow if you can define dunders in class body

#

ah you can

floral meteor
#

!e ```py
class w:
gt=print
str=lambda s:"Hello"
w() > "World!"

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

World!
floral meteor
#

huh it didn't pass self

#

to gt

#

huhhhhh

simple crystal
#

interesting

hard spoke
#

!e

class w:
  __gt__=print
  __repr__=lambda s:"Hello"
w() > "World!"
night quarryBOT
#

@hard spoke :white_check_mark: Your eval job has completed with return code 0.

World!
hard spoke
#

hmm, I knew it uses repr for container classes, but not sure what happened here.

floral meteor
#

i think we borke it

tribal moon
#

Is there a way to make like a variable have a "whitespace" character in it?

floral meteor
#

sure...

tribal moon
#

like not a unicode space 32 like some other special character

#

one that looks like a space, but isn't

simple crystal
#

!e

class f:
    __eq__ = lambda s, x: print(s, x)

g = f()
g == 'test'
night quarryBOT
#

@simple crystal :white_check_mark: Your eval job has completed with return code 0.

<__main__.f object at 0x7f9edd460fd0> test
tribal moon
#

Somewhere between chr(8190) and chr(8200)

floral meteor
#

!e ```py
globals().update({"a\tb":4})
print(globals()['a\tb'])
print(dir())

tribal moon
#

not like that though

night quarryBOT
#

@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']
floral meteor
#

that's a variable name with whitespace in it :>

tribal moon
#

!e py for i in range(8190, 8200): print(f"Special Character {i} : '{chr(i)}'")

night quarryBOT
#

@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 : ' '
tribal moon
#

one that can be referenced without globals

#

it can be defined with globals, but it should be something like ```py

value```

#

something like that

floral meteor
#

!e ```py
class stdout:
eq=print
stdout() == "hehe Im dum"

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

hehe Im dum
simple crystal
#

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'
night quarryBOT
#

@simple crystal :white_check_mark: Your eval job has completed with return code 0.

(<__main__.f object at 0x7faca57e1fd0>, 'test')
floral meteor
#

!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 :>"

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

<class '__main__.MetaStupid'> ImDum () {'__module__': '__main__', '__qualname__': 'ImDum'}
simple crystal
#

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

floral meteor
#

I made a whole module to do

std << "some string"
std <= "Error"
std < File("filename")
exit << 0

etc...

simple crystal
#

haha nice

#

you can overload bitshift eh

#

never realized that

#

learning so many USEFUL FACTS today

rugged sparrow
#

@floral meteor you could still mod the __bool__ method

#

Just need to use ctypes

floral meteor
#

:>

tribal moon
#

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?

floral meteor
tribal moon
#

What do those bytecode things mean?

simple crystal
#

omg I could even have p<object print the name of the object variable if it doesn't exist so I could skip quotes

tribal moon
#

and why are you slicing instructions by half of index + 1

simple crystal
#

so ridiculous

tribal moon
#

because that makes something = Array<int>(1, 2, 3) valid

#

but how?

rugged sparrow
#

basically Array.__lt__ is called when the interpreter hits Array<int

floral meteor
#

@simple crystal this is a peek of my cursed module

#

I only use def if i need to use try

rugged sparrow
#

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 ^

simple crystal
#

lol nice

#

if I was a recruiter and saw that on ur github, hired on the spot

tribal moon
#

And you learned how to do all of this in your free time?

rugged sparrow
#

@floral meteor what class do you need to shim __bool__?

#

yea

#

@simple crystal look up chilaxan/fishhook on github

simple crystal
#

Im walking to store rn but will when I'm back home

floral meteor
#

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): ...
tribal moon
#

try making Java in Python

rugged sparrow
#

@floral meteor what class was it that you wanted to shim bool on

rugged sparrow
#

dope gimme a min

tribal moon
#

so like ```
public+static+void+"Main"+(String[]+args)+{
stufff

simple crystal
#

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

tribal moon
#

it'd be awesome

floral meteor
#

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')

night quarryBOT
#

@floral meteor :warning: Your eval job has completed with return code 139 (SIGSEGV).

[No output]
floral meteor
#

hehehehe

#

that crashed python on my pc

#

no error just exit

#

what is SIGSEGV?
that's not very verbose

earnest wing
#

segfault

floral meteor
#

what is a segfault?

#

did i borke python?

earnest wing
#

patching things through cpython gets of rid of stability guarantees

floral meteor
#

i borke python :>

earnest wing
#

!e ```py
import ctypes
ctypes.string_at(0)

night quarryBOT
#

@earnest wing :warning: Your eval job has completed with return code 139 (SIGSEGV).

[No output]
earnest wing
#

pretty simple

rugged sparrow
#

!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)))```

floral meteor
#

i borke python, u borke python, everyone broke python

night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

True
rugged sparrow
#

@floral meteor ^ that swaps out the original __bool__

simple crystal
#

nice

floral meteor
#

noice...
does it return False when the array is "unsized"?

rugged sparrow
#

not currently

simple crystal
#

I've got some crazy ideas for this module now but I have to make dinner

rugged sparrow
#

but you can just modify the lambda to have the correct operation

floral meteor
#

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

simple crystal
#

can only catch SyntaxErrors if you wrap the whole program in exec >_> hmmmmm

rugged sparrow
#

thats due to syntax errors being raised as code is compiled not as it is ran

simple crystal
#

but if I write a module that can wrap the whole program in exec......

floral meteor
#

it'd need to be executed before the rest of the code is compiled

simple crystal
#

or it can rewrite the module and then execute that maybe?

floral meteor
#

!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]])))

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

001 | .
002 | True
floral meteor
#

:>

simple crystal
#

lol my gf wants dinner I just wanna do stupid things

#

bbl

rugged sparrow
#

@floral meteor use fishhook its more stable

floral meteor
#

pip install fishhook?

rugged sparrow
#

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)

floral meteor
#

!e import fishhook

night quarryBOT
#

@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'
rugged sparrow
#

its not on the bot 😦

floral meteor
#

you want me to test fishhook for borke python?

#

:>

rugged sparrow
#

it shouldnt break

floral meteor
#

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']
rugged sparrow
#

it imports everything from ctypes

floral meteor
#

...

#

unproffessional keeping it in globals

rugged sparrow
#

¯_(ツ)_/¯

#

im working on making it fully native (ie not needing ctypes)

floral meteor
#

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
>>> 
rugged sparrow
#

it should work for any class

floral meteor
#

and it transmits to all instances of that class already existing :O

rugged sparrow
#

i also wrote a function orig that calls the original implementation of the function automatically

floral meteor
#

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

rugged sparrow
#

you can also do py fishook.hook(print.__class__, name='__lshift__')(lambda s,f:s(f))

floral meteor
#

hehe you gave a clue how to borke it

rugged sparrow
#

did i?

floral meteor
rugged sparrow
#

orig just wont do anything except raise an exception outside a hooked function

floral meteor
#

RuntimeError

rugged sparrow
#

ya

#
>>> @hook(int)
... def __matmul__(self, other):
...     return self, other
... 
>>> 1@2
(1, 2)
>>> ```
floral meteor
#

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?
rugged sparrow
#

in theory

#

that will be more complex to implement tho

floral meteor
#

show me :>

rugged sparrow
#

nah i prefer the bytecode hackery

#

its better imo

floral meteor
#

:<

rugged sparrow
#

you can try to implement it

#

but you'll run into a major issue

floral meteor
#

Borke python?

rugged sparrow
#

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

snow beacon
#

The first half, at least.

#

Maybe with a global variable set when Array<int is called, that int>(1,2,3) reads?

floral meteor
#

and does not have to return a boolean

rugged sparrow
#

oh i was thinking about in

floral meteor
#

!e print(1 and "Hello World!")

night quarryBOT
#

@floral meteor :white_check_mark: Your eval job has completed with return code 0.

Hello World!
snow beacon
#

bool is called on the first part.

floral meteor
#

bool(1)

#

so Array<int has to return something truthy

#

ooh ik!

rugged sparrow
#

@snow beacon is correct a global var would work

floral meteor
#

Array<int will hook int

#

then int<args will pipe the args to the Array init

snow beacon
#

Or it could store data in the int class somehow.

floral meteor
#

don't need globals

#

dont need to store in int class

rugged sparrow
#

however what will happen if i just did Array<int

floral meteor
#

then that would curse int

rugged sparrow
#

or just int>(1,2,3)

floral meteor
#

put the fishooks inside the methods

#

just int>(1,2,3) would not have been pre-hooked

snow beacon
floral meteor
#

:>

#

imma write up what im talkiong about

rugged sparrow
snow beacon
#

!e ```python
print(int < (1, 2, 3))

night quarryBOT
#

@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'
snow beacon
#

As you can see, it's not normally supported.

rugged sparrow
#

true but what would it do after type.__gt__ is hooked?

snow beacon
#

I don't recall what sort of object Array<int> was meant to be.

rugged sparrow
#

its java-like template syntax

snow beacon
#

Then some representation of a template object applied to the argument.

rugged sparrow
#

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

floral meteor
#
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)
rugged sparrow
#

type.__class__ is type

floral meteor
#

k

#

does it work?

rugged sparrow
#

nope

#

it sets int.__gt__ so 1 > obj

floral meteor
#

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

rugged sparrow
#
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
floral meteor
#

But...
It doesn't assert

rugged sparrow
#

wont work for HashMap<(str, int)>{} tho

#

*it might work, but its a hack that it does

floral meteor
#

We cans make it works easy

rugged sparrow
#

the bytecode is more elegant then passing around random references inside function closures

#

imo

floral meteor
#

It's just that my laptop is about to die so I'm on phone now

simple crystal
#

ok done with dinner time to try some black magic

floral meteor
#
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) 
simple crystal
#

..fishhook can overwrite built-in class dunders?

#

neato

floral meteor
#

it can dunderise the class class itself

#

:>

#
...     return list(args) 
  File "<stdin>", line 8
    return list(args) 
                     ^
SyntaxError: invalid non-printable character U+200A
twilit grotto
#

!charinfo return list(args)

#

!charinfo

night quarryBOT
#
Missing required argument

characters

twilit grotto
#

lol what

#

!charinfo " "

night quarryBOT
earnest wing
#

U+200x is used for all sorts of whitespace
as well as whitespace-esque non-whitespace chars

simple crystal
#

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__']

simple crystal
#

okay so how can I get a class to return a function as itself

#

without calling it

snow beacon
simple crystal
#

returns the function

snow beacon
#

So Class() = e.g. print?

simple crystal
#

yeah

#

but not called

snow beacon
#

Return return print from __new__?

simple crystal
#

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')
night quarryBOT
#

@simple crystal :white_check_mark: Your eval job has completed with return code 0.

test
simple crystal
#

ignore docstring

#

was doin something else haha

snow beacon
#

Metaclass? You can do ```py
class MyClass:
def new(cls):
return print

simple crystal
#

let's try it

snow beacon
#

Oh, I see.

simple crystal
#

!e

class P():
    """Prints with p>, """
    def __new__(self, *args):
         return print

P('test')
night quarryBOT
#

@simple crystal :warning: Your eval job has completed with return code 0.

[No output]
simple crystal
#

__new__ is only called on instantiation

snow beacon
#

Yes, a metaclass looks like the way to go there, although the mesaclass shouldn't need any particular __new__.

simple crystal
#

yeah lots of fluff from other experiments

#

hmmm can I define __lt__ for the uninstantiated class?

snow beacon
#

Again, in the metaclass.

simple crystal
#

!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'

night quarryBOT
#

@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'
simple crystal
#

tried a few things

snow beacon
#

That's the instantiated class.

simple crystal
#

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'
night quarryBOT
#

@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'
snow beacon
#

__lt__ should take two arguments.

simple crystal
#

oh and I have __new__ defined

snow beacon
#

That would be why, I forgot.

simple crystal
#

this is some esoteric stuff haha I'm pretty lost

#

I thought i kinda "got" metaclasses before

#

ooh I know I think

snow beacon
#

__new__ means "instead of whatever would be instantiated, return this thing instead". So P is print.

simple crystal
#

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'
night quarryBOT
#

@simple crystal :white_check_mark: Your eval job has completed with return code 0.

t
simple crystal
#

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

snow beacon
#

!e ```python
class SelfInit(type):
def lt(self, other):
return print(other)

class P(metaclass=SelfInit):
pass

P < "t"

night quarryBOT
#

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

t
simple crystal
#

ahhhh nice

#

ty

#

!e

class p(metaclass=type('p', (type,), {'__lt__':print})):
    """Prints with p<"""
p < 'test'
night quarryBOT
#

@simple crystal :white_check_mark: Your eval job has completed with return code 0.

test
simple crystal
#

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

snow beacon
simple crystal
#

!e

p = type('p', (type,), {'__lt__':print})("p", (), {})
p < "test"
night quarryBOT
#

@simple crystal :white_check_mark: Your eval job has completed with return code 0.

test
simple crystal
#

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

fiery hare
#

@simple crystal Guido reading this channel ^

simple crystal
#

lol he will be proud when my module is finished

#

it will be pure black magic

fiery hare
#

Woah

simple crystal
#

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

floral meteor
#

^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
night quarryBOT
#

@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
floral meteor
#

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

night quarryBOT
#

@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__'
floral meteor
#

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

night quarryBOT
#

@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__'
floral meteor
#

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.

simple crystal
#

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

floral meteor
#

same

#

I could use exit.class instead of _sitebuiltins.Quitter

#

;)

simple crystal
#

that's the spirit

simple crystal
#
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

simple crystal
#

can you run a function from imported module in importing module in import statement?

snow beacon
#

No.

simple crystal
#

cuz then you wouldn't have to actually call or even specifically import p

#

damn thought so

snow beacon
#

Well, sort of.

#

You can't import the file while it's being run, but importing runs the file.

simple crystal
#

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

rugged sparrow
toxic jewel
#

!e

cout = type('p', (type,), {'__lshift__':print})("p", (), {})
cout << "test"
night quarryBOT
#

@toxic jewel :white_check_mark: Your eval job has completed with return code 0.

test
toxic jewel
#

c++

simple crystal
#

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

simple crystal
#

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

rugged sparrow
#

you could use a file encodeing handler to run your code on the module before the module is compiled

simple crystal
#

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

rugged sparrow
#

!e py cout = type('p', (), {'__lshift__':print})() cout << "test"

night quarryBOT
#

@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.

test
thin trout
simple crystal
#

...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

fluid tree
simple crystal
#

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
simple crystal
#
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

toxic jewel
#
cout = type('cout', (type,), {'__lshift__':print})("cout", (), {})
cin = type('cin', (type,), {'__rshit__':input})("cin", (), {})
cout << "test";
cin >> "test: "
#

not exactly like c++ but whatever

simple crystal
#

I hate cout <_< prefer printf when I can get away with it

floral meteor
# floral meteor
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

toxic jewel
simple crystal
#

real shit

floral meteor
#

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?

floral meteor
#

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 :>

simple crystal
#

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

floral meteor
#

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.

fluid tree
#

I wonder if you can make -> in python...

simple crystal
#

would need to code it in C I think because it'll raise a SyntaxError on compile

fluid tree
stark fable
#

you can have it going the other way

#

<-

#

idk if you can make -> work though

snow beacon
#

=>?

stark fable
#

it looks like that doesn't work, the = needs to be second

#

you can use <= as another backwards arrow though beecloseloaf

fluid tree
#

I got it

#

Use a chinese or korean character

#

Loads of them look like -

frigid wharf
#

you can have ー>

snow beacon
#

That also looks like a syntax error.

#

Oh, never mind, that's a letter.

dusky dagger
sudden osprey
earnest wing
#

At some point I'd like to use this trick to mislead readers :>

@callable
def foo(n: int) -> str:
  return "foo" * n
snow beacon
#

I have an uncanny desire to steal that.

dusky dagger
thin trout
dusky dagger
#

nope

thin trout
#

Hmm

#

Do you use a VPN?

dusky dagger
#

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.

proper vault
#

fuckitpy just uses that as the version

thin trout
#

Hahaha, okay

dusky dagger
#

also if their coverage is 110% and their downloads are 1.1M/month I don't expect the versioning to be real

stark fable
#

...is that version 5.3.1 or version 1.3.5 beethinking

rugged sparrow
#

Theoretically if you modify pythons internal symbol table you can do anything with syntax

#

I'm still working on that tho

bitter iris
rugged sparrow
#

@bitter iris can you point me in the direction of the easier ways?

#

Or is that stuff like brm?

bitter iris
#

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)

rugged sparrow
#

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)

bitter iris
#

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(...))
stone bane
#

Which python version introduced the new parser?

bitter iris
#

3.9

#

All we could have wanted was though PEP 511

fluid tree
#

Is it possible to make something implicitly become lazy (genexpr or lambda or anything)

proper vault
#

generators are always lazy

#

not sure what a lazy lambda would be

toxic jewel
#

probably something along the lines of (lambda: "esoteric python")()

fluid tree
toxic jewel
#

!e print(().__dir__())

night quarryBOT
#

@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__']
fluid tree
#

My point is, i want to input normal code and get something lazy

my_function(print(123)) returns lamda that prints 124

toxic jewel
#

what does getitem do?

fluid tree
toxic jewel
#

oh

tribal moon
#

__getitem__ is the slicing thing

#

[0:0:0]

proper vault
#

@fluid tree that is more or less impossible without changing the python compiler

toxic jewel
#

().__setattr__('__lt__', '__gt__')

fluid tree
#

What's the shortest way of doing it, then?

toxic jewel
#

type('', (), {}) creates a class right

fluid tree
#

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: ???

toxic jewel
#
_open = type('', (), {'__rshift__':open})()

_open >> ""
earnest wing
vale pike
#

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

earnest wing
#

You could do something with variable annotations under the __future__ import, but it's not exactly "first-class" lazy evaluation

earnest wing
#
from __future__ import annotations # except py3.10
x: lazily_evaluated

get("x") # evaluates x, which in this case is a name error
vale pike
#

I’m née go coding

#

So I don’t know much

#

@tribal moon

snow beacon
#

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.

tribal moon
#

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!

night quarryBOT
#

@floral meteor :warning: Your eval job has completed with return code 0.

[No output]
snow beacon
#

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

floral meteor
#

I do considered giving it a @callable decorator

snow beacon
#

That would break it.

fiery hare
#

@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.

earnest wing
#

@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
night quarryBOT
#

@earnest wing :white_check_mark: Your eval job has completed with return code 0.

001 | Not yet evaluated!
002 | 10
003 | 10
simple crystal
#

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...

next flame
#

coughs in ast module

simple crystal
#

yeah but that's not ridiculous enough

earnest wing
simple crystal
#

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...

floral meteor
earnest wing
#

Sure

#

Actually, probably not

#

case[4]: ... is a valid statement but doesn't get collected into __annotations__

floral meteor
#

.

#

;-;

#

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?

#

:>:>:>:>:>:>

snow beacon
floral meteor
#

lol

floral meteor
#
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 :>

simple crystal
#

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

floral meteor
#

match case?

#

wait, that would work even if the annotation was an empty, string, i.e. execute blank....

snow beacon
earnest wing
#
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:
fluid tree
simple crystal
#

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

snow beacon
fluid tree
snow beacon
#

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)

simple crystal
#

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

wide delta
simple crystal
#

true

fluid tree
simple crystal
#

yeah it has a style for sure but why is functional programming worth it?

snow beacon
#

The right tool for the job, always.

snow beacon
simple crystal
#

ah makes sense

#

I'm interested in functional programming but mostly just to learn a new paradigm for fun

snow beacon
#

That's how I started.

#

First it was Scheme though; I bounced off Haskell.

simple crystal
#

I'm working towards a math and cs major tho so maybe haskall will be something I get into for a reason

snow beacon
#

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.

simple crystal
#

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

snow beacon
#

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.

simple crystal
#

lol I prefer to taste the forbidden fruit

#

rn I think python is top tier

snow beacon
simple crystal
#

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

snow beacon
simple crystal
#

...which makes it slow though

#

so I gotta dive deeper into faster stuff sometime

snow beacon
#

Python tries to accommodate everything (which makes esoteric programming easier), while other languages have opinions that some things should not be done.

simple crystal
#

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

snow beacon
#

It pins you to its philosophy with peer pressure rather than compiler restrictions.

simple crystal
#

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

snow beacon
#

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.

simple crystal
#

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

snow beacon
#

That's heresy in this channel.

simple crystal
#

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

snow beacon
#

Another comparison: C is to Rust what Python is to Haskell.

simple crystal
#

ah damn

#

so rust is beautiful and impractical too

snow beacon
#

Well, no, not really.

simple crystal
#

okay what's the analogy?

snow beacon
#

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.

simple crystal
#

true = True

#

there

snow beacon
simple crystal
#
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

snow beacon
#

Any args beyond the first are discarded? Why use *args at all rather than an argument with a default?

simple crystal
#

yeah I should fix that

snow beacon
#

I think though, whatever name you give your first parameter might shadow whatever would be passed to the exception, if that matters.

simple crystal
#

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

fluid tree
#

Btw the super() function is such a hack

#

And you can make it work outside classes 🌚

simple crystal
#
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

simple crystal
astral rover
#

!d super

simple crystal
#

on modules or something?

night quarryBOT
#
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)
astral rover
#

no you can use it with arguments

simple crystal
#

oh so just with classes defined in args

fluid tree
simple crystal
#

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

snow beacon
#

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.

simple crystal
#

ah neat

#

thanks!

snow beacon
#

You could store the old one in another attribute, but that seems equally indirect.

simple crystal
#

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

snow beacon
#

The attributes aren't stored in the closure, just the parameter.

#

It's a meaningless distinction, in a way.

simple crystal
#

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

simple crystal
#
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

toxic jewel
#

"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

snow beacon
fluid tree
simple crystal
sick hound
#

from where did you learn to do this weird stuff

thick adder
#

books

verbal totem
#

Lol this chat's dead

steel siren
#

@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

rugged sparrow
#

@steel siren you shouldnt have to do that

steel siren
#

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

rugged sparrow
#

what does the error look like?

steel siren
#

strange

#

i cant seem to replicate it

#

weird

night quarryBOT
snow beacon
#

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.

vague cairn
#

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." 😉

rugged sparrow
#
>>> 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  👀
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.

astral rover
#

In the haste bin link

sick hound
#

ah

#
def fix(code):
    return 'exec(' + '+'.join(['chr(len(\'' + 'l'*ord(c) + '\'))' for c in code]) + ')'

print(fix(input('Code? ')))```
snow beacon
#

Eleven characters or so? That is so much cleaner than my approach.

#

(Not meant as a bad thing.)

terse mortar
#

Lmao only in this channel is having cleaner code worse

fringe rune
#

sup fam'

floral meteor
#

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
32512

KeyboardInterrupt

#

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

snow beacon
rugged sparrow
#

@floral meteor what did you do?

#

*send the code that caused it if you can

floral meteor
#

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

floral meteor
#

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 :>

broken mesa
floral meteor
#

there's a lot of function pairs in brainfuck

#

noice can i abuse it to make a switch case otherwise suite with annotations?

broken mesa
floral meteor
#

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

broken mesa
#

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

floral meteor
#

aw

#

so how do i access the annotations to something i've getitemed?

earnest wing
#

You can use irrefutable patterns in matching but that's of course not very useful