#esoteric-python

1 messages · Page 130 of 1

snow beacon
#

Do you mean with dis.dis?

grave rover
#

yes and no
good luck with that because it's hell PainPeko

sick hound
#

how could u de obfusucate pyarmor?

grave rover
#

by hand

vast cargo
#

can i view whats on the stack?

#

i mean constants or whatever is pushed to the stack

#

how to view it?

#

is this the right channel to ask about disassembling python code?

cloud fossil
#

Yes.

proper vault
#

!e

import json
try:
    json.loads('')
except Exception as json:
    pass
print(json)
night quarryBOT
#

@proper vault :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 6, in <module>
003 | NameError: name 'json' is not defined
rugged sparrow
#

yea except blocks forcibly unload their exception instance

#

!e py import dis dis.dis(''' try:pass except Exception as e:pass ''')

night quarryBOT
#

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

001 |   2           0 SETUP_FINALLY            3 (to 8)
002 |               2 POP_BLOCK
003 |               4 LOAD_CONST               0 (None)
004 |               6 RETURN_VALUE
005 | 
006 |   3     >>    8 DUP_TOP
007 |              10 LOAD_NAME                0 (Exception)
008 |              12 JUMP_IF_NOT_EXC_MATCH    22 (to 44)
009 |              14 POP_TOP
010 |              16 STORE_NAME               1 (e)
011 |              18 POP_TOP
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/usamoyomiv.txt?noredirect

cloud fossil
#

Now I am curious about how does disassembled code of match look like

foggy thorn
#

Good afternoon: I have a question about a part of a code I'm working on. I'm trying to make sure that the the input() function needs to be inside the loop for this to work:

#

question != "bye"
while question != "bye":
question = input("What's your question?")
print("What kind of question is" + question + "?")

print("END OF GAME")

#

When I answer with "bye" without spacing it''ll display "END OF PROGRAM" however when I make a space between "What's your question?" and "bye" then it'll display "What kind of question is..." what am I doing wrong?

rugged sparrow
#

@sick hound ive made progress on allowing dynamic hooking of __doc__ and __name__ ```py

find_char_p(int, int.name.encode())
3
find_char_p(int, int.doc.encode())
22

#

(it would fail if __doc__ was equal to __name__)

#
def isvalidptr(addr):
    import os
    r, w = os.pipe()
    try:
        os.write(w, getmem(addr, 1))
        return True
    except OSError:
        return False
    finally:
        os.close(r)
        os.close(w)

def find_valid_ptrs(obj):
    omem = getmem(id(obj), sizeof(obj), 'P')
    for i, v in enumerate(omem):
        if isvalidptr(v):
            yield i, v

def find_char_p(obj, data):
    for idx, ptr in find_valid_ptrs(obj):
        if getmem(ptr, len(data)).tobytes() == data:
            return idx
``` it uses `os.write` to determine if a pointer can be read (to prevent segfaults)
grave rover
#

wait, os.write has protection for that?

rugged sparrow
#

Yeah the c write function has protection for it for some reason

#

I'm trying to find another code path to that function that doesn't require an import of os now

#

You also have to construct some object that has the buffer protocol that points to your address to test

#

getmem constructs a memory view

snow beacon
grave rover
#

meanwhile I've made 0 progress on that esopython guide I said I was gonna write

rugged sparrow
#

I just keep writing more things I'll need to document lol

grave rover
#

it's mainly like

#

where do I even start

#

what should be separate subjects

#

what knowledge should I assume the reader has

#

etc

snow beacon
rugged sparrow
fleet bridge
#

!e

import dis
dis.dis('''
match x:
  case 1: pass
  case 2 | 3: pass
  case int(): pass
  case _: pass
''')

night quarryBOT
#

@fleet bridge :white_check_mark: Your eval job has completed with return code 0.

001 |   2           0 LOAD_NAME                0 (x)
002 | 
003 |   3           2 DUP_TOP
004 |               4 LOAD_CONST               0 (1)
005 |               6 COMPARE_OP               2 (==)
006 |               8 POP_JUMP_IF_FALSE        8 (to 16)
007 |              10 POP_TOP
008 |              12 LOAD_CONST               4 (None)
009 |              14 RETURN_VALUE
010 | 
011 |   4     >>   16 DUP_TOP
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/subahukeve.txt?noredirect

grave rover
#

oh god I just remembered that that's a thing

#

yeah screw this disassembler thing

grave rover
#

how does it handle listcomps

#

cuz that's the part that made me give up

#

also that range() call looks off

#

oh are s and g kwonly params there

#

in that case I said nothing

royal sun
#

thats an assignment expression it returns and stores

rugged sparrow
#
def isvalidptr(addr):
    import os
    r, w = os.pipe()
    try:
        mem = getmem(addr, 1)
        os.write(w, mem)
        return len(mem) == 1
    except OSError:
        return False
    finally:
        os.close(r)
        os.close(w)``` @grave rover better `isvalidptr` (if it returns True, the address should be readable at least)
grave rover
#

nice

#

maybe add an optional size parameter just in case?

rugged sparrow
#

instead of just using 1?

#
def isvalidptr(addr, size=1):
    import os
    r, w = os.pipe()
    try:
        return os.write(w, getmem(addr, size)) == size
    except OSError:
        return False
    finally:
        os.close(r)
        os.close(w)```
bleak ermine
#

If you have an async function that returns a coroutine, can you await that function and await the returned value? basically a double await?

#

theoretically could you chain like 5 awaits that way

vast cargo
#

co_lnotab is gone in 3.10?

#

whats is its replacement?

grave rover
#

I think it's called co_linetable now

#

nice

shut trail
#

How does this work?

grave rover
#

and how do you handle indents

#

e.g. ```py
if x:
if y:
if z:
return 10
elif a:
print(20)
else:
raise Exception(30)

#

so when you hit a branching statement you just call disassembler() with indent level incremented?

#

how do you know from where to resume

shut trail
#

what is co_linetable for speaking of

grave rover
#

there's reljumps and absjumps

shut trail
#

How would you make a basic disassembler that just disassembles:

a = 2
#

I understand everythign except htis part:

    bytecode = list(zip(code_object.co_code[::2], code_object.co_code[1::2]))
night quarryBOT
#

@sick hound :white_check_mark: Your eval job has completed with return code 0.

a = 2
shut trail
#

ah

#

OH

#

step 2 is all instructions

#

1::2 is all opargs

#

Last question, what does 'a' do in compile?

#

ah

rugged sparrow
potent comet
vast cargo
rapid sparrow
#
void print_address_ranges(char *linetable, Py_ssize_t length, int firstlineno) {
    PyCodeAddressRange range;
    PyLineTable_InitAddressRange(linetable, length, firstlineno, &range);
    while (PyLineTable_NextAddressRange(&range)) {
        printf("Bytecodes from %d (inclusive) to %d (exclusive) ", range.start, range.end);
        if (range.line < 0) {  // no line number
            printf("have no line number\n");
        } else {
            printf("have line number %d\n", range.line);
        }
    }
} ```
#

that's the example from the PEP

#

my bad, those functions are not part of the API for some reason

rapid sparrow
#

so they're already committed to providing them in all future versions of cpython.. just wondering why not consider them API functions

grave rover
#

@snow beacon do you have any tips for writing guides for people who know basically nothing on a subject

snow beacon
sick hound
#

is there a module/lib that allow modifying bytecode without having to go through the whole process of importing types and creating the code object and function object and such

tacit cobalt
#

You don't need to import types?

#

!e ```py
def test():
pass

test.code = test.code.replace(co_code=b"t\x00d\x01\x83\x01S", co_consts=(None, "Hello, World!"), co_names=("print",))
test()

night quarryBOT
#

@tacit cobalt :white_check_mark: Your eval job has completed with return code 0.

Hello, World!
marsh void
#

from 3.8 onward, that is

tacit cobalt
#

You can still easily do it before 3.8

thin trout
#

why

tacit cobalt
thin trout
#

I guess it isn't a question suitable for this channel

rapid sparrow
#

it could be, right?

#

just for the record

#

nvm it does work on 3.9

thin trout
#

lol

rapid sparrow
#
>>> test.__code__.replace(co_code=b"t\x00d\x01\x83\x01S", co_consts=(None, "Hello, World!"), co_names=("print",))
<code object test at 0x5555c22b10, file "<stdin>", line 1>
>>> test();
Hello, World!
#

on 3.11 though:
ValueError: code: co_code is malformed

#

also 3.10 works

#

PyBytes_GET_SIZE(con->code) % sizeof(_Py_CODEUNIT) != 0 is true

#
$7 = 7
(gdb) p sizeof(_Py_CODEUNIT)
$8 = 2```
#

not sure why either of those would change. maybe it's just my build.

tacit cobalt
rapid sparrow
#

btw i checked 3.10 and the sizes are exactly the same, 7 and 2

#

but there's no _PyCode_Validate in 3.10

#

do i need to asssign

rapid sparrow
#

so the extra \x00 works in the other versions too

tacit cobalt
rapid sparrow
#

ohh, i see

#

noice

vast cargo
#
 11     >>   34 POP_TOP
             36 POP_TOP
             38 POP_TOP

 12          40 LOAD_GLOBAL              2 (c)
             42 CALL_FUNCTION            0
             44 POP_TOP
             46 POP_EXCEPT
        >>   48 POP_BLOCK

  6          50 LOAD_CONST               0 (None)
             52 DUP_TOP
             54 DUP_TOP
             56 CALL_FUNCTION            3
             58 POP_TOP

why the line number can decrease?

#
def x():
    with x:
        try:
            for x in x:
                a()
            b()
        except:
            c()
    d()

try disassemble this function using python 3.10

#
def x():
    with x:
        hello()
#

how about this function, it doesn't contain loop

restive void
#

The line number doesn't decrease there, though?

viscid nymph
restive void
viscid nymph
#

the line numbers in that snippet does decrease as well

  4           0 LOAD_GLOBAL              0 (x)
              2 SETUP_WITH              12 (to 28)
              4 POP_TOP

  5           6 LOAD_GLOBAL              1 (hello)
              8 CALL_FUNCTION            0
             10 POP_TOP
             12 POP_BLOCK

  4          14 LOAD_CONST               0 (None)
             16 DUP_TOP
             18 DUP_TOP
             20 CALL_FUNCTION            3
             22 POP_TOP
             24 LOAD_CONST               0 (None)
             26 RETURN_VALUE
        >>   28 WITH_EXCEPT_START
             30 POP_JUMP_IF_TRUE        17 (to 34)
             32 RERAISE                  1
        >>   34 POP_TOP
             36 POP_TOP
             38 POP_TOP
             40 POP_EXCEPT
             42 POP_TOP
             44 LOAD_CONST               0 (None)
             46 RETURN_VALUE
restive void
# viscid nymph the line numbers in that snippet does decrease as well ``` 4 0 LOAD_...

is that 3.10? In 3.9 it doesn't (or I'm doing something wrong):

  2           0 LOAD_GLOBAL              0 (x)
              2 SETUP_WITH              22 (to 26)
              4 POP_TOP

  3           6 LOAD_GLOBAL              1 (hello)
              8 CALL_FUNCTION            0
             10 POP_TOP
             12 POP_BLOCK
             14 LOAD_CONST               0 (None)
             16 DUP_TOP
             18 DUP_TOP
             20 CALL_FUNCTION            3
             22 POP_TOP
             24 JUMP_FORWARD            16 (to 42)
        >>   26 WITH_EXCEPT_START
             28 POP_JUMP_IF_TRUE        32
             30 RERAISE
        >>   32 POP_TOP
             34 POP_TOP
             36 POP_TOP
             38 POP_EXCEPT
             40 POP_TOP
        >>   42 LOAD_CONST               0 (None)
             44 RETURN_VALUE
rapid sparrow
#

one way the line number can go backwards, is if you are calling a function with several subexpressions as arguments, it will emit those line numbers first, then the line number with the original function call

#

a bunch of work went into emitting the corect sequence of line numbers for 3.10, so that's probably why there's a difference, iirc

vast cargo
#

i just need a function to encode/decode co_linetable

#
from struct import iter_unpack


def decode(code):
    curroff = 0
    endoff = 0
    currline = code.co_firstlineno
    for off, line in iter_unpack("BB", code.co_linetable):
        endoff += off
        currline += line
        yield curroff, endoff, currline
        curroff += off
#

this seems to work

vast cargo
vast cargo
#
>>> def x():
...     print(
...             a(),
...             b()
...     )
... 
>>> dis.dis(x)
  2           0 LOAD_GLOBAL              0 (print)

  3           2 LOAD_GLOBAL              1 (a)
              4 CALL_FUNCTION            0

  4           6 LOAD_GLOBAL              2 (b)
              8 CALL_FUNCTION            0

  2          10 CALL_FUNCTION            2
             12 POP_TOP
             14 LOAD_CONST               0 (None)
             16 RETURN_VALUE
#

I haven't implemented it in my program

night quarryBOT
#

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

esoteric
#

:incoming_envelope: :ok_hand: applied mute to @simple crystal until <t:1634967682:f> (9 minutes and 59 seconds) (reason: newlines rule: sent 23 consecutive newlines in 10s).

simple crystal
#

too esoteric for automod

sick hound
#
type pip install pyartificialintelligence
restive void
#

!e

class hello(**{"metaclass":type("",(type,),{"__new__":lambda*_:"world"})}):...
print(hello)
night quarryBOT
#

@restive void :white_check_mark: Your eval job has completed with return code 0.

world
restive void
#

Assignment when your equals key is broken

#

Shorter, but boring alternative (since 3.9):

@lambda _:"world"
def hello():ö
knotty delta
#

what's the challenge?

#

nvm

proper vault
#
globals().__setitem__('hello', 'world')
tacit cobalt
knotty delta
#
exec(f"globals()['hello'] {chr(61)} 'world'")
proper vault
#
def __getattr__(name):
    return 'world'
from __main__ import hello
knotty delta
#

!e
def getattr(name):
return 'world'
from main import hello
print(hello)

night quarryBOT
#

@knotty delta :white_check_mark: Your eval job has completed with return code 0.

world
knotty delta
#

o it worked

#

what does __getattr__ do

proper vault
#

module level getattr gets called when you import a name that is not defined in the module

knotty delta
#

ooo

prisma coral
#

Interestingly, to set other module level dunders, you have to reassign the entire class of the module itself

proper vault
#

ye, and even then it won't work all the time IIRC

import sys
class Mod:
        def __getattr__(self, name):
            return 'world'

sys.modules[__name__] = Mod()
from __main__ import hello
print(hello)
prisma coral
# proper vault ye, and even then it won't work all the time IIRC ```py import sys class Mod: ...

Oh that's cool. I was actually referring to something like this though:

# my_module.py
import sys
import types
class EditedModuleType(types.ModuleType):
    def __call__(self, func: types.FunctionType):
        def wrapper(*args, **kwargs):
            print(
                f"Running {func.__name__}({', '.join([str(arg) for arg in args]+[f'{k}={v}' for k,v in kwargs.items()])})"
            )
            func(*args, **kwargs)
        return wrapper
sys.modules[__name__].__class__ = EditedModuleType
# REPL
>>> @__import__("my_module")
... def f(a, b):
...     ...
... 
>>> f(1, b=2)
Running f(1, b=2)
shut trail
#

Speaking of, tampering with modules are pretty cool

#

!e

from sys import modules
from types import ModuleType

class Organize(ModuleType):
   hello_world = 1

modules["test"] = Organize

from test import hello_world
print(hello_world)
night quarryBOT
#

@shut trail :white_check_mark: Your eval job has completed with return code 0.

1
earnest wing
#

You can also

#

!e

import sys

class Evil:
  foo = 0
  @type.__call__
  class __all__:
    def __getitem__(self, key):
      return "foo"

sys.modules["evil"] = Evil()

from evil import *
print("hello? is there anyone there?")
night quarryBOT
#

@earnest wing :warning: Your eval job timed out or ran out of memory.

[No output]
marsh void
#

hahaha

#

beautiful

shut trail
#

Does it override the module's __all__ and therefore everything returns foo

golden finch
#

Hey, me again

golden finch
#

Also, how do I get the default arguments of a lambda?

golden finch
astral rover
golden finch
#

I'm not sure which dunder to reda

astral rover
#

so the same way using lambda.__defaults__

#

or just use inspect

golden finch
#

strange, it's None for me

#

weirder still

#

hmmm

#

I must be breaking something else

sly root
#
__import <<"os"
__import <<"tempfile"
__import <<"subprocess"
__import <<"ctypes" <(
 "addressof", 
 "c_int", 
 "cdll", 
 "create_string_buffer", 
 "CFUNCTYPE",
 "memmove"
)

__asm(c_int) <(
  "BITS 64",
  "mov rax, rdi",
  "add rax, rsi",
  "ret"
)```
#

Can't send the whole source because it's too big

earnest wing
earnest wing
sick hound
#

@sly root how many crimes have you commited in the python interpreter?

sly root
sick hound
#

Your insane bro.

sly root
#

idk but although in the inline assembler snippet, I used a method to create variables and run many functions sequentially and at the same time not get an error from python (for example, if you create a variable in a lambda, you get a syntax error)

sick hound
#

I just use exec("") if it gives error

#

But awsome job man

sly root
#
lambda_that_will_give_an_error = (lambda: b=3)

lambda_that_wont_give_an_error = (lambda a: ___e(a,'b',3)
sly root
rugged sparrow
#

i dont see any code there that resembles any of my snippets

#

and even if someone wanted to use that code that would be fine as long as they put a comment or something. I put it online to share it

floral meteor
#

same as above

#

also it looks too neat to be my code

dire lark
#

helo

sick hound
#

@dire lark o/ Hi!

dire lark
sick hound
#

Well @sly root you have interesting taste in repos. In a good way.

#

If that isn't cool to post just let me know, I'll delete it. It looked interesting to me.

thin trout
#

@sick hound let's not post nuker bot repositories in this server, or anywhere for that matter please

sick hound
#

@thin trout Thanks Akarys! Will do.

earnest wing
#

My snippets tend to expand to real projects

#

See: easy_z3, unibitmap

#

both are totally cursed and yet both serve a practical function

muted wolf
#

hey i want to learn to write obsfucated python code mainly to rickroll my friend. how can i get started? i am good at core python but still have lots to learn.

earnest wing
#

Here's a simple program I wrote for a code contest! As a challenge, try to reverse engineer it :)

muted wolf
earnest wing
#

Some of them are part of the algorithm.

#

Don't be fooled by linters!

muted wolf
muted wolf
earnest wing
#

Red herrings everywhere

#

Look around to find which parts are relevant

sick hound
#

@earnest wing # trolled eh? 😄

earnest wing
#

There's some really interesting python feature intersections at play there imo

sick hound
snow beacon
#

If anyone wants to cheat at the reverse engineering, my entry is a lot less ornamental.

grave rover
#

Who doesn't

snow beacon
#

I say "made" but I really need to finish the rest of it. Some other time.

#

After other things.

#

My "finish project wherewithal" budget is currently being diverted towards other ends.

rapid sparrow
#

i cheat and do

globals().__setitem__("v", val)
#

!e

l = lambda a: globals().__setitem__("a", a)

l(6)
print(f'{a=}')
night quarryBOT
#

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

a=6
rapid sparrow
#

like so. not the cleanest way to set a variable from a lambda,. I'm open to suggestions

#

lower memory consumption?

#

!e

import sys
l = lambda a: sys._getframe(1).f_locals.__setitem__("a", a)
l(6)
print(f"{a=}")
night quarryBOT
#

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

a=6
rapid sparrow
#

now if I could add a shorthand for that (without messing up the call stack) ...

#

!e

import sys
def setv(k, v): sys._getframe(2).f_locals.__setitem__(k, v)
l = lambda a: setv("a", 6)
l(6)
print(f'{a=}')
night quarryBOT
#

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

a=6
rapid sparrow
#

not bad, probably works in more places than globals()?

#

!e

import sys
def setv(k, v): sys._getframe(2).f_locals.__setitem__(k, v)

l1 = lambda: (l2(), a)[-1];
l2 = lambda: setv("a", 6)
print(f'{l1()=}')
night quarryBOT
#

@rapid sparrow :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 6, in <module>
003 |   File "<string>", line 4, in <lambda>
004 | NameError: name 'a' is not defined
rapid sparrow
#

why doesn't that work? 😦

#

i see why

#

!e

from sys import _getframe as gf
def setv(n, v, d=0): gf(2+d).f_locals.__setitem__(n, v)

l  = lambda: (l2(), a)[-1]
l2 = lambda: setv("a", 6, 1)
print(f'{l()=}')
night quarryBOT
#

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

l()=6
rapid sparrow
#

very cool @sick hound

rugged sparrow
#

that only works when f_locals is globals()

#

yes

#

in that code Null is actually just a singleton flag value

#

its not actually NULL but when it shows up it tells the code to actually write NULL

sly root
#

!e ```py
def __e(obj,n,v):obj[n]=v
def raise(e):raise e
e,,
,__c,__p,__if,__join=(lambda obj,n,v:setattr(obj,n,v)),(lambda ret,*argc:ret),(lambda *argc:0),(lambda obj,n:e(globals(),obj,{*obj,n:""})),(lambda obj:print(obj)),(lambda:[0]if __[1]else __[2]),(lambda a:[a[0],a[1]])
__import=type("import",(),{"init":lambda self:None,"lshift":lambda self,mod:(self,__e(self,"mod",mod),e(globals(),mod,import(mod))),"lt":lambda self,sub:(self,e(globals(),sub,getattr(import(getattr(self,"mod")),sub)))if type(sub)==str else[(self,e(globals(),sub,getattr(import(self.mod),sub)))for sub in sub]})()
include=type("include",(),{"init":lambda self:None,"lt":lambda self,file:exec(open(file,"r").read())})()
cf=type("cf",(object,),{
"init":(lambda self,c:
(None,
(
(___e(self,"tfile",___join(tempfile.mkstemp(".cpp","temp",os.getcwd()))),e(self,"source",getattr(self,"tfile")[1])),(open(getattr(self,"source"),"wb").write(c.encode("utf-8")),___e(self,"sts",subprocess.check_output(f'cat {getattr(self,"source")} | g++ -x c++ - ',shell=True)),__if(primt(subprocess.check_output("./a.out").decode('utf-8')),status==0,print(getattr(self,"sts"))))),os.unlink(getattr(self,"source"))))
})
__c=type("c",(),{
"init":lambda self:None,
"lt":(lambda self,c:
cf("\n".join([c+"\n" if c.endswith("{") else c
for c
in c])))
})()

__import <<"os"
__import <<"tempfile"
__import <<"subprocess"

__c <(
"#include <iostream>",
"",
"int main() {"
" std::cout << "Hello from C++" << std::endl;",
"}"
)```

night quarryBOT
#

@sly root :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 20, in <module>
003 |   File "<string>", line 12, in <lambda>
004 |   File "<string>", line 7, in <lambda>
005 |   File "/usr/local/lib/python3.10/tempfile.py", line 337, in mkstemp
006 |     return _mkstemp_inner(dir, prefix, suffix, flags, output_type)
007 |   File "/usr/local/lib/python3.10/tempfile.py", line 252, in _mkstemp_inner
008 |     fd = _os.open(file, flags, 0o600)
009 | OSError: [Errno 30] Read-only file system: '/snekbox/temp3ieav8cz.cpp'
sly root
#

nah

sly root
#

running it from mobile gives an error:

PermissionError: [Errno 13] Permission denied: './a.out'```
#

cuz it's not rooted

sly root
#

idk if g++ is available on windows

#

but gcc is

sly root
#

-x to compile from stdin

#

c++ means c++ 🤓

#

replace > with |

#

my bad

#

hm

#

for me, it compiles without errors, but i can't run the a.out file

#
# author: Dimitriy i0x <annihilation.ga>
# feel free to modify or copy this code 
# but also specify credits (link to this repo or file)

def __e(obj,n,v):obj[n]=v
def __raise(e):raise e
___e,__,___,__c,__p,__if,___join=(lambda obj,n,v:setattr(obj,n,v)),(lambda ret,*argc:ret),(lambda*argc:0),(lambda obj,n:___e(globals(),obj,{**obj,n:""})),(lambda obj:print(obj)),(lambda*__:__[0]if __[1]else __[2]),(lambda a:[a[0],a[1]])
__import=type("__import",(),{"__init__":lambda self:None,"__lshift__":lambda self,mod:__(self,___e(self,"mod",mod),__e(globals(),mod,__import__(mod))),"__lt__":lambda self,sub:__(self,__e(globals(),sub,getattr(__import__(getattr(self,"mod")),sub)))if type(sub)==str else[__(self,__e(globals(),sub_,getattr(__import__(self.mod),sub_)))for sub_ in sub]})()
__include=type("__include",(),{"__init__":lambda self:None,"__lt__":lambda self,file:exec(open(file,"r").read())})()
__cf=type("__cf",(object,),{"__init__":(lambda self,c:__(None,___(___(___e(self,"tfile",___join(tempfile.mkstemp(".cpp","temp",os.getcwd()))),___e(self,"source",getattr(self,"tfile")[1])),___(open(getattr(self,"source"),"wb").write(c.encode("utf-8")),___e(self,"sts",subprocess.check_output(f'cat {getattr(self,"source")} | g++ -x c++ - ',shell=True)),__if(print(subprocess.check_output("./a.out").decode('utf-8')),getattr(self,"sts")==0,print(getattr(self,"sts"))))),os.unlink(getattr(self,"source"))))})
__c=type("__c",(),{"__init__":lambda self:None,"__lt__":(lambda self,c:__cf("\n".join([c_+"\n"if c_.endswith("{")else c_ for c_ in c])))})()


__import <<"os"
__import <<"tempfile"
__import <<"subprocess"

__c <(
  "#include <iostream>",
  "",
  "int main() {"
  "  std::cout << \"Hello from C++\" << std::endl;",
  "}"
)```
fixed
rapid sparrow
#

why couldn't you set a local anywhere in the stack

sly root
#
# author: Dimitriy i0x <annihilation.ga>
# feel free to modify or copy this code 
# but also specify credits (link to this repo or file)

def __e(obj,n,v):obj[n]=v
def __raise(e):raise e
___e,__,___,__c,__p,__if,___join=(lambda obj,n,v:setattr(obj,n,v)),(lambda ret,*argc:ret),(lambda*argc:0),(lambda obj,n:___e(globals(),obj,{**obj,n:""})),(lambda obj:print(obj)),(lambda*__:__[0]if __[1]else __[2]),(lambda a:[a[0],a[1]])
__import=type("__import",(),{"__init__":lambda self:None,"__lshift__":lambda self,mod:__(self,___e(self,"mod",mod),__e(globals(),mod,__import__(mod))),"__lt__":lambda self,sub:__(self,__e(globals(),sub,getattr(__import__(getattr(self,"mod")),sub)))if type(sub)==str else[__(self,__e(globals(),sub_,getattr(__import__(self.mod),sub_)))for sub_ in sub]})()
__include=type("__include",(),{"__init__":lambda self:None,"__lt__":lambda self,file:exec(open(file,"r").read())})()
__cf=type("__cf",(object,),{"__init__":(lambda self,c:__(None,___(___(___e(self,"tfile",___join(tempfile.mkstemp(".cpp","temp",os.getcwd()))),___e(self,"source",getattr(self,"tfile")[1])),___(___e(self,"f",open(getattr(self,"source"),"wb")),getattr(self,"f").write(c.encode("utf-8")),getattr(self,"f").close(),___e(self,"sts",subprocess.check_output(f'g++ -x c++ {getattr(self,"source")}',shell=True)),__if(print(subprocess.check_output("./a.out").decode('utf-8')),getattr(self,"sts")==0,print(getattr(self,"sts"))))),os.unlink(getattr(self,"source"))))})
__c=type("__c",(),{"__init__":lambda self:None,"__lt__":(lambda self,c:__cf("\n".join([c_+"\n"if c_.endswith("{")else c_ for c_ in c])))})()


__import <<"os"
__import <<"tempfile"
__import <<"subprocess"

__c <(
  "#include <iostream>",
  "",
  "int main() {"
  "  std::cout << \"Hello from C++\" << std::endl;",
  "}"
)```
fixed
#

idk how to make it work for windows

rapid sparrow
#

worked for me, I think

sly root
#

yes, but i forgot to os.unlink the a.out file

rapid sparrow
#

./a.out Hello from C++

#

what does the huge block do tho 😅

sly root
#

maybe it will be a problem if you will run it many times in a row

rapid sparrow
#

is it basically just doing echo "<source>" | g++ -x c++ -

sly root
#

there was also inline-assembly snippet but i can't run/test it because i don't have libc.so.6

#

btw thanks for helping me fixing inline-c

rapid sparrow
#

oh i see, there'a some DSL in there

night quarryBOT
sly root
#

i was closing it at the end

#

maybe there was problem in parens so it was closing at the moment when it was needed for g++

#

thx

rapid sparrow
#

__include isn't used?

sly root
rapid sparrow
#

it looked like it would be cool

sly root
#

it just reads the file and executes everything cuz there's no preprocessor

rapid sparrow
#

how annoying that there's no wsy to emit an executable with the same name that will work on both platforms

#

on linux a.exe works?

sly root
#

@sick hound I'll put your nickname at the top in the "# modified by "comment

#

okay

#

soo, i've pushed it to git

#

@rapid sparrow can you help me with inline-asm snippet?

#

need to know if its working

#

can't run it myself because i don't have libc.so.6

sick hound
#
    await ctx.send ("https://cdn.discordapp.com/attachments/884636730945314847/901406494111727666/IMG_7080.jpg")
    ^
IndentationError: unexpected indent
 
``` could someone help me please.
rapid sparrow
#

sure

sick hound
#

how do i fix the error?

rapid sparrow
#

I get FileNotFoundError: [Errno 2] No such file or directory: 'nasm'

rapid sparrow
sick hound
rapid sparrow
#

you want to unindent await

sick hound
#

I did.

#

It still shows that.

rapid sparrow
#

unless there's supposed to be the header of a function there

#

afaik await .... isn't a valid target for a decorator

sick hound
#
await ctx.send ("https://cdn.discordapp.com/attachments/884636730945314847/901406494111727666/IMG_7080.jpg")```
#

could you please fix it

#

i'm really new to coding.

#

srry.

rapid sparrow
#

you are missing a function def that would have the await ctx.send(...) in it

#

there's a different channel you should ask in though, #discord-bots

sick hound
#

ok

sly root
#

hmhmhm

#

oh i forgot

#

i need to pass 3 ret_types, not 1

#

replace __asm(c_int) with __asm(c_long, c_long, c_long)

#

then just c_long, c_long

#

@sick hound so, does it work?

sly root
#

where i can find libc.so.6 for termux?

#

i'll try to fix it

sly root
#

@sick hound ```py
import subprocess, os, tempfile
from ctypes import *

PAGE_SIZE = 4096

class AssemblerFunction(object):

def init(self, code, ret_type, *arg_types):
# Run Nasm
fd, source = tempfile.mkstemp(".S", "assembly", os.getcwd())
os.write(fd, code)
os.close(fd)
target = os.path.splitext(source)[0]
subprocess.check_call(["nasm",source])
os.unlink(source)
binary = open(target,"rb").read()
os.unlink(target)
bin_len = len(binary)

# align our code on page boundary.
self.code_buffer = create_string_buffer(PAGE_SIZE*2+bin_len)
addr = (addressof(self.code_buffer) + PAGE_SIZE) & (~(PAGE_SIZE-1))
memmove(addr, binary, bin_len)    

# Change memory protection
self.mprotect = cdll.LoadLibrary("libc.so.6").mprotect
mp_ret = self.mprotect(addr, bin_len, 4)   # execute only. 
if mp_ret: raise OSError("Unable to change memory protection")

self.func = CFUNCTYPE(ret_type, *arg_types)(addr)
self.addr = addr
self.bin_len = bin_len

def call(self, *args):
return self.func(*args)

def del(self):
# Revert memory protection
if hasattr(self,"mprotect"):
self.mprotect(self.addr, self.bin_len, 3)

if name == "main":
add_func = """ BITS 64
mov rax, rdi
add rax, rsi
ret
"""

Add = AssemblerFunction(add_func, c_int, c_int, c_int)
print(Add(1, 2))

#

does this work?

sly root
#

hmm

#

interesting

#

@sick hound I've got why there was an error

#

first c_int return type, and then two other c_ints are arg types

#

try __asm(c_int, c_int, c_int)

#

hm

sly root
rapid sparrow
#

LoadLibrary("") also works

#

then you might not require the clib to be libc.so.6

sly root
#

fixed all errors by rewriting the method🤓

#

!e ```py

author: Dimitriy i0x <annihilation.ga>

feel free to modify or copy this code

but also specify credits (link to this repo or file)

def __e(obj,n,v):obj[n]=v
def raise(e):raise e
e,,
,__c,__p,__if,__join=(lambda obj,n,v:setattr(obj,n,v)),(lambda ret,*argc:ret),(lambda *argc:0),(lambda obj,n:e(globals(),obj,{*obj,n:""})),(lambda obj:print(obj)),(lambda:[0]if __[1]else __[2]),(lambda a:[a[0],a[1]])
__import=type("import",(),{"init":lambda self:None,"lshift":lambda self,mod:(self,__e(self,"mod",mod),e(globals(),mod,import(mod))),"lt":lambda self,sub:(self,e(globals(),sub,getattr(import(getattr(self,"mod")),sub)))if type(sub)==str else[(self,e(globals(),sub,getattr(import(self.mod),sub)))for sub in sub]})()
__include=type("__include",(),{"init":lambda self:None,"lt":lambda self,file:exec(open(file,"r").read())})()

af=type("af",(object,),{"init":(lambda self,asm:(None,(__(___e(self,"tfile",___join(tempfile.mkstemp(".S","temp",os.getcwd()))),e(self,"source",getattr(self,"tfile")[1]),e(self,"f",open(getattr(self,"source"),"wb")),),(getattr(self,"f").write(asm.encode("utf-8")),getattr(self,"f").close(),),(___e(self,"sts",subprocess.check_output(f"nasm {getattr(self,'source')}",shell=True)),__if(print(subprocess.check_output(getattr(self,"source")[:-2]).decode("utf-8")),getattr(self,"sts")==0,print(getattr(self,"sts"))),),os.unlink(getattr(self,"source")))))})
__asm=type("__asm",(),{"init":lambda self:None,"lt":(lambda self,asm:__af("\n".join(asm)))})()

__import <<"os"
__import <<"tempfile"
__import <<"subprocess"

__asm <( """
global start
section .text

start:
mov rax, 0x2000004
mov rdi, 1
mov rsi, msg
mov rdx, msg.len
syscall
mov rax, 0x2000001
mov rdi, 0
syscall

section .data

msg: db "Hello, world!", 10
.len: equ $ - msg
""")

night quarryBOT
#

@sly root :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 19, in <module>
003 |   File "<string>", line 12, in <lambda>
004 |   File "<string>", line 11, in <lambda>
005 |   File "/usr/local/lib/python3.10/tempfile.py", line 337, in mkstemp
006 |     return _mkstemp_inner(dir, prefix, suffix, flags, output_type)
007 |   File "/usr/local/lib/python3.10/tempfile.py", line 252, in _mkstemp_inner
008 |     fd = _os.open(file, flags, 0o600)
009 | OSError: [Errno 30] Read-only file system: '/snekbox/tempsfx6x5ga.S'
sly root
#

eeh

rugged sparrow
#

@sly root i dont think snekbox has nasm either (otherwise you could pipe the binary to stdout and write it into python's process mem)

restive void
sly root
#

yes, I know, but now I have a different problem, windows won't let me delete the file

#
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\i0x\\PycharmProjects\\pysnippets\\inlinec\\temp76ue_7jp.cpp'
#

i've rewritten it fully from scratch

#
__cf=type("__cf",(object,),{"__init__":(lambda self,c:
__(None,
 ___(
  ___e(self,"tfile",tempfile.mkstemp(".cpp","temp",os.getcwd())),
  ___e(self,"source",getattr(self,"tfile")[1]),
  ___e(self,"f",open(getattr(self,"source"),"wb")),
 ),
 ___(
  getattr(self,"f").write(c.encode("utf-8")),
  getattr(self,"f").close(),
 ),
 ___(
  ___e(self,"sts",subprocess.check_output(f"g++ -o a.out {getattr(self,'source')}",shell=True)),
  __if(print(subprocess.check_output("a.out").decode("utf-8")),getattr(self,"sts")==0,0),
 ),
 os.unlink("a.out"),
 os.unlink(getattr(self,"source")),
)
)})
#

everything works normally on linux

#

problem is in os.unlink(getattr(self,"source")), when deleting the .cpp file

#

fixed the error

sly root
#

@sick hound also closing __s not works, cuz then os basically not unlinks it xd

dapper atlas
#

What is a python vm language 🤔

#

Is it a language which has its interpreter written in python?

floral meteor
#
class yeet(list):
  def __setitem__(self,x,y):
    try:super().__setitem__(x,y)
    except:self.append(y)
def chicken(CHICKEN):
  a=yeet()
  c=[len(yay.split())for yay in CHICKEN.split('\n')]
  assert all([all([this=='chicken'for this in yay.split()])for yay in CHICKEN.split('\n')])
  p=q=0
  while p<len(c):
    if c[p]==0:break;
    if c[p]==1:a+=['chicken']
    elif c[p]==2:a[-1]=a.pop(-1)+a[-1]
    elif c[p]==3:a[-1]=a.pop(-1)-a[-1]
    elif c[p]==4:a[-1]=a.pop(-1)*a[-1]
    elif c[p]==5:a[-1]=a.pop(-1)==a[-1]
    elif c[p]==6:
      p+=1
      if not c[p]:a+=[a[a.pop(-1)]]
      else:a+=[input()[a.pop(-1)]]
    elif c[p]==7:
      x,y = a.pop(-1), a.pop(-1)
      a[x]=y
    elif c[p]==8:
      x,y = a.pop(-1),a.pop(-1)
      if y:p+=x-1
    elif c[p]==9:a[-1]=chr(a[-1])
    else:a+=[c[p]-10]
    p+=1
  print (''.join([str(this)for this in a[::-1]]))
#

icr what chicken is supposed to print at the end

#

dammit i got something wrong

woven bridge
blissful swan
#

x = int(input("hsjsvdh"))

pastel ibex
vestal solstice
#

what people call "bytecode"

#

if it had a name people would call it by the name

#

but it doesn't, it's python vm language

floral meteor
#

I think i see the issue.
It has now been edited to prevent the issue.

#

I think the specifications just aren't clear enough

floral meteor
#

chicken

glacial sorrel
#

code:

def online():
    content = ploudos.req()
    try:
        return f"{0 if content['onlineCount'] == None else str(content['onlineCount']) + '/' + str(content['onlineMax'])}"

    except KeyError:
        return "0/0"

question: Any idea how to make it more compact (maybe lambda 1 liner). (shouldn't be focused on readability)

last locust
glacial sorrel
#

and is there any way to one line this?

last locust
#

32 chars less

#

Then you can remove spaces etc.

#

Use shorter variable names

#

Use another walrus for content['onlineCount']

#

etc.

glacial sorrel
last locust
#

You can't one-line a try/except

glacial sorrel
last locust
#

true

glacial sorrel
#

thanks

robust girder
tacit cobalt
#

Pretty easy to do a simple try except in one line at least

def foo():
    1/0

with type("handler", (), {"__enter__": lambda self: None, "__exit__":  lambda self, et, ev, tb: True})(): foo()
robust girder
#

with, you can't put it wherever you want

tacit cobalt
#

What am I not allowed to use?

#

.-. but exec

#

lmao

robust girder
#

thats not statement

#

but no exec

tacit cobalt
#

What other functions?

#

Am I allowed to change the bytecode of functions?

#

So no changing bytecode

earnest wing
#

Using contextlib

#

Hold on, there was a snippet somewhere here

#

.

pastel ibex
rapid sparrow
#

ha! I've written this same function

#

including nearly that exact signature

floral meteor
pastel ibex
floral meteor
#

its 4:30 am its staying failed until tomorrow

#

wait its already tomorrow

#

its still staying failed today

rapid sparrow
#

it's kind of hard to keep up, hoping it's not used that often

vestal bluff
#

hey guys could someone please tell me why the first decorator on this picture has an additional "decorator" function above @wraps and the second decorator doesnt have it?

rapid sparrow
simple crystal
#

!e

class test:
    def __init__(self, d={}):
        self.d=d
t1 = test()
t1.d |= {0:0}
t2 = test()
print(t2.d)
night quarryBOT
#

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

{0: 0}
simple crystal
#

thought so but making sure initializer default mutables do that

#

in case it didn't work like I thought

snow beacon
vestal bluff
#

oh, please sorry guys, here is the code:

import cProfile, pstats, io

def permission_required(role):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.has_role(role):
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator

def profile(fnc):
@wraps(fnc)
def inner(*args, **kwargs):
pr = cProfile.Profile()
pr.enable()
retval = fnc(*args, **kwargs)
pr.disable()
s = io.StringIO()
sortby = 'cumulative'
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
print(s.getvalue())
return retval
return inner

#

so my question is: why the first decorator on this picture has an additional "decorator" function above @wraps and the second decorator doesnt have it?

viral river
#

how do i bring back the >>> in IDLE

vestal bluff
#

the second has a call: return retval

#

wouldnt first decorator work even without "def decorator(f):" line?

#

i guess it would so im wondering what s the purpose of it

rapid sparrow
#

so f can get called later with those same args is my guess

#

actually, looking again, that's not what's being captured, but f and role are I believe

floral meteor
night quarryBOT
#

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

['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__', '__package__', '__spec__', '__stderr__', '__stdin__', '__stdout__', '__unraisablehook__', '_base_executable', '_clear_type_cache', '_current_exceptions', '_current_frames', '_deactivate_opcache', '_debugmallocstats', '_framework', '_getframe', '_git', '_xoptions', 'abiflags', 'addaudithook', 'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix', 'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth', 'getallocatedblocks', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 'hash_info', 'hexversion', 'implementation
... (truncated - too long)

Full output: https://paste.pythondiscord.com/afutipapeb.txt?noredirect

floral meteor
#

It's not shown there, possibly due to being in a sandbox.
Open command prompt enter py or python3 and then import sys
dir(sys)
And there will be more options than above

#

Unless you've played with idle itself then probably reinstall

#

But in this channel, impossibility is impossible

astral rover
#

its ps1 and ps2

floral meteor
#

yes, ps1 defaults to >>>
ps2 defaults to ...

fleet bridge
#

!e

import sys
print(repr(sys.ps1), repr(sys.ps2))
night quarryBOT
#

@fleet bridge :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 2, in <module>
003 | AttributeError: module 'sys' has no attribute 'ps1'
floral meteor
#

As I said, it won't work on the sandbox

potent comet
#

They're only there in interactive mode, and IDLE itself might not use them - though it probably does.

night quarryBOT
#

@sick hound :white_check_mark: Your eval job has completed with return code 0.

5
fleet bridge
#

!e

print(repr(r''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''fr''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''f'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''r'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''r'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''f'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''fr'''''''''''''''''''''''''''''''''''''''''''''''''''''rb'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''))
night quarryBOT
#

@fleet bridge :white_check_mark: Your eval job has completed with return code 0.

"'frfrfr'rb"
fleet bridge
#

!e
print(f"""{f'''{f"{f'{0}'}"}'''}""")

night quarryBOT
#

@fleet bridge :white_check_mark: Your eval job has completed with return code 0.

0
rapid sparrow
#

!e

from code import InteractiveConsole
cons = InteractiveConsole()
cons.push("def fun():")
cons.push("  print('hello from fun')")
cons.push("")
cons.push("print(fun())")
night quarryBOT
#

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

001 | hello from fun
002 | None
rapid sparrow
#

!e

from code import InteractiveConsole
class SpecialConsole(InteractiveConsole):
  _last: str = None
  _cmd: str = None
  def raw_input(self, prompt):
    try:
      self._last = self._cmd
      if not self.buffer:
        if self._rest:
          self.buffer += self._rest.splitlines()
          self.rest = None
        else:
          raise EOFError
      self.buffer.reverse();
      self._cmd = self.buffer.pop()
      self.buffer.reverse();
      self._rest = "\x0a".join(self.buffer)
      self.buffer.clear()
      return self._cmd
    finally:
      print(f"{prompt}{self._cmd}")

if __name__ == "__main__":
  c = SpecialConsole()
  c.buffer.append("import sys")
  c.buffer.append("sys")
  c.interact()
night quarryBOT
#

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

001 | Python 3.10.0 (default, Oct  6 2021, 00:08:37) [GCC 8.3.0] on linux
002 | Type "help", "copyright", "credits" or "license" for more information.
003 | (SpecialConsole)
004 | >>> import sys
005 | >>> sys
006 | <module 'sys' (built-in)>
007 | >>> sys
008 | 
009 | now exiting SpecialConsole...
rapid sparrow
#

not perfect, but close?

#

btw InteractiveConsole sets sys.ps1 and sys.ps2 if they aren't attributes of sys yet

#

wow we got an upgrade to 3.10 👏

knotty delta
#

oops

#

sorry

#

wrong paste

rapid sparrow
#

anyone know a way to get the referent from a weakref object?

astral rover
#

you call it

rapid sparrow
#

ah, thanks!

#

I was trying to figure out how __issubclass__ knows e.g. list is a Collection. I don't see anything in the abc registry for Collection and it's not derived from anything (except object). Wondering what I'm missing.

astral rover
#

it checks what methods exist on the object passed to it (im assuming youre talking about __subclasshook__)

rapid sparrow
#

so that's determined by calling Collection.__subclasshook__ ?

night quarryBOT
#

Lib/_collections_abc.py lines 78 to 88

def _check_methods(C, *methods):
    mro = C.__mro__
    for method in methods:
        for B in mro:
            if method in B.__dict__:
                if B.__dict__[method] is None:
                    return NotImplemented
                break
        else:
            return NotImplemented
    return True```
night quarryBOT
#

Lib/_collections_abc.py line 412

return _check_methods(C,  "__len__", "__iter__", "__contains__")```
rapid sparrow
#

ohhhh

astral rover
#

its part of python's move towards structural type checking

rapid sparrow
#

so the registry thing is probably just an optimization, then

vestal bluff
#

thanks so much @rapid sparrow! highly appreciated sir!

rapid sparrow
#

abc.ABC.register and friends

astral rover
#

i couldnt tell you

rapid sparrow
#

register(subclass) method of abc.ABCMeta instance Register a virtual subclass of an ABC.

rapid sparrow
#

this is what I came up with to show the ABC registry (empty classes not printed)

#

!e

from pprint import pp; import _abc, inspect, collections.abc; clzs = dict(inspect.getmembers(collections.abc, lambda v: inspect.isclass(v) and hasattr(v, "_abc_impl"))).values(); regclzs = {c.__name__: [d() for d in list(_abc._get_dump(c)[0])] for c in clzs}; pp({k: v for k,v in regclzs.items() if v});
night quarryBOT
#

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

001 | {'ByteString': [<class 'bytearray'>, <class 'bytes'>],
002 |  'ItemsView': [<class 'dict_items'>],
003 |  'KeysView': [<class 'dict_keys'>],
004 |  'Mapping': [<class 'mappingproxy'>],
005 |  'MutableMapping': [<class 'dict'>],
006 |  'MutableSequence': [<class 'bytearray'>,
007 |                      <class 'list'>,
008 |                      <class 'collections.deque'>],
009 |  'MutableSet': [<class 'set'>, <class '_weakrefset.WeakSet'>],
010 |  'Sequence': [<class 'str'>,
011 |               <class 'tuple'>,
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/yijozugipe.txt?noredirect

rapid sparrow
#

it didn't show the whole picture, that's why I was curious 🙂

#

I guess if I wanted a list of all Collection classes the way would be basically call issubclass on every class

#

!e

import gc, inspect, collections.abc; allclz = [*filter(inspect.isclass, gc.get_objects())]; print(f"{len(allclz)} classes"); print([c.__qualname__ for c in allclz if issubclass(c, collections.abc.Collection)])
night quarryBOT
#

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

001 | 314 classes
002 | ['Arguments', 'ArgSpec', 'FullArgSpec', 'ArgInfo', 'ClosureVars', 'Traceback', 'FrameInfo', '_OrderedDictKeysView', '_OrderedDictItemsView', '_OrderedDictValuesView', 'Counter', 'ChainMap', 'UserDict', 'UserList', 'UserString', 'CacheInfo', '_HashedSeq', '_EnumDict', 'EnumMeta', '_Instruction', 'Instruction', '_Environ', 'TokenInfo', 'Attribute', 'TokenInfo', 'waitid_result', 'stat_result', 'statvfs_result', 'sched_param', 'terminal_size', 'times_result', 'uname_result', '_NamespacePath', 'CodecInfo', 'Collection', 'Set', 'MutableSet', 'Mapping', 'KeysView', 'ItemsView', 'ValuesView', 'MutableMapping', 'Sequence', 'ByteString', 'MutableSequence']
sick hound
#

!e

print("hello")
night quarryBOT
#

@sick hound :white_check_mark: Your eval job has completed with return code 0.

hello
sinful badger
patent zenith
#

can you explain me this code : data = [x + random() for x in range(1, 100)]

#

thanks

#

i know it is a loop comprehension

#

but what the (+) means

astral rover
#

its adding x to a random value between 0 and 1

patent zenith
#

what ?

#

the range is between 1 and 100

#

so from 1 to 99

#

I don't understand your answer

astral rover
#

random() generates a pseudo random value between 0 < y <= 1

#

!d random.random

night quarryBOT
#

random.random()```
Return the next random floating point number in the range [0.0, 1.0).
rapid sparrow
#

who knows the answer to this

#
# local to function
>>> def func():
...     f = open("test.txt", "w")
...     f.write("hello world")
...
>>> func()
>>> Path("test.txt").read_text()
'hello world'

# global var 
>>> Path("test.txt").unlink()
>>> f = open("test.txt", "w")
>>> f.write("hello world")
11
>>> Path("test.txt").read_text()
''
#

that's a re-enactment of someone else' code I got asked about

#

it writes out the file when the f is a local but not a global

#

do the _io classes that wrap open files have a finalizer that runs only in the first case?

#

could you explain

#

open("test.txt", "w") is backed by a file descriptor, isn't it

#
PyTypeObject PyFileIO_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_io.FileIO",
    sizeof(fileio),
    0,
    (destructor)fileio_dealloc,                 /* tp_dealloc */
    0,                                          /* tp_vectorcall_offset */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    ...
    PyType_GenericAlloc,                        /* tp_alloc */
    fileio_new,                                 /* tp_new */
    PyObject_GC_Del,                            /* tp_free */
    // ^^ it has __del__
#
static void
fileio_dealloc(fileio *self)
{
    self->finalizing = 1;
    if (_PyIOBase_finalize((PyObject *) self) < 0)
        return;
    _PyObject_GC_UNTRACK(self);
    if (self->weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) self);
    Py_CLEAR(self->dict);
    Py_TYPE(self)->tp_free((PyObject *)self);
}
#

ah

#
>>> from pathlib import Path
>>> f = open("test.txt", "w")
>>> f.write("hello world")
11
>>> Path("test.txt").read_text()
''
>>> del f
>>> Path("test.txt").read_text()
'hello world'
#

nice

rapid sparrow
#

I'm looking for the shortest (or weirdest) way to read a file to a string

#

if anyone has ideas

#

i'll start

#

!e

print(open(__import__("json").__file__).read()[:250])
night quarryBOT
#

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

001 | r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of
002 | JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
003 | interchange format.
004 | 
005 | :mod:`json` exposes an API familiar to users of the standard library
006 | :mod:`marshal` and :m
rapid sparrow
#

!e

print((m:=__import__("pathlib")).Path(m.__file__).read_text()[:250])
night quarryBOT
#

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

001 | import fnmatch
002 | import functools
003 | import io
004 | import ntpath
005 | import os
006 | import posixpath
007 | import re
008 | import sys
009 | import warnings
010 | from _collections_abc import Sequence
011 | from errno import EINVAL, ENOENT, ENOTDIR, EBADF, ELOOP
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/oxuyanejip.txt?noredirect

rapid sparrow
#

there's a slightly cooler, but kinda obvious, one

#

!e

print((o:=__import__("subprocess")).check_output([f"/usr/bin/cat", o.__file__])[:250])
#

there's no cat 😩

#

!e

print((o:=__import__("subprocess")).check_output([f"exec < {o.__file__} ; while read -r ln; do echo \"$ln\"; done"], shell=True)[:250])
#

sandbox: 2 me: 0

#

seems like external commands used to work

#

!e

import sys; sys.addaudithook(print); exec('try:\n  print((o:=__import__("subprocess")).check_output([f"/usr/bin/cat", o.__file__])[:250]);\nexcept:\n  pass\ntry:\n  print((o:=__import__("subprocess")).check_output([f"exec < {o.__file__} ; while read -r ln; do echo \\"$ln\\"; done"], shell=True)[:250]);\nexcept:\n  pass\n')
night quarryBOT
#

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

001 | compile (b'try:\n  print((o:=__import__("subprocess")).check_output([f"/usr/bin/cat", o.__file__])[:250]);\nexcept:\n  pass\ntry:\n  print((o:=__import__("subprocess")).check_output([f"exec < {o.__file__} ; while read -r ln; do echo \\"$ln\\"; done"], shell=True)[:250]);\nexcept:\n  pass\n', '<string>')
002 | exec (<code object <module> at 0x7f891c4c1e70, file "<string>", line 1>,)
003 | import ('subprocess', None, ['', '/snekbox/user_base/lib/python3.10/site-packages', '/usr/local/lib/python310.zip', '/usr/local/lib/python3.10', '/usr/local/lib/python3.10/lib-dynload'], [<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>], [<class 'zipimport.zipimporter'>, <function FileFinder.path_hook.<locals>.path_hook_for_FileFinder at 0x7f891c5e8af0>])
004 | os.listdir ('/snekbox',)
005 | open ('/usr/local/lib/python3.10/__pycache__/subprocess.cpython-310.pyc', 'r', 524288)
006 | marshal.loads (b'\xe3\x00\
... (truncated - too long, too many lines)

Full output: too long to upload

rapid sparrow
#

damnit

#

well it was fun trying

last locust
#

As in os.system etc.

rapid sparrow
floral meteor
#

hi

sly root
#

there was a :bigbrain: thing, and now you'll never see it

steady lily
#
>>> ().__class__.__class__.__eq__.__name__[:2]+print.__module__+[].__class__.__dir__.__name__[:2]
>>> '__builtins__'

a script that can create a string entirely out of these class and method names would be so cool.

#
>>> convert('abc')
"string.__class__.__class__.__subclasses__.__name__[7]+print.__module__[0]+ord.__class__.__name__[11]"
patent zenith
#

hey guys, how can i do to take some expressions or a value from another app with a python script ? thanks

restive void
#

e.g. ```py
class AddExpression(Tree):
AddExpression + AddOperator + AddExpression
MulExpression

patent zenith
restive void
rapid sparrow
#

!e

print(repr(
    f"{{:{[].__class__.__mro__[1].__name__[4]}}}".format((int(().__class__.__name__[3],36)+92))
))
night quarryBOT
#

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

'q'
rapid sparrow
#

shorter would be cool, but ..

steady lily
rapid sparrow
#

😵

#

!e

print(
    [].__doc__[19]
)
night quarryBOT
#

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

q
rapid sparrow
#

wonder how likely is it that list's docstring would change

#

tries om 2.7

#
Python 2.7.18 (default, Mar 20 2021, 14:58:25)
[GCC 4.2.1 Compatible Android (6454773 based on r365631c2) Clang 9.0.8 (https:/ on linux2
>>> [].__doc__[19]
' '```
#

set.__doc__ ?

#

!e

print(repr(
    [].__class__.__class__.__eq__.__name__[3]
))```
night quarryBOT
#

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

'q'
rapid sparrow
#

that's really not bad ^

#

2.7-compatible 👌

rapid sparrow
#

you have python 2.1 ? does it give a REPL after that?

#

looks pretty normal then right

proper vault
#

yup

earnest wing
#

Because eval returns

nimble basalt
#

!e py print(repr( f"{{:{[].__class__.__mro__[1].__name__}}}".format((int(().__class__.__name__[3],36)+92)) ))

night quarryBOT
#

@nimble basalt :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 2, in <module>
003 | ValueError: Invalid format specifier
nimble basalt
#

!e py print(repr( f"{{:{[].__class__.__mro__[1].__name__[0:]}}}".format((int(().__class__.__name__[3],36)+92)) ))

night quarryBOT
#

@nimble basalt :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 2, in <module>
003 | ValueError: Invalid format specifier
nimble basalt
#

!e py print(repr( f"{{:{[].__class__.__mro__[1].__name__[4]}}}".format((int(().__class__.__name__[3],36)+92)) ))

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

'q'
nimble basalt
#

!e print(repr([].doc))

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

'Built-in mutable sequence.\n\nIf no argument is given, the constructor creates a new empty list.\nThe argument must be an iterable if specified.'
nimble basalt
#

!e print(repr([].doc[19]))

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

'q'
nimble basalt
#

!e print(repr([].doc[19:]))

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

'quence.\n\nIf no argument is given, the constructor creates a new empty list.\nThe argument must be an iterable if specified.'
nimble basalt
#

!e ```py
print(
getattr(
[
0
],
'append'
)(
1
)
)

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

None
nimble basalt
#

!e ```py
print(
repr(
str(
repr(
getattr(
[
0
],
'append'
)(
1
)
)
)
)
)

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

'None'
nimble basalt
#

!e ```py
print(
repr(
str(
repr(
getattr(
[
0,
[
0,
[
1
][
0
]
]
],
'append'
)(
1
)
)
)
)
)

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

'None'
nimble basalt
#

!e print(repr(repr(repr(...)))))

#

!e print(repr(repr(repr(...))))

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

"'Ellipsis'"
nimble basalt
#

!e print(repr(repr(repr(repr(repr(...))))))

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

'\'"\\\'Ellipsis\\\'"\''
nimble basalt
#

!e print(repr(str(repr(repr(repr(repr(...)))))))

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

'\'"\\\'Ellipsis\\\'"\''
nimble basalt
#

!e ```py
print(repr(repr(repr(
repr(repr(repr(
str(repr(repr(
repr(repr(
getattr(
[
0,
[
0,
[
1
][
0
]
]
],
'append'
)(
1
)
))
)))
)))
))))

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

'\'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'None\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\\\\\\\\\\\\\\\'\\\\\\\'\\\'\''
nimble basalt
#

Wht lol

nimble basalt
#

!e ```py
_=repr(repr(repr(repr(
repr(repr(repr(
str(repr(repr(
repr(repr(
getattr(
[
0,
[
0,
[
1
][
0
]
]
],
'append'
)(
1
)
))
)))
)))
))))
globals().update({'None': ,})
del globals()['
']
shit = None
while "'" in shit:
shit=shit.replace("'","")
while '"' in shit:
shit=shit.replace('"',"")
globals().update({'moreshit': shit})
print(moreshit)

night quarryBOT
#

@nimble basalt :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 28, in <module>
003 | TypeError: argument of type 'NoneType' is not iterable
nimble basalt
#

!e ```py
_=repr(repr(repr(
repr(repr(repr(
str(repr(repr(
repr(repr(
getattr(
[
0,
[
0,
[
1
][
0
]
]
],
'append'
)(
1
)
))
)))
)))
)))
globals().update({'none': ,})
del globals()['
']
shit = none
while "'" in shit:
shit=shit.replace("'","")
while '"' in shit:
shit=shit.replace('"',"")
globals().update({'moreshit': shit})
del globals()['shit']
print(moreshit)

night quarryBOT
#

@nimble basalt :white_check_mark: Your eval job has completed with return code 0.

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\None\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
maiden river
#

easy codin, easy brahmi

snow beacon
maiden river
#

well for sure a keyboard for python

#

a planned python implementation for brahmi & devanagari scripts : )
(sample python code in Sanskrit for calculating the Fibonacci sequence)

snow beacon
#

Does it work as an encoding? Or is it more of a preprocessor? Or an entirely separate interpreter based on Python?

fleet bridge
#

instead of a, b = b, a + b you wrote a, b = b, a + 1

clever finch
#

anyone here to help me in this code ?

#

i mean question on the left

maiden river
fair dune
#

found at github

snow beacon
#

For reference, the idiomatic* way to write it would be for i in map(next, map(iter, enumerate(iter(int, "")))):.

tacit cobalt
#

Couldn't you just do for i, _ in enumerate(iter(int, 1)):

night quarryBOT
#

@sick hound :x: Your eval job has completed with return code 143 (SIGTERM).

001 | <generator object <genexpr> at 0x7f54901afd80>
002 | <generator object <genexpr> at 0x7f54901afd80>
003 | <generator object <genexpr> at 0x7f54901afd80>
004 | <generator object <genexpr> at 0x7f54901afd80>
005 | <generator object <genexpr> at 0x7f54901afd80>
006 | <generator object <genexpr> at 0x7f54901afd80>
007 | <generator object <genexpr> at 0x7f54901afd80>
008 | <generator object <genexpr> at 0x7f54901afd80>
009 | <generator object <genexpr> at 0x7f54901afd80>
010 | <generator object <genexpr> at 0x7f54901afd80>
011 | <generator object <genexpr> at 0x7f54901afd80>
... (truncated - too many lines)

Full output: too long to upload

hollow gust
#

lol even better’for i in range(0, float(“inf”))’

#

lol it was a joke

snow beacon
wintry dove
#

!e

night quarryBOT
#
Command Help

!eval [code]
Can also use: e

*Run Python code and get the results.

This command supports multiple lines of code, including code wrapped inside a formatted code block. Code can be re-evaluated by editing the original message within 10 seconds and clicking the reaction that subsequently appears.

We've done our best to make this sandboxed, but do let us know if you manage to find an issue with it!*

night quarryBOT
#

@sick hound :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 'doc' is not defined
tacit cobalt
#

!e ```py
import ctypes

tup = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

(ctypes.c_longlong).from_address(id(tup) + 16).value = 11
print(tup)

night quarryBOT
#

@tacit cobalt :white_check_mark: Your eval job has completed with return code 0.

(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, <NULL>)
tacit cobalt
#

!e ```py
import gc
import ctypes

def modify(self, value):
length = self.len()
(ctypes.c_longlong).from_address(id(self) + 16).value = length + 1
(ctypes.c_longlong).from_address(id(self) + (3 + length)*8).value = id(value)

gc.get_referents(tuple.dict)[0]["append"] = modify

tup = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
tup.append(11)
print(tup)

night quarryBOT
#

@tacit cobalt :white_check_mark: Your eval job has completed with return code 0.

(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
floral meteor
#

nice, show python who's boss XD

fleet bridge
potent comet
#

That'll only work if there happens to be free memory after the tuple.

#

You could use _PyTuple_Resize() instead.

maiden river
leaden vault
#

those punctuation keys are more cursed than everything else combined

earnest wing
#

How do you press those keys?

#

With a toothpick?

#

Or are they meant to be used like a macro, all at once

#

I mean the lack of enter key is fine

formal sandal
#

So I noticed that from module import name1, name2, name3 looks very similar to SELECT col1, col2, col3 FROM table in SQL...

# table.py
_cols = []
_AS = False
_data = []


def insert(row):
    _data.append(row)


def _compute_result():
    return [
        {col: row[col] for col in _cols if col in row}
        for row in _data
    ]


def __getattr__(name):
    global _AS
    if name == "AS":
        _AS = True
    elif _AS:
        _AS = False
        rv = _compute_result()
        _cols.clear()
        return rv
    else:
        _cols.append(name)
``` ```py
# main.py

import table
table.insert({"email": "a@a.com", "name": "alice", "age": 42})
table.insert({"email": "b@b.com", "name": "bob", "age": 25})
table.insert({"email": "c@c.com", "name": "charlie", "age": 35})

from table import email, age, AS, rows1
print(rows1)
#

output:
[{'email': 'a@a.com', 'age': 42}, {'email': 'b@b.com', 'age': 25}, {'email': 'c@c.com', 'age': 35}]

rugged sparrow
#

and also a great way to clobber memory lol

#

!e ```py
import gc
def replace_tuple(self, new):
for container in gc.get_referrers(self):
if isinstance(container, dict):
for k, v in container.items():
if v is self:
container[k] = new
elif isinstance(container, list):
for i, v in enumerate(container):
if v is self:
container[i] = new
elif isinstance(container, tuple):
for i, v in enumerate(container):
if v is self:
temp = list(container)
temp[i] = new
replace_tuple(container, tuple(temp))
elif isinstance(container, set):
container.remove(self)
container.add(new)

def append(self, i):
t = list(self)
t.append(i)
replace_tuple(self, tuple(t))

gc.get_referents(tuple.dict)[0]["append"] = append

x = (0,1,2)
x.append(1)
print(x)```

night quarryBOT
#

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

(0, 1, 2, 1)
rugged sparrow
#

^ personal favorite awful tuple.append

night quarryBOT
#

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

[No output]
rugged sparrow
#

_PyTuple_Resize makes a new tuple thats larger then sets that into the pointer you give it

#

so you dont replace the original, you just make a copy

#

It can't do that because tup->ob_item is an array on the tuple struct not a pointer to an array

#

(Lists have a pointer to an array)

fleet bridge
#

why not use this?

maiden river
terse mortar
#

Why have an enter key when you can use \n and ;? /s

terse mortar
#

It was satire.

#

Sorry if I didn't make that clear lol

sick hound
#

Well in fact the keyboard only sends keycodes

#

The OS can do whatever it wants with those

earnest wing
#

\r in ancient versions of MacOS, it's been the *nix \n for ages now

earnest wing
earnest wing
#
with database("test.db") as db:
    from table1 import (
        foo, bar, thing as baz, _,
        limit    as one_hundred,
        offset   as five,
        order_by as foo, asc, baz, desc, 
    )
    for foo, bar, baz in db:
        print(foo, bar, baz)

How's this

#

probably some tweaking needed in the syntax

formal sandal
earnest wing
#

check caller globals in module getattr

#

for the next import name

#

(this example should have another extra _ at the end)

marsh void
#

LOL

#

someone should definitely create a sticker for that

sick hound
#

challenge: make the shortest code in python that always wins tic tac toe/noughts and crosses.
criteria:

  1. always gets win or draw
  2. is short
  3. uses no modules

i tried doing it and its surprisingly really painful. there's no prize or anything but im curious to see how it'll be approached, considering most of what i've found online is at least 100 lines.

proper vault
# sick hound challenge: make the shortest code in python that always wins tic tac toe/noughts...

not perfect, but it is a start

def c(b,g):
 for i,n in enumerate(b):r=b.copy();r[i] = g;n or (yield i,r)
w=lambda b:next((sum(c) for c in [b[:3],b[3:6],b[6:],b[::3],b[1::3],b[2::3],b[::4],b[2:7:2]] if sum(c)in[3,-3]),0)
def m(g,b):
 if a:=w(b):return a,-1
 l=[(m(-g,n)[0],i)for i,n in c(b,g)]
 return [min,max][g>0](l)if l else (0,-1)
s=[0]*9
while not all(s):_,v=m(1,s);s[v]=1;w(s)and mw;print(s[:3],s[3:6],s[6:],sep='\n');s[int(input())]=-1;w(s) and hw
d
sick hound
#

very impressive so far.

#

just realised i should probably say the format of input and output...

proper vault
#

ye, I am using nameerrors to indicate game results

sick hound
#

players input has to be dictated by the coordinates of the place they make their turn. e.g a1 = the top left square. output has to be a grid of the board formatted like:
OXX
XOO
OXX
after each time the bot makes the move, the board must be printed.
if the other player forces a draw, the program should return False
otherwise, it should return True

i'll create a document of each entry and how it works.
if its very obfuscated or very weird u get a cookie (but dont win)

multiple entries are allowed, btw! if i see anything particularly cool thats cool.

finally, the code should be run by entering c(v).
v should be who goes first.

minor changes to this format are ok!

finally, its ending on the 13th. ping me with your entries.

have fun

#

if anything there doesn't make sense dm me.

marsh void
#

... not something I'd call a "hug" ._.')

formal sandal
rapid sparrow
#

!e

class Sneaky:
  def __eq__(self, other):
    other['bit_length'] = 42

int.__dict__ == Sneaky()
print(repr(int.__dict__)[0:250])
print((1).bit_length)
night quarryBOT
#

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

001 | mappingproxy({'__new__': <built-in method __new__ of type object at 0x7f8174455540>, '__repr__': <slot wrapper '__repr__' of 'int' objects>, '__hash__': <slot wrapper '__hash__' of 'int' objects>, '__getattribute__': <slot wrapper '__getattribute__' 
002 | 42
rapid sparrow
#

the talk of fixing this by having mappingproxy copy the undetlying dict when calling comparison operators, which.... just no...

#

thankfully they're not fixing it

fleet bridge
#

def str__invert__(self: str) -> str:
    return self[::-1]

class str__invert__trick:
    def __eq__(self, other):
        other['__invert__'] = str__invert__

str.__dict__ == str__invert__trick()
print(str.__invert__('123')) # 321
print('123'.__invert__()) # 321
print(~'123') # TypeError: bad operand type for unary ~: 'str'
#

why ~'123' doesnt work?

vast cargo
#

can i use the result of INPLACE_XXX for anything other than STORE_XXX?
for example:

LOAD_GLOBAL      (print)
LOAD_FAST        (x)
LOAD_CONST       1
INPLACE_ADD         # result pushed to stack
CALL_FUNCTION    1  # result used as function argument
#

i mean when you see INPLACE_XXX, the next instruction is always STORE_XXX.
.

#

so i get a segfault for fiddling with code object,
one possible cause is what i asked above, but that's just my guess

rapid sparrow
#

someone here had a package that might help with that (@rugged sparrow ?)

#

!e

from forbiddenfruit import curse
def __invert__(self):
    return self
curse(str, "__invert__", __invert__)
print(~"hello")```
night quarryBOT
#

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

hello
rugged sparrow
#

Forbidden fruit or fishhook can do it

#

I prefer fishhook cause it can handle exceptions in hooked methods (disclaimer I wrote fishhook)

rapid sparrow
#

!e

from forbiddenfruit import curse
def __invert__(self):
    raise BaseException(self)
curse(str, "__invert__", __invert__)
print(~"hello")```
night quarryBOT
#

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

001 | Exception ignored on calling ctypes callback function: <function __invert__ at 0x7fafbf8b8d30>
002 | Traceback (most recent call last):
003 |   File "/snekbox/user_base/lib/python3.10/site-packages/forbiddenfruit/__init__.py", line 328, in wrapper
004 |     return func(*args, **kwargs)
005 |   File "<string>", line 3, in __invert__
006 | BaseException: hello
rapid sparrow
#

SIGSEGV lol

#

that could be an issue

#

!e

from fishhook import hook
@hook(int)
def __invert__(self):
    raise BaseException(self)
print(~"hello")```
night quarryBOT
#

@rapid sparrow :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
#
>>> from fishhook import hook
>>> @hook(str)
... def __invert__(self):
...     raise BaseException(self)
... 
>>> ~'a'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __invert__
BaseException: a
>>> ```
rapid sparrow
#

there's something to be said for letting the interpreter keep running

rugged sparrow
#

!e ```py
from forbiddenfruit import curse
def f(self):
raise Exception

curse(str, 'invert', f)
try:~'a'
except:pass```

night quarryBOT
#

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

001 | Exception ignored on calling ctypes callback function: <function f at 0x7fa3c11f8d30>
002 | Traceback (most recent call last):
003 |   File "/snekbox/user_base/lib/python3.10/site-packages/forbiddenfruit/__init__.py", line 328, in wrapper
004 |     return func(*args, **kwargs)
005 |   File "<string>", line 3, in f
006 | Exception: 
rapid sparrow
#

is it just because they don't call PyExc_Check ?

rugged sparrow
#

its because forbiddenfruit uses ctypes to wrap functions

#

and ctypes is for external libs, not functions that use exceptions

rapid sparrow
#

ah

rugged sparrow
#

fishhook on the other hand hijacks the process that python already has in place for user defined classes

rapid sparrow
#

can any C callback function propagate exceptions?

rugged sparrow
#

not easily

#

because ctypes is built for C code that doesnt mesh with python

#

otherwise youre supposed to make an extension module

rapid sparrow
#

that looks handy

#

so 3 / 5 is 0 in python 2

#

ahh

#

that's why you say it's useless then

#

oh, I didn't realize

#

there's no replacement I guess

#

does it mention it's deprecated in its doc?

#

ah, since 3.11

#

well, the python2 lib2to3 will never be deprecated 😄

#

true, and I still run across repos that never converted, occasionally

#

there's been a move away from LL(1) parsers which parso and LibCST are still using it looks like

#

so they won't be able to parse pattern matching

#

probably not an issue in practice for converting

inland axle
#

fissix and modernize are still around ish

rapid sparrow
sick hound
#

How could i decompile pyarmor?

golden finch
#

!eval

f=lambda _=[]:(_.append(0),~-len(_))[1]
while f()<5:
  print('foo')
night quarryBOT
#

@golden finch :white_check_mark: Your eval job has completed with return code 0.

001 | foo
002 | foo
003 | foo
004 | foo
005 | foo
golden finch
#

!eval

n=type('',(),{'__pos__':lambda _:getattr(_,'')(1),'__neg__':lambda _:getattr(_,'')(-1),'__repr__':lambda _:f'{getattr(_,"")(0)}','':lambda s,n,_=[0]:(_.__setitem__(0,_[0]+n),_[0])[1]})()

while ++n <= 5:
  print('n is',n)
night quarryBOT
#

@golden finch :white_check_mark: Your eval job has completed with return code 0.

001 | n is 1
002 | n is 2
003 | n is 3
004 | n is 4
005 | n is 5
#

@sick hound :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 2, in <module>
003 |   File "<string>", line 1, in <lambda>
004 | SystemError: _PyEval_EvalFrameDefault returned NULL without setting an exception
#

@sick hound :white_check_mark: Your eval job has completed with return code 0.

001 | foo
002 | foo
003 | foo
004 | foo
005 | foo
golden finch
#

what on earth even is that

#

I think I see what you mean actually

#

neat tricks, but pointlessly obfuscated

#

yeah I figured that was it

#

the ellipsis bit is neat though

#

mhm

floral meteor
#

Just seeing if I still have the brainfuck interpreter memorised. ```py
def brainfuck(c):
a=import('collections').defaultdict(int)
i=p=t=0
def add(i):
a[i]=(a[i]+1)%256
return i,0
def sub(i):
a[i]=(a[i]-1)%256
return i,0
def left(i):return i-1,0
def rite(i):return i+1,0
def dot(i):
print(end=chr(a[i]))
return i,0
def com(i):
a[i]=ord(import('sys').stdin.read(1))
return i,0
def loop(i):
return i,not a[i]
def end(i):
return i,-bool(a[i])
while 0<=p and p<len(c):
if t:t+=(c[p]=='[')-(c[p]==']')
else:i,t=[
add,sub,left,rite,dot,com,loop,end,lambda i:(i,0)
] ['+-<>.,[]'.find(c[p])] (i)
p+=1-2*(t<0)
return int(bool(t))

cloud fossil
#

rite? why not rght

crimson pumice
#

I have a friend who I need to show some weird stuff

#

We're talking about private attributes and immutability

#

Anybody has like a codeblock that changes elements in a tuple?

rugged sparrow
#

thats not a safe method tho, you shouldnt try to mess with the length of a tuple in place cause youll write over memory

sick hound
#
people = ["Jeff", "Meriesa", "Emily", "Ken"]
count = 0
while count < len(people):
  print(people[count])
  count += 1  
#

Dear lord the unholy ways Python has been used for

worn storm
#

heeey

rapid sparrow
#

looks like pretty normal from here

sick hound
#

It's not pythonic

#
people = ["Jeff", "Meriesa", "Emily", "Ken"]
for person in people:
  print(person)
#

this is Pythonic

rapid sparrow
#

indeed, very

#
[print(p) for p in ["Jeff", "Meriesa", "Emily", "Ken"]]

who doesn't love throwing away a list though

#

now esoteric and pythonic

#
[*map(print, ["Jeff", "Meriesa", "Emily", "Ken"])]
``` or *functional*
terse mortar
#

Remove all the spaces

rapid sparrow
#

!e

class PrintVisitor:
    def visit_person(self, person):
        print(person)

class Person:
    def __init__(self, name):
        self.name = name
    def accept(self, visitor):
        visitor.visit_person(self)
    def __repr__(self):
        return self.name

class People:
    def __init__(self, *names):
        self.names = names
    def accept(self, visitor):
        for p in self.names:
            p.accept(visitor)

pv = PrintVisitor()
people = People(
    Person("Jeff"),
    Person("Meriesa"),
    Person("Emily"),
    Person("Ken"),
)
people.accept(pv)
night quarryBOT
#

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

001 | Jeff
002 | Meriesa
003 | Emily
004 | Ken
rapid sparrow
#

tada, object-oriented

terse mortar
#

It's still too well formatted

crimson pumice
rapid sparrow
# terse mortar It's still too well formatted

!e

_=type("Person",(),{"__init__":lambda self,name:setattr(self,"name",name),"accept":lambda self,visitor:visitor.visit_person(self),"__repr__":lambda self:self.name});pp=type("People",(),{"__init__":lambda self,*names:setattr(self,"names",names),"accept":lambda self,visitor:list(_.accept(visitor)for _ in self.names)});pp(*map(_,["Jeff","Meriesa","Emily","Ken"])).accept(type("PrintVisitor",(),{"visit_person":lambda self,person:print(person)})())
night quarryBOT
#

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

001 | Jeff
002 | Meriesa
003 | Emily
004 | Ken
rapid sparrow
#

"minified" enterprise version 💄

sick hound
#

!e

print("hello, world")
#

nice

rapid sparrow
#

worry no more if somebody already imported sys or not

golden finch
#

!eval

n=type('',(),{'__pos__':lambda _:getattr(_,'')(1),'__neg__':lambda _:type('',(),{'__neg__':lambda s,c=_:getattr(c,'')(-1)})(),'__repr__':lambda _:f'{getattr(_,"")(0)}','':lambda s,n,_=[0]:(_.__setitem__(0,_[0]+n),_[0])[1]})()

while ++n <= 5:
  print('n is',n)

while --n >= -5:
  print('n is',n)
night quarryBOT
#

@golden finch :white_check_mark: Your eval job has completed with return code 0.

001 | n is 1
002 | n is 2
003 | n is 3
004 | n is 4
005 | n is 5
006 | n is 5
007 | n is 4
008 | n is 3
009 | n is 2
010 | n is 1
011 | n is 0
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/etiliqayar.txt?noredirect

rugged sparrow
#

thats because python cant know how big to make the stack then

#

python allocates the stack for a frame on the frame object, and if compositions are inlined then the stacksize is indeterminate

#

the reason they arent inlined and just call LIST_APPEND is because they are implemented like inline generators (which require the code object) and use most of the same code and logic to compile

rapid sparrow
#

ah.. so not a function with yield

#

I find these preferable, very rarely write them "out-of-line"

rugged sparrow
#

that (a) leaks names into the outer scope, and (b) requires adding new compiler logic that differs from the generator logic

#

!e ```py
[x for x in range(1)]
print(x)

night quarryBOT
#

@rugged sparrow :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 'x' is not defined
rugged sparrow
#

this would not fail given your version (some may say thats a good thing, but that also differs from inline generator semantics as well)

#

fair but the point still stands

#

also the PEPs that added list comprehensions and generator expressions both specify it as a syntactical change, not a core change

#

that means that changes to the eval loop should not be required for implementation

rugged sparrow
#

it does

brazen geyser
#

is there any possible code that, when added at the top level of a module, could change the __code__.co_code of a function below it before the module is even executed?

#
source_original = """
def func():
    pass
"""

source_altered = f"""
# code here to change the compiled bytecode of func

def junk():
    pass

{source_original}
"""

code_original = compile(source_original, "", "exec")
code_altered = compile(source_altered, "", "exec")

assert (
    code_original.co_consts[-3].co_code !=
    code_altered.co_consts[-3].co_code
)

you can use this for testing if you like

#

oh, and you can change the signature of func as long as its the same in both

#

basically im trying to figure out how much of a module's code you need to give the compiler the correct context when compiling a function (including arbitrarily nested ones, and methods). safest bet seems to be to use the whole module then extract the function bytecode from that, but i'm wondering if it's safe to use a subset of the module code instead, like just grabbing whatever's nearest from the top level leading to that function and using that.

sick hound
#

is it possible to modify *iterable (unpacking iterables into func args) behavior?

#

for example make it unpack double the iterable's content

#

if its a list of ints, make it unpack all those ints but squared

rugged sparrow
#

!e ```py
def doubler(it):
for v in it:
yield v
yield v

print([*doubler(range(2))])```

night quarryBOT
#

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

[0, 0, 1, 1]
rugged sparrow
#

@sick hound like that?

sick hound
#

no no like actually modifying the values, eg [1, 2, 3] turns into [1, 4, 9] when unpacking

#

and without having to add a doubler() there

brazen geyser
#

one way could maybe be to use sys.settrace. you could track code execution, down to individual lines and instructions. then when encountering an unpack do it yourself into the frame.

#

another way could be to use an import hook + ast, or a custom codec to change the unpacking into whatever you want

sick hound
#

do you have any website explaining that or any resource

brazen geyser
sick hound
#

nice, thanks

brazen geyser
#

a frame object keeps track of the current execution info, for example the bytecode being currently run, what was the previous function being run, the globals, locals, etc

#

!e

import inspect

def what_called_me():
  current_frame = inspect.currentframe()
  previous_frame = current_frame.f_back
  print(inspect.getframeinfo(previous_frame))

def test():
  what_called_me()

test()
night quarryBOT
#

@brazen geyser :white_check_mark: Your eval job has completed with return code 0.

Traceback(filename='<string>', lineno=9, function='test', code_context=None, index=None)
brazen geyser
#

if you scroll down a little on the inspect doc you can see a list of what variables frame objects have

#

there's something called a 'call stack'. this is more or less a list of frame objects. every time a function is called, a module is executed or a class is defined, a new frame is added on top of the call stack to keep track of the code being executed inside of it. there might be other cases where a new frame is added too but i cant remember atm if so.

#

the call stack comes in handy when figuring out where to continue off of after the current function returns, or to print helpful error messages pointing to where an exception occurred, since frames keep track of all that.

sick hound
#

woah, thanks for taking the time to explain it all that clearly

brazen geyser
floral meteor
rapid sparrow
#

but 99.99% of the time it shouldn't

floral meteor
#

well how do we make it so that 0% of the time it shouldn't?

brazen geyser
golden finch
#

(that example probably doesn't work)

brazen geyser
#

im looking for changes before the module is executed

#

i.e. something thatll change the bytecode of a function below it purely during compilation

golden finch
#

I don't believe that's possible (though I'm not aware of the import hacks, which could 50/50 do this)

brazen geyser
#

for example, having a value defined in an outer scope can change which LOAD instruction gets used inside the function

golden finch
#

#bot-commands message
working version for posterity

#

I think you'd have to mess with imports to do that

brazen geyser
#

not so much something im trying to do, just want to know if i should take into account for something im working on atm

golden finch
#

Are you evaluating user input?

brazen geyser
#

im transforming and recompiling code

#

not from user input, just ordinary files

#

then after recompiling im putting the code back into the function it originally came from

#

textwrap.dedent(inspect.getsource(function)) doesnt cut it for all functions because it can leave out some important context that affects compilation, so instead im recompiling the entire module with changes done to the specific function

#

and then after that its just a matter of traversing the recompiled meodule's co_consts to get the new function code

rapid sparrow
brazen geyser
#

ideally though, instead of recompiling the entire module, i'd want to cut down the code to just the bits that are context relevant. it seems like that would be whatever ancestor node is at the top level, but im not sure so just sticking with the whole module for now

rapid sparrow
#

you mean looking at the source AST?

brazen geyser
#

yeah, i mean ast node

rapid sparrow
brazen geyser
#

ive already got it working

#

the issue is more to do with potential pitfalls

rapid sparrow
#

I'd like to see it

brazen geyser
#

should be ready soon, getting the repo up and going and all that now

#

it relies on line number to make a mapping from code -> node -> code which admittedly isnt the best option but couldnt really think of any better alternative ast markers

rapid sparrow
#

my experience (I think for the same reason typing.get_type_hints is problematic when deferred annotations are used) is it's difficult to get the scopes exactly right for any context in order to make sure all the right names are available to the compiler

#

but if you have something that works, that'd be amazing

brazen geyser
floral meteor
#

me trying to figure out what I wrote half a year ago to relearn python:

#

this is how a mathematician writes python

#

I'm actually starting to understand this.

#

time to write an image deepfryer now

maiden river
#

we can
p = print

#

p(1,2,3,4)

#

1 2 3 4

#

is there a way to 'rename' keywords too ?

#

like custom names for 'for','import' etc

coral kernel
#

why would you want that?

floral meteor
#

There is it's just too tedious to be worth it

maiden river
#

pls share
i wanna see how tedious it is : )

coral kernel
#

very

#

it's the basic syntax, you'd need to work on the parser level

native wave
restive void
#

Alternatively: codec, import hook, ...

coral kernel
#

i don't think import hook would work on files that have syntax errors

snow beacon
coral kernel
#

you could pre-process the code though, replace the keywords before parsing

native wave
sick hound
#

is there any resource to get started with obfuscating python?

#

this is some interesting shit i wanna do

maiden river
floral meteor
#

and my deepfryer is complete!

coral kernel
maiden river
coral kernel
#

if they want to read any python code, they'd need to learn it either way

floral meteor
#

The results do not pass the explicit filter, it's so cursed

coral kernel
maiden river
#

so was wondering if there's an easy way to change those 'for' 'if''s into somethin else

snow beacon
coral kernel
#

no idea what the vars mean, but at least i can guess the what it does

coral kernel
maiden river
floral meteor
#

I can set the constant to deepfry at

coral kernel
#

i wouldn't recommend it though, for the simple reason that they couldn't even read the help() without confusion

#

let alone SO

floral meteor
#

!e would you catch this?

print(*[0x00for x in input("hello world!")])
night quarryBOT
#

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

15
tiny knot
#

it shows error in editor but works in terminal

#

what the heck

floral meteor
#

the editor is dumb lol

#

Here is my deepfryer, enjoy yourselves

import PIL.Image
def deepfry(victim='victim.png', cursed='cursed.png',constant=380):
  Im = PIL.Image.open(victim)
  x,y = Im.size
  target = PIL.Image.new('RGB',(x,y),0xFF0000if constant>0else 0x0000FF)
  for j in range(y):
    for i in range(x):
      if sum(Im.getpixel((i,j))[:3])>abs(constant):
        target.putpixel((i,j),0x0000FFif constant>0else 0xFF0000)
  target.save(cursed)
  target.close(),Im.close()
  return 0
if __name__=='__main__':deepfry(constant=100)
tiny knot
#

oh it doesn't show error in pycharm

#

only vs code

floral meteor
#

pycharm is smort

tiny knot
#

pycharm holds it's "smart" title

maiden river
#

i wonder if regex has the capability tho

floral meteor
coral kernel
#

honestly, if it's about teaching programming to someone who doesn't understand english, i would probably recommend a no-code language even

#

something graphical without any code-constructs at all

floral meteor
#

or just start with brainfuck

#

or maybe even ASM

floral meteor
#

I remade the logo

maiden river
coral kernel
#

go ahead 😉

maiden river
#

: )

#

gotta learn this regex first ;-;

maiden river
floral meteor
#

Make it harder to read

sonic river
rapid sparrow
floral meteor
#

I think only a robot could read that

maiden river
#

: ) basically

maiden river
#

saying from my sanskrit tests with gpt-3

floral meteor
#

That's the code for the deepfryer, deepfried

rapid sparrow
#

it seems to be blurry and have alternating thick and thin letters. maybe it's subpixel anti-aliasing gone bad? 🤣

last locust
#

I know this isn't a help channel as such but I feel like the people here will know.

How can I redirect stdout such that I can assign to it. E.g. if I did help_text = help(list.sort) I could then do print(help_text) to get the help text

Edit:
this seems to work

import io
import sys

old_stdout = sys.stdout

s = io.StringIO()
sys.stdout = s
print("test")
sys.stdout = old_stdout

print(s.getvalue())
unreal anvil
#

<@&267628507062992896>

#

??

#

help

floral meteor
#

cos I rounded down

last locust
#

Please don't ping users/roles for help. Just ask your question in a help channel (see #❓|how-to-get-help) and someone will help you when they can. @unreal anvil

floral meteor
#

!e ```py
from ctypes import py_object as p
class annotations(metaclass=lambda*a:type(*a)()):
q={}
def setitem(self, this, that):
if this in globals():
dict.update(globals(),{this:that(globals()[this])})
else:self.q[this]=that
def getitem(self, this):
if this in self.q:return q[this]
return globals()[this].class
def del(self):
p.from_address(id(globals())+8).value = dict
print("Unused variables:",*self.q)

class flogbals(dict):
def setitem(self, this, that):
if this in annotations.q:that=annotations.q.pop(this)(that)
dict.update(globals(),{this:that})
p.from_address(id(globals())+8).value=flogbals

#start
a:str
a = 6
b:str = 9
c: int = a + b
print(c)
#end

night quarryBOT
#

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

69
floral meteor
#

well it still does it but doesn't clean up properly

last locust
#

!e ```py
import difflib
import io
import site; site.main()
import sys

def get_difference(a: str, b: str) -> list[tuple[int, str]]:
return [(i, x) for i, x in enumerate(difflib.ndiff(a, b)) if x[0] != ' ']

def get_actual_help_text(item):
old_stdout = sys.stdout
s = io.StringIO()
sys.stdout = s
help(item)
sys.stdout = old_stdout
return s.getvalue()

def get_generated_help_text(item):
item_class_name = type(item).name + ":"
method = item.name.split('.')[-1]
signature = item.text_signature.replace("$", "") or "(...)"
item_doc_string = "\n".join(map(lambda s: " " * 4 + s, item.doc.split("\n")))
return (
f"Help on {item_class_name}\n\n"
f"{method}{signature}\n"
f"{item_doc_string}\n\n"
)

def test_help_texts_match(item):
actual_help_text = get_actual_help_text(list.sort)
my_help_text = get_generated_help_text(list.sort)

try:
    assert actual_help_text == my_help_text
except AssertionError:
    print(get_difference(actual_help_text, my_help_text))
else:
    print(f"Help texts for list.{item.__name__} are equal!")

for attr_name in dir(list):
attr = getattr(list, attr_name)
if callable(attr):
test_help_texts_match(attr)

night quarryBOT
#

@last locust :white_check_mark: Your eval job has completed with return code 0.

001 | Help texts for list.__add__ are equal!
002 | Help texts for list.type are equal!
003 | Help texts for list.__class_getitem__ are equal!
004 | Help texts for list.__contains__ are equal!
005 | Help texts for list.__delattr__ are equal!
006 | Help texts for list.__delitem__ are equal!
007 | Help texts for list.__dir__ are equal!
008 | Help texts for list.__eq__ are equal!
009 | Help texts for list.__format__ are equal!
010 | Help texts for list.__ge__ are equal!
011 | Help texts for list.__getattribute__ are equal!
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/elixupakaz.txt?noredirect

floral meteor
#

!e ```py
from ctypes import py_object as p
class annotations(metaclass=lambda*a:type(*a)()):
q={}
def setitem(self, this, that):
if this in globals():
dict.update(globals(),{this:that(globals()[this])})
else:self.q[this]=that
def getitem(self, this):
if this in self.q:return q[this]
return globals()[this].class
def del(self):
print("Unused variables:",*self.q)

class flogbals(dict):
def setitem(self, this, that):
if this in annotations.q:that=annotations.q.pop(this)(that)
dict.update(globals(),{this:that})
def start():p.from_address(id(globals())+8).value=flogbals
def end():p.from_address(id(globals())+8).value=dict

start()
a:str
a = 6
b:str = 9
c:int = a + b
d:dict
print(c)
end()

night quarryBOT
#

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

001 | 69
002 | Unused variables: d
floral meteor
#

perfect

copper iris
#

Hey can I get assistance in python over here?

night quarryBOT
#

contextlib.redirect_stdout(new_target)```
Context manager for temporarily redirecting [`sys.stdout`](https://docs.python.org/3/library/sys.html#sys.stdout "sys.stdout") to another file or file-like object.

This tool adds flexibility to existing functions or classes whose output is hardwired to stdout.

For example, the output of [`help()`](https://docs.python.org/3/library/functions.html#help "help") normally is sent to *sys.stdout*. You can capture that output in a string by redirecting the output to an [`io.StringIO`](https://docs.python.org/3/library/io.html#io.StringIO "io.StringIO") object. The replacement stream is returned from the `__enter__` method and so is available as the target of the [`with`](https://docs.python.org/3/reference/compound_stmts.html#with) statement:

```py
with redirect_stdout(io.StringIO()) as f:
    help(pow)
s = f.getvalue()
```  To send the output of [`help()`](https://docs.python.org/3/library/functions.html#help "help") to a file on disk, redirect the output to a regular file...
astral rover
#

do you want this?

floral meteor
#

well that exists cool

#

I used to do it manually

brazen geyser
#

pydoc's in the stdlib, but not very well documented

floral meteor
#

this is how I do it generally: ```py
class redirect_stdout:
def enter(self, target):
self._kerfunkles = sys.stdout or sys.stdout
sys.stdout = target
return target
def exit(self, *fuckit):
sys.stdout.close()
sys.stdout=self._kerfunkles
with redirect_stdout(open('example.txt'))as f:
help(pow)

#

write it from scratch, and you can tweak it.

rapid sparrow
#

i dont know how long it's been there

#

nice vararg .. that's a pythonic name if I ever saw one

fleet bridge
#

__enter__ takes no arguments, only self

astral rover
#

!e py while True or a: pass

night quarryBOT
#

@astral rover :warning: Your eval job timed out or ran out of memory.

[No output]
astral rover
#

never compiles

rugged sparrow
#

it compiles it just loops infinitely

astral rover
#

try it :)

#

on 3.9+

rugged sparrow
#

wait what

astral rover
#
James@Jamess-Air ~ % python3
Python 3.10.0 (v3.10.0:b494f5935c, Oct  4 2021, 14:59:20) [Clang 12.0.5 (clang-1205.0.22.11)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> while True or a: pass
... 
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^Z
zsh: suspended  python3
James@Jamess-Air ~ % ```
rugged sparrow
#

!e py print(compile('while True or a: pass', '', 'exec'))

night quarryBOT
#

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

[No output]
astral rover
rugged sparrow
#

i was about to ask lol

#

thats a cool bug tho

real brook
#

does this count?

snow beacon
real brook
#

yeah i couldnt find a way to get it in there

snow beacon
#

Does C use any colons?

real brook
#

yeah and you cant have it in macros

snow beacon
#

You could make main() and numbers expand to something you can put before and after a colon.

#

Then you could put the colon between them.

real brook
#

yeah

#

that would be a good idea

snow beacon
#

Also, the list won't work in Python.

#

It takes one iterable argument, rather than any number of arguments.

real brook
#

right

#

havent done python in a while

real brook
#

I got the colon thing working

sick hound
#

I can't tell if that's C and your screwing with define or python comments

golden finch
#

would likely run in either

cedar vessel
#

Where can I ask questions on structure of simple programs?
I am newer to Python.

#

My friends dad is in the hospital right now and is all he can do is move a finger or two at a time for now. We want to code a program where he can use 1 button on a keyboard to type sentences... like the guy in breaking bad...

#

Where should I start... any tips are HIGHLY appreciated.

#

Nevermind

snow beacon
maiden vine
#

I once saw a way of building a class that was its own metaclass

#

Or atleast did a pretty good job pretending to be

#

Does anyone have that handy?

golden finch
#

yes, I do

#

one second

#
class A(type):pass
class B(type,metaclass=A):pass
B.__class__ = B
#

this?

golden finch
#

Is there any way to chain metaclasses past depth-2?

#

i.e for all objects, can their __class__.__class__ be anything other than type?

floral meteor