#esoteric-python

1 messages · Page 122 of 1

noble bloom
#

!e

floral meteor
#

How can PyObject be NULL?

#

Maybe I have to reference the integers

rugged sparrow
#

A PyObject is actually a pointer to a python object

#

!e from ctypes import py_object
print(py_object.from_buffer_copy(id(1).to_bytes(8, 'little')))

night quarryBOT
#

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

py_object(1)
floral meteor
#

.

#

Why is it segfaulting there?

#

!e ```py
from ctypes import*
hack=lambda victim:py_object.from_address(id(victim))
victims = [range(32) ]
a = [hack(i)for i in victims]
print("before")
gulag = [yay.value for yay in a]
print('after')
new = [
{*gulag}]
for i in a:
print(i)
i.value = new[i.value]
print (victims)

night quarryBOT
#

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

before
floral meteor
#

If I don't reference victims at the end the object will be NULL.
But it segfaults reading the integers

#

I get 0xc0000005 not 139

#

Why doth thee fault thine segments?

floral meteor
#

!e ```py
class dunder(metaclass=lambda*a:type(*a)()):format=lambda s,spec:f'{spec}'
def dir(target=import(f'{dunder:main}')):
v=[*target.class.dict]
if hasattr(target,f'{dunder:dict}'):v+=[*target.dict]
return v
print(dir())
print(dir({}))

night quarryBOT
#

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

001 | ['__repr__', '__getattribute__', '__setattr__', '__delattr__', '__init__', '__new__', '__dir__', '__dict__', '__doc__', '__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'dunder', 'dir']
002 | ['__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__init__', '__or__', '__ror__', '__ior__', '__len__', '__getitem__', '__setitem__', '__delitem__', '__contains__', '__new__', '__sizeof__', 'get', 'setdefault', 'pop', 'popitem', 'keys', 'items', 'values', 'update', 'fromkeys', 'clear', 'copy', '__reversed__', '__class_getitem__', '__doc__']
floral meteor
#

reinvented dir

floral meteor
#

!e ```py
class Yeet(Exception):
def init(self, metadata):
self._metadata = metadata
super().init()
@property
def metadata(self):return self._metadata

def a():
def b(W):
def c():
def d():
def f():
raise Yeet(W)
f()
d()
c()
print ("This line won't run");
try:b("Hello World!")
except Yeet as yeet:print (yeet.metadata)
a()

night quarryBOT
#

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

Hello World!
acoustic gust
#

Bruhh

floral meteor
#

@crimson pumice here's a simple demonstration of the error-slinging I was talking about

crimson pumice
#

Oh yeah that's really nice

floral meteor
#

!e @crimson pumice and here's the whileTrue-Switch event loop I was talking about```py
from random import randint as r
def event_loop():
while True:
switch = r(0,10)
if switch==0:
return print("done!")
elif switch==1:
print(1)
elif switch==2:
print(switch*2, switch**2)
elif switch==3:
print("third time lucky!")
elif switch==4:
print("Hello World!")
else:
print(NotImplemented)
event_loop()

night quarryBOT
#

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

001 | Hello World!
002 | 4 4
003 | 4 4
004 | 1
005 | third time lucky!
006 | NotImplemented
007 | NotImplemented
008 | third time lucky!
009 | NotImplemented
010 | 1
011 | 1
... (truncated - too many lines)

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

woven bridge
floral meteor
#

what does that do?

woven bridge
#

basically iirc from_address is intended to be used with CData objects, e.g. another py_object instance's id/addressof. cast does extra necessary housekeeping.

tribal moon
#

Can't you just directly create a new py_object with the thing instead of casting it?

tribal moon
woven bridge
golden finch
#

Wow - I've tried to do this in the past

#

I got number shuffling working, but couldn't do all of them

#

!e

import ctypes
ctypes.c_int8.from_address(id(4)+8).value=5
print(2+2)
night quarryBOT
#

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

[No output]
golden finch
#

oop

#

spicy

#

seems to segfault after the second line

#

I'll brute-force offsets until it works

#
0-8: No segfault
8-16: Segfault
16-?: Something
#

ctrl-c doesn't work

tribal moon
#

🤔

#

!e py import ctypes ctypes.c_int64.from_address(id(4)-8).value = id(5) print(2+2)

night quarryBOT
#

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

4
golden finch
#

well I got ... something

#

just not the right something

#

I did a stupid

#

!e

__import__('ctypes').c_int8.from_address(id(4)+16).value=id(5)
night quarryBOT
#

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

[No output]
golden finch
#

[it hangs]

#

on closer inspection the value is 1

#

!e

import ctypes
def deref(addr,typ):
  return ctypes.cast(addr,ctypes.POINTER(typ))
deref(id(4),ctypes.c_int)[6]=5
print(2+2)
night quarryBOT
#

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

5
golden finch
#

@floral meteor got it working- idk how to shuffle though

tribal moon
#

ctypes is awesome

golden finch
#

ctypes is just the best

#

!e

import ctypes
deref=lambda a,b:ctypes.cast(a,ctypes.POINTER(b))
deref(id(4),ctypes.c_int)[6]=5
print(2+2)
night quarryBOT
#

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

5
golden finch
#

interesting

#

gonna do some coding

marsh void
#

don't forget about the int representation

golden finch
marsh void
#

well, I assumed the initial attempt to mutate an integer was through accessing its digits

rugged sparrow
#

@golden finch it's faster to get the offsets by looking at cpython source code

#

But for reference, all python objects start with <0-8> ref count, <9-16> pointer to object type

#

Ref count is an 64 bit integer, and object type is a 64 bit pointer

night quarryBOT
#

Include/longintrepr.h lines 85 to 88

struct _longobject {
    PyObject_VAR_HEAD
    digit ob_digit[1];
};```
pure flame
#

this channel is weird.

tribal moon
harsh spear
#

!e ```py
metamaker = (lambda meta, cls: ( lambda: [ (dict_.pop(es, None) for es in dict_.get("slots", tuple())) if [None for [globals()["dict_"]] in [[dict(cls.dict)]]][0] is None else None, [None for [globals()["dict_"]["metaclass"]] in [[meta]]], [None for [globals()["dict"]["wrapped"]] in [[cls]]], meta(str(cls.name), tuple(cls.bases), dict), ][-1]))
printf = lambda format_string, *args: print(format_string,end="") if not args else print(format_string % args,end="")
main = metamaker(type("b", (type,), {"call": lambda self, : {None}}), type("", (object,), {}))()
int = metamaker(type("a", (type,), {"sub": lambda self2, : {None} if isinstance(, set) else [None for [globals()[
.split("=")[0]]] in [[import('builtins').int(_.split("=")[1])]]][0]}), type("a", (object,), {}))()
void = None
return_0 = None

int-main(void)-{
printf("Hello, World!\n"),

int-"num1=2",
int-"num2=3",

printf("%d + %d = %d\n", num1, num2, num1+num2),
return_0
}```

night quarryBOT
#

@harsh spear :white_check_mark: Your eval job has completed with return code 0.

001 | Hello, World!
002 | 2 + 3 = 5
floral meteor
#

cool, now make that 2+2=5

#

everyone importing sqrt from math smh.

#

x**.5

#

is better than

#

sqrt(x)

#

and if you want to floor something, instead of importing floor from math...

#

x//1

#

all you need from math is constants like e and π

#

change my mind

simple crystal
#

haha wow somehow I never thought of that

snow beacon
#

Logarithms.

#

Anything to do with manipulating floats precisely.

floral meteor
#

that's what algorithms are for ;)

floral meteor
#

you just need... two integers

snow beacon
narrow shard
#

So I discovered a really weird thing: when using ipython (which powers for example jupyter notebook) the is operator behaves really weirdly with strings that are longer than 1 character and contain non-alphanumeric characters.
This code prints false when run in ipython:

a = '.a'
b = '.a'
print(f'a is b: {a is b}')```This code prints true:
```py
a = 'abc123'
b = 'abc123'
print(f'a is b: {a is b}')```Any string with only alphanumeric characters seems to print true.
```py
a = '.'
b = '.'
print(f'a is b: {a is b}')```But this also returns true, in fact all strings of length 1 print true. But if the string is longer than 1 character it prints false.
Is this intended or a bug? What's causing it?
snow beacon
#

This is intended.

#

You'll likely find that very long strings with only alphanumeric characters also compare unequal with is.

#

Python makes no guarantees about which strings will be interned at the same address.

#

It seems to also depend on whether the string is made from operations on literals, such as adding constant strings together, or if it has intermediate steps.

#
In [4]: foo= "a"

In [5]: (foo + foo) is (foo + foo)
Out[5]: False

In [6]: ("a" + "a") is ("a" + "a")
<>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
<ipython-input-6-7cfee5715f00>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
  ("a" + "a") is ("a" + "a")
Out[6]: True
narrow shard
#

hmm, trying longer and longer alphanumeric strings, but they all print true.
so can this happen with regular python too if the string is long enough?

snow beacon
#

IPython is based on CPython, and only changes some of the user-facing things. I can't imagine regular Python would behave much differently.

narrow shard
#

It does behave differently, the examples I gave don't work in regular python, tho the example you gave works

#

PyCharm:

#

Google colab (which is based on jupyter):

floral meteor
#

!e print('yeet' is "yeet")

night quarryBOT
#

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

001 | <string>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
002 | True
floral meteor
#

!e print(" 69"is" 69")

night quarryBOT
#

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

001 | <string>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
002 | True
dawn kayak
#

!e ```py
_ = chr(ord('6')) is '6'
print(_)

night quarryBOT
#

@dawn kayak :white_check_mark: Your eval job has completed with return code 0.

001 | <string>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
002 | True
slim yarrow
#

!e

_ = ''
__ = []

for i in range(1 << 8):
    _ += chr(i) + '!'
    __.append(chr(i))

print(_[:-1] == '!'.join(__))
print(_[:-1] is '!'.join(__))
night quarryBOT
#

@slim yarrow :white_check_mark: Your eval job has completed with return code 0.

001 | True
002 | False
slim yarrow
#

there we go

#

as you can see, is is not guaranteed to return True on equal strings

#

as for only alphanumeric characters:

narrow shard
#

so googling shows that this is string interning. by storing only one copy of equal strings python saves space and computing power, but I still don't understand why ipython does it differently form regular python.

slim yarrow
#

!e

_ = ''
__ = []

for i in 'abcdefghijklmnopqrstuvwxy':
    _ += i + '0'
    __.append(i)

print(_[:-1] == '0'.join(__))
print(_[:-1] is '0'.join(__))
night quarryBOT
#

@slim yarrow :white_check_mark: Your eval job has completed with return code 0.

001 | True
002 | False
slim yarrow
slim yarrow
#

as a test, you can try this:

a = '..'
b = '..'
print(a is b)
a, b = '..', '..'
print(a is b)```
#

the first is false in ipy, the second is true

#

as for the case with 1 character, probably because it's (maybe?) optimized to a c char

narrow shard
slim yarrow
#

that's interesting

narrow shard
#

well I gotta go to sleep, but this was very interesting. I guess this is just another reason not to use is for comparison, not that I was using it before :)

slim yarrow
#

if i had to guess, maybe it's because colab uses some different version of python (cuz it's containerized, so maybe a version compiled for alpine?)

#

since alpine uses musl rather than glibc maybe there's a difference there

#

but i really have no idea what i'm talking about

narrow shard
#

lol I have no idea what any of that means, but I will google this tomorrow, sounds interesting

slim yarrow
#

just spun up a docker container with alpine; alpine isn't the reason for this difference

#

but it is because of a difference in python

#

colab uses cpython 3.7.11

#

after which (so 3.8+), this behavior changes

simple crystal
floral meteor
#

theoretically

#

in fact, theoretically, you can calculate it in brainfuck, so you just need too write a brainfuck interpeter

slim yarrow
#
$ docker run --rm -i -t python:3.7-alpine python
Python 3.7.11 (default, Jun 29 2021, 21:06:34) 
[GCC 10.3.1 20210424] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = '..'
>>> b = '..'
>>> a is b
False
>>> a, b = '..', '..'
>>> a is b
False
>>> exit()
$ docker run --rm -i -t python:3.8.0-alpine python
Python 3.8.0 (default, Nov 15 2019, 02:22:06) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = '..'
>>> b = '..'
>>> a is b
False
>>> a, b = '..', '..'
>>> a is b
True
>>> exit()
``` @narrow shard
floral meteor
#

```py
#code
```
would help the eyes very much

slim yarrow
#

except it's not entirely python

floral meteor
#

I would rather not be investing in SpecSavers

slim yarrow
#

but sure

#

here

floral meteor
#

much better

#

thank you

floral meteor
#

I'm gonna start with the basic tail end recursion structure for mathematical generation```py
def __e(n=100):
v = ...
if n:
return v + __e(n-1)
else:
return v;
def __π(n=100):
v = ...
if n:
return v + __π(n-1)
else:
return v;
calculimificate = {
'e':__e,
'pi':__π
}
print(*(calculimificateafor a in calculimificate),sep='\n')

#

and then i'm gonna thonk for a solid few hours

#

I used to know how to do e

#

lim(n->inf){(1 + 1/n)^n}

#

nope i think i got the wrong formula

#

imma try sum to inf (1/n!)

simple crystal
floral meteor
#

!e ```py
def f(n):
return n*f(n-1)if n else 1
def _make_e(n=100):
if n:return f(n:=n-1)**-1 + _make_e(n);
else:return 0;
e = _make_e(100)
print(e)

night quarryBOT
#

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

2.7182818284590455
floral meteor
#

there's e

simple crystal
#

!e print((10001/10000)**10000)

night quarryBOT
#

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

2.7181459268249255
floral meteor
#

mines accurater

simple crystal
#

ya not vry good at 10k haha

#

!e print((100001/100000)**100000)

night quarryBOT
#

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

2.7182682371922975
simple crystal
#

I'm so close to infinity though

floral meteor
#

mine chews it up a little

#

!e ```py
print(((1010+1)/(1010))(1010))

night quarryBOT
#

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

2.7182820532347876
floral meteor
#

compare it to 2.7182818284590455

#

and 'actual' is 2.7182818284590452

#

!e ```py
_make_e = lambda acc:((10acc+1)/(10acc))(10acc)
print(_make_e(12))

night quarryBOT
#

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

2.7185234960372378
floral meteor
#

you try to get more accurate it get's less accurate

simple crystal
#

hmmm 10**29 gives a pretty good one but 10**30 is just 1.0 for some reason

#

with Decimal

floral meteor
#

!e ```py
def f(n):
return n*f(n-1)if n else 1
def _make_e(n=100):
if n:return f(n:=n-1)**-1 + _make_e(n);
else:return 0;
e = _make_e(150)
print(e)

simple crystal
#

with floats it gives up at 15 zeroes

night quarryBOT
#

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

2.7182818284590455
simple crystal
#

!e

from decimal import Decimal
for x in range(27,30):
    n=Decimal(10**x)
    print(x, ((n+1)/n)**n)
floral meteor
#

there must be a floating point error somewhere

night quarryBOT
#

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

001 | 27 2.718281828459045235360287470
002 | 28 1
003 | 29 1
floral meteor
#

ooh that one's good

simple crystal
#

need Decimal tho

floral meteor
#

yeah

#

could probably remake Decimal

#

i'm gonna do it in pycharm

simple crystal
#

gl

floral meteor
#

nah pycharm frozen im ggonna do it in vs code

floral meteor
#

one for the data, one for the position of the decimal point

simple crystal
#

ah true

floral meteor
#
  def __lt__(self, other):
    a, b, c, d = self.n, self.offset, other.n, other.offset;
    while b < d:
      b += 1;
      a *= 10;
    while b > d:
      d += 1;
      c *= 10;
    return a > c;
#

would that work?

#

where offset is like the log base 10 floored

#

and n is just the number without the dot

#
  def __str__(self):
    return ''.join([*str(self.n)].insert(self.offset,'.'))
#

that's how n and offset are defined

harsh spear
#

this channel is weird.

tribal moon
#

this channel is beautiful

slim yarrow
#

!e

print((1097-(55**5+311**3-11**3)/68**5)**(1/7))
from math import e
print(math.e)```
night quarryBOT
#

@slim yarrow :x: Your eval job has completed with return code 1.

001 | 2.7182818284590455
002 | Traceback (most recent call last):
003 |   File "<string>", line 3, in <module>
004 | NameError: name 'math' is not defined
slim yarrow
#

i'm an idiot

#

!e

print((1097-(55**5+311**3-11**3)/68**5)**(1/7))
from math import e
print(e)```
night quarryBOT
#

@slim yarrow :white_check_mark: Your eval job has completed with return code 0.

001 | 2.7182818284590455
002 | 2.718281828459045
floral meteor
#

i moved the offset to represent from the right

#

my equils algerithim ```py

def eq(self, other):
return self>=other>=self

#
  def __ge__(self, other):return not self<other;
  def __le__(self, other):return not self>other;
#

big brain go brrr

tribal moon
#

Wanna hear a fun idea? Try to make your own COMPLETELY different syntax "mini-language" within Python by messing with the opcodes and objects (sys, dis, and ctypes) and see how far you can go

#

I really really want to see someone do this

floral meteor
#

I would start by hacking globals

slim yarrow
#
def __eq__(self, other):
  return ~-self < other and -~self > other
floral meteor
#

and i did it already, in a way

tribal moon
#

open a github repository or something and do it

#

I'd love to see the progress

#

do you know how to rearrange/edit a frame's opcodes?

#

because it looks way better than using ctypes and stuff

#

well it is using ctypes but whatever

#

I tried to make one a while back and I just used dunders and stuff

#

it kinda looked like a new language

#

but it still looked like Python

slim yarrow
#

why not just make a new language

floral meteor
#

@tribal moon you mean like this?

tribal moon
#

not really brainfuckish

#

something else

floral meteor
#

oh you want something like basicfuck?

slim yarrow
#

make python have ruby syntax

#

that would be interesting

tribal moon
#

Hold on a second

#

I wanna see someone do something like this, except without dunder stuff

#

just with changing the frames

#

and a lot of ctypes stuff

floral meteor
#

annotations can also be used

#

to reverse the polarity of type hints

#

and/or enforce them

tribal moon
#

sure that could work but that's not the point

#

see the lines that make arrays

#
something = Array<int>()```
#

I had NO idea how to do something like that

floral meteor
#

that's mostly brute force stack modification

tribal moon
#

the only way was to change the bytecode for the frame and stuff, not sure how it works

#

chilaxan made a really good example of code that does this

dawn kayak
#

<int> would be rejected as invalid syntax, but im sure with black magic you can make it legal

tribal moon
#

that's the point

dawn kayak
#

!e ```py
def legal():
Array<int>()

night quarryBOT
#

@dawn kayak :warning: Your eval job has completed with return code 0.

[No output]
slim yarrow
#

maybe i'm stupid but why would that syntax be invalid

dawn kayak
#

damn its legal

tribal moon
slim yarrow
#

looks like chained comparisons

dawn kayak
#

maybe some ast hacking decorator ?

tribal moon
#

really good code

#

appreciate it

floral meteor
#

I'm still trying to replace UNARY_POSITIVE UNARY_POSITIVE with LOAD_CONSTANT(1) BINARY_ADD DUP_TOP ASSIGN_VALUE

#

dis.get_instructions that's what i need

#

anyways i'm already working on arbitrary precision floats

#

I will name my invention...
"doubles"

#

;)

tribal moon
#

tbh I don't really like the changes made after 3.7

#

walrus, patma, that, list[int] n stuff

dawn kayak
#

i like list[int]

#

dont need to import from typing

floral meteor
#

importing typing is dinky

#

type hints that don't do anything are dinky

#

I like how you can just name your variables whatever you want

round=lambda floater:(floater+0.5)//1
#

!e ```py
from future import annotations
import builtins as new
@lambda c:c()
class annotations:
def setitem(self, a, b):
globals()[b] = new.dict [a] (globals()[a])
class System:
class out:
println,print=print,lambda s:print(end=s)

str: a = 6;
str: b = 9;
int: c = new.int (a + b);
System.out.println(c);

night quarryBOT
#

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

69
pastel ibex
#

what in the world is this channel

floral meteor
#

this is the torture chamber for python

pastel ibex
#

ah i see

floral meteor
#

!e ```py
from signal import*
from ctypes import*
signal(11, print)
string_at(0)

#

XD

night quarryBOT
#

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

[No output]
floral meteor
#

oh it didn't print

pastel ibex
#

I thought System.out.println was java....

floral meteor
#

it is

pastel ibex
#

I...

#

I thought python was easy...

floral meteor
#

it is in literally every other channel than this one

pastel ibex
#

this chat is my kind of chat

floral meteor
#

!e ```py
print(0x00for x in input("Hello World!"))

night quarryBOT
#

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

15
floral meteor
#

I ate a chocolate i found in my car now my teeth hurt

tribal moon
#

did you hear about 3.10s int.jor() and int.jand() additions?

#

!e java print(100.jor(), 100.jand())

night quarryBOT
#

@tribal moon :white_check_mark: Your eval job has completed with return code 0.

100j ()
tribal moon
#

lol

floral meteor
#

wat

#

!e ```py
a: print(5) = 2 + 2

night quarryBOT
#

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

5
floral meteor
#

!e ```py
print(import('sys').version)

night quarryBOT
#

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

001 | 3.9.6 (default, Jun 29 2021, 19:27:32) 
002 | [GCC 8.3.0]
floral meteor
#

it's still on 3.9

golden finch
floral meteor
#

!e ```py
print((100).jor.doc)

snow beacon
#

That's clever.

tribal moon
#

Hahaha

floral meteor
#

oh

#

i see

golden finch
#

what

#

how does it work?

floral meteor
#

!e ```py
print(100.jor())

night quarryBOT
#

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

100j
snow beacon
#

1.foo is a syntax error, because it thinks 1. is a float.

#

1.j is a complex literal.

golden finch
#

ah

#

that's smart

floral meteor
#

!e ```py
print(100.jor(), (0xc0000000for x in 100% yo_mamma is fat),)

night quarryBOT
#

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

100j 51539607567
pastel ibex
#

my pycharm is having a heart attack right now my god

snow beacon
tribal moon
#

Java

#

I made it Java so the or and and wouldn't show

floral meteor
#

what i have so far on the double precision float ```py
class double:
def init(self, a):
try:self.n,self.o=a;
except Exception:
f,=a;o=0;
while f>f//1:o+=1;f
=10;
self.n,self.o=int(f),o;
def float(self):
return self.n / 10**self.o
def index(self):return self.n
def str(self):
k=len(str(n:=self.n));
return''.join((a:=[str(n)]).insert(k-self.o,'.')or a);
def repr(self):return str(self);
def eq(self, other):return self>=other>=self;
def reduce(self):
return self.n, self.o;
def lt(self, other):
try:a, b, c, d = self.n, self.o, other.n, other.o;
except Exception:return type(other)(self)<other;
else:
while b<d:b+=1;a
=10;
while b>d:d+=1;c*=10;
return a<c;
def gt(self, other):
try:a, b, c, d = self.n, self.o, other.n, other.o;
except Exception:return type(other)(self)>other;
else:
while b<d:b+=1;a*=10;
while b>d:d+=1;c*=10;
return a>c;
def ge(self, other):return not self<other;
def le(self, other):return not self>other;

#

includes the intuitive i-dont-give-a-fuck typing system

pastel ibex
#

thats really cool

floral meteor
#

i'm gonna give it a few maximum precision mathematical operations now

#

and they're all gonna work with integers only

woven bridge
#

pep 263 is another way of implementing syntax hackery

tribal moon
#

!pep 263

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

Final

Python-Version

2.3

Created

06-Jun-2001

Type

Standards Track

woven bridge
#

!e

import codecs
import typing
import io


def encode(text: str) -> typing.Tuple[bytes, int]:
    raise NotImplementedError


def decode(binary: bytes) -> typing.Tuple[str, int]:
    result = io.StringIO()
    buffer = io.BytesIO(binary)

    for line in buffer:
        if line.startswith(b'#'):
            continue

        if line.startswith(b'namespace'):
            name = line.split()[1][:-1].decode()
            result.write(f'class {name}:\n')

        else:
            result.write(line.replace(b'::', b'.').decode())

    return result.getvalue(), result.tell()


codecs.register(
    lambda name: codecs.CodecInfo(encode=encode, decode=decode, name='namespaces')
)

code = b"""
# coding=namespaces

namespace example:
    a = "example value"

print(example::a)
"""

exec(code)
night quarryBOT
#

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

example value
tribal moon
#

Can't you do the same thing with ast?

#

nevermind it won't work

woven bridge
#

ast wont work with weird stuff that causes syntax errors

tribal moon
#

that's very interesting

#

I'd still love to see people combine that, frames and bytecode stuff, and ctypes to make something really cool

woven bridge
#

once you register a codec then it can be used in any modules that get imported afterwards with # coding=[name] as the first line.

floral meteor
#

but by then it would be an interpreter of another language

woven bridge
#

had to condense it all into one snippet for the bot.

#

otherwise it'd be something like this:
file_1.py

import namespaces_codec
namespaces_codec.register() # does the codecs.register(...) part

import file_2
file_2.test()

file_2.py

# coding=namespaces

namespace example:
  a = "example value"

def test():
  print(example::a)
tribal moon
#

try to recreate C or something like that

#

so you'd need to like compress it or something

woven bridge
#

one thing im a little confused by is why the decoder needs to return both a string and its length

#

maybe it can return any indexable, even those without a __len__

#

havent investigated it

tribal moon
#

Can you do anything with ctypes?

#

in Python

woven bridge
#

more or less

#

cant really think of something you wouldnt be able to

floral meteor
# tribal moon Can you do *anything* with ctypes?

!e here's the official class override ```py
class hack:
def new(cls, a, *b):
from ctypes import py_object as p
return super().new(cls)if b else p.from_address(id(a)+8)
@property
def value(self):
"""Kept here just to keep pycharm happy."""
from ctypes import py_object as p
return p.from_address(id(self)+8).value
@value.setter
def value(self, v):
from ctypes import py_object as p
p.from_address(id(self)+8).value = v
def init(self, *pairs):
v = self.victims = []
for i,j in zip(pairs[::2],pairs[1::2]):
if i not in[k for k,_ in v]:v.append((i,hack(i).value))
hack(i).value = j
def enter(self):return self
def exit(self, a, b, c):
self.del()
return a is b is c is None
def del(self):
for victim, prisoner in self.victims:
hack(victim).value = prisoner

with hack(True, int, False, int):
print (False, not 0, not 1)
print (False, not 0, not 1)
with hack(..., type('std::cout',(),{
'lshift':lambda s,o:print(end=o)or s,
'endl':'\n'
})):
... << "Hello World!" << ....endl;

night quarryBOT
#

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

001 | 0 1 0
002 | False True False
003 | Hello World!
floral meteor
#

!e ```py
class hack:
def new(cls, a, *b):
from ctypes import py_object as p
return super().new(cls)if b else p.from_address(id(a)+8)
@property
def value(self):
"""Kept here just to keep pycharm happy."""
from ctypes import py_object as p
return p.from_address(id(self)+8).value
@value.setter
def value(self, v):
from ctypes import py_object as p
p.from_address(id(self)+8).value = v
def init(self, *pairs):
v = self.victims = []
for i,j in zip(pairs[::2],pairs[1::2]):
if i not in[k for k,_ in v]:v.append((i,hack(i).value))
hack(i).value = j
def enter(self):return self
def exit(self, a, b, c):
self.del()
return a is b is c is None
def del(self):
for victim, prisoner in self.victims:
hack(victim).value = prisoner

with hack(0,float,1,float):
print(0, 1)
print(0, 1)

night quarryBOT
#

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

001 | Traceback (most recent call last):
002 |   File "<string>", line 27, in <module>
003 |   File "<string>", line 17, in __init__
004 |   File "<string>", line 3, in __new__
005 | TypeError: __int__ returned non-int (type float)
006 | Exception ignored in: <function hack.__del__ at 0x7fea387823a0>
007 | Traceback (most recent call last):
008 |   File "<string>", line 25, in __del__
009 |   File "<string>", line 3, in __new__
010 | TypeError: __int__ returned non-int (type float)
floral meteor
#

I think i broke something

#

XDDDDD

#

!e ```py
import sys
poopy = sys.meta_path
class hack:
def new(cls, a, *b):
from ctypes import py_object as p
return super().new(cls)if b else p.from_address(id(a)+8)
@property
def value(self):
"""Kept here just to keep pycharm happy."""
return import('ctypes').py_object.from_address(id(self)+8).value
@value.setter
def value(self, v):
import('ctypes').py_object.from_address(id(self)+8).value = v
def init(self, *pairs):
v = self.victims = []
for i,j in zip(pairs[::2],pairs[1::2]):
if i not in[k for k,_ in v]:v.append((i,hack(i).value))
hack(i).value = j
def enter(self):return self
def exit(self, a, b, c):
self.del()
return a is b is c is None
def call(self, other):
return self.class(other)if other is not self else self
def del(self):
sys.meta_path = poopy
for victim, prisoner in self.victims:
import('ctypes').py_object.from_address(id(victim)+8).value = prisoner

with hack(hack, hack) as h:
print(h, hack, hack.class, hack.class is hack.class.class is hack)

night quarryBOT
#

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

001 | <__main__.hack object at 0x7fe40f2446d0> <__main__.hack object at 0x5599532f2b50> <__main__.hack object at 0x5599532f2b50> True
002 | Exception ignored in: <function hack.__del__ at 0x7fe40f2464c0>
003 | Traceback (most recent call last):
004 |   File "<string>", line 28, in __del__
005 |   File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
006 |   File "<frozen importlib._bootstrap>", line 982, in _find_and_load_unlocked
007 |   File "<frozen importlib._bootstrap>", line 925, in _find_spec
008 |   File "<frozen importlib._bootstrap_external>", line 1414, in find_spec
009 |   File "<frozen importlib._bootstrap_external>", line 1380, in _get_spec
010 | TypeError: 'NoneType' object is not iterable
floral meteor
#

why can't i finish deleting this bad boy?

#

smh

#

!e ```py
import sys
poopy = sys.meta_path
class hack:
def new(cls, a, *b):
from ctypes import py_object as p
return super().new(cls)if b else p.from_address(id(a)+8)
@property
def value(self):
"""Kept here just to keep pycharm happy."""
return import('ctypes').py_object.from_address(id(self)+8).value
@value.setter
def value(self, v):
import('ctypes').py_object.from_address(id(self)+8).value = v
def init(self, *pairs):
v = self.victims = []
for i,j in zip(pairs[::2],pairs[1::2]):
if i not in[k for k,_ in v]:v.append((i,hack(i).value))
hack(i).value = j
def enter(self):return self
def exit(self, a, b, c):
self.del()
return a is b is c is None
def call(self, other):
return self.new(self, other)
def del(self):
sys.meta_path = poopy
for victim, prisoner in self.victims:
import('ctypes').py_object.from_address(id(victim)+8).value = prisoner

with hack(hack, hack):
print(hack is hack.class)
print(dir(hack))

night quarryBOT
#

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

001 | True
002 | []
floral meteor
#

lmfao

#

maybe I should implement dict so it doesn't die to death

tribal moon
#

Too bad you can't create a new operator with ctypes

#

imagine how awesome that'd be

night quarryBOT
#

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

[] [(<__main__.hack object at 0x56144d8bd160>, <class 'type'>)]
woven bridge
#

but thatd be a pain in the back and a half

tribal moon
#

too difficult

#

I don't think it'll ever be done

floral meteor
#

!e ```py
import sys
poopy = sys.meta_path
class hack:
victims = []
def new(cls, a, *b):
from ctypes import py_object as p
return super().new(cls)if b else p.from_address(id(a)+8)
@property
def value(self):
"""Kept here just to keep pycharm happy."""
return import('ctypes').py_object.from_address(id(self)+8).value
@value.setter
def value(self, v):
import('ctypes').py_object.from_address(id(self)+8).value = v
def init(self, *pairs):
v = self.victims = []
for i,j in zip(pairs[::2],pairs[1::2]):
if i not in[k for k,_ in v]:v.append((i,hack(i).value))
hack(i).value = j
def enter(self):return self
def exit(self, a, b, c):
self.del()
return a is b is c is None
def call(self, a, *b):
return self.new(a, *b)
def del(self):
sys.meta_path = poopy
for victim, prisoner in self.victims:
import('ctypes').py_object.from_address(id(victim)+8).value = prisoner

with hack(hack,hack) as h:
print(h(h,h))
del h

tribal moon
#

should give it a read

night quarryBOT
#

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

py_object(<__main__.hack object at 0x560287406230>)
floral meteor
#

hack has hacked itself to become it's own class, but that's really messing with python

tribal moon
#

Do you put all of this in a github repositroy or something

woven bridge
tribal moon
#

can't do it with ctypes

woven bridge
#

you can use os api calls to overwrite any process memory using ctypes

tribal moon
#

I know

woven bridge
#

so then why say you cant do it with ctypes

tribal moon
#

Prove me wrong

golden finch
#

What's the easiest way to bluescreen in Python?

woven bridge
#

challenge possibly accepted 😛

tribal moon
#

good luck!

golden finch
#

bonus points if no ctypes

#

Also, I was reading a SO answer recently

#
eval((lambda:0).__code__.replace(co_consts=()))
#

it obviously segfaults

#

but the answer said that it had the potential for arbitrary code execution "if you are smart about it"

#

how?

tribal moon
floral meteor
#

!e ```py
import sys
poopy = sys.meta_path
class hack:
victims = []
def repr(self):
return'<hacked '+str([yay[0]for yay in self.victims])+'>'if self.victims else'<class hack>'
def new(cls, a, *b):
from ctypes import py_object as p
if not b:return p.from_address(id(a)+8)
else:
return super().new(cls)
@property
def value(self):
"""Kept here just to keep pycharm happy."""
return import('ctypes').py_object.from_address(id(self)+8).value
@value.setter
def value(self, v):
import('ctypes').py_object.from_address(id(self)+8).value = v
def init(self,*pairs):
v = self.victims = []
for i,j in zip(pairs[::2],pairs[1::2]):
if i not in[k for k,_ in v]:v.append((i,hack(i).value))
hack(i).value = j
def enter(self):return self
def exit(self, a, b, c):
self.del()
return a is b is c is None
def call(self, a, *b):
return self.new(self.class,a, *b)
def del(self):
sys.meta_path = poopy
for victim, prisoner in self.victims:
import('ctypes').py_object.from_address(id(victim)+8).value = prisoner

with hack(hack, hack) as h:
print(hack, h, hack.class)
hack(hack).value = h
hack.victims#SIGSEV
del h;
print('can',hack,'be unhacked?')#yes

tribal moon
#

Too vague to find out

night quarryBOT
#

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

<class hack> <hacked [<class hack>]> <class hack>
golden finch
#

not so

#

but se

tribal moon
#

@woven bridge any luck?

woven bridge
#

also wanna look deeper into the stuff numba is doing with llvm, might be useful

tribal moon
#

How do you think you'd do it?

#

Only with Python?

quiet niche
#

cause a bsod?

woven bridge
# tribal moon How do you think you'd do it?

might be possible to replace the parser instructions entirely with a precompiled replacement bundled with the script, so it would be python only for the end user, but creating the script itself would require another compiler

#

aside from that im thinking if there are smarter ways to go about it than just replacing the entire thing

woven bridge
tribal moon
#

Can only use Python

woven bridge
#

it would simplistically boil down to something like this

instructions = b"very long byte string"

inject(instructions)
#

the instructions would be generated using something else

#

but the script itself would ultimately be only python

#

is that within the rules? 😅

tribal moon
#

You can do ANYTHING you want

#

as long as it's Python

#

even if you use C functions

#

it doesn't matter

#

as long as it can be ran within Python

woven bridge
#

got it

earnest wing
#

i heard they're going to be removed in 3.11 :>

sick hound
#

Is there a way to have a class’ “parent” be itself? I want to allow for things like this:

class a:
    def __getitem__(self, idx):
        return “test”
print(a[10])
sudden osprey
#

In this case you could use __class_getitem__, for other dunders you would want to define a metaclass

#

e.g.

class a:
    def __class_getitem__(cls, idx):
        return "test"

print(a[10])

or with a metaclass

class Meta(type):
    def __getitem__(self, idx):
        return "test"

class a(metaclass=Meta):...

print(a[10])
jaunty creek
sudden osprey
#

None others like __class_getitem__ iirc

jaunty creek
#

oh only this?

sudden osprey
#

!pep 560

night quarryBOT
#
**PEP 560 - Core support for typing module and generic types**
Status

Accepted

Python-Version

3.7

Created

03-Sep-2017

Type

Standards Track

sudden osprey
#

was added as part of that

jaunty creek
#

oh i see

woven bridge
dawn kayak
#

i just learnt you can use the gcc preprocessor on non-c files

#

so you can do gcc -E - < main.py and it will preprocess it

#

you know what this means right....

#

MACROS!!!

proper vault
#

yup, CPP works on arbitrary files

dawn kayak
#

im going to abuse macros in python

#

brb

proper vault
#

have fun!

#

it's going to be even worse than macros in C

dawn kayak
#

exactly

#

eh, i thought #include works with only .h but seems it works with any file

#

why is this so fun

sick hound
#

Wait what

dawn kayak
#

yes

#

you can use macros in python

#

because gcc can preprocess ANY file

#
from subprocess import run
o = run('gcc -E - < file.py', shell=True, capture_output=True)
exec(o.stdout)
#

this is what i use to run the file

#

why use import when you can use #include

#

altho, are there any serious uses of this?

#

i suppose not

#

but this is hecka fun

#

me too

#

i just ripped it off of a stackoverflow answer

sudden osprey
#

Just pipes the content of file.py into gcc, right?

dawn kayak
sudden osprey
#

The bare - in the gcc command says to read from stdin

#

as < file.py provides it into stdin

#

rather than as part of the command

dawn kayak
#

is there a more convenient way to do this than capturing output and the exec'ing it

#

it literally copy pastes that file

#

this is the gcc preprocessor, it doesn't care about __all__

#

it just straight up copies the file onto the other file

#

so // This is include.py print("Hi!!!") and py (This is main.py) #include "include.py" print("Bye!") it becomes ```py
print("Hi!!!")
print("Bye")

#

look at this

#

it literally copy pasted stdio.h

#

thats why you get that weird error

proper vault
#

that's the cpp for you

dawn kayak
#

c doesnt really have an import system, you literally copy paste all the files 😂

#

using #include ofcourse

proper vault
#

well, it puts all declerations in the file

#

the definitions are elsewhere

dawn kayak
#

yup

#

luckily c++ has namespaces

#

looks like preprocessor leaves normal python comments alone

#

which makes these even better

#

unfortunately i can't replace : in python because its not a valid c token

#

aktually

#

it is valid

#

no more :

#

the macros are in include.py

#

and i include them

#

it doesnt actually need to be py

#

what ridiculous extension name should i give it 🤔

#

perfect

snow beacon
#

It'll raise a warning.

#

Right at the top of the deprecations.

dawn kayak
#

when will 3.10 be out of beta?

snow beacon
#

The release candidate was slated for three days ago, and is presumably out.

sick hound
dawn kayak
#

i have ruined python's syntax

sick hound
#

explicit do and ends in a forced tabs lang pithink

dawn kayak
#

the end is actually nothing

#
#define end
#define do :
``` this is what i did
sick hound
#

That is so cool

#

Wait would this work:

#define }
#define { :
dawn kayak
#

i tried that

#

but { and } cannot be macros

#

unfortunately

sick hound
#

Why not…?

dawn kayak
#

i dont know, but they give errors

sick hound
#

Oh

#

How does the preprocessing work? Does it accept the -o parameter or does it replace the source file?

dawn kayak
#

the command is gcc -E - < file.py

#

here gcc only does preprocessing and no parsing

sick hound
#

Yes but like does it produce an output file?

dawn kayak
#

it sends it to stdout, which i capture and then execute

#
from subprocess import run
o = run('gcc -E - < file.py', shell=True, capture_output=True)
exec(o.stdout)
#

this is the main script

pure flame
last locust
#

!e py swapcase = lambda string: "".join(chr(asc+32) if (asc:=ord(char)) in range(65, 91) else chr(asc-32) if asc in range(97, 123) else char for char in string) print(swapcase("hEllO WorLd!?#")) quick implementation of str.swapcase without using any str-methods 'cause why not

night quarryBOT
#

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

HeLLo wORlD!?#
earnest wing
#

chr(asc ^ 32) if asc | 32 in range(97, 123)

#

+- 32 is just xor 32

last locust
#

Yeah true

#

Knew there would be a smarter way to implement that bit

earnest wing
#

I guess the ability to toggle a bit for case was part of the design

last locust
#
swapcase = lambda s:"".join(chr(a+32)if(a:=ord(c))in range(65,91)else chr(a-32)if a in range(97, 123)else c for c in s)
```becoming```py
swapcase = lambda s:"".join(chr(a^32)if a|32 in range(97,123)else c for c in s)```?
#

Nvm that doesn't work @earnest wing

earnest wing
#

(a:=ord(c))

last locust
#

Ah yeah

#

Still not working

#
swapcase = lambda s:"".join(chr(a^32)if(a:=ord(c))|32 in range(97,123)else c for c in s)```
#

SyntaxError at the for

#

@earnest wing

earnest wing
#

else c

#

remember your ternary

pure flame
#

what's ^ in py

maiden blaze
#

bitwise xor

#

hrm i got it to 114 chars

swapcase=lambda s:"".join(map(lambda c:chr(c+32*[0,1,-1][2*(c in range(97,123))+(c in range(65,91))]),s.encode()))
last locust
#

My original was 117, Olivia's is 86 lol

pure flame
#

!e ```py
x = "lambda s:"".join(map(lambda c:chr(c+32*[0,1,-1][2*(c in range(97,123))+(c in range(65,91))]),s.encode()))"
print(len(x))

night quarryBOT
#

@pure flame :white_check_mark: Your eval job has completed with return code 0.

103
maiden blaze
#

hmm mine is shorter with the for instead of a map

last locust
maiden blaze
#
swapcase=lambda s:"".join(chr(c+32*[0,1,-1][2*(c in range(97,123))+(c in range(65,91))])for c in s.encode())
pure flame
#

ah

last locust
#
swapcase=lambda s:"".join(chr(a^32)if(a:=ord(c))|32 in range(97,123)else c for c in s)
#

Wait that's not right

#

There we go

#

So mine is slightly shorter

#

Or rather, Olivia's is

maiden blaze
#

crazy

maiden blaze
knotty delta
#

trying to join the golf

#

:)

maiden blaze
#

bonjour

proper vault
#

a|32 in range(97,123)
96<a|32<123

earnest wing
#

yep

#

you could even ditch the walrus

maiden blaze
#

that

earnest wing
#

and use ordered string comparison

last locust
dawn kayak
#

you missed a ] at the end

last locust
#

Nope

dawn kayak
#

join([ should end with ] right?

last locust
#

It's [c,chr(...)^32][96<a....]

dawn kayak
#

hmmm

#

yeah my bad

last locust
#
>>> swapcase=lambda s:"".join([c,chr((a:=ord(c))^32)][96<a|32<123]for c in s)
>>> print(swapcase("HeLLo WorLd042#!"))
hEllO wORlD042#!
maiden blaze
#

73 👀

knotty delta
#

wait what happened i've gone for only 1 minute+

dawn kayak
#

lel

last locust
#

lol

last locust
#

Replacing with the appropriate ascii values?

earnest wing
#

just for fun because I like this pattern:
lambda s:"".join([c,chr(ord(c)^32)][all(eval("%r<c<%r,"*2%(*"@[`{",))]for c in s)

last locust
#

Longer smh

#

lol

earnest wing
#

Just for fun because I like this pattern:

last locust
#

!ban 156021301654454272 We don't do fun here 👢

earnest wing
#

take notes kids:

  • unpack into tuples using (*blah,)
  • %r formatter for strings
  • * and % conveniently have the same precedence
knotty delta
#

is regex cheating

#

nvm i don't think it's possible

#

but i'm close to. so i should stop thinking of another solution

earnest wing
#

you can pass a lambda into re.sub

maiden blaze
maiden blaze
last locust
#

Can you unpack it or something instead?

earnest wing
#

you can't unpack into a string no

#

you can format :)

maiden blaze
#

we could have abused sum but for some reason its pretty explicit about not liking strings

astral rover
#

you could also justlambda s:b"".join([c,chr(ord(c)^32)][all(eval("%r<c<%r,"*2%(*"@[`{",))]for c in s).decode() :)

last locust
earnest wing
#

"%c"*len(s)%tuple(your iterable here)

last locust
#

!e py swapcase = lambda s:"%c"*len(s)%tuple(chr(a+32)if(a:=ord(c))in range(65,91)else chr(a-32)if a in range(97, 123)else c for c in s) print(swapcase("HeLLo WorLd042#!"))

night quarryBOT
#

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

hEllO wORlD042#!
dawn kayak
maiden blaze
#

||arguably that also calls a str method, str.__mod__||

dawn kayak
#

actually wait

#

i got it

earnest wing
#

iterable of 1-length strings

earnest wing
maiden blaze
#

yeah

last locust
earnest wing
#

just encode bytes :v)

maiden blaze
#

i'll pretend i didn't see that

dawn kayak
#

then you can't concat strings because its __iadd__ or __add__

knotty delta
dawn kayak
#

grrr

maiden blaze
#

yeah lets just ignore that

earnest wing
#

there should be no top level str methods

#

internally it can be whatever

knotty delta
#

i cheated

swapcase=__import__("builtins").str.swapcase
maiden blaze
#

lol you don't even need that import

#

just swapcase = str.swapcase would work

knotty delta
#

yes

earnest wing
#

just because you're accessing a string method indirectly doesn't mean you're not accessing it

#

assert builtins.str is str

knotty delta
#

!

pure flame
#
swapcase=lambda s:s.swapcase
``` ![potatohide](https://cdn.discordapp.com/emojis/530552687402549268.webp?size=128 "potatohide")
earnest wing
#

strictly speaking iterating over a string directly calls str.__iter__ :>

pure flame
knotty delta
dawn kayak
#

ye

pure flame
#

yeh swapcase(str)

knotty delta
#

did everyone giveup i see no new messages

#

is this too long

#
swapcase=lambda s:"%c"*len(s)%tuple([chr(ord(c)+(32 if ord(c)in range(65,91)else-32 if ord(c)in range(65,123)else-0))for c in s])
#

oops i used an extra space

#

seems like everyone gave up alr

#

nvm i can still remove two chars

#
swapcase=lambda s:"%c"*len(s)%tuple(chr(ord(c)+(32 if ord(c)in range(65,91)else-32 if ord(c)in range(65,123)else-0))for c in s)
#

nvm i lost

woven bridge
#

obligatory recursion

swapcase=lambda s:chr(c+32if(64<(c:=ord(s[0]))<92)else(c-32)if(96<c<124)else c)+swapcase(s[1:])if s else''
slim yarrow
#

!e py swapcase=eval(bytes('慬扭慤猠∺⸢潪湩嬨Ᵽ档⡲愨㴺牯⡤⥣帩㈳崩㥛㰶籡㈳ㄼ㌲晝牯挠椠⥳','u16')[2:]) print(swapcase("HeLLo WorLd042#!"))

night quarryBOT
#

@slim yarrow :white_check_mark: Your eval job has completed with return code 0.

hEllO wORlD042#!
slim yarrow
#

!e py print(len("eval(bytes('慬扭慤猠∺⸢潪湩嬨Ᵽ档⡲愨㴺牯⡤⥣帩㈳崩㥛㰶籡㈳ㄼ㌲晝牯挠椠⥳','u16')[2:])"))

night quarryBOT
#

@slim yarrow :white_check_mark: Your eval job has completed with return code 0.

57
sick hound
tribal moon
tribal moon
#

Weird

#

maybe 100.jand would work

#

and, like they mentioned, something like 0xfor something wouldn't

#

but it's the same thing though

#

idk

dawn kayak
woven bridge
tribal moon
#

What do you mean gdb python api?

woven bridge
#

gdb has a python api, and can compile and inject code into a process on the fly

#

so that could be one approach

tribal moon
#

I don't know, the goal is to make a payload that can work within Python itself

#

you can use gdb to debug

#

you can use anything it doesn't matter

woven bridge
#

ive found some really interesting python injectors but they all seem to rely on ctypes and gdb

#

theres even stuff that can inject a python interpreter into any process

#

cool af

tribal moon
#

doing lots of research that's cool

#

I think you will prove me wrong

#

good luck

woven bridge
#

im just genuinely curious to see how easy this could be

#

there are probably people in the server who are more knowledgeable on reverse engineering and stuff who can already do this

#

ive never really done anything like this before so still pretty much learning the basics

tribal moon
#

alright we'll see how you do

#

maybe if you have any questions with gdb I can try to help you

rugged sparrow
#

ik a way to inject and run assembly with only one import (for mmap)

golden finch
#

What's the goal?

tribal moon
#

operators

golden finch
#

operators in physics or operators in programming?

tribal moon
#

physics

rugged sparrow
#

you want to add a new operator at runtime?

tribal moon
#

just joking programming

golden finch
#

I was thinking what the fuck

#

my background is physics so I was scared for a second there

woven bridge
#

well actually i was wondering, does windbg have on the fly compilation/injection too? i see theres a dll injection extension for it but i dont see any docs on being able to do the same kind of injection gdb can do

#

the goal is to basically inject into the python process at runtime to alter the parser at the lowest level

#

and implement a new operator

rugged sparrow
#

you could use a .pth file (gets ran before main file is parsed) to do your modifications

golden finch
#

so what are you trying to do with operators?

woven bridge
woven bridge
golden finch
#

so an entirely new operator - say a ` operator

rugged sparrow
tribal moon
#

yes

golden finch
#

that's... terrifying

rugged sparrow
#

.pth files are ran at every python startup as they are meant to make a corresponding module work properly. they are intended to be low impact

woven bridge
#

so the idea with this would be to set up an import hook at startup?

golden finch
#

what if... you make a python script called, say, compiler.py, that takes your script, runs it through compile(), and then messes with the bytecode, and then passes it to python?

golden finch
#

so why can't you do that?

rugged sparrow
#

!pypi brm

night quarryBOT
rugged sparrow
#

already been done

golden finch
#

so what are you trying to do then?

rugged sparrow
#

i assume modify the parser at runtime

#

instead of just doing preprocessing

golden finch
#

what the hell

#

what if you read file?

#

so you want something you can put at the start of your python script to allow for new operators?

woven bridge
golden finch
woven bridge
#

yep, easier said than done though

#

the goal is to directly alter the cpython parser at runtime with an injection

rugged sparrow
#

i mean if we can figure out exactly what function always gets called for parsing we could just hook it and inject some new assembly

woven bridge
#

aside from a single entry point

#

one sec there was an article SomeDude posted a while back that detailed the process

rugged sparrow
#

ping me if you can find it

woven bridge
#

might be out of date by now though

#

also statement centric

rugged sparrow
#

yea its out of date

#

python has a new parser

#

ill do some research tomorrow

woven bridge
#

looks like the general steps for implementing new syntax are still more or less the same, just with a new backend

rugged sparrow
#

true but that is if you are doing it at the C level

#

we kinda have to do it manually, prob with some fun assembly

tribal moon
#

assembly lemon_scared

rugged sparrow
#

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

base_size = sizeof(c_void_p)
libc = cdll.LoadLibrary(util.find_library('c'))

PAGE_SIZE = libc.getpagesize()
MEM_READ = 1
MEM_WRITE = 2
MEM_EXEC = 4
ENDIAN = 'little' if memoryview(b'\1\0').cast('h')[0]==1 else 'big'

libc.mprotect.argtypes = (c_void_p, c_size_t, c_int)
libc.mprotect.restype = c_int

def mprotect(addr, size, flags):
addr_align = addr & ~(PAGE_SIZE - 1)
mem_end = (addr + size) & ~(PAGE_SIZE - 1)
if (addr + size) > mem_end:
mem_end += PAGE_SIZE
memlen = mem_end - addr_align
libc.mprotect(addr_align, memlen, flags)

def addr(cfunc):
ptr = c_void_p.from_address(addressof(cfunc))
return ptr.value

def hook(cfunc, restype=c_int, argtypes=()):
cfunctype = PYFUNCTYPE(restype, argtypes)
cfunc.restype, cfunc.argtypes = restype, argtypes
o_ptr = addr(cfunc)
mprotect(o_ptr, 5, MEM_READ | MEM_WRITE | MEM_EXEC)
mem = (c_ubyte
5).from_address(o_ptr)
default = mem[:]
def wrapper(func):
@cfunctype
def injected(*args, **kwargs):
try:
mem[:] = default
return func(*args, **kwargs)
finally:
mem[:] = jmp
n_ptr = addr(injected)
offset = n_ptr - o_ptr - 5
jmp = b'\xe9' + (offset & ((1 << 32) - 1)).to_bytes(4, ENDIAN)
mem[:] = jmp
@atexit.register
def unhook():
mem[:] = default
injected.unhook = unhook
return injected
return wrapper

@hook(pythonapi.PyDict_SetDefault, restype=py_object, argtypes=[py_object]*3)
def setdefault(self, key, value):
if key == 'MAGICVAL':
return self
return pythonapi.PyDict_SetDefault(self, key, value)

pythonapi.PyUnicode_InternFromString.restype = py_object
interned = pythonapi.PyUnicode_InternFromString(b'MAGICVAL')
setdefault.unhook()

print(interned)```

night quarryBOT
#

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

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

Full output: too long to upload

rugged sparrow
#

i've had to do stuff with assembly before when i implemented this C function hooker

woven bridge
#

woah

#

what is this doing exactly? overriding dict.setdefault?

rugged sparrow
#

it gets the address of the C function PyDict_SetDefault and sticks a relative jump instruction right at the start that jumps to my hooks C address, which unpatches PyDict_SetDefault, calls the python hook function, and then repatches PyDict_SetDefault

#

it does the unpatching and repatching to ensure the original C function works inside the python hook

woven bridge
#

oh i see

#

damn thats pretty neat

#

thanks for sharing @rugged sparrow

#

do you have a repo or something of other stuff like this?

#

oh also, whats the goal of the last 4-5 lines?

rugged sparrow
woven bridge
#

cheers!

rugged sparrow
#

oh i wrote asm_hook to get a reference to pythons interned strings dictionary

#

@woven bridge just pushed from my machine so it should have just got a bunch of random stuff

#

f_locals.py is one im particularly proud of, it makes the dictionary returned by locals() modify the local scope

woven bridge
#

awesome, gonna check it out

rugged sparrow
#

thats why i wanted to implement it

sick hound
dawn kayak
#

actually you are right

#

how does it work then 🤔

sick hound
#

Oh wait nvm figured it out

sick hound
#

Welcome to the esoteric python channel where we break python

vague cairn
#

So a while ago there was a challenge on here to deconstruct a dictionary (make a, b, c = deconstruct({'a':1, 'c':3, 'd':4, 'b':2}) do the logical thing).
Recently I've been wondering about whether it would be possible to do a with statement:

d = {'a':1, 'c':3, 'd':4, 'b':2}
with deconstruct({'a':1, 'c':3, 'd':4, 'b':2} as c,b,a:
    a+=1
    b-=1
    c*=2
print(d)
#should output:{'a':2, 'c':6, 'd':4, 'b':1} ```
#

I suspect that think I could modify my previous deconstruct() to handle that sort of call environment. (and return an object that was effectively a tuple with an enter / exit? But getting access to the locals environment in __exit__() might be tricky.

earnest wing
#

you can do that by hooking into the namespace

#

and collaborating that with the __iter__() of the deconstruct return

#

the only ways I know to hook that is using a namespace + class scope or ctypes to replace dict methods

vague cairn
#

Hmm, are you telling me that rather than dis ing the calling scope, there's an easier way with with an __iter__(), __enter__() and __exit__()

earnest wing
#
class Deconstruct(_):
    a, b, c = _({"a":6, "c":4, "b":3})

should be possible

#

given _ has a metaclass which defines __call__ and __prepare__

#

Heh, a challenge would be to make that work with a one-line (no cheating) _ = ... definition

#

calling forth all python villains!

vague cairn
#

Oooh I was unaware of __prepare__ reading up on it now.

earnest wing
#

Yeah you can basically customize everything with the whole namespace there

vague cairn
#

I'm not sure you understand what I'm trying to do. Though I'd find it totally believeable that there's a way to get the normal call by named parameter mechanism to do what I want.

woven bridge
#

something like

def deconstruct(mapping):
  return [mapping[name] for name in varname.varname(multi_vars=True)]
#

not sure how well it can handle with specifically

#

in with you can use the frame to get the line of code and regex out the names

#

ah i see, you want to mutate the values using the vars too

#

in that case youd just return some proxies with operator overloads

vague cairn
#

you know how you can do

li = [1,2,3,4]
a, b, c, d = li```
and it behaves similarly to ```py
li = [1,2,3,4]
def func(a,b,c,d):
    print(a,b,c,d)
func(*li)```

I have an implementation of deconstruct() so that:
```py
d = {'a':1, 'c':3, 'd':4, 'b':2}
a, b, c, d = deconstruct(li)```
behaves similarly to:
```py
def func(a,b,c,d):
    print(a,b,c,d)
func(**d)```
#

I'm contemplating how I'd implement a feature such that: py d = {'a':1, 'c':3, 'd':4, 'b':2} with deconstruct({'a':1, 'c':3, 'd':4, 'b':2}) as c,b,a: a+=1 b-=1 c*=2 print(d) not only deconstructs as intended, but also saves the ordering & vars, and a reference to the original dict, and at __exit__() repacks them from the calling namespace back into the dict. etc.

#

varname looks cool!

vague cairn
woven bridge
#

ohh nice

vague cairn
#

Once I remembered that with requires parenthesis around the return tuple, it was fairly straightforward: ```py
@contextmanager
def Destructure(di):
values, varnames = destructure(di, 2,#<--skip one frame for Destructure() one frame for contextmanager()'s helper function
report_varnames=True)
try:
yield values
finally:
frame_locals = sys._getframe(2).f_locals
for varname in varnames:
di[varname] = frame_locals[varname]

def test():
di = {'d':1, 'c':2, 'b':3, 'a':4, 'g':0}
print(di)
with Destructure(di) as (a,b,c,d):
print(a,b,c,d)
a+=1
b-=1
c*=2
print(a,b,c,d)
print(di)
test()

And I had to add the named parameter report_varnames to the destructure() function, but all the data was there, I just had to return it so I could use it later.
rugged sparrow
#

You could hook dict.__enter__ and dict.__exit__ so you can just do with di as (...,): ...

earnest wing
#

challenge:

a, *b = "test"    # "t", "est"
*_, c, d = {"a": 5, "c":0, "d":1, "b":2} # {"a":5,"b":2}, 0, 1
floral meteor
#

Hack tuple with fishhook

#

Or dict

#

Hmmm

rugged sparrow
#

the most tricky part of that challenge is setting _ to be a dict instead of a list

#

because UNPACK_EX hardcodes a list (it calls PySequence_List)

pastel ibex
rugged sparrow
#

I look at the cpython source code

short crag
#
__annotations__ = globals();
x: 5 = int;
stdout: open(1, 'w');
number: __import__('random').randint(1, 5) = int;
for function in [type]:
    Main = function("Main", (), {
     '__init__':lambda self:{
        (x == 5) & stdout.write(str(x)),
        (x <= 10) & stdout.write(__import__('codecs').decode(b'\x48\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x21')),
        ({1:True, 2:True}.get(number, False)) & stdout.write(__import__('codecs').decode(b"\x4e\x69\x63\x65\x21"))
    } and None,
     'Start' :(lambda*self,: (()in((),),((),)in()))(),
     '_':0==0})      
y = int;
if (y := 12): {(lambda SubMain: stdout.write(str(SubMain)))(Main().Start)}; 
``` reviving my old project, anyway of making this more esoteric?
floral meteor
#

uef-16-be encode the entire thing and throw the result in an exec

#

As bytes ;)

golden finch
golden finch
#

compile, marshal, pass to exec

golden finch
#

@floral meteor did you find a way to get the integer cache shuffling working?

rugged sparrow
#

I can write something to shuffle the numbers

#

The trick is keeping python from crashing

golden finch
#

yeah

golden finch
rugged sparrow
#

I believe it covers all of the edge cases

earnest wing
#

heck yeah

rugged sparrow
#

just fixed one bug that i noticed, should be good now

#

(if you had an invalid name after the unpack arg, the unpack arg would still be set)

#

now that doesnt happen

night quarryBOT
#

dict_destructure.py lines 44 to 45

elif op_name == 'STORE_FAST':
    frame.f_locals[ex_name] = copy```
rugged sparrow
#

@floral meteor ^ success

vague cairn
#

That is impressive. f_locals.py and fishhook are based

sick hound
#

is there like a site i could read that has short obscure python snippits and explanations for beginner-intermediates?
like id never seen the thing in the channel description >>> (lambda: 'x')() # 'x' before

sudden osprey
astral rover
#

if you wanted to write that as a lambda function it would be func = lambda: "esoteric python"

sick hound
sudden osprey
#

ah yeah, it's an expression rather than a statement so you can do whatever you want with it

#

like (lambda _:_()())(lambda : lambda: print('lol'))

#

or put it in a print and do print((lambda _:_()())(lambda : lambda: 'Hello') + ' World!')

rugged sparrow
#

@earnest wing any more challenges? the dict_destructure was fun

floral meteor
#

@rugged sparrow

>>> x = 4
>>> y = --x
>>> y
3
>>> --x
2
>>> ++++x
4
>>> ++4
4
>>> print(x, -(---x))
4 3
>>>
#

Made a mistake lol, edited

rugged sparrow
#

so --x == (x := x - 1) in functionality?

rugged sparrow
#

see this gets tricky because -(---x) is the same as ----x after compliation

tribal moon
#

Just go with the simple -- and ++

floral meteor
floral meteor
#

I might instead specify```py

x = 4
x = -x
x = -x
x # ensure two consecutive negatives don't incorrectly decrement
4
x = --x # name assign
x
3
--x, x # java decrement behaviour
(2, 2)
print(++x, ++x) # ensure precise stack edits
3 4
y = --x # java decrement behaviour
x, y
(3, 3)
---y # negative decrement y
-2
----y, ++++x # this should double decrement/increment
(0, 5)
--(1 + x), x # this shouldn't mutate x
(6, 5) # should behave normally in this case

#

@rugged sparrow updated specs

rugged sparrow
#

sounds good

floral meteor
#

meanwhile I'm gonna exercise these skills on a hopefully easier task: goto, where labelling is done with and stored in annotations

rugged sparrow
#

damnit just found a major bug in dict_destructure.py

floral meteor
#

if only this worked ```py
from future import annotations
import sys

class Annotations(dict):
def setitem(self, name, value):
if name.lower()=='label':
super().setitem(value, sys._getframe(1))
elif name.lower()=='goto':
if value in self:
target_frame=self[value]
current_frame=sys._getframe(1)
current_frame.f_lasti=target_frame.f_lasti ;# prowgremenng
else:raise NameError(value)
else:raise SyntaxError(f"Unkown token: {name}")
annotations = Annotations();

c = 0
i = import('random').randint(3, 99999);
Label: hither;
print (i, 'incomplete');
if i > 2:
i = 3*i+1 if i%2 else i//2;
c += 1
Goto: hither;
print ('completed', c, 'iterations');

golden finch
#

voodoo magic

floral meteor
#

but i can't voodoo it with a function because annotations and locals behave differently to the global namespace

#

otherwise i'd make a function, paste the frame's remaining code, voodoo it with the above frame, then terminate the program

#

!e this is a little less customisable than _sitebuiltins.Quitter```py
print('before abortion')
import('os').abort()
print('after abortion')

night quarryBOT
#

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

before abortion
floral meteor
#

@rugged sparrow what does this line do?

night quarryBOT
#

f_locals.py line 20

self._r = True```
rugged sparrow
#

oh its for the recursive repr

tribal moon
#

@woven bridge Any luck with the operator problem?

#

Looks like a really fun exercise

floral meteor
#

then it isnt used, then it's set to False

#

but it already has to be truthy to get there

#

and in most cases, truthy is as good as True

rugged sparrow
night quarryBOT
#

f_locals.py line 22

return f'locals({dict(self.items())})'```
rugged sparrow
#

@floral meteor ^

floral meteor
#

oh i see

#

lol i got it the wrong way around

#

thats why theres computer parsing these if statements, not me

#

!e print(import('dis').opname)

night quarryBOT
#

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

['<0>', 'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'DUP_TOP', 'DUP_TOP_TWO', 'ROT_FOUR', '<7>', '<8>', 'NOP', 'UNARY_POSITIVE', 'UNARY_NEGATIVE', 'UNARY_NOT', '<13>', '<14>', 'UNARY_INVERT', 'BINARY_MATRIX_MULTIPLY', 'INPLACE_MATRIX_MULTIPLY', '<18>', 'BINARY_POWER', 'BINARY_MULTIPLY', '<21>', 'BINARY_MODULO', 'BINARY_ADD', 'BINARY_SUBTRACT', 'BINARY_SUBSCR', 'BINARY_FLOOR_DIVIDE', 'BINARY_TRUE_DIVIDE', 'INPLACE_FLOOR_DIVIDE', 'INPLACE_TRUE_DIVIDE', '<30>', '<31>', '<32>', '<33>', '<34>', '<35>', '<36>', '<37>', '<38>', '<39>', '<40>', '<41>', '<42>', '<43>', '<44>', '<45>', '<46>', '<47>', 'RERAISE', 'WITH_EXCEPT_START', 'GET_AITER', 'GET_ANEXT', 'BEFORE_ASYNC_WITH', '<53>', 'END_ASYNC_FOR', 'INPLACE_ADD', 'INPLACE_SUBTRACT', 'INPLACE_MULTIPLY', '<58>', 'INPLACE_MODULO', 'STORE_SUBSCR', 'DELETE_SUBSCR', 'BINARY_LSHIFT', 'BINARY_RSHIFT', 'BINARY_AND', 'BINARY_XOR', 'BINARY_OR', 'INPLACE_POWER', 'GET_ITER', 'GET_YIELD_FROM_ITER', 'PRINT_EXPR', 'LOAD_BUILD_CLASS', 'YIELD_FROM', 'GET_AWAITABLE', 
... (truncated - too long)

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

floral meteor
#

so how do I edit the code of the above frame?

#

I'm stuck on that

rugged sparrow
floral meteor
#

now which one would i use to jump to an instruction number?
'JUMP_FORWARD': 110, 'JUMP_ABSOLUTE': 113

rugged sparrow
#

!e print(import('dis').opname[114])

night quarryBOT
#

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

POP_JUMP_IF_FALSE
rugged sparrow
#

i use this one

#

for my implementation

tribal moon
#

How do you know all of this?

#

Did you just figure everything about this in your free-time

rugged sparrow
#

yea

#

whenever someone says xyz cant be done in python i feel a need to prove them wrong

#

and that lead to me learning a ton of stuff

tribal moon
#

You feel a need to prove them wrong?

#

Then you can't add an operator of your choice in Python

#

doesn't matter the functionality

rugged sparrow
#

see i know how to do that at the C level

#

but at the python level you need to use a preparser and that feels like cheating

tribal moon
#

How would you do it at the C level

floral meteor
#

edit the source code

rugged sparrow
#

modify the grammar file

tribal moon
#

I already read it

#

So you can't do it at the Python level without it being too easy

rugged sparrow
#

yes

#

also a preprocessor isnt elegant

floral meteor
#

well it can be done at the python level but then it sort of becomes making an interpreter of another language, and integrating it into python

rugged sparrow
#

also by the time your code is running the parser isnt running anymore (except for eval or exec) so its moot

#

you can do the hooks but they will never get called because python is done parsing your code

tribal moon
#

Interesting

#

How about trying to implement features and syntax from other languages

#

that sounds fun to me

floral meteor
#

so the python syntax override engine would look like

from hackery_repository import hack_python_itself
from specs import data, main
hack_python_itself(data)
import victim
main(victim)

where specs is the code to run and must specify data including the syntax to override, and a main function, and hack_python_itself has the dirty stuff

rugged sparrow
#

see but all this is like replacing the door after you entered the house with goal of the door being changed before you entered

floral meteor
#

although this becomes using python as an engine to modify a python interpreter, only it's itself

rugged sparrow
#

unless you delayed imports but if youre doing that you can just use an import hook to call a preparser

floral meteor
#

although with quantum computing...

#

maybe we could affect an anti-particle to go back in time and preparse the code

rugged sparrow
#

modifying the python grammer inplace is a very complicated problem, involving getting addresses of unexposed functions, modifying their assembly (or adding jmps to new assembly) and it has no purpose, because there are easier and more effective ways to solve the problem (preparser)

floral meteor
#

@rugged sparrow is it okay if i plagiarise your code to make an annotations implementation?

rugged sparrow
#

Go ahead

#

Just add a comment or something

floral meteor
#

what's op 106?

#

should i replace it with 85 for annotations?

#

!e ```py
"""
adapted to annotations from https://github.com/chilaxan/pysnippets/blob/main/goto.py
"""
from future import annotations
from ctypes import c_char
def getmem(addr, size):
return memoryview((c_char*size).from_address(addr)).cast('B')

all = ['goto', 'label']

def getframe(depth=0):
try:raise
except Exception as e:
frame = e.traceback.tb_frame
for _ in range(depth + 1):
frame = frame.f_back
return frame

def get_dest(frame, label):
code, names = frame.f_code.co_code, frame.f_code.co_names
ops, args = code[::2], code[1::2]
for idx, (op, arg) in enumerate(zip(ops, args)):
try:
if names[arg-2]=='Label'and names[arg]==label:return(idx-1)*2
except:pass
raise RuntimeError(f'label {label!r} not found')

def set_instr(code, idx, op, arg):
code_addr = id(code) + bytes.basicsize - 1
mem = getmem(code_addr, len(code))
(op, arg), mem[idx:idx + 2] = mem[idx:idx + 2], bytes((op, arg))
return op, arg

restore_instr = [None, None, None]

class annotations(dict, metaclass=lambda*a:type(*a)()):
def setitem(self, token, name):
if token.lower()=='goto':
code = (frame:=getframe(1)).f_code.co_code
idx = frame.f_lasti + 2
op, arg = set_instr(code, idx, 114, get_dest(frame, name))
restore_instr[:] = idx, op, arg
elif token.lower()=='label':
frame = getframe(1)
if None not in restore_instr:
set_instr(frame.f_code.co_code, *restore_instr)
restore_instr[:] = None, None, None
super().setitem(name, frame)
elif token.lower()=='rem':pass
else:raise SyntaxError(f'Unknown token: {name}')

c = 0
i = import('random').randint(3, 99999);
REM: these-bloody-batch-files
Label :hither
print (i, 'incomplete');
if i > 2:
i = 3*i+1 if i%2 else i//2;
c += 1;
Goto :hither
print ('completed', c, 'iterations');

night quarryBOT
#

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

001 | 27607 incomplete
002 | Traceback (most recent call last):
003 |   File "<string>", line 58, in <module>
004 |   File "<string>", line 39, in __setitem__
005 |   File "<string>", line 23, in get_dest
006 | IndexError: tuple index out of range
golden finch
#

the virgin JUMP_FORWARD vs the chad JUMP_ABSOLUTE

floral meteor
dawn kayak
#

what

#

pycharm doesn't like you

earnest wing
#

"pycharm doesn't like a lot of my perfectly reasonable code" - this place

fleet yacht
#

Can you run flask and ursina at the same time
Because they both use a app.run

woven bridge
#

building up more familiarity with the parser's workings by messing around with it

tribal moon
#

I see

pure dew
tribal moon
#

Wanna show it?

rugged sparrow
#

@floral meteor ```py

x = 5
while --x:
... print(x)
...
4
3
2
1```

#

currently supports globals and locals

#

i want to update later to support ++x[0] or ++x.a but that requires some more work

#

@tribal moon ^ implemented prefix ++ and --

earnest wing
#

finding the fastest way to unpack an iterable
step 1: scope the grounds

#

step 2: know why

#

step 3: improvise

#

step 4: recognize your failures when they approach you

marsh void
#

fun

tribal moon
#

sounds like it'd be fun for you

rugged sparrow
#

oo ternary is tricky

tribal moon
#

good luck!

dawn kayak
#

we need to decide the ternary syntax

#

how's this? ```py
(condition @ T) << if_true | if_false

#

T is the ternary class

golden finch
dawn kayak
#

!e ```py
class :
def init(_,
):_.=;.=None
def lshift(
,漢):
.
___=漢 if .
_ else .;return _
def or(
,漢):return 漢 if ._____-1 else .
;
class :
def rmatmul(
,
):return __()
T=
_()

print((1 > 0) @ T << 'True!!' | 'False!')
print((1 < 0) @ T << 'True!!' | 'False!')

night quarryBOT
#

@dawn kayak :white_check_mark: Your eval job has completed with return code 0.

001 | True!!
002 | False!
dawn kayak
#

this seems to work eh

earnest wing
golden finch
#

Exactly - you learn more!

earnest wing
#

there's no learning in forwarding the same values you were given

woven bridge
#

also different python versions can have different parameters for CodeType. Using replace means you dont have to use different calls to CodeType per python version if youre not altering version dependent parameters.

#

e.g. 3.8 added posonlyargcount

golden finch
#

Portability is for the weak.

rugged sparrow
tribal moon
#

Yeah that works

#

But the real challenge is to make something like 1 > 0 ? True : False

#

you'd need to make 2 new operators ? and :

proper vault
#

if you make ? return a specific sentinel and : checks for that sentinel, it shouldn't be too bad

snow beacon
#

If it matters, ? isn't valid Python.

formal sandal
#

Is there a good way to hook custom types instead of *args and **kwargs? e.g. if i wanted to pass a Counter instead of kwargs.

#

e.g.

@kwarg_class(Counter)
def foo(**kwargs):
    assert isinstance(kwargs, Counter)
#

with CPython hacks, of course

opaque fossil
#

As I mentioned, I have a problem about web scraping to get dataset. import pandas as pd df = pd.read_html('http://www.olympedia.org/editions/61/medal') df[0] My problem are defined below.
1 ) As you can see, main sport event is composed of all columns. How can I add it at the end of column named for "Main Sport/Event".
2 ) As I mentioned before, multi athletes appear in bronze column of some sport events. How can I fix it?
I hope anyone can help me. I'm looking forward to waiting your response.

rugged sparrow
formal sandal
rugged sparrow
#

Yea you can do that by changing the code flags on foo and then wrapping it

rugged sparrow
#

!e ```py
def kwargs_type(typ):
def wrapper(func):
code = func.code
func.code = code.replace(
co_flags=code.co_flags ^ 0x0008,
co_argcount = code.co_argcount + 1
)
def wrapped(*args, **kwargs):
return func(*args, typ(**kwargs))
return wrapped
return wrapper

from dataclasses import dataclass

@dataclass
class Foo:
a: int
b: int

@kwargs_type(Foo)
def foo_func(a, b, **kwargs):
print(a, b, kwargs)

foo_func(1, 2, a=3, b=4)

night quarryBOT
#

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

1 2 Foo(a=3, b=4)
rugged sparrow
#

@formal sandal ^ not to bad

floral meteor
#

okay i didn't know max had a default kwarg, that might come in handy for golfing

(function)
max(__arg1: SupportsLessThanT@max, __arg2: SupportsLessThanT@max, *_args: SupportsLessThanT@max, key: None = ...) -> SupportsLessThanT@max

max(__arg1: _T@max, __arg2: _T@max, *_args: _T@max, key: (_p0: _T@max) -> SupportsLessThan) -> _T@max

max(__iterable: Iterable[SupportsLessThanT@max], *, key: None = ...) -> SupportsLessThanT@max

max(__iterable: Iterable[_T@max], *, key: (_p0: _T@max) -> SupportsLessThan) -> _T@max

max(__iterable: Iterable[SupportsLessThanT@max], *, key: None = ..., default: _T@max) -> (SupportsLessThanT@max | _T@max)

max(__iterable: Iterable[_T1@max], *, key: (_p0: _T1@max) -> SupportsLessThan, default: _T2@max) -> (_T1@max | _T2@max)
max(iterable, *[, default=obj, key=func]) -> value max(arg1, arg2, *args, *[, key=func]) -> value

With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument.

floral meteor
#

https://github.com/chilaxan/pysnippets/blob/4535d870bbb3dab8c6db2de0baf8fd474e99032c/memview_fromaddr.py#L7 @rugged sparrow where's memoryview defined?


import gc, ctypes
def find(obj, typ):
    for o_obj in gc.get_objects():
        if isinstance(o_obj, typ) and obj==o_obj:
            return o_obj

mp_dict = find(memoryview.__dict__, dict)

def getmem(addr, size):
    return (ctypes.c_char*size).from_address(addr)

@classmethod
def from_address(cls, addr, size, fmt='c'):
    return cls(getmem(addr, size)).cast(fmt)

mp_dict['from_address'] = from_address
night quarryBOT
#

memview_fromaddr.py line 7

mp_dict = find(memoryview.__dict__, dict)```
floral meteor
#

wait that's a builtin?

rugged sparrow
#

Yea

#

That file gives memoryview a convenience method for making one that points to arbitrary memory

floral meteor
#

im deciding what my brainfuckery of the week is going to be

rugged sparrow
#

!e ```py
def args_type(atyp=None, kwtyp=None):
def wrapper(func):
code = func.code
flags = code.co_flags
oldargcount = argcount = code.co_argcount
if atyp is not None:
flags ^= 0x0004
argcount += 1
if kwtyp is not None:
flags ^= 0x0008
argcount += 1
func.code = code.replace(
co_flags = flags,
co_argcount = argcount
)
def wrapped(*args, **kwargs):
nargs = args[:oldargcount]
return func(
*nargs,
*[atyp(args[oldargcount:])] if atyp is not None else [],
*[kwtyp(kwargs)] if kwtyp is not None else []
)
return wrapped
return wrapper

from dataclasses import dataclass

@dataclass
class Foo:
a: int
b: int

@classmethod
def from_dict(cls, dct):
    return cls(**dct)

@args_type(list, Foo.from_dict)
def foo_func(*args, **kwargs):
print(args, kwargs)

foo_func('a', 'b', a=1, b=2)```

night quarryBOT
#

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

['a', 'b'] Foo(a=1, b=2)
rugged sparrow
#

in case you wanted to control *args type as well

floral meteor
#

!e ```py
from future import barry_as_FLUFL
exec("print(3 <> 4)")

night quarryBOT
#

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

True
floral meteor
#

!e ```py
from ctypes import*
py_object.from_address(0).value = 69

night quarryBOT
#

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

[No output]
floral meteor
#

!e ```py
from ctypes import*
*pointer(py_object.from_address(id(1))),

night quarryBOT
#

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

[No output]
floral meteor
#

a few easy segfaults

rugged sparrow
#

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

night quarryBOT
#

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

[No output]
floral meteor
#

it gets caught and raises OSError instead

#

memory access violation at 0x00000000000000000000000

#

zero-x-holddownthezerokeyforfiveseconds

rugged sparrow
#

nah sizeof from ctypes reports the size of the memory a c_object references. so c_int -> 4 but byref returns a python object not a c_type

hybrid hare
#

how do i convert py to a exe looked one yt it doesent show in the dist folder

pure dew
floral meteor
#

actually, windows segfault is 0xc0000005

#

STATUS_ACCESS_VIOLATION

pure dew
#

thats not the error code it gives, thats the address

floral meteor
#

Exception Code: c000005

pure dew
#

yes?

floral meteor
#

that's memory access violation

pure dew
#

yes, thats what you just posted

#

isnt it?

floral meteor
#

that's different to windows behaviour using string_at(0)

#

string_at(0) raises a python error and doesn't crash it

#

py_object.from_address(0).value crashes python and registers a critical event

pure dew
#

see what the OSError.winerror is for string_at

#

I'm curious now

floral meteor
#

winerror?

pure dew
#

no i think thats the strerror

#

yea do try:catch and print e.winerror

#

thats the actual native NT error code

floral meteor
#

it's None