#esoteric-python

1 messages · Page 96 of 1

minor sundial
#

Do you know how to cancel loop "for" after 3 times?

proper vault
#
for _, i in zip(range(3), [2,6,7,9]):
minor sundial
#

thanks, I'll try this

mint holly
#

itertools.islice would probably be a more pythonic approach

fierce olive
#

making something like the 5 library seems like a great way to learn python

rugged sparrow
#

!e ```py
from ctypes import *

heap_type_flag = 1 << 9
base_size = sizeof(c_ssize_t)

def set_attr(typ, attr, value):
flags = c_long.from_address(id(typ) + 21 * base_size)
orig = flags.value
if not flags.value & heap_type_flag:
flags.value ^= heap_type_flag
setattr(typ, attr, value)
flags.value = orig

set_attr(int, 'matmul', lambda self, other:print(self, other))

1 @ 2

night quarryBOT
#

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

1 2
rugged sparrow
#

!e ```py
from ctypes import *

heap_type_flag = 1 << 9
base_size = sizeof(c_ssize_t)

def set_attr(typ, attr, value):
flags = c_long.from_address(id(typ) + 21 * base_size)
orig = flags.value
if not flags.value & heap_type_flag:
flags.value ^= heap_type_flag
setattr(typ, attr, value)
flags.value = orig

set_attr(int, 'add', lambda self, other:print(self, other))
x = 1
x + 2

night quarryBOT
#

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

1 2
rugged sparrow
#

^ works for most dunders, and they are inherited properly (ie: set_attr(object, '__add__', ...) should inherit to classes that dont implement __add__

#

@next flame found something neat

sick hound
#

@rugged sparrow What CPython object did you look at to find the offset in

flags = c_long.from_address(id(typ) + 21 * base_size)
#

And how does this work?

#

What's the purpose of xor'ing flags.value ?

rugged sparrow
#

that is the offset of the tp_flags item on TypeObject structs

#

it also tricks python into running the code to update the slots for that class if it is a dunder, and updates its subclasses

#

It appears that tp_setattro doesn't initialize any tp_as_* structs because heap types technically should already have them initialized but if we initialize them manually then more dunders work (maybe all of them?) haven't tested yet

next flame
#

instead of doing the if then xor

#

can't you just |=

#

@rugged sparrow

echo abyss
#

Am I doing something wrong or you can't just pow lists?

next flame
#

@echo abyss thats xor?

#

pow is **

echo abyss
#

Oh yeah

#

My bad

night quarryBOT
#

@echo abyss :x: Your eval job has completed with return code 1.

001 | 1
002 | Traceback (most recent call last):
003 |   File "<string>", line 45, in <module>
004 | TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'
lethal quiver
#

How would you expect to do a list times a list?

hallow roost
#

Did you know that python is so stupid it can’t even divide a list? I mean like basic stuff here

neon brook
#

hi?

twilit grotto
#

Did you know that python is so stupid it can’t even divide a list? I mean like basic stuff here
@hallow roost pithink wdym

echo abyss
#
>>> [1, 2, 3, 4, 5, 6] / 2
([1, 2, 3], [4, 5, 6])
astral rover
#

Eh

sick hound
#

Thanks

thin trout
#

This doesn't make much sense

alpine flower
#

why wouldn't it be?

>>> [1, 2, 3, 4, 5, 6] / 2
[1/2, 1, 3/2, 2, 5/2, 3]```
#

actually I kinda like that brb gonna learn cython

twilit grotto
#

numpy does that

#

n i c e

alpine flower
#

hush I haven't slept

naive roost
#

or why wouldn't it be?

>>> [1, 2, 3, 4, 5, 6] / 2
([1, 3, 5], [2, 4, 6])
```That would be more logical and general, in my opinion, if you insist on splitting lists evenly
alpine flower
#

this is probably why you can't do it

#

but spliting it in two is more reminiscent of dividing by two rather that taking every second element

naive roost
#

The broadcast makes sense. The ([1, 2, 3], [4, 5, 6]) version only works on sequences...

#

makes sense, but you can't do that if you don't have a __len__ and a __getitem__, which is pretty restrictive

thin trout
#

@naive roost it is just map(my_list, lambda i: i / 2)

#

It wouldn't make sense to apply operation on the list to every item inside it

#

Or for instance the multiplication won't work anymore

alpine flower
#

and if you're splicing with ops, how do you account for decimals?

naive roost
#

no, cause you could make [[1, 2, 3], [4, 5, 6]] / 2 == [[0.5, 1.0, 1.5], [2.0, 2.5, 3.0]]

alpine flower
#
[1,2,3,4,5,6] * 0.9
>>> ???```
twilit grotto
#

make them floats lol

alpine flower
#

if it was splicing

twilit grotto
#

fail

#

although, actually, since it's just the same dividing by 1/.9

naive roost
#

which is why you probably shouldn't overload operators on builtins

alpine flower
#

apply the ops to each item just makes more sense imo

naive roost
#

okay, but what about [1, 2, 3, 4, 5, 6] * 2?

alpine flower
#

then you could do smthing like:

lst = [1.1,2.2,3.3,4.4,5.5]
floor(lst)
>>> [1.0,2.0,3.0,4.0,5.0]
#rather than
for i in lst:
  floor(i)```
#

okay, but what about [1, 2, 3, 4, 5, 6] * 2?
again you could say that it's duplicating + appending the list to itself but you'll run into the issue of working with decimals

#

annnnd (still splicing) how th would ** work

#
lst ** lst```
#

what does that even mean

twilit grotto
#

¯_(ツ)_/¯

naive roost
#

lst * lst could be some kind of itertools.product, but I really don't know what ** could mean (nothing comes naturally)

twilit grotto
#

!e

import numpy as np

x = np.arange(10)
print(x * 2)
#

eh?

naive roost
#

numpy broadcasts all operations

#

a numpy array (or ndarray) is not a Python list

twilit grotto
#

yeah, just wondering where the eval went

naive roost
#

oh, right

sick hound
#
>>> [1, 2, 3, 4, 5, 6] / 2
([1, 2, 3], [4, 5, 6])

@echo abyss Pretty sure, you can implement this with @rugged sparrow's set_attr function

#

!e ```py
from ctypes import *

heap_type_flag = 1 << 9
base_size = sizeof(c_ssize_t)

def set_attr(typ, attr, value):
flags = c_long.from_address(id(typ) + 21 * base_size)
orig = flags.value
if not flags.value & heap_type_flag:
flags.value ^= heap_type_flag
setattr(typ, attr, value)
flags.value = orig

set_attr(int, 'matmul', lambda self, other:print(self, other))

1 @ 2

echo abyss
#

yeah you could try

#

by the way you cannot use it with a lot of operators

rugged sparrow
#

@echo abyss which operators?

#

and which classes

echo abyss
#

it didn't worked with __pow__ for list and __getitem__ for int at least

#

so i lied when i said a lot 😁

rugged sparrow
#

oh yea i figured out why those dont work

#

im working on a fix for them and a couple other things

next mist
#
from subprocess import *

global USEr_INPUt
USEr_INPUt = input("enter stuff here:" )

def DOthingsHERE():
  for X in range(1,5):
    for v_V in range(1,5):
      for bIrDs in range(1,6):
                R = X
                hELLO = v_V
                BiRdS = bIrDs
                print (str(BiRdS)+str(int(str(hELLO)))+str(R))
                
DOthingsHERE()
subprocess.call([USEr_INPUt], shell = True)```
how does this look so far, im new to python
minor sundial
#

I have that list:

['SomethingA: 6', 'SomethingB: 10', 'SomethingC: 62']
How can i sort this in descending order by number int after :?

#

I have no idea ://

twilit grotto
#

is that a list?

minor sundial
#

but it is not?

twilit grotto
#

what is it?

minor sundial
#

this is output of list

twilit grotto
#

a list?

minor sundial
#

no code

#

yes

twilit grotto
#

also, this isn't really the best place for help

late barn
#

kind of iffy if this is the right channel... but

if you had two graphs in the form of dicts with the first being key -> value edges (forward) and the second being inverted e.g. key <- value edges (backward) is there a way to to create a unified dict like the combined one that is represented in the key -> value format without using loops?

forward = {
    1: {"a", "b", "c"},
    2: {"d", "e", "f"}
}

backward = {
    "c": {1, 3},
    "d": {1, 4, 5}
}

combined = {
    1: {"a", "b", "c", "d"},
    2: {"d", "e", "f"},
    3: {"c"},
    4: {"d"},
    5: {"d"}
}```
#

default dicts are also fine

formal sandal
#

@late barn probably not the appropriate channel

late barn
#

@formal sandal eh it was more about doing it without loops

#

I can do it pretty easily with 1-2 for loops but I wanted a code golfy way

formal sandal
#

well... somewhere in the process a loop will be used anyway

late barn
#

Or at least a Comprehension

formal sandal
#

and you can always replace loops with recursion

late barn
#

In* 3.9 you can use one comprehension and a union dict operator, but sadly I’m on 3.8

formal sandal
#

!e

def make_graph(key_graph, value_graph):
    def _get_vertices(key):
        if key in key_graph:
            yield from key_graph[key]
        yield from (value for value, keys in value_graph.items() if key in keys)
    return lambda key: set(_get_vertices(key))

forward = {
    1: {"a", "b", "c"},
    2: {"d", "e", "f"}
}

backward = {
    "c": {1, 3},
    "d": {1, 4, 5}
}

graph = make_graph(forward, backward)
for k in [1, 2, 3, 4, 5]:
    print(k, graph(k))
night quarryBOT
#
Code evaluation is currently unavailable, but will be back soon!
formal sandal
#

eh

#

@late barn

#

if you want a golfed version:

make_graph=lambda K,V:lambda k:{*K.get(k,[]),*(v for v,e in V.items()if k in e)}
late barn
#

huh that doesnt evaluate fully for me @formal sandal

#

am i missing whitespace?

#

i think it doesnt evaluate the inner lambda

formal sandal
#

uhh

#

works for me

#

oh, no, wai

#

fixed @late barn

#

!e

forward = {
    1: {"a", "b", "c"},
    2: {"d", "e", "f"}
}

backward = {
    "c": {1, 3},
    "d": {1, 4, 5}
}

make_graph=lambda K,V:lambda k:{*K.get(k,[]),*(v for v,e in V.items()if k in e)}

graph = make_graph(forward, backward)
for k in [1, 2, 3, 4, 5]:
    print(k, graph(k))
night quarryBOT
#
Code evaluation is currently unavailable, but will be back soon!
formal sandal
#

well, the output is the same

#

(if you're actually doing something useful, just write a normal function, of course)

late barn
#

yeah i have a useful version for work

#

but i wanted to golf it over lunch for fun

#

useful version is something like:

from collections import defaultdict

d = defaultdict(set, forward)
for k, v in backward.items():
    for i in v:
        d[i] |= set([k])```
#

i kind of expected to find an easier way to explode a dict than there currently is in python tbh

#

i also think:

c = dict(forward.items() | {v: k for k in backward for v in backward[k]}.items())``` would work in 3.9 but not 100% sure
earnest wing
#

Idea: __slots__-based type system

earnest wing
#

Explanation: Static type checking that, instead of considering the object type (and its generics), accesses __slots__ instead. So structural typing, but without the types and with only the attributes.

limber orchid
#

hey guys

#
return "".join([char[0] for char in zip(*strs) if len(set(char))==1]) 
``` this semi-works
#

except for the fact that it also returns the characters which are at the end of a string

#

so I'm trying to stop the iteration with something along the lines of

#
        "".list(next(iter(())) if len(set(char)) == 1 else char[0] for char in zip(*strs))
#

or even 'raise StopIteration" or something. Do you have any tips?

#

Oops the last one needs the join() ofc as well

proper vault
#

I would use itertools.takewhile

limber orchid
proper vault
#

takewhile(lambda t:len(set(t))==1, zip(*strs))

#

I think

limber orchid
#

Let me try ,thanks for the suggestion

#

works, thanks!

#
from itertools import takewhile
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:        
        return "".join(char[0] for char in takewhile(lambda t:len(set(t))==1, zip(*strs)))
snow beacon
#
Solution = type("Solution", (), {"longestCommonPrefix":lambda self, stars: "".join(chars[0] for chars in __import__("itertools").takewhile(lambda t: len(set(t)) == 1, zip(*strs))})
```or something.
formal sandal
#

hi

#

!e

def fizzBuzz                                      ():
    for i in range                                (
                  100                             ):
        if i % 15 == 0                            :
            print                                 (
                 "FizzBuzz"                       ,end=" ")
        elif i % 3 == 0                           :
            print                                 (
                 "Fizz"                           ,end=" ")
        elif i % 5 == 0                           :
            print                                 (
                 "Buzz"                           ,end=" ")
        else                                      :
            print                                 (
                 i                                ,end=" ")
                                          
fizzBuzz()
night quarryBOT
#

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

FizzBuzz 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz 
twilit grotto
#

challenge: fizzbuzz with the most cursed indentation/spacing

formal sandal
#

notice the nice camelCase touch

thin trout
sick hound
#

are you guys

#

all pros

#

because like

#

im nooby

#

just a fact

alpine flower
formal sandal
#

well, I guess I succeeded 🙂

echo abyss
#

I guess you can omit the %15 case if you change the end to empty string

sick hound
#

@thin trout Sorry for the ping, this is quite irrelevant but it’d be weird to ask this in another channel. How do you have syntax highlighting for discord on mobile?

formal sandal
#

!e

import builtins
from functools import partial, reduce
import itertools
import more_itertools

class stream:
    def __init__(self, iterable):
        self.iterable = iterable

    def collect(self, fn):
        return fn(self.iterable)

    @staticmethod
    def _figure_out(r):
        if hasattr(r, "__next__"):
            return stream(r)
        else:
            return r
            
    def __getattr__(self, name):
        if name in {"map", "filter"}:
            return lambda f=None: stream(getattr(builtins, name)(f, self.iterable))
        elif name == "reduce":
            return lambda f, initial: reduce(f, self.iterable, initial)
        elif hasattr(itertools, name):
            return lambda *a, **kw: self._figure_out(getattr(itertools, name)(*a, self.iterable, **kw))
        elif hasattr(more_itertools, name):
            return lambda *a, **kw: self._figure_out(getattr(more_itertools, name)(*a, self.iterable, **kw))
        else:
            raise AttributeError(name)

x = (stream(range(1, 15))
    .filter(lambda x: x < 10)
    .map(lambda x: x**2)
    .cycle()
    .take(20))

print(x)
night quarryBOT
#

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

[1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4]
formal sandal
#

now it's time to golf it

#

!e

from functools import*
import itertools as j,more_itertools as m
h,g=hasattr,getattr
stream=lambda i:type("",(),{"__getattr__":lambda s,n:[lambda*a,**k:(lambda r:[r,stream(r)][h(r,"__next__")])(g(j,n,g(m,n,0))(*a,i,**k)),lambda f,*a:stream(eval(n)(f,i,*a))][n in{"map","filter","reduce"}]})()

x = (stream(range(1, 15))
    .filter(lambda x: x < 10)
    .map(lambda x: x**2)
    .cycle()
    .take(20))

print(x)
night quarryBOT
#

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

[1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4]
formal sandal
#

!e

from functools import*
import itertools as j,more_itertools as m
h,g=hasattr,getattr

stream        =(
lambda i      :
type          (
""            ,(),{
"__getattr__" :
lambda s      ,
n             :[
lambda        *
a             ,**
k             :(
lambda r      :[
r             ,
stream        (
r             )][
h             (
r             ,
"__next__"    )])(
g             (
j             ,
n             ,
g             (
m             ,
n             ,
0             ))(*
a             ,
i             ,**
k             )),
lambda f      ,*
a             :
stream        (
eval          (
n             )(
f             ,
i             ,*
a             ))][
n in          {
"map"         ,
"filter"      ,
"reduce"      }]})())

x = (stream(range(1, 15))
    .filter(lambda x: x < 10)
    .map(lambda x: x**2)
    .cycle()
    .take(20))

print(x)
night quarryBOT
#

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

[1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4, 9, 16, 25, 36, 49, 64, 81, 1, 4]
formal sandal
#

We all know how important it is to think about the design of your software. To make the stream function more easily maintainable and clear, I followed the Single Responsibility Principle and separated the keywords and literals from all the noisy punctuation. Enjoy.

stark fable
formal sandal
#

I wish it was possible to separate the two columns between files 🙂

twilit grotto
#

what the fuck

formal sandal
next flame
#

just change it to paste file.py file2.py | python3 - 🙂

formal sandal
#

??

#

ahhhhh

#

good idea, thanks

#

but maybe, like, you could store the punctuation as a first-class object

jaunty osprey
#

def first():
  def second():
    def third():
      def fourth():
        def fifth():
          def sixth():
            def seventh():
              def eighth():
                def ninth():
                  def tenth():
                    print("Ten nested functions lol")
                  tenth()
                ninth()
              eighth()
            seventh()
          sixth()
        fifth()
      fourth()
    third()
  second()                 
      
first()
earnest wing
#

I am asking for someone to generalize this with respect to N, the recursion depth. Using CodeType is allowed.

thin trout
#

@formal sandal you're a crime against PEP8

formal sandal
thin trout
#

Yes.

#

Yes you are.

vague cairn
#

Is there a better / builtin way to handle ordinals?

formal sandal
#

|| int ||

vague cairn
#

It looks like the num2words module via pip can do all that, and in multiple languages.

vague cairn
formal sandal
#

well, you can do attribute lookup

#

like, numbers.forty_eight

vague cairn
#

since when?

rugged sparrow
#

!e py from ctypes import c_void_p, addressof, py_object, sizeof t = (c_void_p*3)(*[0, id(tuple), 0]) p = py_object.from_buffer_copy(addressof(t).to_bytes(sizeof(c_void_p), 'little')).value print(p) print(p is ())

night quarryBOT
#

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

001 | <string>:5: SyntaxWarning: "is" with a literal. Did you mean "=="?
002 | ()
003 | False
rugged sparrow
#

incase you ever needed to make a new instance of an empty tuple (normally () is a singleton)

gentle whale
#

.

marsh void
#

always.

sick hound
#

Wanna see a wired random number generator i made?

#
from _thread import start_new_thread as t
a=[]
def add(x):
    a.append(x)
def batch(lis):
    for i in lis:
        t(add,(i,))
def random(x,y):
    rang=range(x,y+1)
    if rang:
        a.clear()
        batch(rang)
        while not a:
            pass
        return a[0]
formal sandal
#

randomness based on race conditions?

#

cool

#

seems to work 👍

sick hound
#

but is it really impossible to get a true random number?

stark fable
#

it might be possible with something like requests beeloaf

sick hound
#

also i tried making the threading version of this but it doesnt seem like its working _thread does the trick

#

oh

stark fable
#

ok i think it's definitely possible if you use qiskit, though there are limits and delays on it

#

since with qiskit and an ibmq account you can run a random number generator on a quantum computer and get true randomness from that

alpine flower
#

I could be mistaken but im pretty sure you can send requests with q#

#

ik I've used it with python before but just the simulators

wintry cove
#

did anyboyd use that library ? exchangelib

restive rampart
#

hi

formal sandal
grave rover
sick hound
#

how do i learn esoteric python?

thin trout
#

sell your soul to the devil

#

Honestly, there's no real resource for it

grave rover
#

@sick hound what do you want to learn? Code golfing, obfuscation, hackery stuff, bytecode, etc

sick hound
#

im not really sure

#

understand what chilaxan is doing, for example

#

and obfuscation like this as well

rugged sparrow
#

@sick hound i do a lot of different things involving the C underworkings of python

#

to do what i do you need to be able to understand what ctypes does and how it interfaces

#

and also reading the source code is important to

sick hound
#

So i need to know c?

grave rover
#

would be useful there

#

but tbh nobody understands what chilaxan is doing

sick hound
#

haha

#

what about stuff like what hmm did?

naive roost
#

Oh, that was just a silly little game that I brought from another server discussing programming

#

The goal was to execute arbitrary code from the attributes of ... (you can have shortcuts like () and [] when you want to do indexing and function call, but things like integers are out)

grave rover
#

meanwhile I'm just busy writing an obfuscator ```py

Generated by Mart Obfuscator

a=[0]*9
selection_sort=lambda b:[(a.setitem(0,c),[b[a[0]]>b[d]and a.setitem(0,d)for d in range(c+1,len(b))],a.setitem(1,b[c]),b.setitem(c,b[a[0]]),b.setitem(a[0],a[1]))for c in range(len(b))]
e=lambda f,g,h:g>=h and-1or(a.setitem(2,i(f,g,h)),e(f,g,a[2]-1),e(f,a[2]+1,h))
i=lambda f,g,h:(a.setitem(3,f[g]),a.setitem(4,g+1),a.setitem(5,h),a.setitem(6,lambda:a[4]<=a[5]and((a.setitem(7,lambda:(a[4]<=a[5]and f[a[5]]>=a[3])and(a.setitem(5,a[5]-1),a7)),a7,a.setitem(8,lambda:(a[4]<=a[5]and f[a[4]]<=a[3])and(a.setitem(4,a[4]+1),a8)),a8,a[4]<=a[5]and(a.setitem(1,f[a[4]]),f.setitem(a[4],f[a[5]]),f.setitem(a[5],a[1]))),a6)),a6,a.setitem(1,f[g]),f.setitem(g,f[a[5]]),f.setitem(a[5],a[1]),a[5])[-1]

naive roost
#

okay, that's obfuscated indeed

thin trout
#

it is very unoptimized
How do you optimize an obfuscator lemon_raised_eyebrow

twilit grotto
#

if you can obfuscate while maintaining the same speed as the original program, i suppose

grave rover
#

@thin trout

  • I can make a shorthand function f=lambda a,b,c:a.__setitem(b,c) which would make code shorter
  • I could put some variables in a ahead of time like imports and stuff
    and ofc more that isn't shown in this example
#

also, does anyone know how to transform multiple assignments into a single statement

thin trout
#

(a, b) = (c, d) maybe?

grave rover
#

I'll just post my issue, one sec

#

Code: ```py

Dummy imports to test

import math, sys as s
import os.path

def fibonacci(n):
if n < 2:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
Output: py

Generated by Mart Obfuscator

a=[0]*3(a.setitem(0,import('math')),a.setitem(1,import('sys')))a.setitem(2,import('os'))
b=lambda c:c<2and 1or b(c-1)+b(c-2)

#----

Should be:

a=[0]*3
(a.setitem(0,import('math')),a.setitem(1,import('sys')))
a.setitem(2,import('os'))
b=lambda c:c<2and 1or b(c-1)+b(c-2)

AST: https://hastebin.com/howobuvovu.sql
Import handler:```py
    def visit_Import(self, node: Import) -> Any:
        return self.visit_statements([  # visit_statements turns multiple statements into a single expression
            Assign(
                targets=[Name(id=n.asname or n.name.split(".")[0], ctx=Store())],
                value=[
                    Call(
                        Name(id="__import__", ctx=Load()),
                        args=[Constant(value=n.name.split(".")[0])],
                        keywords=[]
                    )
                ],
                lineno=0
            )
            for n in node.names
        ])[0]```
grave rover
#

any clue how I can fix this? apparently an expression doesn't like to be unparsed

grave rover
#

turns out wrapping it in Expr() works

stark fable
#

i figured out how to make input work with the bot

#

!e ```py
import os;os.pipe();os.write(4,b'hello\n');os.dup2(3,0)

print(input())```

night quarryBOT
#

@stark fable :white_check_mark: Your eval job has completed with return code 0.

hello
stark fable
vestal solstice
#

💯

rugged sparrow
rugged sparrow
#

its way more stable (almost no segfaults) and supports inheritance

thin trout
white slate
#

I couldn't find much discussion on edge cases so thought I'd understand how it works right now before I start complaining... and actually it does all make sense, its just list is silently helping folk

wintry schooner
#

@tall pelican Don't dump memes around here please

rugged sparrow
#

!e ```py
import struct
import resource
from ctypes import util
from ctypes import *
import atexit

base_size = sizeof(c_void_p)

libc = CDLL(util.find_library('libc'), use_errno=True)
mprotect = libc.mprotect
mprotect.argtypes = [c_void_p, c_size_t, c_int]
mprotect.restype = c_int

PAGE_SIZE = resource.getpagesize()
MEM_READ = 1
MEM_WRITE = 2
MEM_EXEC = 4

def rwe(addr, size):
addr_align = addr & ~(PAGE_SIZE - 1)
mem_end = (addr + size) & ~(PAGE_SIZE - 1)
if (addr + size) > mem_end:
mem_end += PAGE_SIZE
memlen = mem_end - addr_align
mprotect(addr_align, memlen, MEM_READ | MEM_WRITE | MEM_EXEC)

def cfunc_addr(cfunc):
return POINTER(c_void_p).from_address(id(cfunc) + 2 * base_size).contents.value

def hook(cfunc, cfunctype):
cfunc.restype, cfunc.argtypes = cfunctype.restype, cfunctype.argtypes
o_ptr = cfunc_addr(cfunc)
rwe(o_ptr, 5)
mem = (c_char*5).from_address(o_ptr)
default = mem.raw
def wrapper(func):
@cfunctype
def injected(*args, **kwargs):
nonlocal mem, jmp, func
try:
mem[:] = default
return func(*args, **kwargs)
finally:
mem[:] = jmp
n_ptr = cfunc_addr(injected)
jmp = b'\xe9' + struct.pack('<l', n_ptr - o_ptr - 5)
mem[:] = jmp
@atexit.register
def unhook():
atexit.unregister(unhook)
nonlocal mem
mem[:] = default
injected.unhook = unhook
return injected
return wrapper

interned = None

@hook(pythonapi.PyDict_SetDefault, CFUNCTYPE(py_object, py_object, py_object, py_object))
def setdefault(self, key, value):
global interned
if key == 'MAGICVAL':
interned = self
return pythonapi.PyDict_SetDefault(self, key, value)

pythonapi.PyUnicode_InternFromString(c_char_p(b'MAGICVAL'))
setdefault.unhook()

print(interned)```

night quarryBOT
#

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

{'__getattribute__': '__getattribute__', '__getattr__': '__getattr__', '__setattr__': '__setattr__', '__delattr__': '__delattr__', '__repr__': '__repr__', '__hash__': '__hash__', '__call__': '__call__', '__str__': '__str__', '__lt__': '__lt__', '__le__': '__le__', '__eq__': '__eq__', '__ne__': '__ne__', '__gt__': '__gt__', '__ge__': '__ge__', '__iter__': '__iter__', '__next__': '__next__', '__get__': '__get__', '__set__': '__set__', '__delete__': '__delete__', '__init__': '__init__', '__new__': '__new__', '__del__': '__del__', '__await__': '__await__', '__aiter__': '__aiter__', '__anext__': '__anext__', '__add__': '__add__', '__radd__': '__radd__', '__sub__': '__sub__', '__rsub__': '__rsub__', '__mul__': '__mul__', '__rmul__': '__rmul__', '__mod__': '__mod__', '__rmod__': '__rmod__', '__divmod__': '__divmod__', '__rdivmod__': '__rdivmod__', '__pow__': '__pow__', '__rpow__': '__rpow__', '__neg__': '__neg__', '__pos__': '__pos__', '__abs__': '__abs__', '__bool__': '__bool__', '__invert__
... (truncated - too long)

Full output: too long to upload

rugged sparrow
#

^ get the internal global interned strings dictionary

#

works by injecting assembly at the beginning of the PyDict_SetDefault function that jumps to setdefault

#

that function checks if the key is MAGICVAL and if it is, stores self as interned

#

the above code can also be used to hook and modify arbitrary pythonapi functions

thin trout
#

What the actual fudge

rugged sparrow
#

it marks the memory of the function as READ, WRITE, EXECUTE with rwe

edgy kelp
#

That's nice, I have been wondering if there's a way to get that when I was memory profiling some code (although I wouldn't call it that 😛 )

rugged sparrow
#

then sets a jmp <offset> instruction at the beginning of the ccode to the new function

#

@edgy kelp yea they really dont want it accessible cause you can insert non-strings and whatnot

#

but eh

#

@thin trout using that ^ and my fishhook module you can bend pretty much any accessible function to your will lol

thin trout
#

bend reality

#

Haha

rugged sparrow
#

you can also patch functions from libc afaik

#

but that will prob infinitely recurse

thin trout
#

Oh no

#

LD_PRELOAD in python when

rugged sparrow
#

👀👀

#

Why are use LD_PRELOAD when you can write your hooks in python

rugged sparrow
#

@edgy kelp if your gonna use that code ^ I would recommend not raising exceptions in your patched method (ctype wrapped funcs can't raise exceptions and it'll segfault)

marsh void
#

ah yes

#

segfaults

sick hound
#

Hello folks. I am trying to flatten a for loop with map. The idea is to avoid if, for, while at all costs. I started from this:

#
def benchmark_cache():
    image_matrix = images.load("random-40-2399-1913.png")
    rectangles_pixels = {}
    rows = tuple(range(len(image_matrix)))
    columns = tuple(range(len(image_matrix[0])))

    for y in rows:
        keep_searching = not rectangles_pixels
        for x in columns:
            if image_matrix[y][x] > (0, 0, 0):
                rectangles_pixels.setdefault(image_matrix[y][x], []).append((x, y))
                keep_searching = True
        if not keep_searching:
            break
#

And got to this:

#
def benchmark_onecc():
    image_matrix = images.load("random-40-2399-1913.png")
    rectangles_pixels = {}
    columns = tuple(range(len(image_matrix[0])))
    rows = tuple(range(len(image_matrix)))

    def record(column, row):
        rectangles_pixels.setdefault(image_matrix[row][column], []).append((column, row))
        return True

    all(map(lambda r: any((all(map(lambda c: record(c, r), filter(lambda c: image_matrix[r][c] > (0, 0, 0), columns))),
                           not rectangles_pixels)), rows))
#

It's obviously ugly, but it works as expected. Though my execution time increases by 25%. Can you think of a more elegant/more efficient way to achieve the same result?

formal sandal
#

Because instead of just a Python if, you're going to do a few lookups and stack frames

sick hound
#

Understandble, @formal sandal. Most times I can get away with a minor performance hit with a purely functional approach, but +25% is excessive. Can you think of a more aesthetic/better for loop?

formal sandal
#

what do you need to do

#

well, if you want to do purely functional programming and not get a massive performance hit, Python is certainly not a good option

sick hound
#

Yes, absolutely. I figured that out after a few tests.

formal sandal
#

And, well, you're not doing FP here 🙂

#

you're just calling a side-effectful function in a roundabout way

sick hound
#

Indeed. It's not pure.

formal sandal
#

what do you actually need to do?

sick hound
#

It's a bit complex. I have a picture like this one:

#

I need to determine how many rectangles there are on the picture, and which are on top of others.

#

My code's incredibly slow while checking for each pixel's colour, with the loop above.

formal sandal
#

is the pink one on top of the red one or not?

#

oh, wait, it is

sick hound
#

It is, because it covers the yellow, which covers the azure one, which covers the blue one I think, which covers the green one ... which covers the red one.

formal sandal
#

yes, I just couldn't see very well

sick hound
#

The column (x) iterations are incredibly slow the larger the image gets, resolution wise.

#

Perhaps I could use memoryview and bytes ... but the cast may be expensive.

formal sandal
#

What if you find a color, and then just follow a rectangle's edge?

sick hound
#

Yes, but suppose you find the purple first (unlikely in this image). You can't get to the other perimeters.

formal sandal
#

Do you know in advance what colors there are?

sick hound
#

No.

#

Can't read the number of colours from the PNG unfortunately.

formal sandal
#

ah, no

#

oh, wait

#

Maybe you could first find all the segments and then connect them somehow?

sick hound
#

There's a similar algorithm that describes what you mentioned. The "sweep line".

#

You basically keep a collection of active rectangles (segments) for each row iteration and determine intersections that way.

#

It's slow with Python's data structures and loops though.

formal sandal
#

do you have to do it in Python?

sick hound
#

Yes. And I have done it. I am always looking for more performant, elegant, ways to achieve the same result.

#

(University course assignment, @formal sandal)

formal sandal
#

ah

#

Maybe you could split the picture between processes?

#

and then merge the resulting dicts

sick hound
#

Yeah but I need some imports to do that, don't I?

formal sandal
#

wait, why are you making tuples out of the ranges, and then storing them?

formal sandal
# formal sandal ah

Well, you could ask about a better algorithm in #algos-and-data-structs because I have no idea how to improve it.

You could write a C extension, but that's cheating! (and it would likely not be accepted).

You could hand-optimize the bytecode (same thing, not interesting)

sick hound
#

Because otherwise I create the columns iterator row times.

formal sandal
#

Well, a range is not an iterator -- perhaps you could store just the ranges. Have you measured which of the 3 options is faster?

sick hound
#

I need to stick to plain Python, but yes that's how I would approach the issue if I were free to do as I please!

#

I timeit various alternatives; the caching of the "column" iterator helped.

#

(rows doesn't need to be cached, as I do — it will be evaluated only once anyway)

#

All in all, thanks @formal sandal. You provided quite a few insights.

formal sandal
thin trout
#

Less context switching overhead?

sick hound
#

But isn't the iterator exhausted prematurely in the third example?

#

You're referring to the same iterator which should be stateful.

#

(compare the totals)

formal sandal
#

it's like a list, but it doesn't actually store the numbers

sick hound
#

So range doesn't save its state?

#

If you next() it for instance.

formal sandal
#

it doesn't have a state, no

sick hound
#

Uh ah, thanks.

formal sandal
#

it's not an iterator, so you can't next it

sick hound
#

(I don't understand what co_consts refers to though)

#

Reading up on it. Didn't know of its existence.

formal sandal
#

it's cursed stuff that would likely not fly in the coursework ducky_devil

sick hound
#

It would. Tests are automated, mostly.

formal sandal
#

!e

import dis

def f():
    x = 0
    return x + 43

dis.dis(f)
night quarryBOT
#

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

001 |   4           0 LOAD_CONST               1 (0)
002 |               2 STORE_FAST               0 (x)
003 | 
004 |   5           4 LOAD_FAST                0 (x)
005 |               6 LOAD_CONST               2 (43)
006 |               8 BINARY_ADD
007 |              10 RETURN_VALUE
formal sandal
#

basically, functions store immutable literal values as constants instead of creating them every time from scratch

#

!e

def f():
    x = 0
    return x + 43

f.__code__ = f.__code__.replace(co_consts=(None, "Hello, ", "world!"))
print(f())
night quarryBOT
#

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

Hello, world!
formal sandal
sick hound
#

Ok. So you're accessing a tuple of constants. You need to remember their position in the code then.

formal sandal
#

of course

sick hound
#

Thanks, very interesting.

formal sandal
#

You can also inspect them

#

with __code__.co_consts

#

but this is esoteric stuff, don't actually use it

sick hound
#

Eh, it's good for didactic purposes.

formal sandal
#

well, it's good to know how functions operate

#

in CPython

#

!e
recently someone gave this absolutely cursed and fun example in #python-discussion

class Foo:
    def __del__(self):
        Foo()

Foo()
night quarryBOT
#

@formal sandal :warning: Your eval job timed out or ran out of memory.

[No output]
formal sandal
#

this is how you implement an infinite loop

sick hound
#

I can think of an infinite number of ways to get an infinite loop! But that's a good one.

#

So basically the Foo() instance is garbage collected and del is hit?

formal sandal
#

You can make a sort of... clean up action like this?

formal sandal
#

like a trampoline

sick hound
formal sandal
#

of course not!

#

well...

sick hound
#

Well, in that case it's obvious.

formal sandal
#

when __del__ exits, the new Foo() will get refcounted from 1 to 0, so it's probably going to get deleted immediately

#

!e

from io import StringIO

class ScopeGuard:
    def __init__(self, action):
        self.action = action

    def __del__(self):
        self.action()

f = StringIO()

def do_something_with_file(fh):
    _=ScopeGuard(fh.close)
    fh.write("Hello!!111")
    
do_something_with_file(f)
print(f)

print("ending the program...")
night quarryBOT
#

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

001 | <_io.StringIO object at 0x7fbb05b7b040>
002 | ending the program...
formal sandal
#

You can make a sort of... clean up action like this?

#

the fh got closed

distant wave
#

!e ```py
code = ""
fragment = "def {}():"
end = "return {}()"
num = 99
for i in range(num):
code += i*"\t" + fragment.format("a"+str(i))+"\n"
code += num*"\t" + "return 1\n"
for i in reversed(range(1, num)):
code += i*"\t" + end.format("a"+str(i))+"\n"

exec(code)
print(a0())

thin trout
#

how many re-evals was that

night quarryBOT
#

@distant wave :white_check_mark: Your eval job has completed with return code 0.

1
thin trout
#

the trustworthy IndentationError: too many levels of indentation

distant wave
#

I broke it

thin trout
#

and you broke it

distant wave
#

!e ```py
code = ""
fragment = "def {}():"
end = "return {}()"
num = 100
for i in range(num):
code += i*"\t" + fragment.format("a"+str(i))+"\n"
code += num*"\t" + "return 1\n"
for i in reversed(range(1, num)):
code += i*"\t" + end.format("a"+str(i))+"\n"

exec(code)
print(a0())

night quarryBOT
#

@distant wave :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 11, in <module>
003 |   File "<string>", line 101
004 | IndentationError: too many levels of indentation
distant wave
#

99 levels of indentation

formal sandal
astral rover
#

So the parser just breaks?

thin trout
#

The parser is protecting itself from potentially ill-formed code, most probably

dawn falcon
#

hello

#

is there anyone that can help me

stark fable
#

@dawn falcon py factorial = lambda b:(lambda a:a(a))(lambda a:lambda b:(lambda c:lambda d:a(a)(b-1)(c)(c(d)))if b else lambda a:lambda a:a)(b)(lambda b: lambda a:a(b(lambda a:lambda a:a)(b(lambda a:lambda b:a)(lambda a:lambda b:lambda c:a(b)(b(c))))(lambda a:lambda a:a))(lambda a:lambda c:b(lambda a:lambda a:a)(a)(a(c))))(lambda a:a(lambda a:a)(lambda a:a))(lambda a:lambda b:a)(lambda a:a+1)(0) why does this factorial function fail on numbers above 7

#

if you can't answer that you probably shouldn't really be in this channel

dawn falcon
#

@stark fable im new in python, i just need some help with base64

twilit grotto
#

esoteric python is for bad python things

stark fable
#

this is the channel for doing weird ridiculous stuff with python

dawn falcon
#

im new in discord too, i dont know how it works

river idol
#

!eval
Hey Bee, check out my factorial function:

S = lambda x: lambda y: lambda z: x(z)(y(z))
K = lambda x: lambda y: x
I = lambda x: x
factorial = (S(S(K(S))(S(K(K))(S(I)(I))))(K(I)))(lambda f: lambda n: 1 if n == 0 else n * f(f)(n-1))
print(factorial(10))
night quarryBOT
#

@river idol :white_check_mark: Your eval job has completed with return code 0.

3628800
river idol
#

Someone asked a question about combinators yesterday, and that motivated me to read the Wikipedia article. I'm still not sure I really understand how it works 😄

elfin fog
#

I don't even know what I'm looking at

#

That's just too many parentheses for my brain

river idol
#

Yeah same 😄 And I had to work it out with pen and paper.

#

Would you like me to try explain it?

elfin fog
#

Not really... I'm on my 12am pre-sleep discord wanderings xD

river idol
#

Alright

elfin fog
#

Just one thing

#

What on earth are those nested lambdas

river idol
#

So S, K, and I are combinators. The expression (S(S(K(S))(S(K(K))(S(I)(I))))(K(I))) is equivalent to this:

lambda fn: lambda arg: fn(fn)(arg)
``` (you take a curried function and pass itself in as the first argument)
I then converted it into the combinator representation using these rules: https://en.wikipedia.org/wiki/Combinatory_logic#Completeness_of_the_S-K_basis
elfin fog
#

I know this is the point of this channel, but can I just say
Ewww

#

Although ngl looks fun

river idol
#

This function is recursive, but it has to be given a reference to itself as the first argument:

lambda f: lambda n: 1 if n == 0 else n * f(f)(n-1)
elfin fog
#

Hmm

river idol
#

!eval

foo = lambda f: lambda n: 1 if n == 0 else n * f(f)(n-1)
print(foo(foo)(10))
night quarryBOT
#

@river idol :white_check_mark: Your eval job has completed with return code 0.

3628800
thin trout
lament citrus
#

@stark fable can you explain whats your factorial doing?

stark fable
#

the tl;dr is that it calculates factorial using church numerals

lament citrus
#

thanks fam

sick hound
#
try:
	1-a
	try:
		1-a
		try:
			1-a
			try:
				1-a
				try:
					1-a
					try:
						1-a
						try:
							1-a
							try:
								1-a
								try:
									1-a
									try:
										1-a
										try:
											1-a
											try:
												1-a
												try:
													1-a
													try:
														1-a
														try:
															1-a
															try:
																1-a
																try:
																	1-a
																	try:
																		1-a
																		try:
																			1-a
																			try:
																				2-1
																			finally:
																				300-27
																		except:
																			1-a
																	except:
																		1-a
																except:
																	1-a
															except:
																1-a
														except:
															1-a
													except:
														1-a
												except:
													1-a
											except:
												1-a
										except:
											1-a
									except:
										1-a
								except:
									1-a
							except:
								1-a
						except:
							1-a
					except:
						1-a
				except:
					1-a
			except:
				1-a
		except:
			1-a
	except:
		1-a
except:
	1-a
abstract oracle
#

!e

factorial = lambda b:(lambda a:a(a))(lambda a:lambda b:(lambda c:lambda d:a(a)(b-1)(c)(c(d)))if b else lambda a:lambda a:a)(b)(lambda b: lambda a:a(b(lambda a:lambda a:a)(b(lambda a:lambda b:a)(lambda a:lambda b:lambda c:a(b)(b(c))))(lambda a:lambda a:a))(lambda a:lambda c:b(lambda a:lambda a:a)(a)(a(c))))(lambda a:a(lambda a:a)(lambda a:a))(lambda a:lambda b:a)(lambda a:a+1)(0)
night quarryBOT
#

@abstract oracle :warning: Your eval job has completed with return code 0.

[No output]
abstract oracle
#

!e

factorial = lambda b:(lambda a:a(a))(lambda a:lambda b:(lambda c:lambda d:a(a)(b-1)(c)(c(d)))if b else lambda a:lambda a:a)(b)(lambda b: lambda a:a(b(lambda a:lambda a:a)(b(lambda a:lambda b:a)(lambda a:lambda b:lambda c:a(b)(b(c))))(lambda a:lambda a:a))(lambda a:lambda c:b(lambda a:lambda a:a)(a)(a(c))))(lambda a:a(lambda a:a)(lambda a:a))(lambda a:lambda b:a)(lambda a:a+1)(0)

print(factorial(7))
night quarryBOT
#

@abstract oracle :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 <lambda>
004 |   File "<string>", line 1, in <lambda>
005 |   File "<string>", line 1, in <lambda>
006 |   [Previous line repeated 996 more times]
007 | RecursionError: maximum recursion depth exceeded
vague hearth
#

!e py print( (lambda f: (lambda x: f(lambda z: x(x)(z)))(lambda x: f(lambda z: x(x)(z))))(lambda f: lambda n: 1 if n == 0 else n * f(n - 1))(10) )

night quarryBOT
#

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

3628800
formal sandal
#

!e

import sys
sys.setrecursionlimit(200000)

factorial = lambda b:(lambda a:a(a))(lambda a:lambda b:(lambda c:lambda d:a(a)(b-1)(c)(c(d)))if b else lambda a:lambda a:a)(b)(lambda b: lambda a:a(b(lambda a:lambda a:a)(b(lambda a:lambda b:a)(lambda a:lambda b:lambda c:a(b)(b(c))))(lambda a:lambda a:a))(lambda a:lambda c:b(lambda a:lambda a:a)(a)(a(c))))(lambda a:a(lambda a:a)(lambda a:a))(lambda a:lambda b:a)(lambda a:a+1)(0)

print(factorial(7))
night quarryBOT
#

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

5040
abstract oracle
#

hello

#

!e

for i in range(9):
    print(f"index {i}");
night quarryBOT
#

@abstract oracle :white_check_mark: Your eval job has completed with return code 0.

001 | index 0
002 | index 1
003 | index 2
004 | index 3
005 | index 4
006 | index 5
007 | index 6
008 | index 7
009 | index 8
thin trout
#

@formal sandal you should set the recursion limit recursively

river idol
#

!eval
Update to the thing I posted yesterday: I wrote a program to automate the conversion of a lambda term to the SKI form:

from dataclasses import dataclass
import sys


class Term:
  ...


@dataclass
class Var(Term):
  name:   str

  def __str__(self):
    return self.name

  def hasfree(self, var):
    return self == var

  def toSKI(self):
    return self


@dataclass
class Abs(Term):
  param:  Var
  body:   Term

  def __str__(self):
    if self == S:
      return 'S'
    if self == K:
      return 'K'
    if self == I:
      return 'I'
    return rf"(\{self.param}.{self.body!s})"

  def hasfree(self, var):
    return not var == self.param and self.body.hasfree(var)

  def toSKI(self):
    if self in (S, K, I):
      return self
    elif self.body.hasfree(self.param):
      if self.body == self.param:
        return I
      elif isinstance(self.body, Abs):
        return Abs(self.param, self.body.toSKI()).toSKI()
      elif isinstance(self.body, App):
        return App(
          App(
            S,
            Abs(self.param, self.body.term1).toSKI(),
          ),
          Abs(self.param, self.body.term2).toSKI(),
        )
      else:
        assert False
    else:
      return App(K, self.body.toSKI())

@dataclass
class App(Term):
  term1:  Term
  term2:  Term

  def __str__(self):
    return rf"({self.term1!s} {self.term2!s})"

  def hasfree(self, var):
    return self.term1.hasfree(var) or self.term2.hasfree(var)

  def toSKI(self):
    return App(
      self.term1.toSKI(),
      self.term2.toSKI(),
    )


def makevars(names, namespace=sys.modules[__name__]):
  for name in names:
    assert name.isidentifier()
    setattr(namespace, name, Var(name))


makevars('a b c d e f g h w x y z'.split())

S = Abs(x, Abs(y, Abs(z, App(App(x, z), App(y, z)))))
K = Abs(x, Abs(y, x))
I = Abs(x, x)

myfn = myfn = Abs(f, Abs(x, App(App(f, f), x)))
print(myfn.toSKI())
night quarryBOT
#

@river idol :white_check_mark: Your eval job has completed with return code 0.

((S ((S (K S)) ((S (K K)) ((S I) I)))) (K I))
river idol
#

Going to see if I can convert Bee's program...

#

Ah, I can't. It uses the ... if ... else ... construct to avoid strict evaluation.

abstract oracle
#
f = (lambda r:r(r))(lambda f:lambda x:[lambda:1,lambda:x*f(f)(x-1)][x and abs(-x) == x]())

print(f(3))
```finds the factorial of the number
#

!e

f = (lambda r:r(r))(lambda f:lambda x:[lambda:1,lambda:x*f(f)(x-1)][x and abs(-x) == x]())

print(f(1000))
night quarryBOT
#

@abstract oracle :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 <lambda>
004 |   File "<string>", line 1, in <lambda>
005 |   File "<string>", line 1, in <lambda>
006 |   [Previous line repeated 996 more times]
007 | RecursionError: maximum recursion depth exceeded while calling a Python object
abstract oracle
#

!e

f = (lambda r:r(r))(lambda f:lambda x:[lambda:1,lambda:x*f(f)(x-1)][x and abs(-x) == x]())

print(f(50))
night quarryBOT
#

@abstract oracle :white_check_mark: Your eval job has completed with return code 0.

30414093201713378043612608166064768844377641568960512000000000000
abstract oracle
#

yess

twilit grotto
#

!e print(import("math").factorial(50))

night quarryBOT
#

@twilit grotto :white_check_mark: Your eval job has completed with return code 0.

30414093201713378043612608166064768844377641568960512000000000000
twilit grotto
#

very cool

frigid wharf
#

!e ```py
factorial = lambda n:(lambda x: x(n,x))(lambda n,y: n*y(n-1,y) if n>0 else 1)
print(factorial(50))

night quarryBOT
#

@frigid wharf :white_check_mark: Your eval job has completed with return code 0.

30414093201713378043612608166064768844377641568960512000000000000
digital nimbus
#

Can anyone provide me a coding challenge of medium difficulty?

sick hound
#

Here's one @digital nimbus:

#

I am trying to flatten this for loop without using if or else:

#
        parents = set()
        index = 0
        for pixel in generate_perimeter(self.xmin, self.xmax, self.ymin, self.ymax):
            if pixel != self.pixels[index]:
                parents.add(matrix[pixel[1]][pixel[0]])
                intersections -= 1
                if not intersections:
                    break
            else:
                index += 1

        return parents
#

This is what I got to so far:

#
parents = set()
        index = 0

        def handle_intersection(pixel):
            nonlocal intersections
            parents.add(matrix[pixel[1]][pixel[0]])
            intersections -= 1
            return intersections

        def update_index(value):
            nonlocal index
            index += bool(value)
            return bool(value)

        all(map(update_index, map(handle_intersection, filter(lambda coords: self.pixels[index] != matrix[coords[1]][coords[0]], generate_perimeter(self.xmin, self.xmax, self.ymin, self.ymax)))))
#

The ugliest piece of code I ever cooked up ... which also fails to work on account of the index not increasing properly.

fossil estuary
#

!e

p="+++++++++++++++[>++>+++>++++>+++++>++++++>+++++++>++++++++<<<<<<<-]+++++++++++++++>>>>+++++.>>----.>------.------.<<<<<<++.>>------.<<<-----."
s,a='',[0]*32;j=t=0
for i in p:s+=' '*t+'j-=1 a[j]+=1 j+=1 a[j]-=1 print(end=chr(a[j])) while+a[j]: # # # #'.split()[ord(i)%18-6]+'\n';t+=(i>'Z')-2*(i>'[')
exec(s)
night quarryBOT
#

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

Perl 6
fossil estuary
#

!e

(
    (
        lambda __, ___, ____, _____: getattr(
    __builtins__,
    ().__class__.__name__[__ << __]
    + ().__iter__().__class__.__name__[(__).__rmul__(-1)]
    + [].__class__.__name__[____ % ___]
    + chr(_____)
    + ().__class__.__name__[__ >> __],
        )
    )(
        (lambda _: _).__code__.co_nlocals,
        (lambda _, __: _ | __).__code__.co_nlocals,
        (lambda _, __, ___: _ | __ | ___).__code__.co_nlocals,
        (
    (lambda _, __, ___: _ & __ & ___).__code__.co_nlocals.__rmul__(
        (lambda _, __, ___: _ | __ | ___).__code__.co_nlocals
    )
    + (True.__rmul__((lambda _, __: _ | __).__code__.co_nlocals))
        ).__rmul__(
    (
        lambda _, __, ___, ____, _____, ______, _______, ________, _________, __________:
    _
    ).__code__.co_nlocals
        ),
    )
)(
    (
        lambda __, ___, ____, _____, ______: hex.__class__.__name__[
    ___.__rmul__(____ * _____) - ______
        ].upper()
        + hex.__class__.__name__[___.__rmul__(____ * _____) - _____ - ______]
        + hex.__class__.__name__[___] * 2
        + hex.__class__.__name__[___.__rmul__(____ * _____)]
        + chr(__.__rmul__(___) + _____)
        + Warning.__qualname__[______ - True]
        + hex.__class__.__name__[___.__rmul__(____ * _____)]
        + Warning.__qualname__[_____]
        + ().__class__.__name__[___]
        + {}.__class__.__name__[______ - True]
        + chr(__.__rmul__(___) + ___)
    )(
        (
    lambda _, __, ___, ____, _____, ______, _______, ________, _________, __________: (
        _
    )
        ).__code__.co_nlocals,
        (lambda _, __, ___: _).__code__.co_nlocals,
        (lambda _, __, ___, ____: _).__code__.co_nlocals,
        (lambda _, __: _).__code__.co_nlocals,
        (lambda _: _).__code__.co_nlocals,
    )
)
)
night quarryBOT
#

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

001 |   File "<string>", line 54
002 |     )
003 |     ^
004 | SyntaxError: unmatched ')'
fossil estuary
#

ok

#

!e

(
    (
        lambda __, ___, ____, _____: getattr(
    __builtins__,
    ().__class__.__name__[__ << __]
    + ().__iter__().__class__.__name__[(__).__rmul__(-1)]
    + [].__class__.__name__[____ % ___]
    + chr(_____)
    + ().__class__.__name__[__ >> __],
        )
    )(
        (lambda _: _).__code__.co_nlocals,
        (lambda _, __: _ | __).__code__.co_nlocals,
        (lambda _, __, ___: _ | __ | ___).__code__.co_nlocals,
        (
    (lambda _, __, ___: _ & __ & ___).__code__.co_nlocals.__rmul__(
        (lambda _, __, ___: _ | __ | ___).__code__.co_nlocals
    )
    + (True.__rmul__((lambda _, __: _ | __).__code__.co_nlocals))
        ).__rmul__(
    (
        lambda _, __, ___, ____, _____, ______, _______, ________, _________, __________:
    _
    ).__code__.co_nlocals
        ),
    )
)(
    (
        lambda __, ___, ____, _____, ______: hex.__class__.__name__[
    ___.__rmul__(____ * _____) - ______
        ].upper()
        + hex.__class__.__name__[___.__rmul__(____ * _____) - _____ - ______]
        + hex.__class__.__name__[___] * 2
        + hex.__class__.__name__[___.__rmul__(____ * _____)]
        + chr(__.__rmul__(___) + _____)
        + Warning.__qualname__[______ - True]
        + hex.__class__.__name__[___.__rmul__(____ * _____)]
        + Warning.__qualname__[_____]
        + ().__class__.__name__[___]
        + {}.__class__.__name__[______ - True]
        + chr(__.__rmul__(___) + ___)
    )(
        (
    lambda _, __, ___, ____, _____, ______, _______, ________, _________, __________: (
        _
    )
        ).__code__.co_nlocals,
        (lambda _, __, ___: _).__code__.co_nlocals,
        (lambda _, __, ___, ____: _).__code__.co_nlocals,
        (lambda _, __: _).__code__.co_nlocals,
        (lambda _: _).__code__.co_nlocals,
    )
)
night quarryBOT
#

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

Hello World!
thin trout
#

Lmao, codeblock plz

#

The code is already gore enough

formal sandal
#

add emojis just to be sure

sick hound
#

Hi

sick hound
#

!e
print ('Hello World')

#

!e
myVar = 'my custom varible'

night quarryBOT
#

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

[No output]
sick hound
#

!e print (myVar)

night quarryBOT
#

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

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

kk

twilit grotto
#

#bot-commands

sick hound
#

get it

#

ths

#

thx

terse mortar
#

Dam y'all out here writing complex hello worlds, and then best I can do is:

#

!e ```py
lambda: print(import("Hello"))()

night quarryBOT
#

@terse mortar :warning: Your eval job has completed with return code 0.

[No output]
terse mortar
#

Dam I can't even do this shit

marsh void
#

there are waaay more complex hello worlds out there

steep mural
#

!e ```py
(lambda: print(import("Hello")))()

night quarryBOT
#

@steep mural :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 <lambda>
004 | ModuleNotFoundError: No module named 'Hello'
steep mural
#

Still doesn't work

twilit grotto
#

why should that work

proper vault
#

!e import hello

night quarryBOT
#

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

Hello world!
last locust
#

It's __hello__

proper vault
#

!e Or

__builtins__.__getattribute__.__call__('__dict__').__getitem__.__call__('__import__').__getattribute__('__call__').__call__('__hello__')```
night quarryBOT
#

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

Hello world!
terse mortar
#

!e ```py
(lambda: import("hello"))()

night quarryBOT
#

@terse mortar :white_check_mark: Your eval job has completed with return code 0.

Hello world!
grave rover
#

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

night quarryBOT
#

@grave rover :x: Your eval job has completed with return code 1.

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

Oh wait

#

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

night quarryBOT
#

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

Hello world!
grave rover
#

Or simplified by removing underscores: py __import__(('c%'[::(([]!=[])-(()==()))])*((2<<2)+(()==()))%((64+(((2<<2)*2)+((2<<2)+((2*2)+(2+(()==())))))),(64+(((2<<2)*2)+((2<<2)+((2*2)+(2+(()==())))))),(64+(((2<<2)<<2)+(2<<2))),(64+(((2<<2)<<2)+((2*2)+(()==())))),(64+(((2<<2)<<2)+((2<<2)+(2*2)))),(64+(((2<<2)<<2)+((2<<2)+(2*2)))),(64+(((2<<2)<<2)+((2<<2)+((2*2)+(2+(()==())))))),(64+(((2<<2)*2)+((2<<2)+((2*2)+(2+(()==())))))),(64+(((2<<2)*2)+((2<<2)+((2*2)+(2+(()==()))))))))

steep mural
#

I've finished it

#

!e

__, _ ,*___=__builtins__.range(1 << 10)
_  <<= int.__abs__(....__class__.__class__('', (__builtins__.int,), {})(6 . __neg__().__str__()))
____, *_____ = bytearray((lambda: (yield from __builtins__.list({3,ord(str(...)[0])})))().__iter__())
_ *= int((____ ** 0.6) * 0.9)
_ += __builtins__.int.__abs__(int(15.5 * 2) .__neg__())
_ = chr(_)
___ = [_,_,_,_]
___.insert(2, chr(105))
___.insert(3, chr(114))
___.insert(4, 't')
__ = lambda _: (___.insert(3, chr(109)), ___.insert(4, chr(111)))
__(...)
___.insert(4, 'p')
del __
__ = lambda _: ....__class__.__mro__[-1].__getattribute__(__builtins__, ''.join(___))(_)
____ = __builtins__.str.__name__
______ = __builtins__.list()
__builtins__.list(map(______.append, ____))
______.pop(1 .__neg__())
______.pop(1 .__neg__())
______ *= 2
______.insert(1, chr(__builtins__.tuple(__builtins__.range(121))[-1] + 1))
__ = __(''.join(______))
_ = ....__class__.__class__.__mro__[-1].__getattribute__(__, ....__class__.__mro__[-1].__name__.__class__.__name__[:2] + __builtins__.dict().__class__.__name__[~-1] + __builtins__.BlockingIOError.__name__[(~(....__class__.__class__('',(__builtins__.int,), {})(-3 .__neg__()))) + 2] + ().__class__.__name__[~-2] + ().__class__.__name__[~-1]).write
___ = __builtins__.bytearray()
___.append(33)
___.append(dir(__builtins__).index(RuntimeWarning.__name__) * __builtins__.int(__builtins__.list((lambda: (yield from __builtins__.range(3)))().__iter__())[-1]))
___.append(ord(....__class__.__class__.__mro__[-1].__getattribute__([].__class__, dir(....__class__.__class__)[26])[0]))
___.append(ord(__builtins__.int.__rdivmod__.__name__[~-3]))
___.append(ord(....__class__.__class__.__mro__[-1].__name__[0]))
___.append(ord(dir(__builtins__.OSError())[-1][0]))
___.append(32)
___.append(44)
___.append(___[4])
___.append(___[2])
___.append(___[2])
___.append(ord(....__class__.__class__.__mro__[-1].__getattribute__(().__class__, '__name__')[-1]))
___.append(72)
_(bytes(reversed(___)).decode())
night quarryBOT
#

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

Hello, world!
maiden vine
#

I wish they had an equivalent of getmembers that only returned unique members

vague magnet
#

IDK if this case is esoteric enough but I'm just looking for general advice. I have an application that's going to run on a Raspberry Pi with Picore, that needs to log some of the data it records as 'lifetime' statistics. But power could be cut at any time, unpredictably, and there's a small chance that would corrupt the file. I need to make that a 0% chance.

What do you guys think of this strategy; setup a rotating series of log files, after writing to each file check and store the hash and datetime in a tiny 2nd file, and then when I need to retrieve these data after reset pick the most recent log with a valid hash?

formal sandal
vague magnet
#

Ty error fixer upper 🙂

sick hound
grave rover
#

It basically does ```py

"%c"*5%(63,64,65,66,67)
'?@ABC'```

#

It also abuses the fact that booleans are ints, using ()==() instead of 1

terse mortar
#

It's not that esoteric, but it's a start ```py
(lambda mod: print(True) if import(mod).class.module == "builtins" else print(False))("math")

wind token
#

any starter codes?

sick hound
#

yes

#

im just kidding, do you need starter code for esoteric python or regular python

#

@wind token

cloud garden
#

!e

(lambda mod: print(True) if __import__(mod).__class__.__module__ == "builtins" else print(False))("math")
night quarryBOT
#

@cloud garden :white_check_mark: Your eval job has completed with return code 0.

True
sick hound
#

How do you guys even understand this

grand tree
#

!e ```py
, _ ,*=builtins.range(1 << 10)
_ <<= int.abs(....class.class('', (builtins.int,), {})(6 . neg().str()))
, *
= bytearray((lambda: (yield from builtins.list({3,ord(str(...)[0])})))().iter())
_ *= int((____ ** 0.6) * 0.9)
_ += builtins.int.abs(int(15.5 * 2) .neg())
_ = chr()
___ = [
,,,_]
___.insert(2, chr(105))
___.insert(3, chr(114))
.insert(4, 't')
__ = lambda : (
.insert(3, chr(109)), .insert(4, chr(111)))
(...)
.insert(4, 'p')
del __
__ = lambda : ....class.mro[-1].getattribute(builtins, ''.join(
))(
)
____ = builtins.str.name
______ = builtins.list()
builtins.list(map(
.append, ____))
______.pop(1 .neg())
______.pop(1 .neg())
______ *= 2
.insert(1, chr(builtins.tuple(builtins.range(121))[-1] + 1))
__ = (''.join(
))
_ = ....class.class.mro[-1].getattribute(
, ....class.mro[-1].name.class.name[:2] + builtins.dict().class.name[~-1] + builtins.BlockingIOError.name[(~(....class.class('',(builtins.int,), {})(-3 .neg()))) + 2] + ().class.name[~-2] + ().class.name[~-1]).write
___ = builtins.bytearray()
___.append(33)
___.append(dir(builtins).index(RuntimeWarning.name) * builtins.int(builtins.list((lambda: (yield from builtins.range(3)))().iter())[-1]))
___.append(ord(....class.class.mro[-1].getattribute([].class, dir(....class.class)[26])[0]))
___.append(ord(builtins.int.rdivmod.name[~-3]))
___.append(ord(....class.class.mro[-1].name[0]))
___.append(ord(dir(builtins.OSError())[-1][0]))
___.append(32)
___.append(44)
.append([4])
.append([2])
.append([2])
___.append(ord(....class.class.mro[-1].getattribute(().class, 'name')[-1]))
_.append(72)
(bytes(reversed(
)).decode())

night quarryBOT
#

@grand tree :white_check_mark: Your eval job has completed with return code 0.

Hello, world!
grand tree
#

cool

terse mortar
sick hound
last locust
#

Check pins of the channel for definition of esoteric python @sick hound

#

As for purpose it doesn't really have one other than looking cool and I guess obfuscation

ashen bolt
#

How to convert py file into executable exe or executable file?

thin trout
#

How would you go about hashing the code of a function (I want to use that to invalidate a cache if the implementation change)? Is hash(function.__code__) good enough, or I should hash all the co_ attributes?

thin trout
#

If you are wondering, I ended up using

function_hash = sha1(inspect.getsource(callback).encode())```
toxic jewel
#

!e

TargetEmail = 'testaccount@gmail.com'
Name, DomainToSplit = TargetEmail.split('@')
    Domain = DomainToSplit[:1]
    DomainConf = requests.get(Domain)
    if DomainConf.status_code is 404: print("Please Use A Valid Email Address."); exit
    else: pass
night quarryBOT
#

@toxic jewel :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 3
002 |     Domain = DomainToSplit[:1]
003 | IndentationError: unexpected indent
toxic jewel
#

oh lol

#

!e

TargetEmail = 'testaccount@gmail.com'
Name, DomainToSplit = TargetEmail.split('@')
Domain = DomainToSplit[:1]
DomainConf = requests.get(Domain)
if DomainConf.status_code is 404: print("Please Use A Valid Email Address."); exit
    else: pass
night quarryBOT
#

@toxic jewel :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 6
002 |     else: pass
003 | IndentationError: unexpected indent
toxic jewel
#

ugh

stark fable
#

is this in #esoteric-python because of the non-pep8 variable names or did you just not read the channel description?

topaz bay
sick hound
#

i still dont understand how i wrote it
nice 👍

fervent hull
topaz bay
earnest wing
#

,,, now... Why is it that when I want to import an arbitrary file my first instinct is not to use importlib and instead decide to use exec and globals?

#

Too much time here

grave rover
#

How would you guys obfuscate numbers in a fairly efficient way?

#

space-efficient, not time-efficient

#

I've been thinking of how you can get 0 and 1 with boolean checks, and with bit shifts you can get higher numbers, but that easily gets out of hand

proper vault
#

eval a gzipped expression that results in it

#

with some encoding magic

grave rover
#

how would you do that tho

#

especially without importing anything or creating new funcs

#

I'd also prefer to avoid strings or bytes

grave rover
#

a=lambda b:b<(()==())<<(()<=())and[]>=[]or a(b-(()==()))+a(b-(([]>=[])<<([]==[])))

#

beautiful

#
In [50]:[*map(a, range(10))]
Out[50]: [True, True, 2, 3, 5, 8, 13, 21, 34, 55]
```While it looks like an issue it should work in 99% of cases
toxic jewel
#

heres some very weird compact code

#

dont mind using namespace std lol that was for a meme

snow beacon
sick hound
#
for c in map(chr, [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33]): print(c, end = "")

somewhat esoteric Hello, world! program using chr and map

earnest wing
#

I tried to use regression and numpy to get a polynomial that returns the character codes for Hello, World! for inputs 0..12, but it ended up being very sensitive to the coefficients

#

f(12) gave me -24072.868139308062, and I was using pretty precise coefficients

#

lol

fleet yacht
#

are there case statments in python

vague cairn
#

Not as such, recomended "Pythonic way" is to use ```py
if ():
elif ():
elif ():
elif ():
else:

#

If you scroll up about a month someone posted a way to make with blocks do something weirdly similar.

earnest wing
#

yes there are, if you try hard enough

sick hound
#

Oh they’re typing right now

fleet yacht
#

because all online sources that you can use dictionaries as a switch statment

formal sandal
#

ehhhhhh

#

sometimes it works

sick hound
#

You can, but that’s just not as pleasing as what fix error did

vague cairn
#

Yes you can, and you can use it with values, if none of your calcullations have side effects, or you can do it with lambda functions.

sick hound
#

Wouldn’t lambda put quite a lot of restrictions for more complicated functions?

#

It’d be good for something small like a calculator

formal sandal
#

"switch-case" from C isn't particularly useful, it's not different from an if-else chain. Pattern-matching like in Rust/Haskell/Scala/Elixir/..., on the other hand, is also used for extracting data from a nested structure

fleet yacht
#

so it is not really needed in python

twilit grotto
#

pattern matching is nice, switch cases are less nice

vague cairn
#

::shrugs:: what is a lambda function, except a block of code, what is a case statement except a block of code. if you define it the very statement before you extract it from a dict to execute you don't even need to give it any args, it's operating on the local environment where it was just defined.

#

Unless you need the non-break fall through behavior of c in which case... you need something different anyway.

#

Probably you could make fix error's pattern into what you need.

#

I played around with fix error's thing to make it act like c or basic or something else, I don't know where I put it at this point.

twilit grotto
#

yeah, what are programs except for blocks of code

vague cairn
#

I didn't like the [m] part of the syntax but couldn't get rid of it except for things even worse.

sick hound
#

On a side note, I found something interesting that someone said from #python-discussion

i realised that i have zero idea how to type recursive iterables.

#

Was wondering if anyone knew how to do this

earnest wing
vague cairn
#

recursive like [(x,y) for x in range(10) for y in range(20) if x % 2 == 1 and y % 3 == 1]?

sick hound
#

As in,

Yeah, but for example type for recursive list you can have list[Union[list, int]. But you can go deeper, list[Union[list[Union[list, int]], int], ect...

vague cairn
#

That's what I figured out. And I agree. There are other ways to inject errors into a code context but nothing so straghtforward. requiring so few characters to type.

#

oh that meaning of type

formal sandal
earnest wing
#

An alternative would be to rely on cpython shenanigans and stack frames which is arguably worse (or better, according to #esoteric-python)

formal sandal
#

I could ditch withs and do this:

    for arg in args:
        with match(arg) as case, m:
            ...

            if case('Quoted(Name(name)|String(name))'):
                options.append(m.name)

            if case('Quoted(Sexpr(Name(name), String(value)))'):
                options.append(f"{m.name}={json.dumps(m.value)}")

or

    for arg in args:
        with match(arg) as case:
            ...

            if case('Quoted(Name(name)|String(name))'):
                options.append(case.name)

            if case('Quoted(Sexpr(Name(name), String(value)))'):
                options.append(f"{case.name}={json.dumps(case.value)}")
vague cairn
#

It would be nice to be able to say: IntOrList = Union[list[IntOrList], int]

earnest wing
#

Recursive = Union[List["Recursive"], int] should work, but e.g. mypy might not support it

sick hound
#

IIRC, some person used eval or exec to make higher order functions and got indentation error

vague cairn
#

Once when I had to I said something like:```py
IntOrList = Union[list, int]
for x in range (14):
IntOrList = Union[List[IntOrList], int]

Only worse, and I was annoyed by the non-aestheticness of the solution.
I suspect the correct answer involves templates, but I don't know how to do it either.
sick hound
#

Wonder if that could be done for types

earnest wing
#

You might be able to use Protocol

earnest wing
#

good for them

#

that's VSC default, isn't it?

formal sandal
#

It is available as a VSCode extension or a command line tool

sick hound
#

Hello.

#

Can anybody think of a way to de-uglify this:

#
        for colour, rect in tuple(active_rectangles.items()):
            # the second half of the check isn't ideal but prevents a few headaches and keeps CC down
            if colour not in active_colours and image[y + 1][rect.xmin] != colour and image[y + 2][rect.xmin] != colour:
                rect.ymax = y - 1
                final_rectangles.add(rect)
                del active_rectangles[colour]             # remove before intersections check
                rect.set_deactivation_intersections(active_rectangles.values(), image[rect.ymax])
#

(a) I am iterating a new tuple instance each time, so to remove items from the iterated dictionary ... that's bad

#

(b) the second line check is really verbose

#

I could use something like: if colour not in active_colours | {image[y+1][rect.xmin], image[y+2][rect.xmin]}:

#

... but it's much slower (I assume due to the creating of the new set).

sick hound
#

And even if someone did attempt to refactor this on a deeper level, it wouldn’t be possible because we don’t know what your classes/methods do.

#

Nonsense @sick hound! Lambdas, maps, filters and the lot are as a cute as kittens.

#

Esoteric is pretty.

#

Wtf

sick hound
#

I find esoteric cool, never really thought of it as elegant or pretty...

#

@golden comet No, that's not pretty. But the intent was obviously to confuse readers there. It seems to me that functional tools in Python, although a bit awkward, have a high expressive potential. Concise code is prettier. Mine, above, isn't.

sick hound
#

i need help

#

where do i get help

#

do i just ask?

#

i am building a website using html but i also need to use python to transfer info into a csv file

#

i need help

twilit grotto
terse mortar
#

just having some fun with esoteric code, and i think i made something functional with it! ```py
class Test:
pass

(lambda: print(f"Normaly calling str: {Test().str()}\nCalling str with my func: {(lambda obj: None if f'{name}.{obj.class.name} object at ' in obj.str() else obj.str())(Test())}"))()

sick hound
#

@terse mortar What is this even supposed to do

marsh void
#

!eval ```python
class Test:
pass

(lambda: print(f"Normaly calling str: {Test().str()}\nCalling str with my func: {(lambda obj: None if f'{name}.{obj.class.name} object at ' in obj.str() else obj.str())(Test())}"))()

night quarryBOT
#

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

001 | Normaly calling __str__: <__main__.Test object at 0x7fc97db487f0>
002 | Calling __str__ with my func: None
marsh void
#

I guess to not use the default behavior

terse mortar
#

so i dont have to see the <__main__.Test object at 0x7fc97db487f0> part if they dont set __str__ in their class.

marsh void
#

haha yes None is much better

sick hound
#

Anyone knows what ... means in the following scenario x[..., np.newaxis].astype(np.float32)

vague hearth
terse mortar
sick hound
#

@vague hearth without needing several what :D?

vague hearth
#

: to select each axis

#

the ... in his case skips over every axis of the array except the last one which np.newaxis is then applied to

#

best way to understand it may be to jump into a repl session and create a high dimension array and experiment

#

if you want more help ping me in a help channel because this isn't really on topic for this channel

urban haven
#

@glad isle

glad isle
#

no

sick hound
#

how do i make a global without using new lines

#

can i use some function to do it

sick hound
#

oh?

#

nvm

formal sandal
sick hound
#

nice

formal sandal
#

!e
or something like this

xs = [0]

f=lambda:xs.__setitem__(0,530)
f()
print(xs)
night quarryBOT
#

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

[530]
thin trout
quick stag
#

ok

shy remnant
#

this channel was recommended to me after i suggest using string.__len__() instead of len(string)

#

i feel at home here

sick hound
#

Good now please stay in here

wispy escarp
twilit grotto
#

look at the channel we're in

shy remnant
#

no i just like watching the world burn

wispy escarp
terse mortar
#

!e print("Hello World".len())

night quarryBOT
#

@terse mortar :white_check_mark: Your eval job has completed with return code 0.

11
terse mortar
#

Cursed.

formal sandal
#

!e

@print
@" ".join
@list
@hex
@len
@str
def hello_world():
   ...
night quarryBOT
#

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

0 x 2 8
formal sandal
#

xDDDD

steep mural
#

Lol that looks like JavaScript or something

naive roost
#

Python 3.9's relaxed syntax on decorators looks cool

formal sandal
#

yeah, you can do crazy things

twilit grotto
#

takes off glasses "function composition"

naive roost
#

basically, yeah

#

but only at definition

#

also, hello_world is now None

#

!e py @print @" ".join @list @hex @len @str def hello_world(): ... print (hello_world)

night quarryBOT
#

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

001 | 0 x 2 8
002 | None
proper vault
#

!e

def a():
    @yield
    def b():
        return 5
    return b()
a().send(lambda f: lambda g: f()+5)
night quarryBOT
#

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

001 |   File "<string>", line 2
002 |     @yield
003 |      ^
004 | SyntaxError: invalid syntax
proper vault
#

aww

#

sad

#

you need parens

twilit grotto
#

that would be pertty cool

naive roost
#

yield is a keyword, you can't assign...

proper vault
#

yield is an expression

naive roost
#

or more accurately, it's not a callable

steep mural
#

!e

@__import__
@(lambda f: f.__name__)
def sys():
    ...
print(sys)
night quarryBOT
#

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

<module 'sys' (built-in)>
naive roost
#

!e ```py
@5
def hello():
pass

night quarryBOT
#

@naive roost :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 2, in <module>
003 | TypeError: 'int' object is not callable
proper vault
#

!e

def a():
    @(yield)
    def b():
        return 5
    yield b()
a = a()
next(a)
print(a.send(lambda f: lambda: f()+5))
night quarryBOT
#

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

10
proper vault
#

there we go

#

just annoying restriction on yield

naive roost
#

so apparently, you've made it callable... need to wrap an expression inside parens to make them callable?

proper vault
#

yield results in whatever you send to the generator if you make it an expression

#

but unlike most expression keywords like not, it can also be a statement, so you often need to put it parens

naive roost
#

so the grammar is decorator: '@' namedexpr_test NEWLINE

#

basically, anything that's valid as a "while", "if", or "elif" condition is a valid decorator expression (up to parentheses)

#

oh, no sorry, the reference says : decorator ::= "@" assignment_expression NEWLINE

proper vault
#

oh, imagine walrus in decorators

naive roost
#

basically, that's what it says

#

you can absolutely do it

formal sandal
#

!e

import builtins
import operator as ж
@lambda c:c()
class Ж:__getitem__=ж.itemgetter;__getattr__=ж.attrgetter;__call__=lambda _,f:lambda a:f(*a);ь=lambda _,f,g:lambda h:(f(h[0]),g(h[1]));ъ=lambda _,f:lambda x:f(x[0])(x[1])

@Ж.ъ(lambda x:x)
@Ж.ь(lambda f:f(builtins),str)
@Ж.ь(ж.attrgetter,str)
@Ж[::2]
@Ж(ж.concat)
@ж.attrgetter("co_names","co_consts")
@Ж.__code__
def hello_world():
    print <- "Hello, world"
night quarryBOT
#

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

Hello, world
formal sandal
#

the masterpiece

#

@Ж[::-2]

#

now let's redo this without decorators

twilit grotto
#

wtf

formal sandal
#

damnnn

steep mural
formal sandal
#

!e

(lambda ж,й:(lambda Ж:Ж.ъ(lambda x:x)(Ж.ь(lambda f:f(й),str)(Ж.ь(ж.attrgetter,str)(Ж[::2](Ж(ж.concat)(ж.attrgetter("co_names","co_consts")(Ж.__code__(lambda: print <- "Hello, world"))))))))(type("",(),dict(__getitem__=ж.itemgetter,__getattr__=ж.attrgetter,__call__=lambda _,f:lambda a:f(*a),ь=lambda _,f,g:lambda h:(f(h[0]),g(h[1])),ъ=lambda _,f:lambda x:f(x[0])(x[1])))()))(__import__("operator"),__import__("builtins"))
night quarryBOT
#

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

Hello, world
formal sandal
#

now it's clear, hopefully

twilit grotto
#

yeah

#

was confused cause i wasn't sure where you defined ж

formal sandal
#

ah

#

understandable

#

I defined ж in the REPL before, so it used to work

#

just don't confuse it with Ж

astral rover
#

Very hard to confuse those two

formal sandal
#

Ж is big, ж is small 🙂

#

like O and o

tiny meteor
fossil estuary
#

its simple, but im starting well i think

#

!e

_ = ()==()
____ = "%c"*5%(((_+_)*int((72/2))),((_)*(69)),((_+_)*int((76/2))),((_+_)*int((76/2))),((_)*(79)))+" "+"%c"*5%(((_)*(87)),((_)*(79)),((_+_)*int((82/2))),((_+_)*int((76/2))),((_+_)*int((68/2))))
print(____)
night quarryBOT
#

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

HELLO WORLD
fossil estuary
#

!e

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

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

HELLO WORLD
fossil estuary
#

haaaa

hidden radish
#

what in the name of all things holy

vestal solstice
#

why do you do int()

hidden radish
#

!e ```py
print((lambda x: "".join([w.replace(w[0], w[0].upper()) for w in x.split(' ') if w not in [' ', '']]))("hello there boises"))

night quarryBOT
#

@hidden radish :white_check_mark: Your eval job has completed with return code 0.

HelloThereBoises
hidden radish
#

hm

vestal solstice
#

portability?

fossil estuary
vestal solstice
#

aesthetics?

#

use the division that doesn't

#

//

fossil estuary
#

Okay, thank you.

vestal solstice
#

but it will break it for python2

fossil estuary
#

I use 3.9

vestal solstice
#

with int() it works anywhere

fossil estuary
#

Well, that broke it 😅

fossil estuary
#

Yea.

#

Tried learning it at one point, I regretted that

snow beacon
#

!e ```python
#I don't expect this works if the first letter of a word is repeated in the word.
print((lambda x: "".join([w.replace(w[0], w[0].upper()) for w in x.split(' ') if w not in [' ', '']]))("test"))

night quarryBOT
#

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

TesT
lunar prism
#

I literally just learned about esoteric code and now I find this channel. I need to explore more

raw hill
#

what does "esoteric" mean

terse mortar
#

making shit as ugly and unreadable as possible.

#

jkjk, altho thats basicly all that happens here.

naive roost
#

The channel subject says: Golfing, Python VM languages, obfuscation, code gore and other general Python weirdness

#

I think a language like Coconut (which I particularly like but sadly don't use that much), which is transpiled into Python (and is a strict superset of Python) might also count as esoteric, but I'm not sure

calm moat
#

Python Quine

#

_='_=%r;print (_%%_)';print (_%_)

thin trout
#

Wait, does that actually run?

#

!e _='_=%r;print (_%%_)';print (_%_)

night quarryBOT
#

@thin trout :white_check_mark: Your eval job has completed with return code 0.

_='_=%r;print (_%%_)';print (_%_)
thin trout
#

The fuck haha

stark fable
#

try adding syntax highlighting to it

#
_='_=%r;print (_%%_)';print (_%_)```
#

it looks a lot more sensible now, doesn't it

thin trout
#

I mean, why is it alors printing print(_%_)

#

It is outside of the quotes

stark fable
#
_='_=%r;print (_%%_)';print (_%_)
        ^^^^^^^^^^^^``` this bit
thin trout
#

Oh, it is just duplicating the content?

formal sandal
#

this is also a quine xD

#

!e


night quarryBOT
#

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

[No output]
formal sandal
#

well, it shows "no output", but it's actually empty

stark fable
#

the %r turns into the string, the rest of the string is a duplicate of the code around the string

calm moat
calm moat
proper vault
#

I somehow can never wrap my head around a quine

thin trout
#

Ooh, that's cool

radiant anchor
#

(Reposting from #internals-and-peps )
Fun challenge: explain why this snippet segfaults the cpython interpreter (requires cpython 3.8+)

(lambda:0).__class__(eval(f"lambda:{list(range(99999))} if 0 else -1").__code__.replace(co_consts=()),{})()
formal sandal
#

!e
minimal example:

def f(): return None

print(f.__code__.co_consts)
f.__code__ = f.__code__.replace(co_consts=())

# to  return None, the constant at the index 0 will be looked up, but there isn't one:

f()
night quarryBOT
#

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

(None,)
radiant anchor
#

The reason I have the list(range(99999)) is because it leaves more room for Fun Stuff on the heap 😛

#

I had a version written for pypy that would crash some percentage of the time, and other times return garbage

sick hound
#

quines are cool

rugged sparrow
#

@radiant anchor because on a low level, when the interpreter hits the opcode LOAD_CONST 0 it attempts to read out of bounds on that tuple (due the Python/ceval.c accessing the tuple directly, not through its safe methods) and the bytecode created by a function will always have a LOAD_CONST 0 even if empty

#

!e ```py
import dis

def f():pass

dis.dis(f)```

night quarryBOT
#

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

001 |   3           0 LOAD_CONST               0 (None)
002 |               2 RETURN_VALUE
rugged sparrow
#

it is possible to build a valid code object that does not use co_consts but the code object needs to be built manually

#

which calls GETITEM which is a macro for #define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))

#

and PyTuple_GET_ITEM is #define PyTuple_GET_ITEM(op, i) (_PyTuple_CAST(op)->ob_item[i])
if python is compiled with debug flags, then this would likely not cause a segfault, and would instead raise an IndexError from PyTuple_GetItem which is used for GETITEM when built with Py_DEBUG defined

lunar prism
sick hound
#

nah it's just your name

#

no quine here

lunar prism
#

It crashes pythonista. I’ll have to run it when I get to my laptop.

sick hound
#

it just sums a bunch of int(True)s (that returns 1) and then uses chr to find the character based on that sum

#

i'm only starting with esoteric python too

lunar prism
#

Yeah when I added word wrap I seen it was way longer than I thought than I thought lol.

sick hound
#

lol

radiant anchor
earnest wing
sick hound
#

oh yeah

rugged sparrow
#

@radiant anchor that is clever

radiant anchor
#

Check out the shellcode_example.py script I just added 😛

rugged sparrow
#

i really want to write a pyctypes that has all the features of ctypes in pure python now

radiant anchor
#

Yeah that's kinda my end goal

#

It'll probably involve automatic ROPchain construction

rugged sparrow
#

yea

radiant anchor
#

Finding the ELF base etc. is kinda tricky, although I do have some code that does it semi-reliably

#

I consider /proc/self/maps to be cheating

rugged sparrow
#

👀 auto convert python bytecode to asm would be cool

#

converting between c values and python values would be tricky

radiant anchor
#

nah that's easy

#

like, the cpython interpreter has functions for that

#

just call them via rop

#

or as part of shellcode

rugged sparrow
#

well you could just construct simple types manually if you dont want to bother with the rop there

radiant anchor
#

True

rugged sparrow
#

@radiant anchor if you dont mind, i might implement some of these strategies in my fishhook module

#

to reduce the reliance on ctypes

radiant anchor
#

Sure

rugged sparrow
#

seems to be running into issues in python3.9

#

yea it doesnt work on 3.9 ill try to figure out where it fails

radiant anchor
#

rip

#

It should also work on python 2.7 btw (except setrip(), for now)

rugged sparrow
#

ok

radiant anchor
#

I'm installing 3.9 now so I'll also take a look

rugged sparrow
#

fakeobj returns 2

#

seems to be consistent

radiant anchor
#

strange. What OS are you on?

#

I'm guessing either BYTES_HEADER_LEN or TUPLE_HEADER_LEN needs tweaking

rugged sparrow
#

im on macos

#

3.8 seems to work tho

radiant anchor
#

nice

#

I wonder if there's a reliable way to detect BYTES_HEADER_LEN and TUPLE_HEADER_LEN at runtime

#

maybe like, allocate a bunch of them and observe the minimum distance between their id()'s

#

minus the libc heap overhead

rugged sparrow
#

object().__sizeof__() returns 16 (refcount, ob_base)

#

on a tuple its a variable type, so it has another field, ob_size

#

@radiant anchor use ().__sizeof__() it returns the size of an empty tuple

radiant anchor
#

woah I had no idea __sizeof__ was a thing, tyvm

rugged sparrow
#

which is just the tuple header with a 0 ob_size

radiant anchor
#

are they different on 3.8 and 3.9?

rugged sparrow
#

nope

#

afaik that size has been consistent all of 3.x

radiant anchor
#

hm

#

ok I can reproduce the 2 bug on 3.9

#

ah

#

the problem is with how it builds co_consts

#

on py3.8 it looks like, for example (None, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)

#

on 3.9 it looks like (None, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), 13)

#

I need to make it not do that...

#

damn optimisations...

mint holly
#

its a thing of beauty

rugged sparrow
#

@radiant anchor this is super clever tho

radiant anchor
#

ty

rugged sparrow
#

would it not be easier to make the bytecode for LOAD_CONST yourself?

#

because then you dont run the risk of the compiler optimizing anything

radiant anchor
#

That's what I was doing originally lol

#

the problem is, the bytecode changes between python versions

#

and until 3.9 came along, my method worked on every version, lol

#

I think I can find another

rugged sparrow
#

@radiant anchor your setrip wont work on 3.9 either because FunctionType uses vector call

radiant anchor
#

rip

rugged sparrow
#

thats easier to fix tho, just unset a flag on the type to disable it

#

also you can get the opcode for LOAD_CONST dynamically without imports right? py def get_load_const(): f = lambda:None code = f.__code__ for op, arg in zip(code.co_code[::2], code.co_code[1::2]): if len(code.co_consts) < arg and code.co_consts[arg] is None: return op

#

wait that doesnt work on py2.7

radiant anchor
#

@rugged sparrow fixed it

#

rather than putting the numbers in a big array, they're now in function arguments

#

also setrip() seems to work fine

#

I think the flag is already cleared

#

for vectorcall

rugged sparrow
#

it shouldnt be?

radiant anchor
#
$ python3.9 shellcode_example.py 
sh-5.0$ 
rugged sparrow
#

i was messing with patching tp_call on functiontype and it wasnt working

#

because of that flag

#

weird

radiant anchor
#

I think that's why mine works?

#

or is the flag in the FunctionType type object itself?

rugged sparrow
#

its in the functiontype type object

radiant anchor
#

(it's actually been a while since I wrote that code)

rugged sparrow
#

in tp_flags

#

it segfaults for me on 3.9

#

with a traceback that looks similar to the vectorcall issue i was running into

radiant anchor
#

huh, I wonder if we have different 3.9 sub-versions

rugged sparrow
#

whats yours?

dapper parrot
#

aaaaa what is this

radiant anchor
#
The vectorcallfunc pointer may be NULL, in which case the instance behaves as if Py_TPFLAGS_HAVE_VECTORCALL was not set: calling the instance falls back to tp_call.
dapper parrot
#

what's that random hex offset

rugged sparrow
#

Python 3.9.0 (v3.9.0:9cf6752276, Oct 5 2020, 11:29:23)

radiant anchor
#

how do you get the full version string?

rugged sparrow
#

its at the start of the interpreter

radiant anchor
#

Python 3.9.0 (default, Dec 6 2020, 01:25:29)

rugged sparrow
#

i just copied it

radiant anchor
#

mine doesn't say git hash

#

but I assume its from head

#

I used the AUR package

rugged sparrow
#

i used brew to install mine so it built when i installed

radiant anchor
rugged sparrow
#

also, technically the vectorcallfunc pointer shouldnt be null in your code

dapper parrot
#

ahh right

#

try on an online repl or something maybe?

dapper parrot
#

which will hopefully always be latest

#

subversion i mean

radiant anchor
#

I was going to say, I should zero it

#

probably easier than flag twiddling

rugged sparrow
#

well its easier to just flip the flag

radiant anchor
#

you sure?

rugged sparrow
#

its at a stable offset on the type

#

and you can find it if you need to

#

because you can get the flags value from the type

#
17568768
#

so you could encode that to bytes and just look from id(typ):id(typ) + type.__sizeof__(typ)

radiant anchor
#

Really strange that it works on my machine though

rugged sparrow
#

well you also are instantiating an object larger than it should be

radiant anchor
#

It shouldn't affect anything, if its too big

#

how portable is sizeof?

rugged sparrow
#

been there since before 2.7

#

and yea it shouldnt, but you dont know whats after the FunctionType object in your version

#

cause the vectorcallfunc can be placed directly after (but that depends on the compiler) afaik

#

which is why it would cause an issue on mine and not yours

radiant anchor
#

oh interesting

rugged sparrow
#

yea so its safer to just use type.__sizeof__ (you need to use that one because FunctionType.__sizeof__ is an overloaded method for getting the size of a func object)

dapper parrot
#

'''"""""'''''safer'''"""""'''''

rugged sparrow
#

yea safer

#

none of this is truely safe

dapper parrot
#

looks really fun though

radiant anchor
#

hmmmm are you sure that FunctionType.sizeof() gets the size of the type

#

TypeError: unbound method object.__sizeof__() needs an argument

#

like, isn't it supposed to be called on an instance

dapper parrot
#

at first i assumed it was for interfacing with old badly memory managed c libraries

#

then i realised it's mostly for breaking stuff

radiant anchor
#

is FunctionType.__sizeof__(FunctionType) valid

rugged sparrow
radiant anchor
#

ah

rugged sparrow
#

yea thats gotten me a few times too

#

if you want a universal sizeof method here py def sizeof(obj): return type(obj).__sizeof__(obj)

#

that will work on any pyobject

radiant anchor
#

ty, I'll use that

#

just pushed an update that uses that for BYTES_HEADER_LEN etc. too

rugged sparrow
#

noice that should get rid of all your magic numbers right?

#

@radiant anchor still getting a vector call related segfault

radiant anchor
#

yeah I wasn't expecting that to be fixed yet

#

the last magic number is the 0x100

#

how do I get the size of a FunctionType instance

rugged sparrow
#

so tp_flags is a c_long at the offset 21 * (ptrsize)

radiant anchor
#

I guess I can sizeof any function?

rugged sparrow
#

yea

#

the sizeof func i sent should work on any object

radiant anchor
#

is tp_vectorcall also always at a fixed offset?

rugged sparrow
#

if you unset the flag then itll ignore the tp_vectorcall slot

radiant anchor
#

Nice

#

I just pushed the fix, would you mind testing it?

rugged sparrow
#

segfault again

radiant anchor
#

huh

#

also, the flag was set on my machine

rugged sparrow
#

interesting

radiant anchor
#

Would you mind testing with my_functype[50*8:50*8 + 8] = p64a(0) added?

#

I believe that should clear tp_vectorcall

rugged sparrow
#

yea one sec

radiant anchor
#

but also

#

if it tries to do a vectorcall

#

shouldn't it succeed?

rugged sparrow
#

segfaulted again

radiant anchor
#

can you get any more details about the segfault?

rugged sparrow
#
0   ???                               0x0000000108df301b 0 + 4443811867
1   org.python.python                 0x0000000108b358fc call_function + 876
2   org.python.python                 0x0000000108b32e2b _PyEval_EvalFrameDefault + 25371
3   org.python.python                 0x0000000108a5fa28 function_code_fastcall + 104
4   org.python.python                 0x0000000108b3586c call_function + 732
5   org.python.python                 0x0000000108b32d93 _PyEval_EvalFrameDefault + 25219
6   org.python.python                 0x0000000108b36563 _PyEval_EvalCode + 2611
7   org.python.python                 0x0000000108b2c9eb PyEval_EvalCode + 139
8   org.python.python                 0x0000000108b7f352 PyRun_FileExFlags + 434
9   org.python.python                 0x0000000108b7e92f PyRun_SimpleFileExFlags + 831
10  org.python.python                 0x0000000108b9b7e9 Py_RunMain + 1801
11  org.python.python                 0x0000000108b9bc7f pymain_main + 223
12  org.python.python                 0x0000000108b9be7b Py_BytesMain + 43
13  libdyld.dylib                     0x00007fff6e0e4cc9 start + 1```
radiant anchor
#

Do you know where PyObject_Vectorcall is implemented in the source?

#

ah

#

huh no I can't find it, lol

#

Thought it would be in Objects/call.c

rugged sparrow
#

Include/cpython/abstract.h

#

line 119

radiant anchor
#

also, can you dump the registers? i r

#

ty