#esoteric-python

1 messages ยท Page 65 of 1

grave rover
#

Seems a little bit messy tbh :P

sick hound
#

it is

grave rover
#

Any idea how to rework it into my lib?

brisk zenith
#

oh haha i just ran into the issue pastebean had py_object((((((((((((<NULL>, <class 'ctypes._endian.BigEndianStructure'>), ...

#
Traceback (most recent call last):
  File "testing3.py", line 39, in <module>
[1]    3928 segmentation fault (core dumped)  python3 testing3.py```
well at least it gave me the traceback first
brisk zenith
#

okay so i've tried doing this but it still doesn't work, despite doing exactly what @sick hound did (that is, assignment of frame.f_lineno). the only difference is that i didn't do it from within a trace function. instead, i modified the memory a bit to trick it into thinking it's in a trace function, but it's actually not. still, it doesn't work and i'm adamant to know why :D

code: https://paste.pydis.com/megalovefi.py

grave rover
#

darn

grave rover
#

@brisk zenith gonna do more phone dev, what specifically should I look into for fixing this?

brisk zenith
#

hmm.. i honestly have no idea

#

it's a very low-level thing though, beyond bytecode. this is modifying the content of C structs for frames in memory :D i recommend that you have a good play around with ctypes though

grave rover
#

Ctypes is amazing

#

Oh Juanita wanna work with me on adding the stuff recommended by pastebean?

#

Or wait

#

What random suggested*

brisk zenith
#

what's that?

grave rover
#

Basically messing with name/fast/const access

#

And uh

#

Changing scope of a frame/function

#

Stuff like that

grave rover
#
>>> import numpy as np 
>>> def f1(x): 
...     np.array([float(x)])
... 
>>> def f2():
...     return np.empty((), dtype=np.float).tolist()
... 
>>> f1(1964.5)
>>> f2()
1964.5
brisk zenith
#
>>> @CFUNCTYPE(py_object, py_object)
... def new_boolrepr(self):
...     return "lol no"
... 
>>> bool_struct = PyTypeObject.from_object(bool)
>>> bool_struct.tp_str = new_boolrepr
>>> print(True)
lol no
>>> 
#

i'm going to attempt to map out as many C struct into ctypes.Structure classes as i can

#

got enough working that builtin types can be modified very easily

brisk zenith
#
>>> x = 99999999999999999
>>> int_struct = PyLongObject.from_object(x)
>>> int_struct.ob_digit[0] += 1
>>> x
100000000000000000
>>> 

ints are now mutable

#
>>> x = 5
>>> int_struct = PyLongObject.from_object(x)
>>> int_struct.ob_digit[0] = 4
>>> 2 + 2 == 5
True
>>> 

now we've got a reasonably clean way of doing this lmao

rugged sparrow
#

@brisk zenith oh no

#

What have you done...

brisk zenith
#

i mean, we've done this sort of thing here many times before. i'm just writing a helper so that it makes more sense. the alternative is to have a bunch of magic numbers in the code ```py

digit = c_uint.from_address(id(5) + 24) # 24 what?
digit.value = 4
2 + 2 == 5
True

rugged sparrow
#

Ah ok

brisk zenith
#

the 24 is there because the actual content of an int is stored 24 bytes after the beginning of the int itself, but you can't really tell that from the code

rugged sparrow
#

That's really cool tho

brisk zenith
#

ty ๐Ÿ‘Œ

rugged sparrow
#

Is the source out rn?

#

I kinda want to check it out

brisk zenith
#

i mean, i could throw it in a hastebin for now. really it's just a bunch of dirty ctypes.Structure subclasses. so far i've only done basic stuff (namely, object, int, and all the structs that they need to function)

#

i think i'll do lists now

rugged sparrow
#

sweet

#

this is gonna be fun to look at

sick hound
#
>>> True
1```
#

True is an int now :P

mild swan
#

?

brisk zenith
#

true is an int anyways, technically

nocturne saddle
#

well, bool is a subclass of int, technically, and True has the numerical value 1

#

Sorry

sick hound
#

Actually, we turned bool into int, oops ```py

bool
<class 'int'>```

nocturne saddle
#

Haha

#

Nice

brisk zenith
#

that's quite easily done using my code i believe

sick hound
#

Don't set random pointers, you might turn bool into int :P

brisk zenith
#

haha nice

sick hound
#
>>> False
0``` Which means False is also 0 now
brisk zenith
#

i mean technically they're not even defined as bools or whatever internally, they're PyLongObjects ```c
struct _longobject _Py_FalseStruct = {
PyVarObject_HEAD_INIT(&PyBool_Type, 0)
{ 0 }
};

struct _longobject _Py_TrueStruct = {
PyVarObject_HEAD_INIT(&PyBool_Type, 1)
{ 1 }
};

sick hound
#

we overwrote &PyBool_Type with int apparently

#
>>> type(0) is type(1)
1
>>> type(0) is type(True)
0```
#

this is confusing

fallen heath
#

How is that confusing?

#

Seems like normal behaviour

#

int isn't equal to bool

sick hound
#

firstly, it's returning 1 and 0 instead of True and False

fallen heath
#

Oh, i see now

sick hound
#

and also if you do type(True) it says it's an int? ```py

type(True)
<class 'int'>```

#

True gets printed as 1 ```py

True
1```

fallen heath
#

and does type 0 also return class 'int'

sick hound
#

yes

brisk zenith
#
>>> bool_struct = PyTypeObject.from_object(bool)
>>> int_struct = PyTypeObject.from_object(int)
>>> bool_struct.tp_repr = int_struct.tp_repr
>>> bool_struct.tp_name = int_struct.tp_name
>>> True
1
>>> False
0
>>> bool
<class 'int'>
>>> 

using my helper code above

sick hound
#

The interpreter also crashes when we exit it...

#

what did we expect

fallen heath
#

id(type(True)) vs id(type(1))

sick hound
#
>>> PyObject.from_object(True).ob_type[0] = PyTypeObject.from_object(int)
>>> type(True)
<class 'int'> : # colon to make the syntax highlighting happy
>>> type(1)
<class 'int'> : # ignore these colons
>>> id(type(True))
1783558432
>>> id(type(1))
1783601632
>>> True
1```
brisk zenith
#

oh nice

#

do you like my code? i do.

fallen heath
#

It's not usable in prduction sadly.

brisk zenith
#

of course, but it's fun to play with

sick hound
#

esoteric python stuff is not meant to be used in production, it's meant to be fun and really weird

fallen heath
#

And it teaches you a lot aswell.

sick hound
#

hacking the python internals is a fun way to find out about them :P

brisk zenith
#

as someone who would like to eventually make contributions to cpython, i think this is the best way to learn about the internals

#

if you can break something then fix it you've probably understood enough about it to expand on it

brisk zenith
#
>>> a = object()
>>> struct = PyObject.from_object(a)
>>> b = struct.get_object()
>>> b is a
True
>>> struct.ob_refcount
2
>>> del b
>>> struct.ob_refcount
1
>>> 

implemented a get_object method

#

simple enough, just ```py
def get_object(self):
ptr = c_void_p(addressof(self))
return cast(ptr, py_object).value

#

works at any depth of the struct ```py

obj_type = struct.ob_type.contents.get_object()
obj_type is object
True

brisk zenith
#
>>> my_list = [1, [2, "hello"], 3]
>>> struct = PyListObject.from_object(my_list)
>>> inner_list = struct.ob_item.contents[1].contents.value
>>> inner_list
[2, 'hello']
>>> 

accessing list items has never been so easy

grave rover
#

oh boy

calm rampart
#

back when the comparison operators returned actual ints, True and False didn't exist

#

re. True being 1

desert garden
#

Didn't python 2 just have True = 1 and False = 0 instead of being reserved keywords?

tepid glacier
#

Yeah pretty much

#

You could (still can in 2.7.16) reassign them to completely different values

#

The bool type still existed though

#

Oh huh

# Python 2
>>> True == 1
True
>>> isinstance(True, bool)
True
>>> isinstance(True, int)
True

# Python 3
>>> True == 1
True
>>> isinstance(True, bool)
True
>>> isinstance(True, int)
True
#

Guess I was wrong

#

Yeah the only difference is that it's reserved in Python 3

brisk zenith
#

i remember when i was fascinated by the idea that True is an int. dabward

desert garden
#

Oh that's a bit odd that it's both and int and a bool still in python 3

calm rampart
#

looks like bool was added in Python 2.3

desert garden
#

Does bool just inherit int?

calm rampart
tepid glacier
#

I believe so

#
>>> issubclass(bool, int)
True
#

Time to pyenv install 2.1.3

#

yep

Python 2.1.3 (#1, Apr  8 2019, 19:35:49) 
[GCC 8.2.1 20181127] on linux5
Type "copyright", "credits" or "license" for more information.
>>> True
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'True' is not defined
>>> 1 == 1
1
brisk zenith
#

oh that's fascinating

#

wait wasn't there a 69L literal in all versions of py2?

tepid glacier
#

huh

#

what's it do

#

๐Ÿ‘€

>>> type(69L)
<type 'long int'>
#

Yeah just suffixing numbers with L gives you a long int

desert garden
#

Yeah python2 used to make you manage your int lengths a lot more than python3 does

#

It's always funny when python3 ints have arbitrary precision so a // gets the exact value for a massive number, but because floats don't, if you just use int(... / ...) you can sometimes get a wildly different number

brisk zenith
#

well i'd hope that any int arithmetic is accurate in any language, because integers never get recurring decimals like floats do (which is more or less why they can be imprecise)

snow beacon
#

I wish more languages used rational representations instead of floating point.

#

e.g. 1 / 3 = 1/3

fallen heath
#

from fractions import Fraction
If you want it like that

snow beacon
#

I know it's possible, it's just a bit more complicated than it could be.

fallen heath
#

Floats are way faster than fractions iirc

snow beacon
#

For which operations?

#

Trigonometry of course, and logarithms, but they are inexact anyway.

#

Multiplication seems like it would go a lot quicker with fractions than with floats.

#

Same with division.

#

Actually, I guess the hard part would be factorising the numbers

fallen heath
#

The fractions module is written in pure python

gentle pagoda
#

(sorry if this is the wrong place to ask)
can this factorial function be made any shorter? it only needs to work for n>0 py f=lambda n:n**(n>0)*(n==0*1or f(n-1))

fallen heath
#
f=lambda n:n==0 or n*f(n-1)```
I got this
gentle pagoda
#

:O why didnt i think of that

#

thanks

fallen heath
#

This looks like the standard regular function approach I think.

gentle pagoda
#

you can save 2 characters like this btw py f=lambda n:n<1or n*f(n-1)

supple jasper
#

and if you memoize it, then the running times aren't horrible either, as far as I understand!

shy vector
#

@gentle pagoda what happens with f(-1)

fallen heath
#

Returns True

#

But the scope was only n > 0

gentle pagoda
#

i dont want to deal with n<0 because it makes the code longer xd

#

if you find a clean way of doing it im really interested tho

grave rover
gentle pagoda
#

ooh nice, how tf does that work?

fallen heath
#

It's a formula for calculating the nth element of the sequence. Without calculating the rest of it

grave rover
#

^

#

no recursion

gentle pagoda
#

ooh thats really cool ๐Ÿ˜„

grave rover
#

in case you wanna try it

#

the 1000th fibonacci number according to this is
26863810024486259428057328890462071226932128417886493703576991815165644098340129752887649389042242022037970113428562978866498563272624804026557522173602820491641993157883791984718503223913747590579636943192064

gentle pagoda
#

wow i need to look at that formula later. looks really useful

grave rover
#

I think I found a decent way to do gotos but it's gonna be a pain to do properly line-number wise

#

Nvm we have dis.findlinestarts(code)

grave rover
#

Ignore the 3044 that's left from debug prints

#

The trick: I simply replace the goto call with a JUMP_ABSOLUTE

brisk zenith
#

yeah i considered doing that but it would be neat to do it like a normal function without a decorator or something :D

grave rover
#

yea

sick hound
#

what's the point of doing:

#
if(a <= 0 | b <= 0 | c <= 0):
        return False

vs using or

brisk zenith
#

i guess the only difference in that case is that or short-circuits whereas | doesn't. as soon as or reaches a True, it stops and doesn't evaluate the rest of the conditions. to be fair though, the use of parentheses there is a sign that the person who wrote that code came from another language and hasn't adapted to python's syntax properly.

sick hound
#
def is_triangle(a, b, c):
    
    if(a <= 0 | b <= 0 | c <= 0):
        return False
    elif( a + b <= c or a + c <= b or b + c <= a): 
        return False
    else:
        return True
brisk zenith
#

yeah, just looks poorly-formatted

#

you could change that to ```py
def is_triangle(a, b, c):

if a <= 0 or b <= 0 or c <= 0:
    return False
elif a + b <= c or a + c <= b or b + c <= a: 
    return False
else:
    return True
and it would work just the same
brisk zenith
#

i am determined to at least figure out why my goto code didn't work. there's probably a better way to debug this, but i don't really care :D i have modified the interpreter slightly to show me exactly what's going on: ```py
import ctypes
import sys

def goto(line):
print("beep!")

def test():
print("first")
goto(13)
print("second")
print("third")

test()

gives me an output of ```py
DEBUG: entering frame 'test' (0x55fcc5f779b0)
first
DEBUG: entering frame 'goto' (0x55fcc5f77c10)
beep!
DEBUG: returning from frame 'goto' (0x55fcc5f77c10) to line 9 of 'test' (0x55fcc5f779b0)
second
third
DEBUG: returning from frame 'test' (0x55fcc5f779b0) to line 1 of '<module>' (0x55fcc5f6e370)
wind maple
#

isnt this jmp

fast torrent
#

@brisk zenith have you got a goto func working?

open ore
#
class WrongType(Exception):
    def __init__(s,func,right,inp={"OBJNONEFOREXCEPTION"}):
        s.msg = "{} needs {}".format(func,right) if inp is {"OBJNONEFOREXCEPTION"} else "{} needs {}, not {}".format(func,right,NKfunc.typeName(inp))
    __str__ = (lambda s: s.msg)```
#

lambda is fun

#

:)

#

any([i <= 0 for i in [a,b,c]]) works as a <= 0 or b <= 0 or c <= 0

green nymph
#

nope, at least in the way you have it, it's a bit different

#

any(i <= 0 for i in [a,b,c]) would be kinda same

#

because in your case it will evaluate all the conditions

#

and then would pick first truely if there is first truely

brisk zenith
#
Python 3.8.0a3+ (heads/master-dirty:2fb2bc81c3, Apr 11 2019, 12:28:57) 
[GCC 8.2.1 20181127] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> Maybe
True
>>> Maybe
False
>>> 

i have successfully modified the python interpreter for no good reason

nocturne saddle
#

Maybe i have successfully modified the python interpreter for what may be a good reason

brisk zenith
#
>>> Maybe = 1
  File "<stdin>", line 1
SyntaxError: cannot assign to True
>>> 
``` this is rather queer
rugged sparrow
#

@brisk zenith i assume you used the helper thing you made?

brisk zenith
#

actually, no. i'm modifying cpython here.

#

although we did have a challenge recently of implementing Maybe in pure-python. on that topic, i need to merge those submissions

stray needleBOT
brisk zenith
#

wow spicy

#

i'm gonna continue making changes so that Maybe = "hi" gives a proper error

fallen heath
#

Someone in another chat wanted a way to get all different capitalizations of a word.

#

So I made this.

#
f=lambda w:w==""and[""]or[c+s for s in f(w[1:])for c in[w[0].upper(),w[0].lower()]]```
sick hound
#
f=lambda w:w and[c()+s for s in f(w[1:])for c in[w[0].upper,w[0].lower]]or[""]```
fallen heath
#

nice

desert garden
#

Is there a way to make JUMP_ABSOLUTE set the bytecode pointer at module scope not at local scope without cpython modification?

sick hound
#

@brisk zenith hacking the cpython it self is funny thing

#

i tried to implement new grammars like goto challange you made here in the past. It is really easy to modify it

#

also James Powell has great talks about it

#

This is the patch for adding a new conversion char to paths

desert garden
#

I'm trying to see how far I can get with just internal bytecode stuffs

sick hound
#

i think this is the equlivent of segfault on posix

brisk zenith
#

yes it is

desert garden
#

Yee

sick hound
#

using ctypes?

desert garden
#

That was from ```py
LOAD_GLOBAL 0
LOAD_CONST 0
CALL_FUNCTION 1
RETURN_VALUE

#

Where the consts tuple was just (print,)

#

The stack's set to 99 just to be safe, but I can't work out what's up with it

#

Oh nvm lol

#

I should have just LOAD_CONST'd the first and not tried to load print as a global

brisk zenith
#

print isn't a const

desert garden
#

It is if you define it as one ๐Ÿ˜‰

brisk zenith
#

oh dear

sick hound
#

print is a name

desert garden
#

: (

#

I did a good and stopped passing it as a const

#

Shame there's no JUMP_ABSOLUTE that'll break out of the current section of bytecode

brisk zenith
#

what do you mean?

desert garden
brisk zenith
#

ah, yeah. you'd have to modify the bytecode of other frames which, although very possible, is probably very difficult to get right without fucking up a ton of stuff

desert garden
#

Would it not be almost impossible because of CALL_FUNCTION encapsulating things?

#

So you'd need some way to cleanup some things while transferring other things into the new scope

brisk zenith
#

i've tried doing this by modifying the attributes of the previous frame object. do you know what frame objects are?

desert garden
#

Roughly. The frame for the current block of code is the object that contains info about the current execution state, the namespace, etc.?

brisk zenith
#

yeah, pretty much. it also contains the index of the last instruction executed. i thought that changing this value would change where the interpreter resumes execution in that frame, but that doesn't work because frame.f_lasti is set by the interpreter, not checked by it. the only way i can think of doing it without using a trace function is by somehow modifying the value of next_instr in this function as it's simply a pointer to the currently executing intruction bytes. https://github.com/python/cpython/blob/master/Python/ceval.c#L1104
however, i don't think this is possible at all :D

#

that's just for my idea of a solution, though. if you can think of a way to do it differently, go ahead.

#

maybe @sick hound can figure out how to do what i'm thinking. is it possible to change the value of a variable in a running C function? i think this is getting even beyond #esoteric-python though haha.

#

to be fair that's probably a big XY problem right there

#

i don't know how C works on that level :D

sick hound
#

is it possible? probably just about

brisk zenith
#

probably incredibly difficult though

sick hound
#

assuming you know exactly where the function called another function that eventually ran your code,

#

you could disassemble the function, find that CALL instruction, and figure out the difference between the esp/rsp value at that time and the place the variable you want to change is

#

(which would probably be easier in a debugger actually)

brisk zenith
#

haha sounds 100% doable with python, sure :D

sick hound
#

well you'd do that before writing the python code

#

the actual python code would get the address of the function, add the number of bytes between the CALL and the beginning of the function, and then look backwards through the stack to find that value

#

then it would subtract the other offset you found from the address it finds that CALL

#

that is an address that can be written to

#

...maybe

#

we only know a bit about assembly and that might be completely wrong ._.

brisk zenith
#

that is ok ๐Ÿ‘Œ ty for your knowledge, i'll poke around a bit

sick hound
#

also actually, a debugger would probably help

brisk zenith
#

yeah for sure

rugged sparrow
#
>>> x = lambda a=None,b=[None]:[b.pop(),b.append(a),None][2] if a != None else b[0]
>>> x()
>>> x(1)
>>> x()
1
>>> x(None,[0])
0
>>> x()
1
>>> 
``` anyone know why this happens?
calm rampart
#

@rugged sparrow without working through the whole thing by hand, I assume it's because the default b is the same list object every time.

rugged sparrow
#

Ah cool

#

Im writing a shoddy version of solitaire in one line and was having an issue due to thar

#

*that

#

Thought it was weird

#

Cause afaik wouldn't expected behavior be for default b to be a new list object every time?

sick hound
#

nope

#

you can even use .__defaults__ and .__kwdefaults__ to get the default values

#
>>> f = lambda x=[], *, y=[]: (x, y)
>>> f()
([], [])
>>> f()[0].append(0)
>>> f()
([0], [])
>>> f.__defaults__
([0],)
>>> f.__defaults__[0].append(1)
>>> f()
([0, 1], [])
>>> f()[1].append(0)
>>> f()
([0, 1], [0])
>>> f.__kwdefaults__
{'y': [0]}
>>> f.__kwdefaults__['y'].append(1)
>>> f()
([0, 1], [0, 1])```
rugged sparrow
#

Thats cool

desert garden
#

It will skip over print('a') and output b

frozen fog
#

Solution for the Maybe problem using a simple metaclass ^_^

brisk zenith
#

i like that one. it's not perfect to the test cases but certainly a nice submission for it's simplicity. i'll merge it when i get on my computer next :)

frozen fog
#

I guess I can add a __str__ and __format__ for the metaclass for case of print(Maybe)

#

I think assignment can also be prevented somehow, I forget which method that invokes.

desert garden
brisk zenith
#

neat!

fast torrent
#

How do you stop assignment?

#

And if you do - can you do it with a metaclass and add stuff like static typing?

snow beacon
#

I would assume not, at least not for a variable. Variables are references to objects; it makes sense that the objects themselves wouldn't get a say in assignment.

brisk zenith
#

yup

#

the assignment part is probably the trickiest but there's been some really cool submissions which make a damn good effort :D

fast torrent
#

Yeah

sick hound
#

...we have an evil idea...

fast torrent
#

Evil ideas belong here!

desert garden
#

I used settrace and then just had it sys.stderr a fake "error" if it noticed a mutation to Maybe in the bytecode

#

It doesn't work if you try and put a debugger or something on it though, which is a pain

sick hound
#

...we did something ```py

a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "wtf.py", line 7, in getitem
return super().getitem(item)
File "wtf.py", line 7, in getitem
return super().getitem(item)
File "wtf.py", line 7, in getitem
return super().getitem(item)
[Previous line repeated 329 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object```

#
>>> x = 4
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined```
desert garden
#

wtf.py indeed

sick hound
#

Well now everything is _getframe ```py

x
<built-in function _getframe>
what
<built-in function _getframe>
lol
<built-in function _getframe>```

#

we were not expecting that ```py

x = 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "wtf.py", line 14, in setitem
super().setitem(item, value)
AttributeError: 'frame' object has no attribute 'setitem'```

#

but i guess it makes sense ```py

super
<built-in function _getframe>```

#

this is amazing

#

Now it kind of actually does something ```py

x
'x'```

desert garden
#

What are you even doing to the poor interpreter

sick hound
#

changing the type of locals()

desert garden
sick hound
#
>>> x
False
>>> y
False
>>> Maybe
True```
#

now Maybe is True and everything else is False

#

now everything is just False ```py

x
False
y
False
Maybe
False```

brisk zenith
#

changed the type to bool?

sick hound
#

nope

#

we're messing with locals()

#

we overwrote the type with our own class and we're changing the __getitem__ on that class

#

but since that gets called every time a variable is accessed we have to write it without using any variables

#

so we're writing it in bytecode

#

all of the functions we need to use like _getframe are constants

#

to get the arguments we use _getframe().f_locals

#

all variables are now randomly either 0 or 1 ```py

x
0
x
1
x
1
x
0
x
1
x
0
x
1```

#

we've turned everything into Maybe now ```py

x
True
x
False
x
False
x
False
x
True
x
False
x
False
x
False```

tropic gulch
#

Schrรถdinger's Python

#

cats are outdated

sick hound
#

now everything's super ```py

x
<class 'super'> :
y
<class 'super'> :```

#

(ignore the extra :)

#

uh... hmm... ```py

x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "wtf.py", line 7, in getitem

# there is no source code for this function

RuntimeError: super(): class cell not found```

#

Now everything is an empty dictionary, oops... ```py

x
{}```

#

What's more interesting, the result you get when everything works or the weird errors you get when things don't work? :P ```py

x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "wtf.py", line 7, in getitem

# there is no source code for this function

TypeError: 'cell' object is not subscriptable```

brisk zenith
#

i love the weird errors

#

i got a bus error yesterday

#
>>> 0x7ffd867b2bd8
[1]    30916 bus error (core dumped)  ./python Test/goto_test.py
sick hound
#

...from typing in a number?

#

did you mess with numbers or did the previous result have one reference and a weird/broken __del__

#

also we set up a function in a way that means its "source code" points to # there is no source code for this function

#

WE DID IT ```py

x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined```

#

@brisk zenith this is another Maybe implementation ```py
from ctypes import *
from sys import *
from sys import _getframe
from types import *
from random import *

there is no source code for this function

class PatchedLocals(dict):
getitem = FunctionType(CodeType(
2, 0, 2, 10, 0, b'd\0\x83\0j\0d\1\x19\0d\2k\2r\x1cd\5d\3d\4\x83\1\x83\1S\0d\6j\1d\0\x83\0j\0d\7\x19\0d\0\x83\0j\0d\1\x19\0\x83\2S\0', (_getframe, 'item', 'Maybe', getrandbits, 1, bool, dict, 'self'),
('f_locals', 'getitem'), ('self', 'item'), file, 'getitem', 7, b'', (), ('class',)
), {})
def setitem(self, item, value):
if item == 'Maybe':
raise SyntaxError("can't assign to keyword")
super().setitem(item, value)
def delitem(self, item):
if item == 'Maybe':
raise SyntaxError("can't delete keyword")
super().delitem(item)

py_object.from_address(id(locals()) + sizeof(c_ssize_t)).value = PatchedLocals```

brisk zenith
#

oh neat :D

stray needleBOT
sick hound
#

by the way, the way that works is by changing locals()'s type to our own subclass of dict

#

the reason there's loads of bytecode in there is because to prevent recursion we had to implement __getitem__ without using any instruction that gets a local variable

#

so sys._getframe, random.getrandbits, bool and dict are all constants

#

also the reason we used random.getrandbits is because it's a builtin method, random.choice or anything like that is in Python and uses variables

brisk zenith
#

huh nice

grave rover
#

I have a funny idea

#

Is anyone here familiar with pysimplegui?

#

We could make a GUI scratch-like bytecode editor, with arrows for e.g. jumps and references

brisk zenith
#

haha sounds interesting actually

desert garden
#

My plan for this weekend is getting a nice inline ```py
bytec(
LOAD_GLOBAL(5),
CALL_FUNCTION,
)

#

Gonna be a pain though because I'll have to offset the JUMP_ABSOLUTEs following it

#

Or have a wall of NOPs

brisk zenith
#

i've tried doing something similar to that but couldn't really be bothered to follow through with it. here was my decided syntax:

with __bytecode__:
    LOAD_NAME     ("print")
    LOAD_CONST    ("hello")
    LOAD_FAST     [0]  # load local value at index 0
    CALL_FUNCTION (2)
    RETURN_VALUE
desert garden
#

It should be pretty easy to do because the number of instructions that it'll be compiled to will be less than number it takes up to define

brisk zenith
#

yeah true

#

so just fill the extra space with nops

#

as you said, actually

desert garden
#

Constants like "print" and "hello" might be a bit of a pain because there's the possibility of a block of bytecode containing more than one with __bytecode__

brisk zenith
#

yeah

#

it's easy to use a with block for that because the SETUP_WITH block also provides the bytecode location of the end of the block as its oparg

desert garden
#

Oh really? That's actually pretty neat

rugged sparrow
#

so im nowhere near as talented as y'all are, but im working on a oneline card game and thought of this ```python
newCard = lambda card,suite:lambda self={
'card':card,
'suite':suite, #0:heart,1:diamond,2:clubs,3:spades
'visible':False
}:[
[
self.update({
'flip':lambda:self.update({'visible':not self['visible']})
}),
self.update({
'getCard':lambda:'โ™ฅโ™ฆโ™ฃโ™ '[self['suite']]+self['card']
}),
self.update({
'printCard':lambda:print('โ™ฅโ™ฆโ™ฃโ™ '[self['suite']]+self['card'] if self['visible'] else '[]',end='')
})
],
self
][1]

Ace = newCard('A',3)
Ace()'printCard'
Ace()'flip'
Ace()'printCard'```

desert garden
#

I just realized earlier today that my goto implementation will crash python

sick hound
#

"just realized earlier today"

desert garden
#

It's 16:23 here

sick hound
#

nice pleonasmic oxymoron :P

desert garden
#

Because it jumps out of things like while without going over the bytecode instruction that tells the interpreter that it left those blocks, so after ages and ages it'll hit the block limit and error

sick hound
#

oh

brisk zenith
#

@rugged sparrow that reminds me very much of my early submissions for the esoteric challenges (before i became an event handler for them). my first attempt at one-lining something like that is the first pin of this channel, feel free to take a look. :D

rugged sparrow
#

@brisk zenith cool I'll check it out

sick hound
#
(lambda a:setattr(a,'d',((lambda b:b(b))(lambda b:lambda f,x:(lambda c,d:lambda:c(*d))(b(b),(f,f(x)))))(lambda n:print(n)or n+1,0))or list(setattr(a,'d',a.d())for _ in iter(int,1)))(type('',(),{})())```
rugged sparrow
#

@sick hound does that count infinitely?

sick hound
#

yes

#

with no recursion errors

rugged sparrow
#

cool

#

@brisk zenith this is the first oneline/code golf i did

#
print(eval(f"(LB=Lc='X',b=L:int(input(a)),d=[*range(9)],e=Lp=print:[a,p('_'*7),[p('',*a[x:x+3],'',sep='|')for x in[0,3,6]]][0]:(Lb:[b]*9if 1in[all([b==a[int(x)]for x in str(list(map(ord,'ร’ล™สฆษถฦกฤ‚อˆรถ'))[y])])for y in range(8)]else a)((Lb,c,d:[b.pop(c),b.insert(c,d),b][2])([e(d),e(a)],a,d.index(b(c)),c)if['X']*9!=a!=['O']*9else a,c):(L:'X'*(a==['X']*9)+'O'*(a==['O']*9)or'C')({'B('*9}[' ']*9){',a))'*4}))('O')".replace('L','lambda a,')))```
#

its tictactoe

brisk zenith
#

oh interesting, i remember when there was a golfed tic-tac-toe round here that we got pretty damn short

#

don't think Someone is here anymore though, lemme see if i can find it.

rugged sparrow
#

tbh, with what ive learned since then, i could prob shorten it more

brisk zenith
#
i=input;p=print
C=lambda a:max(a[b//6]&a[b//6+b%6]&a[b//6+b%6*2]for b in[1,3,4,9,14,15,19,37])
P=lambda b:p(*(['-xo'[i]for i in a]for a in[b[i:i+3]for i in(0,3,6)]),sep='\n')
def I(k):
 if 1^k.isdigit():p('INTEGERS MORON');return
 j=int(k)%9-1
 if x[j]:p('Taken')
 else:x[j]=I.g%2+1;I.g+=1
I.g=0
while 1:
 if i('S or Q: ')=='Q':exit()
 x=[0]*9
 while 1^C(x)in(1,2):
  P(x);I(i('Move: '))
  if 0 not in x and not C(x):p('Tie');break
 else:P(x);p('Winner is','x'if C(x)>0else'o')```
#

strings aren't shortened but you get the point

rugged sparrow
#

yea

brisk zenith
#

to be fair, we often consider eval to be some form of cheating because we could just eval(compile(<bytecode>)) to make it ridiculously short

rugged sparrow
#

oh thats true lol

#

what does C do?

brisk zenith
#

i think it checks if there's a win

rugged sparrow
#

ah nice

#
[all([b==a[int(x)]for x in str(list(map(ord,'ร’ล™สฆษถฦกฤ‚อˆรถ'))[y])])for y in range(8)]``` this is how i check my win
sick hound
#

list(map(ord,'ร’ล™สฆษถฦกฤ‚อˆรถ'))

#

what is that

rugged sparrow
#

it gives me all the valid win states for the board

#

[210, 345, 678, 630, 417, 258, 840, 246]

brisk zenith
#

that's pretty smart

sick hound
#

1597463007 :P

rugged sparrow
#

thanks

#

whats that number? @sick hound

sick hound
#

it's a magic number

rugged sparrow
#

how so?

brisk zenith
#

yeah i did see your minesweeper, it's pretty neat

rugged sparrow
#

thanks

sick hound
#

google 0x5F3759DF

rugged sparrow
#

aight

#

woah thats cool

desert garden
brisk zenith
#

neat!

desert garden
#

I had to rewrite all my bytecode parsing code because I realized extended args were a thing

brisk zenith
#

ah yeah haha

sick hound
#

we did another weird thing ```py

type(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x90 in position 0: invalid start byte```

#

this is extremely worrying, what have we done ```py

type(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 1: invalid start byte
type(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x90 in position 0: invalid start byte
type(42)
<class ''> :
type(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 in position 4: invalid continuation byte
type(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 in position 4: invalid continuation byte
type(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 1: invalid start byte
type(42)
<class ''> :
type(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 in position 4: invalid continuation byte```

#

@brisk zenith it looks like we set the name of int to a deallocated piece of memory... oops...

#
>>> int
<class '๐ณธ‚x'>
>>> int
<class ''>
>>> int
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x88 in position 0: invalid start byte
>>> int
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x88 in position 0: invalid start byte
>>> int
<class '๐ณธ‚x'>
>>> int
<class ''>
>>> int
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd8 in position 0: invalid continuation byte
>>> int
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd8 in position 0: invalid continuation byte```
#

...This isn't quite what we wanted but at least it's not "BOX x BOX" ```py

int
<class 'mol'>```

#

oh wait, we're stupid ._.

#
>>> type(0)
<class 'lol'>```
brisk zenith
#

that's quite easy to achieve using my structs code from a few days ago :D

sick hound
#

we renamed int to lol

#

we're going to make it possible to assign anything

#

the way we did that was by doing athing.__name__ = 'lol'

brisk zenith
#

hm okay neat

sick hound
#

with nearly the same code, we can also change the class of things

#

False is now this thing ```py

False
':\x00\x00\x00์ฐๆฉ\x00\x00\x00\x00\x00\x00ใงธๆจป\x00\x00อ \x00\x00\x00(\x00\x00\x00์ซฐๆจก\x00\x00\x00\x00\x00\x00'```

#

that's interesting ```py

x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError```

#

object is now an empty string. that's not good. ```py

int.base
''```

brisk zenith
#

the shit you get up to is hilarious at times. i'm just waiting for the day i see "oh yeah by the way bool is now a particle accelerator"

sick hound
#

@brisk zenith oh yeah by the way bool is now a particle accelerator

#
>>> bool
<__main__.ParticleAccelerator object at 0x000000006A4EF120>```
tepid glacier
#

lol

brisk zenith
#

i'm sorry but what the actual fuck is that memory address

fast torrent
#

Lmao

sick hound
#

0x6A4EF120

brisk zenith
#

for fucks sake lmao

sick hound
#

it's 1783558432

#

which is what the id of bool was before we made it a particle accelerator

brisk zenith
#

that's not a sentence you hear every day

brisk zenith
#
>>> ...
TypeError: unhashable type: '6'
>>> 
#

this makes me very confused

desert garden
#

How do you even

brisk zenith
#

i literally have no idea

#

i thought i changed the memory of ellipsis.__repr__ to point to ellipsis itself but apparently not.

desert garden
#

How did you overwrite __repr__? ctypes?

brisk zenith
#

yeah but using my helper program that makes it slightly higher-level than modifying data at memory addresses

#

have you seen it?

#
>>> bool_struct = PyTypeObject.from_object(bool)
>>> int_struct = PyTypeObject.from_object(int)
>>> bool_struct.tp_repr = int_struct.tp_repr
>>> bool_struct.tp_name = int_struct.tp_name
>>> True
1
>>> False
0
>>> bool
<class 'int'>    :
>>> 
#
>>> @CFUNCTYPE(py_object, py_object)
... def new_boolrepr(self):
...     return "lol no"
... 
>>> bool_struct = PyTypeObject.from_object(bool)
>>> bool_struct.tp_str = new_boolrepr
>>> print(True)
lol no
>>> 

i want to implement more structs. i've got it private on github at the moment but there is a link with the main parts somewhere in this channel

desert garden
#

I have a patch decorator I wrote so I can py @patch(str) def reverse(self): return self[::-1] and it'll overwrite str.reverse

#

Or more usefully, ```py
@patch(str)
def spongebob(self):
return ''.join(
i.upper() if n % 2 == 0 else i.lower() for n, i in enumerate(self)
)

desert garden
tepid glacier
#

OH NO

fallen heath
#

!e from future import braces

night quarryBOT
#

@fallen heath Your eval job has completed.

001 | File "<string>", line 5
002 | SyntaxError: from __future__ imports must occur at the beginning of the file
fallen heath
brisk zenith
#

@desert garden nice try, that wouldn't even run because python would give a SyntaxError before it reached your import. ;)

desert garden
#

That's what you think

brisk zenith
#

that is what i think

desert garden
#

But what you don't see is me calling it from another import

#

That wraps importlib

#

And replaces __import__ with something that modifies the file before importlib sees it

brisk zenith
#

hmmm

#

okay that's spicy

grave rover
#

Damn

#

That's some good shit fam

sick hound
#
print('what')
sys.excepthook is missing
1 + 1
sys.excepthook is missing
HELP
sys.excepthook is missing
exit()
sys.excepthook is missing
^Z```
#

apparently sys.excepthook was missing

#
>>> what
b"\xe4\x00lass '\x00\x00\x00\x00\x00\x00\x00\x00"
>>> what
'\r\n'
>>> what
b"\xe4\x00lass '\x00\x00\x00\x00\x00\x00\x00\x00"
>>> what
'\r\n'```
#

huh??? ```py

what, what
('(hat\x00\x00', '(hat\x00\x00')```

#

this is very interesting ```py

[what]
[''\']
[what]
[''\']```

#

oh, mi segfaulted it :(

#

this object has way too many references ```py

obj.ob_refcount
2179898566729```

brisk zenith
#

:D

sick hound
#

mi now has a cparam, whatever that is ```py

param
<cparam 'P' (000001978EBB4340)>```

#

but now it's turned into this again ```py

param
b'\xe4\xa0\xbb\x8e\x97\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
param
'\r\n'
param
b'\xe4\xa0\xbb\x8e\x97\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
param
'\r\n'```

#

it seems like this stuff is deterministic but unpredictable

#

if you do this, you will always get a <cparam 'P'

#
>>> obj = PyObject.from_object('hello')
>>> cast(pointer(obj), py_object).value
<cparam 'P' (000002EC46904340)>
>>> param = _```
#

(on min computer, at least)

#

but if you do it even slightly differently, that doesn't happen

#

...this is weird

#

mi's confused, what on earth is going on ._.

#
>>> cast(paramO._obj, py_object).value
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
# <it crashes>```
brisk zenith
#

i mean, PyObject is just a subclass of ctypes.Structure

#

which is defined in _ctypes as _Structure in C code

#

so it might be related

sick hound
#

but what on earth is <cparam 'P'

brisk zenith
#

fuck knows

sick hound
#

and what is b'\xe4\xa0F\xc9\xb1\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

brisk zenith
#

search for "cparam" in the cpython github and see if you find any related strings

#

that's literally all i do

sick hound
#

aha

#

Modules/_ctypes/callproc.c

brisk zenith
#

ah that makes sense actually

#

callproc.c is what makes CFuncPtr (and PyCFuncPtrType and stuff) work, right?

sick hound
#

mi has no idea, but here's the struct c struct tagPyCArgObject { PyObject_HEAD ffi_type *pffi_type; char tag; union { char c; char b; short h; int i; long l; long long q; long double D; double d; float f; void *p; } value; PyObject *obj; Py_ssize_t size; /* for the 'V' tag */ };

brisk zenith
#

interesting

#

also pastebean, should i add you to my github repo for those helper structs? it's private for now but you can contribute if you want. i want to add structs for code object, frame objects, etc. but haven't gotten round to it yet.

sick hound
#

you could

#

mi doesn't really have anything better to do so mi'll probably contribute if you do

brisk zenith
sick hound
#

it worked

brisk zenith
#

neat

#

for struct fields that begin with _ like for PyBytesObject._ob_sval, it should be given a placeholder (probably c_void_p) and you should make a property called ob_sval which handles the field manually. this is because some fields are dynamically-sized and that can't be configured automatically.

vocal oyster
#

sometimes I come here to take a look at a foreign language

calm rampart
#

Experimentation of one way to handle ob_sval @brisk zenith

import ctypes

class PyBytesObject(ctypes.Structure):
    _fields_ = [
    ('ob_refcnt', ctypes.c_ssize_t),
    ('ob_type', ctypes.py_object),
    ('ob_size', ctypes.c_ssize_t),
    ('ob_shash', ctypes.c_ssize_t),
    ('ob_sval', ctypes.c_char),
    ]

obj = b'foobar'
ptr = ctypes.cast(id(obj), ctypes.POINTER(PyBytesObject))
vp = ctypes.cast(ptr, ctypes.c_void_p)
vpv = ctypes.c_void_p(vp.value + PyBytesObject.ob_sval.offset)
``` ```py
>>> ptr.contents.ob_refcnt
1
>>> repr(ptr.contents.ob_type)
"<class 'bytes'>"
>>> ptr.contents.ob_size
6
>>> ptr.contents.ob_shash
-1415199440176704306
>>> hash(obj)
-1415199440176704306
>>> ptr.contents.ob_sval
b'f'
>>> ctypes.cast(vpv, ctypes.c_char_p).value
b'foobar'  # only works if it is null-terminated
>>> ctypes.cast(vpv, ctypes.POINTER(ctypes.c_char))[:ptr.contents.ob_size]
b'foobar'  # works for any type```
brisk zenith
#

oh huh, interesting.

#

that would work for bytes objects, sure, but i suppose the issue is when you get to lists or ints.

calm rampart
#

you can substitute any type for c_char in class definition and the last one

brisk zenith
#
>>> test = [1, 2, 3, 4, 5]
>>> test.sort()
>>> test
[3, 4, 5, 1, 2]
>>> 
#

code (using my cpystructs module): ```py

import cpystructs
import random

@cpystructs.PyCFunction
... def evil_sort(self, _):
... random.shuffle(self)
...
list_struct = cpystructs.PyTypeObject.from_object(list)
list_struct.tp_methods[13].ml_name
b'sort'
list_struct.tp_methods[13].ml_meth = evil_sort

test = [1, 2, 3, 4, 5]
test.sort()
test
[3, 4, 5, 1, 2]

#

so simple yet so evil

tropic gulch
#

RandomSort ๐Ÿ‘Œ

#

ml_meth ๐Ÿ‘€

#

doesn't effect sorted(my_list) though, does it?

brisk zenith
#

haha that name's in the C struct, i'm being as consistent to the C structs as i can: ```c
struct PyMethodDef {
const char *ml_name;
PyCFunction ml_meth;
int ml_flags;
const char *ml_doc;
};

brisk zenith
#

oh, lemme check sorted

#

oh hot, segfault

#
>>> list(sorted(test))
[1]    11340 segmentation fault (core dumped)  python3
#

i wonder why (like, actually)

tropic gulch
#

rip

#

that was unexpected

brisk zenith
#

huh, so sorted uses .sort internally

#

but then why segfau.... ahh. okay. hm.

tropic gulch
#

huh

#

if sorted() uses list.sort(), how can it sort anything other than lists?

fallen heath
#

Doesn't it just need < or > implemented

tropic gulch
#

or is it basically

def sorted(iterable):
    l = list(iterable)
    l.sort()
    return l
brisk zenith
#

i am very confused right now, hold on.

fallen heath
#

Chrome mobile crashes when trying to load source :(

brisk zenith
#

so this is the C code for the sorted builtin. ```c
static PyObject *
builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *newlist, *v, *seq, *callable;

/* Keyword arguments are passed through list.sort() which will check
   them. */
if (!_PyArg_UnpackStack(args, nargs, "sorted", 1, 1, &seq))
    return NULL;

newlist = PySequence_List(seq);
if (newlist == NULL)
    return NULL;

callable = _PyObject_GetAttrId(newlist, &PyId_sort);
if (callable == NULL) {
    Py_DECREF(newlist);
    return NULL;
}

assert(nargs >= 1);
v = _PyObject_FastCallKeywords(callable, args + 1, nargs - 1, kwnames);
Py_DECREF(callable);
if (v == NULL) {
    Py_DECREF(newlist);
    return NULL;
}
Py_DECREF(v);
return newlist;

}

i'm looking at this line in particular: ```c
    callable = _PyObject_GetAttrId(newlist, &PyId_sort);

so, &PyId_sort is from a macro: _Py_IDENTIFIER(sort). the declaration of that macro is as follows: ```c

typedef struct _Py_Identifier {
struct _Py_Identifier next;
const char
string;
PyObject *object;
} _Py_Identifier;

#define _Py_static_string_init(value) { .next = NULL, .string = value, .object = NULL }
#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value)
#define _Py_IDENTIFIER(varname) Py_static_string(PyId##varname, #varname)

so it literally must get that identifier ("sort") as an attribute via the `_PyObject_GetAttrId` function (which just calls `_PyObject_GetAttr` with the name string internally).
#

this part indicates that it literally just makes a list out of it ```c
newlist = PySequence_List(seq);
if (newlist == NULL)
return NULL;

#

actually no

fallen heath
#

This looks to me as if it just copies the list, then sorts it

brisk zenith
#

PySequence_List is defined as follows: ```c

PyObject *
PySequence_List(PyObject *v)
{
PyObject result; / result list */
PyObject rv; / return value from PyList_Extend */

if (v == NULL) {
    return null_error();
}

result = PyList_New(0);
if (result == NULL)
    return NULL;

rv = _PyList_Extend((PyListObject *)result, v);
if (rv == NULL) {
    Py_DECREF(result);
    return NULL;
}
Py_DECREF(rv);
return result;

}

#

actually yeah

#

it literally makes a list from the sequence

#

and performs .sort on it

#

i would expect it to be smarter than that given the fact that it doesn't actually return a list

tropic gulch
#

hm? I think it does...

brisk zenith
#

really?

#

oh huh

#

i thought it was one of those fancy functions that returned a special iterable like range

tropic gulch
#
>>> sorted("foobar")
['a', 'b', 'f', 'o', 'o', 'r']
#

nope

brisk zenith
#

makes sense though

fallen heath
#

The manual reference counting in the c part is so annoying when writing a module. Py_DECREF brings back some bad memories

tropic gulch
#

I wonder if e.g. heapifying it and returning the lowest element on each next() call as a generator would be more efficient than really sorting it as a whole

brisk zenith
#

haha yeah i know what you mean grote. makes C code more gruelling than it needs to be at times

#

also, does list[x] do something different to list.__getitem__(x) internally? it seems to, at least: ```py

import cpystructs

@cpystructs.PyCFunction
... def new_getitem(self, item):
... return "lol no"
...
list_struct = cpystructs.PyTypeObject.from_object(list)
list_struct.tp_methods.contents.ml_meth = new_getitem

test = ["hello", "there", 1, 2, 3]
test.getitem(1)
'lol no' # this works as intended
test[1]
'there' # but this doesn't

#

even though they are said to be equivalent: ```py

list.getitem.doc
'x.getitem(y) <==> x[y]'

#

hmm.. well, there's two definitions of the getitem implementation: c PyObject * PyList_GetItem(PyObject *op, Py_ssize_t i) { if (!PyList_Check(op)) { PyErr_BadInternalCall(); return NULL; } if (!valid_index(i, Py_SIZE(op))) { if (indexerr == NULL) { indexerr = PyUnicode_FromString( "list index out of range"); if (indexerr == NULL) return NULL; } PyErr_SetObject(PyExc_IndexError, indexerr); return NULL; } return ((PyListObject *)op) -> ob_item[i]; } which i believe is list.__getitem__(x), and also:


static PyObject *
list_item(PyListObject *a, Py_ssize_t i)
{
    if (!valid_index(i, Py_SIZE(a))) {
        if (indexerr == NULL) {
            indexerr = PyUnicode_FromString(
                "list index out of range");
            if (indexerr == NULL)
                return NULL;
        }
        PyErr_SetObject(PyExc_IndexError, indexerr);
        return NULL;
    }
    Py_INCREF(a->ob_item[i]);
    return a->ob_item[i];
}

which i think is list[x]

#

surprised me that PyList_GetItem doesn't just wrap around list_item

#

oh hmm, apparently one of my related function type declarations was wrong. let's see if that does anything.

#
>>> import cpystructs
>>> @cpystructs.ssizeargfunc
... def first_getitem(self, item):
...     print("first!")
... 
>>> @cpystructs.PyCFunction
... def second_getitem(self, item):
...     print("second!")
... 
>>> struct = cpystructs.PyTypeObject.from_object(list)
>>> struct.tp_as_sequence.contents.sq_item = first_getitem
>>> struct.tp_methods[0].ml_meth = second_getitem
>>> x = [1, 2, 3]
>>> x[2]
3  # so i assumed the first one didn't work
>>> x.__getitem__(2)
second!  # but this one did work
>>> import dis
first!  # but then this happened as i tried to import dis for debugging
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.7/dis.py", line 8, in <module>
    from opcode import *
TypeError: attribute name must be string, not 'NoneType'
>>> 
#

time to investigate what exactly the BINARY_SUBSCR instruction does.

#

it calls PyObject_GetItem

#

so... let's see then. what does that do?

#

oh hmm

#

so, that checks if struct.tp_as_mapping.contents.mp_subscript exists in the type struct before going for struct.tp_as_sequence.contents.sq_item

#

well then, let's see if changing that first one does the magic i want

#
>>> import cpystructs
>>> 
>>> @cpystructs.binaryfunc
... def new_getitem(self, item):
...     print("moist")
... 
>>> struct = cpystructs.PyTypeObject.from_object(list)
>>> struct.tp_as_mapping.contents.mp_subscript = new_getitem
>>> test = [1, 2, 3]
>>> test[1]
moist
>>> 

that output describes me pretty accurately at this point

#

but __getitem__ behaves normally, so you'd have to modify both of these:

struct.tp_as_mapping.contents.mp_subscript``` for `x[y]`
and
```struct.tp_methods[0].ml_meth``` for `x.__getitem__`

@sick hound is this what you were looking for?
sick hound
#

thanks

grave rover
#

@brisk zenith know of a good UI library for a drag-and-drop view?

brisk zenith
#

nope

sick hound
#
>>> for x in [1]:
...  for x in [2]:
...   for x in [3]:
...    for x in [4]:
...     for x in [5]:
...      for x in [6]:
...       for x in [7]:
...        for x in [8]:
...         for x in [9]:
...          for x in [10]:
...           for x in [11]:
...            for x in [12]:
...             for x in [13]:
...              for x in [14]:
...               for x in [15]:
...                for x in [16]:
...                 for x in [17]:
...                  for x in [18]:
...                   for x in [19]:
...                    for x in [20]:
...                     print(x)
...
20
>>> for x in [1]:
...  for x in [2]:
...   for x in [3]:
...    for x in [4]:
...     for x in [5]:
...      for x in [6]:
...       for x in [7]:
...        for x in [8]:
...         for x in [9]:
...          for x in [10]:
...           for x in [11]:
...            for x in [12]:
...             for x in [13]:
...              for x in [14]:
...               for x in [15]:
...                for x in [16]:
...                 for x in [17]:
...                  for x in [18]:
...                   for x in [19]:
...                    for x in [20]:
...                     for x in [21]:
...                      print(x)
...
SyntaxError: too many statically nested blocks```
brisk zenith
#

i'm surprised that gives a SyntaxError to be fair

nocturne saddle
#

The rationale for using SyntaxError is in there

#

It's not much, though

#
But SystemError is not an exception that should be raised. SystemError is for errors that can't be occurred in normal case. It should only be caused by incorrect use of C API or hacking Python internals. I think SyntaxError is more appropriate in this case (as in case of passing more than 255 arguments to a function).
brisk zenith
#

huh fair enough

sick hound
#

"incorrect use of C API or hacking Python internals" so basically it should only be caused by this channel? :P

brisk zenith
#

haha most certainly

sick hound
#

also apparently python checks the number of arguments before checking if any of them are the same ```py

def lol(a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a):
... return 'lol'
...
File "<stdin>", line 1
SyntaxError: more than 255 arguments```

brisk zenith
#

i wonder what happens if you exceed 65535 local variables in a scope so that not even extended args can cover it

nocturne saddle
brisk zenith
#

:D

sick hound
#

it seems like you can have multiple EXTENDED_ARGs if you need them

#

here's the end of a dis of a code object that creates a 70000-element tuple 288360 LOAD_NAME 69990 (v69990) 288362 EXTENDED_ARG 1 288364 EXTENDED_ARG 273 288366 LOAD_NAME 69991 (v69991) 288368 EXTENDED_ARG 1 288370 EXTENDED_ARG 273 288372 LOAD_NAME 69992 (v69992) 288374 EXTENDED_ARG 1 288376 EXTENDED_ARG 273 288378 LOAD_NAME 69993 (v69993) 288380 EXTENDED_ARG 1 288382 EXTENDED_ARG 273 288384 LOAD_NAME 69994 (v69994) 288386 EXTENDED_ARG 1 288388 EXTENDED_ARG 273 288390 LOAD_NAME 69995 (v69995) 288392 EXTENDED_ARG 1 288394 EXTENDED_ARG 273 288396 LOAD_NAME 69996 (v69996) 288398 EXTENDED_ARG 1 288400 EXTENDED_ARG 273 288402 LOAD_NAME 69997 (v69997) 288404 EXTENDED_ARG 1 288406 EXTENDED_ARG 273 288408 LOAD_NAME 69998 (v69998) 288410 EXTENDED_ARG 1 288412 EXTENDED_ARG 273 288414 LOAD_NAME 69999 (v69999) 288416 EXTENDED_ARG 1 288418 EXTENDED_ARG 273 288420 BUILD_TUPLE 70000 288422 RETURN_VALUE

brisk zenith
#

huh TIL

sick hound
#

the next logical question would be what happens if you put 9223372036854775808 elements in a list so it becomes a negative length

brisk zenith
#

sounds like a plan :^)

sick hound
#

apparently making the size of a list -1 does nothing at all ```py

test
[]
len(test)
-1```

#

...but if you append to it it crashes :(

#

huh ```py

len(test)
-2
test.append(int)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError```

#

if you try to append to a list with a length of -2 you get a memory error

#

extend works fine though apparently

#

as long as the extend gets it to a length of 0 or something positive

#

and if you deallocate a list of a negative length python crashes

#

...this is interesting... ```py

len(test)
-1
test
(,)```

#

a tuple with a negative length is (,)

#

wat ```py

what[0][0][1]
Fatal Python error: GC object already tracked

Current thread 0x0000380c (most recent call first):```

desert garden
#

@brisk zenith Entended args in python 3 are of infinite length

#

Just just stack up multiple EXTENDED_ARGs in a row

brisk zenith
#

fair enough

desert garden
#

It's a pisstake to generate them though because they go in reverse length to how you'd do a loop of ```py
while arg:
e_arg = arg & 0xff
arg >>= 8

#

So you have to build an array of them and reverse it

brisk zenith
#
@replace_builtin_method(list.append)
def new_append(original, self, item):
    # let's be evil and append twice
    original(self, item)
    original(self, item)


x = [1, 2, 3]
x.append(4)
print(x)  # [1, 2, 3, 4, 4]

this is really hot

rugged sparrow
#

@sick hound python [print(x) for x in iter(lambda a=[0]:[a.append(a[0]+1),a.pop(0)][1],-1)] this is infinite counting with no recursion like what you sent 2 days ago

brisk zenith
#

simple golfing challenge here: given two strings, split the first string at occurences of the second string but include the separator on either side of each new part, then print it. example:

input:
hello world!
o

output:
hello
o wo
orld!
#

my shortest is 46

tropic gulch
#

is the separator an arbitrary string or a single character? (not sure if it matters yet, but still)

brisk zenith
#

arbitrary string

#

input: this test is a test string test
output:```
this test
test is a test
test string

#

well, mine's 46 as a function, 54 if inputs are supplied from input

tropic gulch
#

hmm, 47 on first try

#

with input() and print()

brisk zenith
#

huh that's nice

#

what's your code? mine's ```py
s=input()
r=input()
print(*s.split(r),sep=f"{r}\n{r}")

tropic gulch
#

s,r=input(),input();print(s.replace(r,r+"\n"+r))

brisk zenith
#

oh huh idk why i used a fstring there

tropic gulch
#

yeah, that should save 3 bytes

rugged sparrow
#
f = lambda s,r:print(*s.split(r),sep=r+'\n'+r)
#

@brisk zenith i looked at yours for the sep bit

brisk zenith
#

byte's is better tbh :D

rugged sparrow
#

oh nice

#
f = lambda s,r:print(s.replace(r,r+'\n'+r))
shut roost
#

f=lambda s,r:print(s.replace(r,r+'\n'+r)) DABDABzawa

lofty comet
green nymph
#

lol, that is brilliant, not sure if it will be always able to handle floats properly, there you might have a race conditions which would result in invalid order.

brisk zenith
#

i don't understand asyncio that well, what's actually going on there and how does it sort?

rugged sparrow
#

@brisk zenith its running f on all of the input values simultaniously

brisk zenith
#

ohhhh

rugged sparrow
#

obviously larger int causes longer sleep

green nymph
#

you spawn "threads" which sleep for N seconds where N is a value of element in the list, and then return/print value

brisk zenith
#

yeah okay, i get it

#

that's pretty smart ngl :D

green nymph
#

so technically if you don't have race conditions that would sort it

scarlet osprey
#

Shebangs in 2019 ๐Ÿค”

brisk zenith
#

you're saying that as if the shebang is the strange thing in that code.

rugged sparrow
#

of course it is

#

everything else in that code would do well in a production environment /s

rugged sparrow
#

@brisk zenith can i give you a golfing challenge? create a lambda that counts infinity from 0 till infinity with no recursion errors

#

currently im at 58 characters

#

also you can use a generator

#
[*iter(lambda _=[0]:(_.append(_[0]+1),print(_.pop(0))),0)]```
brisk zenith
#

hmm

#
[print(i)for(i,_)in enumerate(iter(int,1))]
#

i mean

#

it'll print it

rugged sparrow
#

nice

#

i didnt think of using enumerate

desert garden
#
i=0
while 1:i=(print(i),i+1)[1]
#

31 characters

#

@rugged sparrow

#

Oh wait, does it have to be a lambda?

rugged sparrow
#

or a generator

#

cause that makes it trickier

grave rover
#

Challenge: find a way to do an exhaustive map function without calling list or map

#

Basically similar to ```kt
myArray.forEach { x => println(x*x) }

Since Python's `map` function has been a generator since Py3, find a way to make it not be a generator. Comprehensions are allowed, but other ways are more impressive.
calm rampart
#

min(myArray,key=lambda x:print(x*x)or 0)

#

if you don't need the results, of course

rugged sparrow
#
f=lambda c,l:[c(i)for i in l]```
#

oh wait

#

no generator

desert garden
#

The bad way to do it is take find a way to make it not be a generator literally and [*map(...)]

#

I think ```py
map = lambda f, d: [] if not d else ([f(d[0])] + map(f, d[1:]))

#

Could probably make a nice lazy wrapper with getitem so you could index it and it'd just do that single one

rugged sparrow
#

@desert garden remove "return" and it works

desert garden
#

Oh yeah

#

I typed it without running lol

rugged sparrow
#

Lol

desert garden
#

Been a long day sataniaWeary

green nymph
#

you can always replace map with reduce :P

In [8]: f = lambda x: x*x                                                                                                                                                                                                               

In [9]: r = reduce(lambda x,y: x+[f(y)], range(10), [])        


In [11]: def my_map(func, sequence): 
    ...:     return reduce(lambda x,y: x+[func(y)], sequence, []) 
fleet blade
#

Oh damn code boxes with scrolly things 0.o?

tropic gulch
#

that seems new indeed

grave rover
#

Oh they actually did it?

desert garden
#

I feel like there's a minor bug with this scrollbar

#

Given that it's allowing me to scroll as if the codeblock is taking up twice the width of my monitor, and the code inside it takes up barely a third

rugged sparrow
#
newCard = lambda card,suit:type(
    'Card', (object,),{
        'card':card,
        'suit':suit,
        'visible':False,
        'setVisible':lambda self,o=1:self.__setattr__('visible',o),
        'getSuit':lambda self,c=0:[f'\x1b[1;{31 if self.suit <= 1 else 0}m' if c else ''][0] + 'โ™ฅโ™ฆโ™ฃโ™ '[self.suit] + ['\x1b[0m' if c else ''][0],
        'fullCard':lambda self,f=0:self.getSuit(self.visible or f)+self.card if self.visible or f else '[]',
        'getValue':lambda self:'A23456789XJQK'.index(self.card),
        'getColor':lambda self:'red' if self.suit <= 1 else 'white'
    }
)()``` declaring classes like this is weird
brisk zenith
#

yeah i did that in my one-line implementation of polish notation. we couldn't use lists so i made a full stack class in a lambda :D

rugged sparrow
#

i just realized i can use a __init__ method ๐Ÿ‘€ python newCard = type( 'Card', (object,),{ '__init__':lambda self,card,suit:[ self.__setattr__('card',card), self.__setattr__('suit',suit), self.__setattr__('visible',False), None ][3], 'setVisible':lambda self,o=1:self.__setattr__('visible',o), 'getSuit':lambda self,c=0:[f'\x1b[1;{31 if self.suit <= 1 else 0}m' if c else ''][0] + 'โ™ฅโ™ฆโ™ฃโ™ '[self.suit] + ['\x1b[0m' if c else ''][0], 'fullCard':lambda self,f=0:self.getSuit(self.visible or f)+self.card if self.visible or f else '[]', 'getValue':lambda self:'A23456789XJQK'.index(self.card), 'getColor':lambda self:'red' if self.suit <= 1 else 'white' } )

#

but it has to return None

brisk zenith
#

yup

rugged sparrow
#

this is really cool

#

never knew i could do any of this

#

wait can it have class methods?

brisk zenith
#

of course

#
@classmethod
def stuff(cls, things):
    ...

is just syntactic sugar for ```py
def stuff(cls, things):
...

stuff = classmethod(stuff)

@rugged sparrow
rugged sparrow
#

oh thats cool

brisk zenith
#

so you could do ```py
...
"stuff": classmethod(lambda cls: ...),
...

rugged sparrow
#

true

#

so you could write literally any python script in one line using type and lambda

#

hmm. i wonder if its possible to write a translator

brisk zenith
#

it's been tried before, and it gets real tricky when async and await syntax comes in

#

try and except is a major one too

#

can't do that in one line

rugged sparrow
#

oh true

#

you could always translate try and except like this exec('try:\n\tprint("entering try block")\n\t1/0\nexcept:print("test")') but that kinda defeats the purpose

brisk zenith
#

yeah definitely.

rugged sparrow
#

@brisk zenith i found this

#

but its python2

brisk zenith
#

yeah that's what i mean when i said it's been tried before. it does a good job though.

rugged sparrow
#

true

#

im interested in how it does try/except

brisk zenith
#

does it do try/except?

rugged sparrow
#

yea

brisk zenith
#

interesting

rugged sparrow
#

yea. i wonder how it works

grave rover
#

Anyone interested in helping me write a .pyc parser?

grave rover
brisk zenith
#

yeah

#

do marshal.loads(...) on everything past the first 12 or 16 bytes

#

gives you a code object

#

kinda disappointing how easy it is but y'know

grave rover
#

Yeah I figured as much

#

Now to do it properly tho blobcat3c

#

Parse it ourselves

brisk zenith
#

haha

rugged sparrow
#

@brisk zenith i have a challenge for you

#

get to a bash shell (like what you'd get from running os.system('bash')) after running del __builtins__

#

so you have no __import__

#

or any builtin functions lol

brisk zenith
#

i assume del __builtins__ must be the first thing done?

rugged sparrow
#

yea

brisk zenith
#

hm

rugged sparrow
#

''.__class__.__class__((lambda:0))(''.__class__.__class__((lambda:0).__code__)('''need to make a code object'''),{})()

#

this is how far ive gotten

brisk zenith
#

i've got an easy way in

#

i think

tropic gulch
#

there are canned builtin discovery code snippets

rugged sparrow
#

@tropic gulch wdym?

tropic gulch
#

I'm currently searching for the link...

#

guess there are more similar variants out there

rugged sparrow
#
(lambda:0).__globals__['__loader__'].load_module('os').system('bash')```
brisk zenith
#
del __builtins__
__loader__.__class__("os", "/usr/lib/python3.7/os.py").load_module().system("bash")
#

heck you beat me to it almost

#

your example won't work if run as a file i'm pretty sure, right?

rugged sparrow
#

hmm one sec

brisk zenith
#

works fine in the REPL though

rugged sparrow
#

yea

brisk zenith
#

i did the exact same thing the first time haha

#

(lambda:0).__globals__['__loader__'] is the same as just __loader__

rugged sparrow
#

yea i noticed lmao

brisk zenith
rugged sparrow
#

add globals().clear() before del __builtins__

brisk zenith
#

right okay suck one

#

lmao

rugged sparrow
#

haha

brisk zenith
#

wow del __builtins__ isn't even needed

#

globals().clear() is enough to be a right twat

rugged sparrow
#

yea i just realized that

#

lol

#

@brisk zenith if you know how to write a code object capable of importing then my over complicated thing from earlier would work

brisk zenith
#

the IMPORT_NAME bytecode instruction relies on the prescense of __import__ i think.

rugged sparrow
#

thats frustrating

brisk zenith
#

i'll test it though

#

yup, ImportError: __import__ not found

rugged sparrow
#

can you still open files?

#

also, another question, now that globals is cleared, can the other files run?

brisk zenith
#

possibly.

rugged sparrow
#

this could be a fun challenge for the esoteric python challenges github. like maybe have people try to rebuild globals() after its been cleared

brisk zenith
#

i've had many impossible ideas for the repo in the past :D. i've decided that i want to keep them reasonably possible so that there can be overly-complex and beautifully weirdly simple solutions

#

cause if it's too hard, only one or two people might make successful submissions and there's little fun in that, really.

rugged sparrow
#

true

#

although looking at the reddit post @tropic gulch sent earlier, it is possible

tropic gulch
#

I have seen some code that would brute-force through all the attributes etc of an object recursively and report all instances of builtins that it finds. The output list was long.

#

But I can't find it any more

brisk zenith
#

[x for x in "".__class__.__base__.__subclasses__() if x.__name__ == "BuiltinImporter"][0].load_module("os").system("bash")
well, this works.

#

but is there a way to do it without literals? i just said that as a joke but.. i think there is.

#

depends what we're calling a "literal".

#

are True and False literals?

#

probably not

#

if not, my little code from over a year ago will help.

rugged sparrow
#

what code?

brisk zenith
#

well, if we need to use any integers, my code from a year ago converts an integer into a bunch of True and << and ^

#

but no literals

rugged sparrow
#

woah thats cool

brisk zenith
#

looking for it

rugged sparrow
#

[x for x in False.__class__.__base__.__base__.__subclasses__() if x.__name__ == "BuiltinImporter"][False].load_module("os").system("bash") well this has no ints in it now

brisk zenith
#

yup

#

so we consider list comps to be literals? if not, its easy i think..

#

!eval ```py
print((True << (True << True) ^ True << (True ^ True << True) ^ True << (True ^ True << (True << True)) ^ True << (True << (True ^ True << True)) ^ True << (True ^ True << (True ^ True << True)) ^ True << (True << True ^ True << (True ^ True << True)) ^ True << (True ^ True << True ^ True << (True ^ True << True)) ^ True << (True << (True << (True << True)))))

night quarryBOT
#

@brisk zenith Your eval job has completed.

69420
rugged sparrow
#

i say that we should consider list comps to be literals

#

same with the strings

brisk zenith
#

yeah okay

rugged sparrow
#

True.__repr__().__class__ this gets str

brisk zenith
#

ooh we could use int.to_bytes with that True << shenanigans to convert a really big integer into strings

rugged sparrow
#

ooh we could

brisk zenith
#

only issue is that to_bytes needs a byteorder string arg

rugged sparrow
#

hmm

#

which needs the strings lol

brisk zenith
#

we could probably find an object whose __doc__ contains "big"

#

and .split()[True << ...] that fucker

#

you go do that while i convert "BuiltinImporter" into a bunch of booleans and bitwise operators.

rugged sparrow
#

to_bytes has the word "big" in it

brisk zenith
#

haha i was just looking at that

#

okay, what's the index?

rugged sparrow
#

one sec

#

275,276,277

brisk zenith
#

of the word after doing .split() i mean

#

just to make it a tiny bit shorter lmao

rugged sparrow
#

to_bytes.__doc__[275:278]

#

that works tho

#

oh nevermind

#

one sec

brisk zenith
#

yeah but these True << ... stuff get real big and nasty

rugged sparrow
#

43 has "big",

brisk zenith
#

okay one sec, i might just use the __doc__[275:278] stuff

rugged sparrow
#

(True-True).__class__.to_bytes.__doc__.split()[43][True:True<<True<<True] this gives the string big

brisk zenith
#

43 in there

#

True.__class__.__base__.to_bytes.__doc__[(True ^ True << True ^ True << (True << (True << True)) ^ True << (True << (True ^ True << True))): (True << True ^ True << (True << True) ^ True << (True << (True << True)) ^ True << (True << (True ^ True << True)))]

#

this also gives the string "big"

rugged sparrow
#

would using 43 instead of 275 and 278 be larger?

brisk zenith
#

no probably not

#

but i realise now that 275 and 278 are tiny compared to the int needed for BuiltinImporter as bytes

rugged sparrow
#

also (True-True).__class__ is smaller than True.__class__.__base__

brisk zenith
#

we're not golfing at this point lmao

rugged sparrow
#

True lmao

brisk zenith
#

i'll get the things for "os" and "bash" now, one sec

rugged sparrow
#

ok

brisk zenith
#

"os" without literals is py True.__class__.__base__.to_bytes((True ^ True << True ^ True << (True << (True << True)) ^ True << (True ^ True << (True << True)) ^ True << (True << True ^ True << (True << True)) ^ True << (True << (True ^ True << True)) ^ True << (True ^ True << (True ^ True << True)) ^ True << (True << True ^ True << (True ^ True << True)) ^ True << (True ^ True << True ^ True << (True ^ True << True)) ^ True << (True ^ True << (True << True) ^ True << (True ^ True << True)) ^ True << (True << True ^ True << (True << True) ^ True << (True ^ True << True))), (True << True), True.__class__.__base__.to_bytes.__doc__[(True ^ True << True ^ True << (True << (True << True)) ^ True << (True << (True ^ True << True))): (True << True ^ True << (True << True) ^ True << (True << (True << True)) ^ True << (True << (True ^ True << True)))]).decode()

rugged sparrow
#

jesus

#

thats just 'os'

brisk zenith
#
True.__class__.__base__.to_bytes((True << (True ^ True << True) ^ True << (True ^ True << (True << True)) ^ True << (True << True ^ True << (True << True)) ^ True << (True << (True ^ True << True)) ^ True << (True ^ True << (True ^ True << True)) ^ True << (True << (True << True) ^ True << (True ^ True << True)) ^ True << (True ^ True << (True << True) ^ True << (True ^ True << True)) ^ True << (True << True ^ True << (True << True) ^ True << (True ^ True << True)) ^ True << (True << (True << (True << True))) ^ True << (True ^ True << (True << True) ^ True << (True << (True << True))) ^ True << (True << True ^ True << (True << True) ^ True << (True << (True << True))) ^ True << (True ^ True << (True ^ True << True) ^ True << (True << (True << True))) ^ True << (True ^ True << (True << True) ^ True << (True ^ True << True) ^ True << (True << (True << True))) ^ True << (True << True ^ True << (True << True) ^ True << (True ^ True << True) ^ True << (True << (True << True)))), (True << True << True), True.__class__.__base__.to_bytes.__doc__[(True ^ True << True ^ True << (True << (True << True)) ^ True << (True << (True ^ True << True))): (True << True ^ True << (True << True) ^ True << (True << (True << True)) ^ True << (True << (True ^ True << True)))]).decode()```
#

"bash"

#

but hey, no literals

#

here's the code i wrote on my first day in this server for making this True shenanigans: ```py
def true_shift(value):
code = ""
count = 0

if value == 0:
    return
elif value == 1:
    return 'True'

while value != 0:

    if value % 2 == 1:

        if count != 0:
            code += "True << {} ^ ".format(true_shift(count))
        else:
            code += "True ^ "

    count += 1
    value >>= 1

return '({})'.format(code.strip(" ^ "))

while True:
print(true_shift(int(input("number: "))))

rugged sparrow
#

damn impressive

#

@brisk zenith (111).to_bytes(1,'big') this gets o but requires 'big'

brisk zenith
#

let's lay this out a bit. py str_big = True.__class__.__base__.to_bytes.__doc__[(True ^ True << True ^ True << (True << (True << True)) ^ True << (True << (True ^ True << True))): (True << True ^ True << (True << True) ^ True << (True << (True << True)) ^ True << (True << (True ^ True << True)))

#

then we can reuse it, simple

rugged sparrow
#

true

#

i wonder if BuiltinImporter is in any __doc__

brisk zenith
#

from a quick grep through the cpython source code, i can't see any

rugged sparrow
#

dang

#

@brisk zenith BuiltinImporter is always at index 80 i think

brisk zenith
#

there'll be loads of ways to make it shorter. let's focus on a way to make it work.

#

i don't like relying on that though

rugged sparrow
#

true

brisk zenith
#

it's not in 3.8

#

it's 82 in 3.8

rugged sparrow
#

ah im on 3.7.3

brisk zenith
#

and in 3.6.8 it's index 69 ||insert obligatory teenager joke||

rugged sparrow
#

lmao

brisk zenith
#

on 3.1.5 it doesn't even exist

#

i wonder when it does come into existence..

rugged sparrow
#

thats very weird

#

is there still something that does that job in 3.1.5 thats similar?

brisk zenith
#

lemme check

#

nothing that i can immediately see

#

closest is imp.NullImporter but it behaves differently

#

i dunno what it really does tbh

rugged sparrow
#

(((True<<True^True<<True<<True<<True)*(True<<True^True<<True<<True<<True)+(True<<True^True<<True<<True<<True)+True).to_bytes(True,'big') + ((True<<True^True<<True<<True<<True)*(True<<True^True<<True<<True<<True)+(True<<True^True<<True<<True<<True)+True+(True<<True<<True)).to_bytes(True,'big')).decode()

#

does it have a __doc__

brisk zenith
#

Null importer object

#

thanks

#

very nice

#

yeah great

#

awesome

#

oh

#

imp.NullImporter.find_module.__doc__ => Always return None

#

it has brighter aspirations than me, at least

rugged sparrow
#

lmao

brisk zenith
#

there's object.__subclasses__ for 3.1.5, how queer.

#

just as an aside, i have plenty of spare space so i'm just gonna install the most recent minor release of all python versions. /shrug

rugged sparrow
#

have fun with that

#

im working with a chromebook

#

space is not a luxury

brisk zenith
#

haha, i just don't use my space all that much

#

but anyways, getting off-topic

#

how to we find BuiltinImporter using its name

rugged sparrow
#

i see no problem with building it using to_bytes

brisk zenith
#

well yeah but then what

#

we can't use listcomps

rugged sparrow
#

store the string to a var

#

then use .index()

#

oh wait

#

damn it

#

cant use .index

brisk zenith
#

yup :D

rugged sparrow
#

and index doesnt have key

brisk zenith
#

i mean, we can't use listcomps but what's stopping us from doing ... ```py
for thing in True.class.base.base.subclasses():
if thing.name == (... builtinimporter ...):
importer = thing
break
...

no literals
#

i don't think for relies on iter internally, i think it does all that itself

rugged sparrow
#

yah that would work

#

also we can create an iterator if we want

#

for building the string with our own sort of range function

brisk zenith
#

how do you mean?

rugged sparrow
#

wait nevermind

#

what i thought would give me the iter class didnt

#

lol making classes after globals().clear() doesnt work with class but it does using type

brisk zenith
#

yeah cause __name__ has to be defined i think

#

this is our final working code

#

no globals, no literals, bash shell

rugged sparrow
#

damn that long line of True<< lmao

brisk zenith
#

haha, little did i know over one year ago that the code i scribbled up would come in handy for something so restrictive :D

rugged sparrow
#

honestly that was a fun challenge

brisk zenith
#

it was.

#

there'll be a way of shortening that code, easily.

rugged sparrow
#

oh definitely

#

also, technically the way we got 'big' isnt safely dynamic enough

brisk zenith
#

that's true.

#

though int.to_bytes is quite new anyways

#

3.4 iirc?

rugged sparrow
#

idk lmao

brisk zenith
#

ah 3.2

rugged sparrow
#

i only learned python midway thru last year

brisk zenith
#

pretty good progress

rugged sparrow
#

thanks

brisk zenith
#

i've been pythoning for around 2 and a half years.

rugged sparrow
#

damn

#

thats awesome

#

ironically i started with a much more pain in the ass language lmao

#

before i learned python i learned objectiveC

#

cause i wanted to make shit for jailbroken phones

#

but im already way better at python than i am in objC

brisk zenith
#

i learned windows batch a little bit and got scared of for loops before being told by a java + javascript hobbyist developer that python is a good starting point for actual programming

rugged sparrow
#

hey i also messed with batch for a while

brisk zenith
#

then we didn't talk for 2 years and recently we got back in touch. now i'm quite good at python and programming concepts (back then i wasn't at all) and he's a professional developer at a bank.

#

so everyone's a winner

rugged sparrow
#

true lol

#

i taught myself python when i realized my compsci teacher didnt know it well enough to teach it

#

so i guess thats a good reason lol

brisk zenith
#

haha fair enough.

#

anyways, if you get any more interesting challenges, let me know. that one was fun.

rugged sparrow
#

will do! i was just procrastinating on my homework and was wondering how difficult it would be

#

still am procrastinating lmao

brisk zenith
#

i'm going to go to bed now though, it's 2am and my brain is evaporating into nitroglycerin and is ready to explode ferociously at any point.

#

goodnight :D

rugged sparrow
#

time zones are wack. its 9:13 here

#

good night lmao

grave rover
#

Oh man I think I actually figured out the marshal format

brisk zenith
#

hm?

rugged sparrow
#

@brisk zenith do you know what "$" is in python? It throws a syntax error so I think it's reserved, but idk what for

brisk zenith
#

literally any invalid token will throw a syntax error

#

it's not reserved, it's just not used currently

#

besides, this isn't PHP

rugged sparrow
#

@brisk zenith I guess I assumed it would be treated like "_" where it can be a var

desert garden
rugged sparrow
#

@brisk zenith i thought of a challenge. get to list,dict,int,str,double,bool,objectandset classes from only True

#

for example: True.__class__ -> bool

brisk zenith
#

hm

#

True.__class__.__base__ -> int

#

True.__str__().__class__ -> str

rugged sparrow
#

double and set might be harder

brisk zenith
#

True.__class__.__class__.__class__ -> object i think

#

also don't you mean float :^)

rugged sparrow
#

oh yea

#

was working in objc earlier

#

lol

brisk zenith
#

True.__float__().__class__

rugged sparrow
#

True.__class__.__base__.__base__ is object

brisk zenith
#

ah i forgot type is an instance of itself

#

you know, as you would expect

rugged sparrow
#

makes perfect sense

brisk zenith
#

mhm

#

object and type are the only builtin objects which are direct instances of themselves as far as i'm aware

#

i want to give a name for that property but i can't think of any lmao

rugged sparrow
#

self-defining

#

ig

brisk zenith
#

self-classifying?

#

idk

rugged sparrow
#

yea

brisk zenith
#

i assume you mean only using True once btw

rugged sparrow
#

yea

#

True.__doc__.split().__class__ -> list

brisk zenith
#

i wonder if it's possible to get complex objects

#

from True of course

rugged sparrow
#

probably

#

would be hard tho

brisk zenith
#

True.__class__.__bases__.__class__ -> tuple

#

i know how to get a mappingproxy but not a dict

#

True.__class__.__dict__

rugged sparrow
#

hmm

brisk zenith
#

easier way of getting list -> True.__dir__().__class__

rugged sparrow
#

ah nice

#

if we can get something with the function class we can get a dict

brisk zenith
#

yeah cause globals and stuff

#

let's make a list of these so that we can keep track. i'll keep editing when we find something new (sorry modlogs :D) ```py
bool: True.class
int: True.class.base
str: True.doc.class
float: True.float().class
object: True.class.base.base
tuple: True.class.bases.class
list: True.dir().class
bytes: True.doc.encode().class

not types but still significant bits and bobs:

False: True.imag.bool()
NotImplemented: True.subclasshook()
None: True.dir().class().sort()

#

ooh wavy

rugged sparrow
#

haha

#

do you want to just get all base classes?

brisk zenith
#

let's go for that for now.

rugged sparrow
#

aight

brisk zenith
#

let's also get things like False and stuff

#

False: True.imag.__bool__()

rugged sparrow
#

ooo thats tricky

#

i like it

brisk zenith
#

NotImplemented: True.__subclasshook__()

rugged sparrow
#

method-wrapper: True.__abs.__class__

brisk zenith
#

hm.. well, if we're going for all base classes, that's a bit trickier

#

cause i doubt i even know them all

rugged sparrow
#

thats true lol

brisk zenith
#

str_iterator and stuff

#

weakcallableproxy

#

yeah no thanks :D

rugged sparrow
brisk zenith
#

bytes i can do, one sec

#

True.__doc__.encode().__class__

rugged sparrow
#

bool,int,float,complex,list,tuple, (range might not be possible),str,bytes,set,frozenset,dict,module,function,method

brisk zenith
#

okay neat

rugged sparrow
#

code,None,NotImplemented

#

so final list to find is python bool int float complex list tuple str bytes set frozenset dict module function method code None NotImplemented

#

@brisk zenith and maybe range

brisk zenith
#

okay sure

rugged sparrow
#

True.__class__.__class__.__base__.__subclasses__()[-1].__init__.__class__ -> function

brisk zenith
#

-1

rugged sparrow
#

yea

#

cause the end of that list will always be a module

#

probably

brisk zenith
#

maybe. what if it's written in C? won't get a function there i'm pretty sure

rugged sparrow
#

it should still have a wrapper to __init__

#

i belive

brisk zenith
#
>>> object.__subclasses__()[-1].__init__.__class__
<class 'wrapper_descriptor'>
>>> 
#

after doing import _ctypes