#esoteric-python
1 messages · Page 131 of 1
In [1]: class Foo(type):
...: pass
In [2]: class Bar(type, metaclass=Foo):
...: pass
In [3]: class Baz(type, metaclass=Bar):
...: pass
In [4]: Baz.__class__.__class__
Out[4]: __main__.Foo
Thanks
i think so.. if the class of the object has a metaclass other than type
that should give the metaclass ?
oh, I just saw @snow beacon answered 🤣
i will show mine amyway
!e
class Meta(type):
pass
class Meta2(type, metaclass=Meta):
pass
class Meta3(type, metaclass=Meta2):
pass
class Meta4(type, metaclass=Meta3):
pass
class SomeClass(metaclass=Meta4):
pass
obj = SomeClass()
print(f"{obj=}")
print(f"{obj.__class__=}")
print(f"{obj.__class__.__class__=}")
print(f"{obj.__class__.__class__.__class__=}")
print(f"{obj.__class__.__class__.__class__.__class__=}")
print(f"{obj.__class__.__class__.__class__.__class__.__class__=}")
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | obj=<__main__.SomeClass object at 0x7f8f2e11e560>
002 | obj.__class__=<class '__main__.SomeClass'>
003 | obj.__class__.__class__=<class '__main__.Meta4'>
004 | obj.__class__.__class__.__class__=<class '__main__.Meta3'>
005 | obj.__class__.__class__.__class__.__class__=<class '__main__.Meta2'>
006 | obj.__class__.__class__.__class__.__class__.__class__=<class '__main__.Meta'>
!e ```py
class Meta(type):
pass
class M(type, metaclass=Meta):
pass
M.class = M
print(M, M.class, M.class is M)```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
<class '__main__.M'> <class '__main__.M'> True
Thanks
I know this is a python server, but... I'm working on recreating the most useful python builtins but in c++ so I can learn more about how things work in the c++ world.
I created a Generator template that is iterable with an iterator that goes through successive calls of a function (that takes a reference to a state as an input) until a custom StopIteration exception is thrown.
Next I should make enumerate()
This channel is literally for horrible ideas
Hi.. has anyone had experience in single linkage hierarchical clustering.. we don’t have to use library functions scikit learn..any useful links sharing will be grateful..
Hello
Is it safe to assume that Python is like a high level wrapper for C?
When using Python, I am actually just using underlying C functionalities in a more user friendly way
There are a lot of different ways to run Python. The most common implementation, CPython, is an interpreter written in C. The C code is then compiled to machine code, so Python could also be viewed as a fancy wrapper around assembly.
Python is a C wrapper the same way soup is a vegetable wrapper
I thought that the interpreter is like a program (compiled once for multiple platforms) written in like C (in case of CPython) that has a finite number of operations or instructions.
No C code is compiled again
At least this is what I thought
Like if you'd want add more possible instructions to your virtual machine, you'd have to recompile it.
But the running interpreter itself is not* C, it's just machine code
(*except for following the C ABI and memory model but those are abstract)
Your python code isn't wrapping anything particularly C-like
It doesn't (usually) interact with the ABI
What is ABI?
A thing used by things in memory to interact with each other in a consistent way
join us next episode where we make Python a real C wrapper!
using ctypes and memory prodding!
!e I've spent a lot of time on expressionless code recently. ```py
from builtins import list as getattr
from main import hello_ as all
class getattr:
from builtins import print as init
from main import *
@snow beacon :white_check_mark: Your eval job has completed with return code 0.
001 | __path__
002 | h
003 | e
004 | l
005 | l
006 | o
007 | _
008 | h
009 | e
010 | l
011 | o
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/efulixuqip.txt?noredirect
!e ```py
class getattr:
class new:
class new:
class new:
class new:
class new:
from builtins import print as init
from main import HELLO
@snow beacon :white_check_mark: Your eval job has completed with return code 0.
001 | <class '__main__.__getattr__.__new__.__new__.__new__.__new__'> <class '__main__.__getattr__.__new__.__new__.__new__'> <class '__main__.__getattr__.__new__.__new__'> <class '__main__.__getattr__.__new__'> <class '__main__.__getattr__'> __path__
002 | <class '__main__.__getattr__.__new__.__new__.__new__.__new__'> <class '__main__.__getattr__.__new__.__new__.__new__'> <class '__main__.__getattr__.__new__.__new__'> <class '__main__.__getattr__.__new__'> <class '__main__.__getattr__'> HELLO
003 | <class '__main__.__getattr__.__new__.__new__.__new__.__new__'> <class '__main__.__getattr__.__new__.__new__.__new__'> <class '__main__.__getattr__.__new__.__new__'> <class '__main__.__getattr__.__new__'> <class '__main__.__getattr__'> HELLO
Yep. I've worked out three functions that Python calls: __getattr__, __import__ and __build_class__.
!e ```
from builtins import print
from operator import methodcaller as import
from builtins import build_class
import main as builtins
class getattr:
from main import call as init
import foo
print(foo)
@snow beacon :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 7, in <module>
003 | ModuleNotFoundError: No module named 'foo'
Weird, that seemed to work in the repl.
Here's what I got:```py
from builtins import print;from operator import methodcaller as import;from builtins import build_class;import main as builtins;
class getattr:
... from main import call as init
...
import foo
print(foo)
operator.methodcaller('foo', {'name': 'main', 'doc': None, 'package': None, 'loader': <class '_frozen_importlib.BuiltinImporter'>, 'spec': None, 'annotations': {}, 'builtins': <module 'main' (built-in)>, 'print': <built-in function print>, 'import': <class 'operator.methodcaller'>, 'build_class': <built-in function build_class>, 'getattr': <class 'main.getattr'>, 'foo': operator.methodcaller(...)}, {'name': 'main', 'doc': None, 'package': None, 'loader': <class '_frozen_importlib.BuiltinImporter'>, 'spec': None, 'annotations': {}, 'builtins': <module 'main' (built-in)>, 'print': <built-in function print>, 'import': <class 'operator.methodcaller'>, 'build_class': <built-in function build_class>, 'getattr': <class 'main.getattr'>, 'foo': operator.methodcaller(...)}, None, 0)
I've figured out how to call many arbitrary functions on any identifier string, then store the result in an arbitrary variable. For instance, I can evaluate the string "foo" with eval and store it in a variable. However, I have immense difficulty loading variables and calling functions on those. I also have difficulty with getting attributes of things, in part because of the above. I can get most attributes of function objects using __build_class__ with operator.attrgetter, most module attributes with classes named __getattr__, and some string attributes, only the ones that aren't also attributes of __main__ due to the way importing works.
I played around with __get__ as well for a while, because it looked promising for composing functions (which would be a bit of a holy grail with this restriction) but unfortunately I couldn't construct anything where it was meaningful to __get__ it.
I think there is more room to explore there, but I don't get the mechanisms well enough to do so.
I only recently realised that function.__get__ was how bound methods work.
There was some discussion of this a while ago, which led me to __getattr__, although __import__ was only mentioned. No one had actually gotten it working. Then I did a lot of testing and looking up obscure Python internal functions.
I figured out how to break Python in a really interesting way actually. Let me find the code...
!e This errors when it tries to import the last module there. ```py
class getattr:
def init(*_):pass
class call:
from importlib._bootstrap import _setup as new
from main import _ as getattr
try:
from main import foo as bar
except:
pass
import b64encode
@snow beacon :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 10, in <module>
003 | File "<frozen importlib._bootstrap>", line 1024, in _find_and_load
004 | File "<frozen importlib._bootstrap>", line 170, in __enter__
005 | File "<frozen importlib._bootstrap>", line 185, in _get_module_lock
006 | AttributeError: 'str' object has no attribute 'acquire_lock'
importlib._bootstrap is for setting up Python. It gets called on sys and one of the internal import libraries. This time, I call it on __main__ (which now contains all of sys's functions) as well as the string "foo". So it tries to use "foo" as a module for importing things.
I had a goal with this little excursion: I wanted to add 1 and 1, then print the result. I didn't succeed. I managed to store 1/2/any number to a variable, but never figured out how to add or print it.
!e It took me a while, but it's not actually that complicated: ```py
from builtins import len as getattr
from main import aaaa as four
print(four)
@snow beacon :white_check_mark: Your eval job has completed with return code 0.
4
By the way, my goal here was to somehow interact with sys.modules, e.g. replace it.
Future work that could be promising: sys.settrace and other sys functions, the inhabitants of operator, functools.partial, and the intricacies of how nested classes with __init__s, __call__s, __new__s or __get__s might interact. I think it would require fresh eyes though, not mine.
For the sake of getting all the info in one place, I'll reiterate the rules, it's to do some programming (ideally prove Turing complete) using only statements. No expressions, or anything that contains an expression.
First proposal: #esoteric-python message
Second time it was brought up: #esoteric-python message
I... wow, that's cursed
Every few minutes working on this I would stop and realise the same thing. People who write expressions don't know how easy they have it, with their lambdas and their list comprehensions. The worst thing they have to deal with is no try/except.
If you don't import contextlib then it can be hard to do with and try/except functionality, but beyond that...
Although you can also exec or edit bytecode for that.
are there any expressions that can replace stuff like break, continue, nonlocal?
assert?
Control flow like that can be emulated with loops and conditionals. (Or try/except.)
That's just an if and throwing an exception.
nonlocal is harder, but I've never seen much use for it. You can bind variables easier with parameters.
You can emulate it all with bytecode, to be fair.
I think it rather blurs the distinction between expressions and statements.
Classes are a lot like functions. I would expect they can have closures.
youre talking about using loops and conditionals and ifs, but i was under the impression that we were talking about just a drop in replacement for any statement.
That last bit was what I was trying to disprove.
Oh, I interpreted it as replacing all statements in one fell swoop.
as for assert, you can disable them from the command line. is there any surefire way to query that at runtime? someone could mess with argv before your code runs.
You can check the __debug__ variable, I think.
if you only have the id, try ctypes.cast(id, py_object). otherwise py_object(object) will work too
right, like i said, try ctypes.cast(id, py_object) then
there could be other botched monkeypatching that could be causing the segfault
the issue is that from_address is meant to be used for ctypes type instances, not just plain old python objects.
the docs on from_address could be a bit clearer on this, or at least have some more examples
what is?
right, it's supposed to represent the PyObject struct type. but what i mean is ctypes.py_object.from_address will play well with the address of another ctypes.py_object instance
!e
import ctypes
pointer_1 = ctypes.py_object(12)
pointer_2 = ctypes.py_object.from_address(ctypes.addressof(pointer_1))
print(pointer_1, pointer_2)
@brazen geyser :white_check_mark: Your eval job has completed with return code 0.
py_object(12) py_object(12)
I get this when I run your code
referring to this code
!e
class __getattr__:
def __init__(*_):pass
class __call__:
from importlib._bootstrap import _setup as __new__
class modules:
def get(n, *args): return 8
from __main__ import _ as __getattr__
try:
from __main__ import foo as bar
except:
pass
import b64encode```
@rapid sparrow :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 13, in <module>
003 | File "<frozen importlib._bootstrap>", line 1024, in _find_and_load
004 | File "<frozen importlib._bootstrap>", line 170, in __enter__
005 | File "<frozen importlib._bootstrap>", line 185, in _get_module_lock
006 | AttributeError: 'str' object has no attribute 'acquire_lock'
not sure exactly what's going on there
File "/data/media/0/src/getattr.py", line 12, in <module>
import b64encode
^^^^^^^^^^^^^^^^
File "/data/media/0/src/python3/src/Lib/importlib/_bootstrap.py", line 1041, in _find_and_load
with _ModuleLockManager(name):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/media/0/src/python3/src/Lib/importlib/_bootstrap.py", line 170, in __enter__
self._lock = _get_module_lock(self._name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/media/0/src/python3/src/Lib/importlib/_bootstrap.py", line 185, in _get_module_lock
_imp.acquire_lock()
^^^^^^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'acquire_lock'```
thinking why would _imp be a str.
>>> __main__.j
<__main__.__getattr__ object at 0x7ff7a2d0a0>
>>> __main__.j()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: _setup() missing 1 required positional argument: '_imp_module'```
certainly very intriguing @snow beacon
alright here's a useless thing
!e ```py
def defaultwrapper3(a, b, c):
def outer(f):
def inner(a=a,b=b,c=c):
return f(a,b,c)
return inner
return outer
@defaultwrapper3(1,2,3)
def yeet(a, b, c=4):
print(a+b+c)
yeet(7)#12
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
12
I just needed default values for an iterable unpacking
f, start,end = (lambda a=__file__,b=0,c=None:(a,b,c))(*message.content.removeprefix('||read').strip().split())
Thanks🤭
yw XD
how's my writing style?
I'm making a line oriented file editing system for a bot that I can patch using it's own commands through discord instead of having to login to replit
In the try, it calls __getattr__ (which is an instance of class __getattr__). That defers to the class's __call__, on which it calls __get__ to bind it to __main__ (because it was calling __main__.__getattr__). Then that result gets called on "foo" (or it might be "__path__"), so it's effectively _setup(__main__, "foo"), which starts off by setting sys and _imp to it's args before throwing an error. Those are global variables inside importlib._bootstrap. Then the next time anything gets imported, it tries to run some function in _imp, but _imp is a string, not a module.
!e
fishhook now exists as part of the modules snekbox has, for those interested
It'll probably be useful for things like hooking int to things like __iter__ and __next__
from fishhook import hook
idx = -1
@hook(int)
def __iter__(self):
return self
@hook(int)
def __next__(self):
global idx
idx += 1
if idx >= len(str(self)):
raise StopIteration
else:
return int(str(self)[idx])
for digit in 123:
print(digit)
@shut trail :white_check_mark: Your eval job has completed with return code 0.
001 | 1
002 | 2
003 | 3
oh that's awesome
and exception safe
ahh but what is the string?
I was unable to use my normal debugging tools because the environment was too trashed :p
__getattr__ usually gets called a few times, on "__path__", then twice on whatever you imported from __main__ (so "foo"). This time though I think it errors the first time, so it will just call it on "__path__".
@rugged sparrow knows I assume
so _ is a thing even outside of the repl?
The _ is just used as a name. You can see the __init__ method ignores all its arguments, so it doesn't matter what name you use there.
but __getattr__ in __main__ is already bound to your class right
Oh sweet they added it
Yep!
Does anybody have some tips on how to deobfuscate website javascript using python?
Ping or reply with response
thx man
i'll check out how-to-get-help
As I understand it, it only gets bound when it's accessed, and it gets accessed as __main__.__getattr__. That means it calls ... .__get__(__main__, type(__main__)), to bind it to __main__ rather than the class.
I don't quite understand where the __get__ method comes from, but it's probably the class definition with a __call__ that creates it automatically (like functions get one automatically).
Hey, look at my cursed golfed code for https://adventofcode.com/2017/day/1
i=input()
p=i[-1]
print(sum((x==p)*int(p:=x)for x in i))
Any ideas to shave off more bytes?
If you do, please ping me. I might not notice it otherwise 😄
Send a link to the rest of the code cause I think your structure definitions may be off
Write the definition of a function power to, which receives two parameters (x and y
respectively). The first is a double and the second is an int. The function returns a
double. If the second parameter is negative, the function returns zero. Otherwise
it returns the value of the first parameter raised to the power of the second. Call
the function with the values 23.1 and 7 respectively. At the end print the function’s
result. (Note: Python’s built-in functions are not allowed.)
is there a __class_getitem__ slot in 3.8
we're thinking of hacking the builtin collection types to support subscripting so that the same code that works in >= 3.9 can work in 3.8
but I figure there would probably need to be interpreter support for that. or is that wrong?
why can't we just use __getitem__ in the first place, why is a special slot for __class_getitem__ needed?
Yeah I think it’s there
!pep 560
To make a distinction between using it on a class and on an instance
really, does "Python version: 3.7" mean 3.7 would actually have support
oh, of course. now it's very clear
hmm ...
__class_getitem__ is just implemented as a classmethod in the namespace of the class
!e py import gc int_d = gc.get_referents(int.__dict__)[0] int_d['__class_getitem__'] = classmethod(lambda c,v:(c,v)) print(int[1])
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
(<class 'int'>, 1)
that looks doable... so if we added this code there would be no more
TypeError: type object 'list' is not subscriptable ?
you would need to add type.__getitem__
tbh you could just hook type._getitem__ and either make that call __class_getitem__ or it could do the type stuff itself
hmm... 🤔
so if you had
x = list[str]
does that call list's __class_getitem__ or type's __getitem__ ?
__class_getitem__ doesnt do anything in 3.8 so you need to reimplement it
but it will get called at least
you can make type.__getitem__ call it
ok
Wait, you can do this?
I thought it would require a lot more black magic to get that to work
without fishhook or forbiddenfruit
__class_getitem__ isnt a slot method
looks like there is some extra indirection so it tries to read the ref count a a pointer
!e
(type(lambda:0))((lambda:0).__code__.replace(co_code=b'd\x00'),globals())()
can't for the life of me work out why this throws SystemError: Unknown opcode
@golden finch :x: Your eval job has completed with return code 1.
001 | XXX lineno: 1, opcode: 0
002 | Traceback (most recent call last):
003 | File "<string>", line 1, in <module>
004 | File "<string>", line 1, in <lambda>
005 | SystemError: unknown opcode
Any ideas? (yes, this is for an esoteric project)
seriously? lol
iirc S is return_value?
huh
personally i would be using the py_object type provided by ctypes not redefining it
PyTypeObject.from_address(id(int)).tp_repr(pointer(PyObject.from_address(id(2))))```
pointer(...from_address(..)) is a double indirection iirc
passing PyObject.from_address(...) passes the structure itself
the memory at id(2) isnt a pointer, its the structure
id(...) is the address right
yes
addressof(id(2)) wouldn't seem to make sense?
or would it
!e
import ctypes
ip = ctypes.POINTER(ctypes.c_int).from_address(ctypes.addressof(ctypes.py_object(int(7))))
print(ip.contents)
@rapid sparrow :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 3, in <module>
003 | ValueError: NULL pointer access
so many crashes
what did you mean by this
more importantly, why does this not work
!e
import ctypes
print(repr(
ctypes.py_object.from_address(
ctypes.addressof(ctypes.py_object(int))
)
))
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
py_object(<NULL>)
ahh
!e
import ctypes
i = int
pi = ctypes.py_object(i)
api = ctypes.addressof(pi)
print(repr(
ctypes.py_object.from_address(api)
))
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
py_object(<class 'int'>)
!e
import ctypes, sys
p = (ctypes.c_char * 4).from_address(id(int))
print(p.raw)
print(int.from_bytes(p.raw, "little"))
print(sys.getrefcount(int))
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | b'D\x00\x00\x00'
002 | 69
003 | 69
it's probably actually 8 bytes though .
maybe tp_as_number is NULL for those number types?
not sure why those would fail
maybe show how they're implemented
tp_as_number, nb_negative in your python class
/*nb_add*/
/*nb_subtract*/
/*nb_multiply*/
/*nb_remainder*/
/*nb_divmod*/
/*nb_power*/
/*nb_negative*/
``` you have all those exact fields?
what's binaryfunc defined as
huh
Howdy to all! I've known python for a couple of years and am looking for a place where I can discuss my work and see what others are doing. I'm kind of a creative programmer. I am not looking for standard approaches and I do programming as my favorite pastime
what if you use c_int as the return type instead of PyObject_p
Did I get to the right place?...
what kind of work is it? mostly you're in the right place, but this chanell is basically for breaking the interpreter or hacking at python internals
or writing really obfuscated or crazy looking code
I do unusual things, but I usually use standard and import packages
you could try #python-discussion l and go from there, there's always somebody there
English is not my native language. In such a stream of messages, I think I'm going crazy there...
And there, the atmosphere is not exactly what I'm looking for, I suppose. I'm looking for a place with creative programmers who are doing interesting small projects in python
Something like. Web-sorter for images on flask
No no! It's just example
I do not use something specific for my own purposes. I'm versatile
I recently developed tetris in curses as an experiment
i got you
I want surrounding people like that, I love doing this, not for profit or school assignments
Thanks for listen
oh wow.. aren't the signatures compatible?
@sick hound PYFUNCTYPE handles ref count incrementing, CFUNCTYPE does not, so your objects were dying mid function
!e
print('Hello'[-True])
@maiden river :white_check_mark: Your eval job has completed with return code 0.
o
!e
def 𑀕𑀫𑀓(*a,**b): print(*a,**b)
𑀕𑀫𑀓("वाओ")
@maiden river :white_check_mark: Your eval job has completed with return code 0.
वाओ
I read a translation of that page but I couldm't work out what it says really
the code is genius tho
which code?
[
[None
for stdin in [input()]
if not #run function
(
loop.clear() if stdin == "Hello" #break
else
loop.append(None) #continue
)
]
for loop in [[None]]
for i in loop
]
this is list comprehension
[None
for Player in
[type('Player',
(),
{
"__init__":lambda self:
(
setattr(self, "HP",20) or
setattr(self, "x", 0) or
setattr(self, "y", 0)
),
"move":lambda self, dx, dy:
(
setattr(self, "x", self.x + dx) or
setattr(self, "y", self.y + dy)
),
}
)]
for player in [Player()]
if not #run funciton
(
print(player.x) or
player.move(3,4) or
print(player.x)
)
]
as is this
oh, yeah, that's cool
https://qiita.com/KTakahiro1729/items/2abef90fee3ec7b31e3e this has the craziest stuff
I have done like
lambda self: (setattr(self,"HP",20), setattr(self,"x",0), setattr(self,"y",0))[0]
but or is a nicer way
like theyre coding an entire game using list comp
best part is could all be in one line
is there a main loop in the game? there are infinite sequences I guess you could use if you wanted a game loop
[
[None
for stdin in [input()]
if not #run function
(
loop.clear() if stdin == "Hello" #break
else
loop.append(None) #continue
)
]
for loop in [[None]]
for i in loop
]
kinda hard to get it to work tho
[
[None
for stdin in [int(input())]
if not #run function
(
print("Higher") or loop.append(None) if stdin < 7 else
print("Lower") or loop.append(None) if stdin > 7 else
print("Correct") or loop.clear()
)
]
for loop in [[None]]
for i in loop
]
this is mostly jsut slightly changing their code, but this is higher or lower in list comp.
problem is with this is it completely breaks golfing and stuff
https://ideone.com/zrQWwa apparently they also made this
how does that repeat?
oh, loop is getting added to
it doesn't yell about list changed during iteration ?
think the reason is simple. lists are ordered, dicts (prior to Python 3.6/3.7) and sets are not. So modifying a lists as you iterate may be not advised as best practise, but it leads to consistent, reproducible, and guaranteed behaviour.
another answer in the same thread:
It wouldn't have been possible to add such a check to lists without breaking backward compatibility. For dicts, there was no such issue.
In the old, pre-iterators design, for loops worked by calling the sequence element retrieval hook with increasing integer indices until it raised IndexError. (I would say getitem, but this was back before type/class unification, so C types didn't have getitem.) len isn't even involved in this design, and there is nowhere to check for modification.
!e
l = list(range(10))
print(l)
print(
[(l.insert(x, x) if i % 2 == 0 else None, x, l.remove(l[i]))[1] for i,x in enumerate(l)]
)
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
002 | [0, 1, 3, 4, 6, 6, 9]
ah, that makes sense
so are they still using the 'counter' variable basically?
there was no iterator to "invalidate" is what it sounds like
im not sure about the first answer there. what if youre iterating and over and altering a list in two separate threads? things can get murky real quick
not sure i understand. what implication does that have for their ordering and iteration?
is it the insertion order?
the set.pop() result seems to be arbitrary
but why would it act as a FIFO
maybe it's dependent on whatever hash the elements had?
looks like it came from comparing dictobject.c with setobject.c
so I guess it started in dict, even though I don't see it there now ?
it's not even there at that same commit
perhaps it was made up from thin air
Anyone have an optimised brainfuck to python transpiler?
How about a befunge98 interpreter?
You wrote one and posted it here
I don't know how much optimized it is but it's something
I don't think it was optimised that much though
what I would find useful is a Java interpreter written in python so I don't have to compile before testing a code snippet.
I guess you can try replit for it
k
probabl y the most useful cursed thing I have made is the "hack_wrapper"
if used a certain way, you could use it to conditionally run or skip blocks using functions, without the function name doing anything
it's simple, yet has OP applications in this channel
!e ```py
def hack_wrapper(n):
from sys import _getframe
frame=_getframe(n+1)
fl = frame.f_locals
fg = frame.f_globals
fb = frame.f_builtins
return lambda f:fl.get(f.name,fg.get(f.name,fb.get(f.name,None)))
d = {}
def decorator(value):
def wrapper(f):
d[value] = f
return hack_wrapper(1)(f)
return wrapper
@decorator('greet')
def print():return"Hello World!"
print(d'greet')
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
Hello World!
there, it changes the behaviour of the function declaration to assign to d instead of locals, leaving locals untouched
unless there's no value in which case it has to create a variable, and initialise it at None
cos you have ascended above statemented python
I'd give another example but I have a Java exam tomorrow
any good source to learn DP?
Dynamic programming?
yes
[fib(4)
for _ in [[]]
for fib in
[
lambda n:1 if n in {1,2}
else fib(n - 1) + fib(n - 2)
]
]
this code is weird because it doeesnt work without the for _ in [[]]. it breaks on line 6, with a namespace error, saying fib isnt defined. i'm not certain about this but
the function is a subsection of the code and is defined by local variables. the fib is defined as a list comp only when the for _ in [[]] is there. i'm fairly certain that this happens because fib is only on that scope when its defined as being part of a nested list comp. when it isnt, its not on that level and therefore fib isnt defined and therefore the code breaks. however, this is very very unpythonic honestly. very weird.
this was from the japanese article i posted yesterday btw. on the bad google translation it looked like they were confused about why they needed it, and they found the solution, but the translation was very very unclear.
as far as I can tell,
[a for a in b]
```evaluates b in the global scope, and a is local to the function, but
```py
[a for u in v for a in u]
```evaluates the second iterable in the scope of the whole listscomp, since it compiles down to a single function, and it can depend on the previous result
there's a thing
look up beanshell.. it's written in Java but it interprets Java code
also you probably want to run it on Java 8, I don't know if it's been updated to deal with modules and whatnot
that's undoubtedly better.. it probably allows the full range of syntax
beanshell doesn't work with most generics, lambdas, complex classes, etc
at least, last I checked
in japanese again
but essentially proves it right yeah
its still pretty unpythonic
ye
its kind of unique in that
did you see this? Its in a similar vein
def fib(n):
return max(
d[1]
for d in [{}]
for d[0], d[1] in [(0, 1)]
for _ in range(n)
for d[0], d[1] in [[d[1], d[0] + d[1]]]
)
ye, cpython converts sets to frozensets and tuples lists to tuples if it can prove the code will be equivalent
which is only true in for loops and in checks IIRC
no, they do end up calling the operator properly
In [7]: 1 in (0, 1, 2), 1 in {0, 1, 2}
Out[7]: (True, True)
In [8]: dis.dis(_i7)
1 0 LOAD_CONST 0 (1)
2 LOAD_CONST 1 ((0, 1, 2))
4 CONTAINS_OP 0
6 LOAD_CONST 0 (1)
8 LOAD_CONST 2 (frozenset({0, 1, 2}))
10 CONTAINS_OP 0
12 BUILD_TUPLE 2
Oh interesting
I mean I figured for literal sets it would have to at least try to hash the elements
it won't inline the view if the view is not only composed of literals and tuple views
@sick hound :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | File "<string>", line 1, in <listcomp>
004 | File "<string>", line 6, in <lambda>
005 | SystemError: no locals when loading 'fib'
Im trying to get an empty string literal and what ive found is this (lambda: 1).__code__.co_lnotab but it returns bytes and I dont want to decode it. Is there another way to do this?
I cant explicitly use strings, I need to get them from elsewhere. like if I wanted an underscore, I would do this True.__abs__.__name__[0]
oh awesome that works
thank you
could also __import__.__class__.__qualname__.__mul__(0)
str()?
lmao it works, but i dont want it to
lambda:0 is a function. type(lambda:0) is FunctionType.
i didn't know you could do that
Which part?
oh... i'm dumb
i thought it was creating a new type
but it is just getting the type of that expression
holy cow
i love the random use of an exception there
there is one more thing i found
https://github.com/KTakahiro1729 person who wrote the article has a github
https://github.com/KTakahiro1729/JunkPy on it they have this
apparently makes anything work in a single line
!e
print(repr(
__builtins__.globals.__class__.__class__.__module__.strip(([]==[]).__repr__()+....__class__.__name__+ConnectionAbortedError().__repr__())
))
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
''
is that really an empty string? lmao
if the apostrophe on my leyboard ever breaks, I think will use this to create strings
Unrelated, but I wrote a new guide page up at https://ifcoltransg.github.io/esoteric-python-guide/.
Excellent suggestion. I'm sure there are some weird points with precedence, but they shouldn't be too important.
It should be up in a few seconds.
I have a bunch of headings written in a file. Then I just say everything I know about the heading.
You just inspired me to write a heading on operator precedence.
!e
(lambda _, __, ___, ____, _____, ______, _______, ________:( #line 232
exec(
"""import os
def main():
os.path.exists('ooga boogas')
try:
main()
except Exception as e:
print(e)"""
)
))(
*(lambda _, __, ___: _(_, __, ___))(
(lambda _, __, ___:
[__(___[(lambda: _).__code__.co_nlocals])] +
_(_, __, ___[(lambda _: _).__code__.co_nlocals:]) if ___ else []
),
lambda _: _.__code__.co_argcount,
(
lambda _: _,
lambda _, __: _,
lambda _, __, ___: _,
lambda _, __, ___, ____: _,
lambda _, __, ___, ____, _____: _,
lambda _, __, ___, ____, _____, ______: _,
lambda _, __, ___, ____, _____, ______, _______: _,
lambda _, __, ___, ____, _____, ______, _______, ________: _
)
)
)
@steady lily :white_check_mark: Your eval job has completed with return code 0.
name 'os' is not defined
Why am I getting this error?
I cannot figure it out for the life of me
Traceback (most recent call last):
File "c:\path\string_names.py", line 232, in <module>
(lambda _, __, ___, ____, _____, ______, _______, ________:(
File "c:\path\string_names.py", line 233, in <lambda>
exec(
File "<string>", line 5, in <module>
File "<string>", line 4, in main
NameError: name 'os' is not defined
But why???
Do you know why?
Aw boo
Brain imAgiNg Analysis iN Arcana (Banana): brain imaging analysis workflows implemented in the Arcana framework (arcana.readthedocs.io)
!e
(lambda :(
exec(
"""import os
def main():
os.path.exists('ooga boogas')
main()
"""
)
)
)()
@steady lily :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | File "<string>", line 2, in <lambda>
004 | File "<string>", line 6, in <module>
005 | File "<string>", line 4, in main
006 | NameError: name 'os' is not defined
whyyyyyy
!e
(lambda :(
exec(
"""import os
def main():
os.path.exists('ooga boogas')
main()
""", globals()
)
)
)()
@steady lily :warning: Your eval job has completed with return code 0.
[No output]
bruh
!e
!eval [code]
Can also use: e
*Run Python code and get the results.
This command supports multiple lines of code, including code wrapped inside a formatted code block. Code can be re-evaluated by editing the original message within 10 seconds and clicking the reaction that subsequently appears.
We've done our best to make this sandboxed, but do let us know if you manage to find an issue with it!*
@sick hound The heading is up now. It's a little unconventional, as is tradition.
you're insane
we're all insane actually
anyone who has ever been in #esoteric-python has either lost their sanity or never been sane
the very use of this channel is indicative of someone's mental state
but if you think about it, it's entirely useless as a test since it also immediately changes it
This channel is a great way to put people on a watchlist, actually
I'd be curious to see the prevalence of mental illnesses
Same, but that's unrelated to my sanity.
yah counting autism as a mental illness seems kinda bad actually
Kinda. But #esoteric-python is fair game. I wonder when APA will officially recognise it.
A multithreaded interpreter for brainfuck written in python lmao -> https://github.com/KittyBorgX/waffle
multithreading? what?
Ah it's multithreaded in the sense that the UI is independent of the interpreter part.
i have an idea for a challenge i think
Yup, im planning to make the interpreter multithreaded as well, i'll have to figure out how
this sounds fun
Things that are "easily parallelizable" in brainfuck are also kind of easy to compile into constant operations (e.g. [>++<-] into "multiply cell by 2 to the right")
Yup! But how would that increase the speed? since you need to iterate twice to check the positioning of the characters right?
Well, you could parse the source code into a more "efficient" representation
I do know someone who wanted to make a brainfuck JIT
wonder how far that project got
essentially the goal is to get the output("Hello, World!) as many times as possible.
rules:
- you cannot use any function more then once.
- each line cannot print Hello, World! more then once.
- you can only use a single line for each Hello, World!
- the different lines, however, can interact with each other.
- you can only use the built in modules
- multiple Hello, Worlds! can be on a single line
- every line has to have at least one function
- every part of a line has to, in some way, contribute to printing hello world.
- using the exact same method multiple times, even if its technically different, isn't allowed. this is to prevent exploits.
- it does not have to work on all platforms.
for example:
#ONE
print("Hello, World!") #uses print()
#TWO
exec("print('Hello, World!')") #uses exc
for each Hello, World! you get a point. the person with the most points wins. i don't know how high you'll be able to take it, but i was experimenting with it for a while and am guessing the highest anyone will get will be about 10.
there are a lot of ways this could be approached.
i personally managed to get 6 points. however, mine was very bad and i imagine there will be definitely be higher scores.
getattr(__import__("os"), "write")(1, b"Hello, World!\n") #uses getattr() and __import__(). mprobably my favourite way of doing it
i'll probably be up until 11pm gmt, and tomorrow i'm unlikely to be able to be on for the entire day
so it makes sense if we end it at 10:30pm, gmt. you can dm me submissions at any time.
since a lot of you are using stuff that only works on unix
we'll probably need some way of working around that too
ok now i have 7
I'm a little unclear about what would count as different uses of a function object. And by "call a function" is that just using function call syntax?
essentially, the challenge doesnt work if you just cant repeat functions since then theres pretty much only 6 ways of doing it. because of that, if you allow using the same function in a different way it does work. i'm just going to say:
as long as when you look through your code and no functions appear twice you're good
list[3]("print('Hello, World')") is the same as anotherlist[3]("print('Hello, World')") to prevent cheating.
and dic[3]("print('Hello, World')") is alllowed since its a dictionary, and therefore different.
sorry for my terrible wording lol
for consistency it has to be Hello, World!
sorry ._.
does it have to work on all platforms?
Can it print out more text than that?
wdym
wdym
some file descriptor nonsense works differently on windows and linux
Can a line print Hello, world! as well as some other text that isn't Hello, world! ?
hmm
i'll allow it, ye
sorry but no- essentially the challenge is to create really weird ways of doing essentially the exact same thing every time. if its different it slightly undermines that
Can the program take input?
Alternatively, can the program explicitly take no input?
I guess step one is finding the stdlib module that imports the most other stdlib modules?
(Preferably one that imports at least os and subprocess)
Can you not simply import os; os....?
Oh, I guess so. I somehow thought is was all supposed to be expressions
Through subprocess alone you can do 5 different ways, if I understand the challenge correctly
i'm stuck on 7 lmao
subprocess: 5 ways. os: 13 ways
Does "You can only use the builtin modules" mean no imports?
Can you import other modules?
yes
I guess the rule is: only standard lib, not e.g. requests
i guess so
Okay then
(otherwise I'll push 99 projects to pypi that each have a function that prints "Hello, World")
So "standard library" instead of "builtin"
because builtins is the module with all the builtin names (print, list, eval, etc)
oh, actually there's 14 ways in os, I guess :D
i meant built in
as in
they;re built into python
i found a method that essentially allows you to double how many you have
but standard library is a better way of saying it lol
when should this end?
I got 5 using logging
i'll probably be up until 11pm gmt, and tomorrow i'm unlikely to be able to be on for the entire day
so it makes sense if we end it at 10:30pm, gmt. you can dm me submissions at any time.
since a lot of you are using stuff that only works on unix
we'll probably need some way of working around that too
Rules 2 and 6 contradict.
what i mean is
if you have 5 lines of code, you should only have 5 Hello, World!s
but you can have
Hello, World!Hello, World! Hello, World!
as how its formatted
This multiplies the number of possibilities by tons
yeah
because even something like int("Hello, world!") contains the string in the output
Okay, so it's not allowed then
Oh oops I misread
the question was whether it has to work on all platforms
the rules always were that Hello, World! has to be the output but i later clarified that it can only be Hello, World! to prevent that
all versions? o.O
i said nothing o.O
!e Here's a few. I might head off now. ```py
print("Hello, World!")
import sys; sys.stdout.write("Hello, World!\n")
try:input("Hello, World!\n")
except:os=sys.modules["os"]; os.system("echo Hello, World!")
exec("print('Hello, World!')")
eval("print('Hello, World!')")
os.write(1, b"Hello, World!\n")
from builtins import *; globals()["print"]("Hello, World!")
x = lambda:0; x.code = compile("print('Hello, World!')", "", "eval"); x()
sys.stdout.writelines(["Hello, World!\n"])
(sp := import("subprocess")).run("/bin/echo Hello, World!", shell=True)
sp.Popen(["/bin/echo", "Hello,", "World!"])
sp.call("/bin/echo Hello, World!", shell=True)
sp.check_call("/bin/echo Hello, World!", shell=True)
import pathlib; path = pathlib.Path("/dev/stdout"); path.write_text("Hello, World!\n")
path.write_bytes(b"Hello, World!\n")
@snow beacon :x: Your eval job has completed with return code 1.
001 | Hello, World!
002 | Hello, World!
003 | Hello, World!
004 | Traceback (most recent call last):
005 | File "<string>", line 3, in <module>
006 | EOFError: EOF when reading a line
007 |
008 | During handling of the above exception, another exception occurred:
009 |
010 | Traceback (most recent call last):
011 | File "<string>", line 4, in <module>
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/diqelifago.txt?noredirect
hmm
isn't write() being used twice tho?
but goodbye
i'll try and get an rpi set up so i can begin testing soon
True.
getattr(__import__("os"), "write")(1, b"Hello, World!\n") #uses getattr() and __import__()
the way i got around that was through this
ok
Could do that, or just from os import write; write(... so it's no longer an attribute.
yeah
i wrote that code while i was still testing it, and was thinking about making it so the modules used in a single line the more points or something, before i decided on the rules we have now
very impressive
dm me
ive almost finished downloading ubuntu and will go over and test the entries so far in a second
I think I encountered an optimization glitch
python seems to have gotten stuck here
ok
oh actually that's just a GC collection
what are you doing it on
3.9
I'm sure what I was doing was using ridiculous memory, so it's probably not actually weird
perhaps I should try with gc disabled... seems like there's a way to do that
I was using elftools and the binary it was reading was 123M
ok, tried it, result is probably not going to be good
lots of time spent building tracebacks, looks like for StopIteration
I wonder why there is explicit support for raising exceptions this way:
raise StopIteration
``` instead of
```py
raise StopIteration()
``` ?
that is kinda odd yeah
I think python 2 half compatibility
or actually, raise ErrorType, reason was outdated even in py2
wonder why we kept half of it
hmm
int is_subclass = 0;
if (PyExceptionInstance_Check(value)) {
inclass = PyExceptionInstance_Class(value);
is_subclass = PyObject_IsSubclass(inclass, type);
if (is_subclass < 0) goto error;
}
// If the value was not an instance, or is not an instance whose class is (or is derived from) type, then use the value as an argument to instantiation of the type class
if (!is_subclass) {
PyObject *fixed_value = _PyErr_CreateException(type, value);
if (fixed_value == NULL) {
goto error;
}
Py_DECREF(value);
value = fixed_value;
}
that appears to new an exception if you just raised the class
funny thing is that in that function (_PyErr_CreateException)
something even crazier is done. It calls _PyErr_Clear
so I assume if you raise an exceptuon withiut making an instance, any pending error is lost?
!e
def foo():
try:
raise Exception("an exception")
except:
raise SystemError
foo()
@rapid sparrow :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 3, in foo
003 | Exception: an exception
004 |
005 | During handling of the above exception, another exception occurred:
006 |
007 | Traceback (most recent call last):
008 | File "<string>", line 6, in <module>
009 | File "<string>", line 5, in foo
010 | SystemError
It's only discarded if you raise from None
so far highest number of points is 10. 7 hours and 41 minutes left
@sick hound what is the challenge
.
I thought maybe I could trick it into discarding the pending Exception, but no 😄
it must save it and then restore it
!e ```py
import hello
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
Hello world!
so i guess this wouldnt be valid cause no comma?
!e
def f() -> ([*map(getattr(_:=open(1,"wb"), dir(_)[-2]), (bytes(x,"ascii") for x in __import__("gzip").decompress(__import__("base64").b64decode(b'H4sIAJp4kmEC/+3GMQ0AIBAEMCvg5h1gALZLPsH/gAumdmqdpMfqmz3L3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3b/8AXIosLggWAAA')).decode().split()))],None)[1]: ...
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld!HelloWorld
... (truncated - too long)
Full output: too long to upload
I forgot there's supposed to be a space.. oh well
I like this one, myself
I got a slight variation of it
!e
def f() -> __import__("__phello__"): ...
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
Hello world!
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | Hello world!
002 | Hello world!
!e
def useless(t): return [*map(lambda y: __import__("__phello__").__spec__.loader().load_module(__import__("__phello__").__name__), t)]
def y(_: useless(range(1000))): pass
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | Hello world!
002 | Hello world!
003 | Hello world!
004 | Hello world!
005 | Hello world!
006 | Hello world!
007 | Hello world!
008 | Hello world!
009 | Hello world!
010 | Hello world!
011 | Hello world!
... (truncated - too many lines)
Full output: too long to upload
need actual overloading for python
what does that mean?
what do you mean by "actual overloading"?
there was talk on #python-discussion about how useless typing.overload is
it's just a more verbose way of type hinting
never used it shrug
right. 4 hours or so left now.
no 5
.oO(well, that was easy)
here's an awful dynamic dispatcher
erases types for breakfast, doesn't bother with kwargs, defaults, variadics or anything, untested, fails on most complex types
import typing, functools
cache = {}
def dynamic_dispatch(fn):
sigs = cache.setdefault(fn.__name__, [])
sigs.append((tuple(typing.get_type_hints(fn).values()), fn))
@functools.wraps(fn)
def inner(*args):
for sig, opt in sigs:
if all(isinstance(arg, param) for for arg, param in zip(args, sig)):
return opt(*args)
return inner
@dynamic_dispatch
def foo(x: int):
return x * 2
@dynamic_dispatch
def foo(x: str):
return x + "!!!"
This probably works though!
did you mean "singledispatch"?
that's just like what I was imagining
well I guess in that case functools.singledispatch is your friend
because it's that but better
while your dispatch may look okay, i'm not sure how happy IDEs would be with that
as I said, it eats types for breakfast
you said it "erases types for breakfast" 😉
It should infer Callable[..., Any] which is "good enough"
hm
no
this appears to take into account all of the arguments?
singledispatch dispatches on the first argument
it can have any number of arguments
right so it takes into account type of one argument?
yes
and this one selects based on the type of multiple arguments?
thinking of a way to check that
moo!
angelic noises
holy cow!
!e
import typing, functools
cache = {}
def dynamic_dispatch(fn):
sigs = cache.setdefault(fn.__name__, [])
sigs.append((tuple(typing.get_type_hints(fn).values()), fn))
@functools.wraps(fn)
def inner(*args):
for sig, opt in sigs:
if all(isinstance(arg, param) for arg, param in zip(args, sig)):
return opt(*args)
return inner
@dynamic_dispatch
def foo(x: int, y: int):
return x * 2
@dynamic_dispatch
def foo(x: str, y: int):
return x + "!!!"
@dynamic_dispatch
def foo(x: int, y: str):
return x * y.upper()
print(f"{foo(1, 1)=}")
print(f"{foo('abc', 2)=}")
print(f"{foo(3, 'def')=}")
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | foo(1, 1)=2
002 | foo('abc', 2)='abc!!!'
003 | foo(3, 'def')='DEFDEFDEF'
that actually worked @earnest wing
it's surprisingly straightforward, there's no need for like 'most specific' signature or anything?
Cannot assign to lambda - why?
Well, that was a 10 line function!
Matching over type signatures and finding the more specific one is hard.
Why is my one-line version falling over..
!e
dynamic_dispatch = lambda fn: ((sigs := ((dynamic_dispatch.__dict__.__setitem__("cache", (cache:=dynamic_dispatch.__dict__.get("cache", {}))), cache.setdefault(fn.__name__, []), cache.get(fn.__name__)))[-1]), sigs.append((tuple(__import__("typing").get_type_hints(fn).values()), fn)), (inner := (__import__("functools").wraps(lambda *args: next(iter(opt(*args) for sig, opt in sigs if all(isinstance(arg, param) for arg, param in zip(args, sig))))))), inner)[-1]
@dynamic_dispatch
def foo(x: int, y: int): return x * 2
@dynamic_dispatch
def foo(x: str, y: int): return x + "!!!"
print(f"{foo(1, 1)=}")
@rapid sparrow :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 7, in <module>
003 | TypeError: update_wrapper() got multiple values for argument 'wrapped'
ah i meant yours is great, i was just thinking of what possible extensions there could be
i think I screwed up the call to wraps
wraps(fn)(your lambda)
4 minutes left
thank you
oh forgot
codes due in
DM it to me and I'll review it tommorow
@snow beacon @sick hound @iakmatiol @restive void @rugged sparrow
please send me the stuff if you did it. you have into tommorow, but stop working in the code if you still are once you read this. sorry about the mass ping tho... I'm going to be now too
goodbye python discord
I admire the people who are active in this channel. This is by far the most interesting channel on here to me and it shows a true mastery of python to be able to do the things some of these guys and gals are doing.
@steady lily if you like tgis check out obfuscated c code events and thwy have made
type('',(),{'today':property(lambda*_:print('The date is '+__import__('datetime').datetime.today().strftime('%B %d, %Y')+'.\n'))}).today
can't work out why this isn't working
Doing this to test my knowledge of properties and their esoteric uses
But... it isn't printing. Where did I mess up?
You don't instantiate the type.
Thanks
(from a noob) what exactly are you coding?
oh is he coding output from a clock?
can't you just use the inbuilt python function?
(again, from a noob)
It's roughly equivalent to this code:```py
import datetime
class MyClass:
@property
def today(self):
print(datetime.datetime.today().strftime('%B %d, %Y'))
my_instance = MyClass()
my_instance.today # prints the time
whats strfttime
They're trying to solidify their knowledge of property, the inbuilt function.
It's a method in the datetime module, which is for str string ft formatting time time.
oh wow
That opens a ton of possibilities
It's based on the command-line tool of the same name.
!e A version without property for comparison. ```py
type('',(),{'today':type('', (), {"get": lambda*_:print('The date is '+import('datetime').datetime.today().strftime('%B %d, %Y')+'.\n')})()})().today
@snow beacon :white_check_mark: Your eval job has completed with return code 0.
The date is November 16, 2021.
you don't actually need the fifth ()
Due to a technicality in how property implements __get__
Does property check to see if it's being accessed from a class before it calls its function?
It does, yes
class Property:
"Emulate PyProperty_Type() in Objects/descrobject.c"
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
if doc is None and fget is not None:
doc = fget.__doc__
self.__doc__ = doc
self._name = ''
def __set_name__(self, owner, name):
self._name = name
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError(f'unreadable attribute {self._name}')
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError(f"can't set attribute {self._name}")
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError(f"can't delete attribute {self._name}")
self.fdel(obj)
def getter(self, fget):
prop = type(self)(fget, self.fset, self.fdel, self.__doc__)
prop._name = self._name
return prop
def setter(self, fset):
prop = type(self)(self.fget, fset, self.fdel, self.__doc__)
prop._name = self._name
return prop
def deleter(self, fdel):
prop = type(self)(self.fget, self.fset, fdel, self.__doc__)
prop._name = self._name
return prop
from the docs
def __get__(self, obj, objtype=None):
if obj is None:#from a class
return self
if self.fget is None:
raise AttributeError(f'unreadable attribute {self._name}')
return self.fget(obj)
_=type('',(),{'_':property(lambda _=[]:(_:=_.__class__._.fget.__defaults__[0],_)and _.append(0)or~-len(_))})()
Which inspired me to make this menace. It's the latest iteration of the cursed counters. Usage:
while _._ < 5:
print('a')
!e
_=type('',(),{'_':property(lambda _=[]:(_:=_.__class__._.fget.__defaults__[0],_)and _.append(0)or~-len(_))})()
while _._ < 5:
print('a')
@golden finch :white_check_mark: Your eval job has completed with return code 0.
001 | a
002 | a
003 | a
004 | a
005 | a
!e
@earnest wing btw I got the compact version:
dynamic=(_i:=__import__,_d:=lambda*v:dynamic.__dict__.__setitem__(str(id),v[0])if v else dynamic.__dict__.get(str(id),{}),lambda fn:(_n:=fn.__module__+'.'+fn.__qualname__, (sigs:=((_d((_:=_d())),_.setdefault(_n,[]),_.get(_n),))[-1]),sigs.append(((*_i("typing").get_type_hints(fn).values(),),fn,)),(inner:=(_i("functools").wraps(fn)(lambda*a:next(iter(o(*a)for sig,o in sigs if all(isinstance(arg,p)for arg,p in zip(a,sig))))))),inner,)[-1])[-1]
@dynamic
def foo(x: int, y: int): return x * 2
@dynamic
def foo(x: str, y: int): return x + "!!!"
@dynamic
def foo(x: int, y: str): return x * y.upper()
print(__import__("textwrap").dedent(f"""
{foo(1, 1)=}
{foo('abc', 2)=}
{foo(3, 'def')=}
"""))```
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
001 |
002 | foo(1, 1)=2
003 | foo('abc', 2)='abc!!!'
004 | foo(3, 'def')='DEFDEFDEF'
any improvements welcome
Did you just create function overloading
@sick hound :white_check_mark: Your eval job has completed with return code 0.
001 |
002 | foo(1, 1)=2
003 | foo('abc', 2)='abc!!!'
004 | foo(3, 'def')='DEFDEFDEF'
!e
My attempt to support generics in this homebrew overloading:
import functools, itertools
from typing import Any, Callable, Iterable, get_type_hints
cache = {}
def dynamic_dispatch(fn):
fnkey = ".".join((fn.__module__, fn.__qualname__))
sigs = cache.setdefault(fnkey, [])
sig = tuple(get_type_hints(fn).values())
sigs.append((fn, sig))
@functools.wraps(fn)
def inner(*args, **kwargs):
best_match = find_best_match(args, sigs)
return best_match(*args, **kwargs)
return inner
def find_best_match(args, sigs: list[Callable[[...], Any], list[type]]):
scores = [0] * len(sigs)
for sidx, (fn, sig) in enumerate(sigs):
if len(sig) < len(args):
continue
for idx, typ in enumerate(
itertools.islice(sig, len(args))
):
arg = args[idx]
argty = type(arg)
if hasattr(typ, "__origin__"):
rawtyp = typ.__mro__[0]
else:
rawtyp = typ
if argty is typ:
scores[sidx] += 25
elif (
issubclass(argty, rawtyp)
or issubclass(rawtyp, argty)
):
scores[sidx] += 5
if (isinstance(arg, Iterable)
and hasattr(typ, "__args__")
):
for obj in arg:
tpar = typ.__args__[0]
if tpar is Any:
continue
if issubclass(type(obj), tpar):
scores[sidx] += 3
else:
scores[sidx] -= 1
scored = list(sorted(zip(scores, sigs),key=lambda i:i[0]))
return scored[-1][1][0]
@dynamic_dispatch
def foo(x: list[Any], y: int):
return ", ".join(list(map(repr, x)))
@dynamic_dispatch
def foo(x: list[int], y: int):
return (x[0] + 10) * y
@dynamic_dispatch
def foo(x: list[str], y: str):
return ", ".join(list(map(str.upper, x)))
print(f"{foo([{},None], 1)=}")
print(f"{foo(['abc', 'def'], 'N')=}")
print(f"{foo([3, 8, 4], 0)=}")
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | foo([{},None], 1)='{}, None'
002 | foo(['abc', 'def'], 'N')='ABC, DEF'
003 | foo([3, 8, 4], 0)=0
@sick hound :white_check_mark: Your eval job has completed with return code 0.
001 |
002 | foo(1, 1)=2
003 | foo('abc', 2)='abc!!!'
004 | foo(3, 'def')='DEFDEFDEF'
wdym
well original code is @earnest wing
you're thats more or less right
come again? did i repost
ohh your version
lol forgiveneds
_d(_) is fun
😄 I like the forgiveness one
we could add a new decorator
@forgive({})
def _d(*v):
if v:
dynamic.__dict__[STR_ID] = v[0]
return dynamic.__dict__[STR_ID]```
what problem can't be solved with a new decorator
or else patching bytecode
@sick hound :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 18, in <module>
003 | File "<string>", line 9, in wrapper
004 | File "<string>", line 9, in wrapper
005 | File "<string>", line 9, in wrapper
006 | [Previous line repeated 994 more times]
007 | File "/usr/local/lib/python3.10/functools.py", line 52, in update_wrapper
008 | value = getattr(wrapped, attr)
009 | RecursionError: maximum recursion depth exceeded while calling a Python object
@sick hound :white_check_mark: Your eval job has completed with return code 0.
None
this looks clever and takes advantage of the fact that none of the BINARY_* ops used their opargs before
although from a bug perspective by specifying an arbitrary oparg you can now directly pivot execution flow with one bytecode modification
which is cool af
@sick hound :white_check_mark: Your eval job has completed with return code 0.
{}
who says wonderful things dont get created here.. they are both created and destroyed
forgive is forgiving itself?
lol is that what this was?
in 3.11 by specifying a calculated oparg you can call an arbitrary address https://github.com/python/cpython/blob/main/Python/ceval.c#L4733
just need to determine the offset from binary_ops to target_func
Python/ceval.c line 4733
PyObject *res = binary_ops[oparg](lhs, rhs);```
on the subject of forgive, I have used a very common _try like many folks here. but I eventually had to weaken it because it was catching everything and hiding coding bugs
i guess that's the benefit of a "raises these exceptions" clause.
you get no univeral, blanket forgiveness (like an advance pardon)
serious? that's a problem..
I don't think I ever succeeded in getting it to build on windows
that's cool 😵
you think it will stay that way?
yea most likely because adding a check there then requires exception handling around it, and no properly generated bytecode would have an invalid oparg like that
im gonna have fun writing some rop code that uses that to get code exec tho lmao
muahaha
it's not possible to type hint a lambda, is it
yea thats correct
f: Callable[int, str] = lambda x: chr(x)
*you can't type hint it using annotations like on a normal function
sel_sqrt(a,b): This function is given integers a and b as arguments, where a < b. It then
returns a list containing the following computed values for the integers i between a and
b: the square root of i if i is odd, and 2*i if i is even. Use list comprehension for this
function.
you're in the wrong channel, #❓|how-to-get-help
you could theoretically set __annotations__ to a custom mapping that would update the annotations on f based on the type hinting, but that would only work at the global scope
!e ```py
import typing
@lambda c:c()
class annotations(dict):
def setitem(self, name, value):
if isinstance(value, typing.Callable):
try:
func = globals()[name]
args = list(value.args)
annots = func.annotations
annots['return'] = args.pop(-1)
for varname in func.code.co_varnames:
if not args: break
annots[varname] = args.pop()
except:pass
super().setitem(name, value)
f: typing.Callable[int, str] = lambda x: chr(x)
print(f.annotations)```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
{'return': <class 'str'>, 'x': <class 'int'>}
@restive void like so ^
nice
whoaa how does ... asdfgh
trying to figure out what @lambda c:c() is doing
Almost nothing, just assigning the name to an instance of the class instead of the class
hey guys
whats the best way
to make py for i in range (10000): os.system('start')
unreadable
in the IDE
i use idle
i thought u weirdos may have something funny because you know this channel name
soz its a habit
I mean.... this doesn't really hide it all that well, tbh. :D
You just assume the reader gets bored before they reach the last line
how can u hide it better then
thanks
tip: if you're trying to prank someone and they see this in they code, they will not run it
it looks pretty funny
for the purpose of what im doing
@sick hound why does it say invalid syntax
cause youre on a bad python version
im on python 3.7.3 linux
that's a very bad version
Far out, 3.7.3 was like, 2019?
should be pretty simple to update it on linux
does anyone know the command to update to 3.8
ah
this isnt the correct place to be asking about this see #❓|how-to-get-help
I think to be truely obfuscated, one should have no alphabetic characters
like BF
or many uses of eval
!e
pretty damn close:
__=((()==[])+(()==[]));___=(__**__);____=((___<<___));_____=((____<<(__**__)));______=((_____<<(__**__)));
_________=((___<<_____));__________=((((___<<_____))<<(__**__)));_=((__**__)+(______<<(__**__)));_______=(__**__)
for ________ in range((_____+(_________<<(__**__))+(__________<<(__**__)))):
_______=_______-((_______**((___<<___))-_)/(((___<<___))*_______))
print(_______)
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
4.123105625617661
!e
_=type('',(),{'__call__':property(lambda instance=lambda num,ins=[]:(_:=ins.__class__.__call__.fget.__defaults__[0],_.__defaults__[0].append(0)or len(_.__defaults__[0])<=num or setattr(_,'__defaults__',([],)))[1]:lambda n:instance.__class__.__call__.fget.__defaults__[0](n,instance))})()
while _(3):
print('a')
while _(2):
print('b')
@golden finch :white_check_mark: Your eval job has completed with return code 0.
001 | a
002 | a
003 | a
004 | b
005 | b
lambda instance=lambda num? how is that allowed
parse it and it becomes clearer
it's basically just a whole lot of storing constants in default arguments
one of those constants is a function
and one of its defaults is a list
yeah, like that
(except it's marginally more complex, since it's in a property too)
Yeah... I tried to play spaghetti code here
the call chain goes something like:
honestly this might be hard to expand
lots of lambdas
good luck
the _:=_ and _=_: creates nice confusion
I like scoping my variables cryptically
mostly deobfuscated
can't really think of a way to deobfuscate that shortcircuit chain
and works on python too
yeah I messed up my deobfuscation somewhere
when two people from the cursed python channel fail to deobfuscate it you know it's good
could it be wrapper_descriptor doesn't have all those attributes, only property does? (why it would be accessing a property vs. wrapper_descriptor idk)
mhm?
would using __slots__ be a reason you'd see wrapper descriptors in a class dict
well, in this case, it's a bit more complicated, since __call__ is a property
however, that property's getter does return a callable
@sick hound :white_check_mark: Your eval job has completed with return code 0.
001 | a
002 | a
003 | a
004 | b
005 | b
@sick hound :white_check_mark: Your eval job has completed with return code 0.
001 | a
002 | a
003 | a
004 | b
005 | b
@sick hound :white_check_mark: Your eval job has completed with return code 0.
001 | a
002 | a
003 | a
004 | b
005 | b
006 | c
007 | c
008 | c
009 | c
010 | c
wow, this is impressively deobfuscated
huh, I didn't even know about that .clear() method
is it possible to hack something up such that a docstring would show up for a random module attribute in help()?
e.g.:
"""Search path for frozen fish bait"""
search_path = [".", "/usr/lib/python3.10"]
could monkeypatch pydoc. tokenize the source and add the attribute docstrings
think this is the one that would need to be changed https://github.com/python/cpython/blob/3.10/Lib/pydoc.py#L1749
https://github.com/python/cpython/blob/3.10/Lib/pydoc.py#L1199 something in this class probably
(help uses pydoc internally)
hmm 🤔
just to make sure I understand this... the way things can be "runtime documented" in general is because each kind of __doc__-carrying thing is special-cased? (like function, class, module)
like functions have a place to store doc, that the parser populates when it parses the function, and same story for module and class docstrings but the mechanics (how they are found during parsing) are slightly different
like tp_doc is a standard field of type objects... what if I were to add a ob_doc field 😂
yeah i think that's accurate. from what im seeing there are Doc.docmodule, Doc.docclass, Doc.docroutine, Doc.docdata and Doc.docother for misc cases
oh a docproperty too
oh, interesting
so I guess, if it has a descriptor, it could be documented, even if accessing gave you a non-'documented' thing
the pydoc code has lots of interesting logic, thanks for the tip
i don't quite follow
ok i did a bit of tracing and isolated module attribute documentation to here: https://github.com/python/cpython/blob/5618c81e139419b4665dc1f1e8a468738546f542/Lib/pydoc.py#L1276-L1280
Lib/pydoc.py lines 1276 to 1280
if data:
contents = []
for key, value in data:
contents.append(self.docother(value, key, name, maxlen=70))
result = result + self.section('DATA', '\n'.join(contents))```
unfortunately docother doesnt receive enough info to specialize with a subclass of TextDoc
so it currently seems the only option would be to rewrite docmodule entirely... :/
ok, consider sys.platform. if I do help(sys) I see:
addaudithook(hook) Adds a new audit hook callback. ... getswitchinterval() Return the current thread switch interval; see sys.setswitchinterval(). ... platform = 'linux' platlibdir = 'lib' prefix = '/usr' ps1 = '>>> ' ps2 = '... '
what I'm talking about is the fact that 'platform' cannot show documentation
Ah, that's a shame ..
... even though I think most would agree sys.platform deserves a real docstring (not just a mention in the module's docstring)
i think so
clearly this is not something normal people would think "needs to be solved"
but i've thought it would nicely enhance python's introspection capability
something strange in pydoc is the repeated use of string concat to build results instead of like... a stringio or a list + join later. backwards compatibility maybe?
why is there even a docother I wonder
yeah, like
contents.append(self.docother(value, key, name, maxlen=70))
result = result + self.section('DATA', '\n'.join(contents))
is a bit cargo-culty
point of docother seems to be miscellaneous cases where the only info retrieved is a name and value
so it doesnt mean it will have a docstring
it could, if you can somehow derive where to look for it from the arguments of docother. but it just seems to be... the name of the variable, some number i dont understand. maybe a counter? and the name of the module.
i wonder if that appending is for easier debugging, or maybe to trace where something got added to the output
guess it's time to inspect the stack to see if the previous call is docmodule lmao
assuming docother is used in other places than just module documentation
oh that's an interesting idea 🤔
docother (object, name: __class__=None, mod: __class__=None, *ignored)
why *ignored lol
stuff from the parent class signature thats not needed in the child class i guess
oh i didn't notice there's inheritance
fwiw, pycharm already picks up attribute docstrings if theyre below it
below, to distinguish from the module's own docstring
e.g. ```py
"""
is this the module's docstring or attribute's docstring?
"""
some_attr = 1
that's what's up
i think doc generators like sphinx probably do too
in docdata they do:
doc = getdoc(object) or ''
``` If object was a data ddescriptor, maybe it would have a `__doc__` but if it's just e.g. a string, that would turn up nothing
I wrote some functions to display this info, and my first few tries, every string attribute (like platform) would show the whole docstring for the str type 😂
lol nice
inspect.getdoc() can now find docstrings for member objects when __slots__ is a dictionary.
just noticed that commit message
esoteric random string generator to generate a string of length n?
well, i got this much to show up
@sick hound :white_check_mark: Your eval job has completed with return code 0.
001 | foo([{},None], 1)='{}, None'
002 | foo(['abc', 'def'], 'N')='ABC, DEF'
003 | foo([3, 8, 4], 0)=0
NAME
pydoc_test
DATA
test_variable = 1
this is a docstring
using ```py
import inspect
import sys
import pydoc
import pydoc_test
import re
attr_regex = re.compile(
r"^(\S*).=.(?:\r\n|\r|\n)"""\s?(.+)\s?"""",
re.MULTILINE
)
class CustomDoc(pydoc.TextDoc):
def docother(
self,
object,
name=None,
mod=None,
parent=None,
maxlen=None,
doc=None
):
result = super().docother(
object, name, mod,
parent, maxlen, doc,
)
if mod is not None:
module = sys.modules[mod]
try:
attribute_docstrings = getattr(
module,
'__attribute_docstrings__'
)
except AttributeError:
source = inspect.getsource(module)
attribute_docstrings = dict(attr_regex.findall(source))
setattr(
module,
'__attribute_docstrings__',
attribute_docstrings,
)
result += '\n' + self.indent(
attribute_docstrings.get(name)
)
return result
pydoc.text = CustomDoc()
help(pydoc_test)
and this is pydoc_test
test_variable = 1
"""this is a docstring"""
just needs some checks to make sure this docother doesnt mess other use cases up
that would be ideal yes
!e
class DocThing:
def __init__(self, doc):
self.__doc__ = doc
def __get__(self, *_): return self
def __set__(self, *_): return self
class Test:
platform=DocThing('The name of the current platform.')
__slots__ = {}
print(__import__("pydoc").render_doc(Test))
@rapid sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | Python Library Documentation: class Test in module __main__
002 |
003 | class TTeesstt(builtins.object)
004 | | Data descriptors defined here:
005 | |
006 | | ppllaattffoorrmm
007 | | The name of the current platform.
oh, forgot about overtype
i could not figure out how to get both the doc and an actual value to show. it's like they're mutually exclusive.
ohh thats georgeous
25if ?? that's allowed?
TIL no space needed between a number and the next thing that's not a number
oh, you solved it
solved is putting it kindly but it's a step somewhere 😛
pydoc, your intended purposes have been thwarted 😄
to think some languages claim "open for extension, closed for modification", not python
it's "open for whatever"
the next time the steering committee is looking for cool stuff to approve they should visit us imo
what's more pythonic
oh i forgot about this. unfortunate.
it was a while back tho
class CustomDoc(pydoc.TextDoc):
def docother(
self,
object,
name=None,
mod=None,
parent=None,
maxlen=None,
doc=None
):
result = super().docother(
object, name, mod,
parent, maxlen, doc,
)
if mod is not None:
module = sys.modules[mod]
try:
attribute_docstrings = getattr(
module,
'__attribute_docstrings__'
)
except AttributeError:
attribute_docstrings = dict()
source = inspect.getsource(module)
node = ast.parse(source)
for child, sibling in zip(node.body, node.body[1:]):
if (
isinstance(child, ast.Assign) and
len(child.targets) == 1 and
isinstance(child.targets[0], ast.Name) and
isinstance(sibling, ast.Expr) and
isinstance(sibling.value, ast.Constant) and
isinstance(sibling.value.value, str)
):
attribute_docstrings[
child.targets[0].id
] = textwrap.dedent(
sibling.value.value
).strip()
setattr(
module,
'__attribute_docstrings__',
attribute_docstrings,
)
result += '\n' + self.indent(
attribute_docstrings.get(name, "")
)
return result
improved with ast
very cool
__attribute_docstrings__ is where you document?
i bet we could even populate that dict from the ast
it was just to give much more weight to one type of match (type A is type B) than a compatible-but-not-same type, to get most specific match if possible
i guess what would also work would be to count the number of parameters that match exactly, amd consider all of those overloads first
this explains why a little:
https://overloading.readthedocs.io/en/latest/matching.html
others have had the same idea seems like 😁
The current solution is to fall back on the function definition order as a last resort: an earlier declaration takes precedence.
i don't think ours does that
Is it possible to "fake" a metaclass?
I'm working in Cython, and cython classes don't support metaclasses
Its not big deal, but I'd like to be able to get at least a bit of custom functionality on the class objects themselves
No biggie, but if there's some back door I don't know about
You guys would know
You don't need to fake it, you have access to the C-API, and so can directly change the type of a class. Note if the types are heap-allocated (Python types, or a mode in the C-API) you will have to incref/decref them.
from cpython.object cimport PyObject, PyTypeObject
(<PyObject *>some_obj).ob_type = <PyTypeObject *>SomeType
what is esoteric python
Spen, this is exactly what I was hoping for
this is really something, @sick hound . have you written languages (or at least type systems) before ?
*> is new to me though
it's a place where we show (or ask) how to do unusual things with python, or push its limits
or obfuscate code, or tweak bytecode, etc.
Yeah make fucking unreadable code
thx
got to learn something new today
if a normal person would say "why would you even want to do that?" or "You shouldn't do that!" it very well might go here
Or "no, no, please! Please no!"
yes "Please make it stop"
you learn a lot in here though
what they don't teach inpython classes 😂
I wish "Python" class was a thing
Some of the more forward thinking school might teach it a bit. Despite the fact that python is a mature, trusted general purpose language these days, most school regard it as a toy and don't teach it
Yeah I agree
I'm in year 9 but when I begin GCSE hopefully they will teach it in computer science
Give me an example
I hate and love looking at it
I saw a guy rig up a class which was its own metaclass
NO
(Or rather, camouflaged itself as such)
Fuck nah man
My school teaches C++, and I'm pretty unconvinced. C++ is a nightmare. And not like JavaScript — JavaScript has an excuse, it got blown way out of proportion and was never intended for widespread use
I like the unreadable code
Gonna play a bit of xbox then try make some code which is unreadable
Very unreadable
C++ suffers from having no rules and steering no Committee. So its deadly powerful but its library is self-inconsistent, ancient, poorly documented, etc
Hebrew font yellow on white text colour and a ton of unneeded code
Plus they've got way overboard with the syntax options. Anyway, </rant>
@potent comet so, this trick of yours is probably exactly what I'm after. I have to ask though, what are the caveats? What I want is to give my cdef class a metaclass. This class actually has no special rules in terms of object creation, funny enough, its more the other behaviours, like stringification, that I'd like to modulate
So I don't see any reason why, even though Cython prohibits it probably as a matter of best practice, a cython class can't have a metaclass
so inspect.get_signature includes both the argument names/counts/kinds, as well as the type hints?
Just, in theory, a simple metaclass which has very little impact on the function and is more a matter of presentation shouldn't do too much damage. But what's the rumb?
Here's an example:
Calculating the square root of 14, I think:
__=((()==[])+(()==[]));___=(__**__);____=((___<<___));_____=((____<<(__**__)));______=((_____<<(__**__)));
_________=((___<<_____));__________=((((___<<_____))<<(__**__)));_=((__**__)+(______<<(__**__)));_______=(__**__)
for ________ in range((_____+(_________<<(__**__))+(__________<<(__**__)))):
_______=_______-((_______**((___<<___))-_)/(((___<<___))*_______))
print(_______)
not written by me, but I would love if I had
makes you want to yell StopIteration
oh, that is the easy way out 🤣
Why are there so many underscored
Howd u do that
my guess is because underscore is not a letter, it makes the code look even less readable
oh I'm not the author, sadly
Ah
Still pretty weird ngl
Bloody hate crime python
Hating on normal programmers
"THATS NOT POSSIBLE"
yep
!e ```py
def foo(x, y, z):
return x + y + z
print(f'{foo(1,2,3)=}')```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
foo(1,2,3)=6
!e
What
guys my code does for I in range(100000):
Os.system('start'
And it opens the terminal a ton
But it does so very slowly
Is there a way for them to open faster?
And I wanna turn that solution into esoteric, unreadable and evil code
you need to use subprocess im pretty sure if you want to to not show terminals being opened
Idm them showing
I want them to open quicker
When I do open all those terminals
It opens like 1 every second but I need them to open like 10 times a second or faster
The caveats are only things that don't really apply - you wouldn't want to change the type to something which expects a different struct layout, etc. You'll also need to test how this behaves on PyPy and such, I don't know if this works properly.
Hehe
Pure madness
Well, in regular Python, you're allowed to assign to __class__, and it does checks to ensure the struct layout doesn't change. But the C API doesn't care.
By struct-layout, do you mean of the __class__, or of the object its attached to?
And if its the former, you're referring to if the new class has different methods (and such) from the old one
What new Array type?
I didn't know this had an Array type
I don't see it in the toc
I think that's just some example they have
It doesn't introduce a new class, it's about type checking, and letting you declare that a numpy array is 2x3x180 for instance, so type checkers can track that dimension through the methods to check if you do something incorrect.
is there a way to implement a while loop inside a lambda function?
ill take a look thanks
@steady lily or you can use [*iter(func, flag)]
another question: how can I open a file and read/write to it and close it within a lambda?
this is what I have so far: ```py
(lambda f: f.close())((lambda fp: open(fp))('data.json'))
(lambda fp: [(file := open(fp, "w")).write(...), file.close()])(...)```
i think this will work, didnt try tho
it does work thank you
check out the antialiasing on this one
I tried to remove the antialiasing but for the brighter colours it converted the antialiasing the wrong way
anyway, this version highlights the antialiasing
same filter, but showing the updated code on a differnt IDE
brb making this into an IDLE theme
it's probably orange cos i missed a 0
it's supposed to be red
antialiasing vs my deepfryer at maximum
how it runs in the terminal
the smart version of the deepfryer selectively deepfries
essentially, it makes text pink, red extremely red and blue extremely blue
black and white pictures, or non antialiased text are immune to this effect
green is ignored
Wow
Hi I have a small request to make, I have an assignment for tomorrow and this assignment is to program a machine that by entering a value in decimal will tell us what class this value is.If someone could help me in private message it would be very nice.
Thanks in advance
True can be used as the integer 1,
so if you do something like,
print(([]==[])+([]==[]))```
which is basically,
```py
print((True)+(True))```
will return 2
But like how is []=[] equal to true
Ah that makes more sense
i found your decorator also works for class methods
idk if that required special code
So any every time I've done a function that involves calling other functions/methods dynamically, there's always some adjustment to be made for @classmethod / @staticmethod.
curious if that's just my code or if it's something others have run into here as well?
when is DICT_UPDATE used? its kinda pointless when DICT_MERGE is a thing and this does raise an exception when duplicate keys are found unlike the first one
or am I getting something wrong? I would like to be corrected
@woven bridge :white_check_mark: Your eval job has completed with return code 0.
001 | 1 0 BUILD_MAP 0
002 | 2 LOAD_CONST 0 (1)
003 | 4 LOAD_CONST 0 (1)
004 | 6 BUILD_MAP 1
005 | 8 DICT_UPDATE 1
006 | 10 RETURN_VALUE
@sick hound
ohhh
makes sense
also is there like somewhere I can find a list of all op codes and their values
dis.opmap and dis.opname
lets gooo thanks
hey guys
how can i make this code more esoteric and unreadable
from threading import Thread
import os
def _function():
os.system('start')
for i in range(5):
Thread(target=_function).start()``` im thinking of using ```[]=[]``` and lambda stuff but i dont know how to do that
Could use a lambda for _function
lambda x: x+1 for example is a function that returns the inputted number plus one
Your lambda would just have to run os.system('start')
You can also use a comprehension instead of the for block
hey
rate my recursive lambda
collapseList = lambda l, n = None: (collapseList(l, j := []) and j) if n is None else ([collapseList(i, n) for i in l] if isinstance(l, list) else n.append(l))