#esoteric-python
1 messages ยท Page 148 of 1
such as data class
!e
from ctypes import py_object
x = "help"
py_object.from_address(id(x)).value = "me"
print(x)
@fair quartz :white_check_mark: Your eval job has completed with return code 0.
help
!e
from ctypes import py_object
x = 1000
py_object.from_address(id(x)).value = 3000
print(x)โ
@fair quartz :white_check_mark: Your eval job has completed with return code 0.
1000
!e
@lambda _: _()
class true:
def __new__(self):
return False
print(true is False)โ
@fair quartz :white_check_mark: Your eval job has completed with return code 0.
True
yes ofc
>>> def decorator(cls):
... print(cls)
... return 3
...
>>> @decorator
... class test:
... pass
...
<class '__main__.test'>
>>> test
3
>>>
What was the rationale for developing it like this? So what method of type is being called when I do type(some_class)?
same method
there's a check in the same function before that snippet
wait so how does type(some_class) return type?
so the check is for one-argument no-keyword type() call https://github.com/python/cpython/blob/main/Objects/typeobject.c#L1075-L1096 ```py
if cls is type:
nargs = len(args)
if nargs == 1 and not kwargs:
return args[0].class # basically getting .ob_type which is equivalent to ctypes.py_object.from_address(id(args[0])+8).value
if nargs != 3:
raise TypeError("type() takes 1 or 3 arguments")
see above
so when I go type(cls) is type.__call__ being invoked?
I can't read this very well I'm afraid
I know a fair bit of C but the internals of python are complex
if type=&PyType_Type - what does this bit do?
if cls is type: where type in the internal function would be replaced with cls to avoid name collisions
basically check against the builtin type class
type.__call__(type) is the funny one really, since both type(type) and type() are correct interpretations of it
yes
any time you call a class, you do type.__call__
so the if (type == &PyType_Type) { is checking if...?
if the first argument is type
oh right, because self is type
wait
!e ```py
def type_call(cls, *args, **kwargs):
if cls is type:
nargs = len(args)
if nargs == 1 and not kwargs:
return args[0].class
if nargs != 3:
raise TypeError("type() takes 1 or 3 arguments")
if cls.new is None:
raise TypeError(f"cannot create '{cls.name}' instances")
obj = cls.new(*args, **kwargs)
if not isinstance(obj, cls):
return obj
if cls.init is not None:
cls.init(obj, *args, **kwargs)
return obj
print(type_call(type, 5)) # type(5)
print(type_call(int, int, 3.3)) # int(3.3)
type_call(type) # type()
@quartz wave :x: Your eval job has completed with return code 1.
001 | <class 'int'>
002 | 3
003 | Traceback (most recent call last):
004 | File "<string>", line 19, in <module>
005 | File "<string>", line 7, in type_call
006 | TypeError: type() takes 1 or 3 arguments
what's wrong with non-type classes ๐ค
oh wait
i'm dumb
!e ```py
def type_call(cls, *args, **kwargs):
if cls is type:
nargs = len(args)
if nargs == 1 and not kwargs:
return args[0].class
if nargs != 3:
raise TypeError("type() takes 1 or 3 arguments")
if cls.new is None:
raise TypeError(f"cannot create '{cls.name}' instances")
obj = cls.new(cls, *args, **kwargs)
if not isinstance(obj, cls):
return obj
if cls.init is not None:
cls.init(obj, *args, **kwargs)
return obj
print(type_call(type, 5)) # type(5)
print(type_call(int, 3.3)) # int(3.3)
type_call(type) # type()
@quartz wave :x: Your eval job has completed with return code 1.
001 | <class 'int'>
002 | 3
003 | Traceback (most recent call last):
004 | File "<string>", line 19, in <module>
005 | File "<string>", line 7, in type_call
006 | TypeError: type() takes 1 or 3 arguments
@golden finch here's a theoretically full replication of type.__call__
thank you
How could I use inspect to get the source of a whole module? (esoteric purposes)
at that point wouldn't you just read from the file to do it
also packages
what about the program it's running from? (side note: you seem familiar, are you from esolangs?)
that was quite offensive code
variable names were dubious
but perhaps a discord server is not the appropriate place fo this discussion
given the typical climate thereof
how do i make them actually useful tho
!e
def decorator(_class):
_class.hello = 10
return _class()
@decorator
class lol:
...
print(lol.hello)
@wheat river :white_check_mark: Your eval job has completed with return code 0.
10
!e
def singleton(cls):
instances = {}
def wrapper(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
@singleton
class Foo:
def func(self):
return 10
a = Foo()
b = Foo()
print(a is b)
@wheat river :white_check_mark: Your eval job has completed with return code 0.
True
!e why not just ```py
class singleton:
instance = None
def __new__(cls, *args, **kwargs):
if cls.instance is not None:
return cls.instance
cls.instance = super().__new__(cls, *args, **kwargs)
return cls.instance
a = singleton()
b = singleton()
print(a is b)
@pastel sparrow :white_check_mark: Your eval job has completed with return code 0.
True
okay there
they wanted class decorators ๐คทโโ๏ธ
eh
.
A nice toolbox for all* of your esoteric needs!
*some
import sys
import ctypes
def swap(a: object, b: object) -> None:
assert sys.getsizeof(a) == sys.getsizeof(b)
n = sys.getsizeof(a)
A = (ctypes.c_byte * n).from_address(id(a))
B = (ctypes.c_byte * n).from_address(id(b))
for i in range(n):
A[i], B[i] = B[i], A[i]
def replace(to_replace: object, replace_with: object, allow_diff_size: bool = False) -> None:
n = min(sys.getsizeof(to_replace), sys.getsizeof(replace_with))
if not allow_diff_size:
assert sys.getsizeof(to_replace) == sys.getsizeof(replace_with)
OLD = (ctypes.c_byte * n).from_address(id(to_replace))
NEW = (ctypes.c_byte * n).from_address(id(replace_with))
for i in range(n):
OLD[i] = NEW[i]
๐ ๐ ๐
divisors = lambda n: len([i for i in range(1, n + 1) if n%i==0])```
divisors=lambda n:sum(n%i==0for i in range(1,n+1))
wait what-
!e py divisors=lambda n:sum(n%i==0 for i in range(1,n+1)) print(divisors(123))
@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.
4
close
def digitize(n): return [int(i) for i in reversed(str(n))]```
n%i==0 is truthy when i is a factor, and booleans are essentially 1 and 0, so taking the sum over them essentially counts the number of n%i==0
so we have a list of true and false vals
and the false values are 0
so the sum cant add it
and the true ones are 1
yes
digitize=lambda n:[*map(int,str(n)[::-1])]
def min_value(digits): return int(''.join(sorted((set(map(str, digits))))))```
whats the :: mean
it's like string slicing
most commonly you see [start:stop]
but there's also [start:stop:step]
ohhh
start and stop by default are "everything", so [:] just takes everything, but [::-1] takes everything with a step of -1, ie reversed
ic ic
def powers_of_two(n): return [1, *[2**i for i in range(1, n+1)]]```
[2**i for i in range(n+1)]
overthinking is great
.bm
sys.getsizeof is rarely correct FYI
It adds in the overhead from the garbage collector, and whatever type(obj).__sizeof__(obj)returns
huh
I don't know anything about the former, but isn't adding the latter correct?
since different types can have different object sizes and all
Think about lists
>>> a = 4
>>> b = 5
>>> swap(a, b)
>>> a
5
>>> b
5
``` doesn't work for cached integers?
2 lists of different size have the same size in memory directly, but their backing arrays are different sizes
huh, weird, hold on
So list sizeof adds in the size of the backing array
Despite that array not being directly after the original object in memory
Yea all of the sizeof functions are more for memory profiling
well, I could manually calculate the size via ctypes The Right Way
by looking at the type, and reading the size from its header
sounds like work though
You can also use a combo of basic size and item size
But it would be tricky, and you would need to know the underlying semantics for each type
PyListObject has that allocated field
(Not even accounting for the fact that this would severely break the cycle garbage collector)
I did swap(a,b), then tried to show 4 and interpreter crashed
so seems to me like it works alright ๐ฅด
List sizeof uses allocated I think
ok
It's prob failing because the ints from range get replaced as it iterates
I can do something fancy like, uhh
You could call memcpy directly but you'd still have the sizeof problem
got it
def swap(a: object, b: object) -> None:
assert sys.getsizeof(a) == sys.getsizeof(b)
n = sys.getsizeof(a)
A = (ctypes.c_byte * n).from_address(id(a))
B = (ctypes.c_byte * n).from_address(id(b))
temp = (ctypes.c_byte*n)()
ctypes.memmove(ctypes.byref(temp), A, n)
ctypes.memmove(A, B, n)
ctypes.memmove(B, ctypes.byref(temp), n)
4,5 still crashes interpreter, 20,25 works fine
>>> a = 4
>>> b = 5
>>> swap(a, b)
>>> a
5
>>> b
4
``` works for me
@hard spoke an improvement to replace: ```py
def replace(to_replace: object, replace_with: object, allow_diff_size: bool = False) -> None:
size_OLD = sys.getsizeof(to_replace)
size_NEW = sys.getsizeof(replace_with)
if not allow_diff_size:
assert size_OLD == size_NEW
elif size_OLD < size_NEW:
res = PyObject_Realloc(id(to_replace), size_NEW)
if res == 0:
raise MemoryError
ctypes.c_void_p.from_address(id(to_replace)).value = res
OLD = (ctypes.c_byte * size_NEW).from_address(id(to_replace))
NEW = (ctypes.c_byte * size_NEW).from_address(id(replace_with))
ctypes.memmove(OLD, NEW, size_NEW)
huh, PyObject_Realloc is inplace?
without that line: ```py
a = 404
b = 'haha'
replace(a, b, True)
Exception ignored deletion of interned string failed:
Traceback (most recent call last):
File "<stdin>", line 12, in replace
KeyError: 'haha'
<segfault right after executing another line/exiting the interpreter>
with that line: ```py
>>> a = 404
>>> b = 'haha'
>>> replace(a, b, True)
>>> a
'haha'
>>> b
'haha'
PyObject_Realloc is not guaranteed to be in place
It does need a pointer to the address of the object, not the address of the object
And it returns the address of the new memory
(And afaik, if it needs to reallocate a new address it invalidates the old one)
well if the above code works then it works
just one problem ```py
a = 'haha'
replace(a, 3, True)
a
3
a is 3
<stdin>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
False
also another problem ```py
a = 3
replace(a, (), True)
segfault
Ie: the realloc problem
well this time size_OLD >= size_NEW
so it's not from realloc
3 is interned tho so it's gonna do numerical operations without checking
Hard to know the issue without the trace back too
hmm yeah
>>> replace(a, (), True)
Debug memory block at address p=00007FFC8C3E4368: API ''
72057594037927936 bytes originally requested
The 7 pad bytes at p-7 are not all FORBIDDENBYTE (0xfd):
at p-7: 0x00 *** OUCH
at p-6: 0x00 *** OUCH
at p-5: 0x00 *** OUCH
at p-4: 0x00 *** OUCH
at p-3: 0x00 *** OUCH
at p-2: 0x00 *** OUCH
at p-1: 0x00 *** OUCH
Because memory is corrupted at the start, the count of bytes requested
may be bogus, and checking the trailing pad bytes may segfault.
The 8 pad bytes at tail=01007FFC8C3E4368 are Windows fatal exception: access violation
Current thread 0x000014cc (most recent call first):
File "<stdin>", line 7 in replace
File "<stdin>", line 1 in <module>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in replace
OSError: exception: access violation reading 0xFFFFFFFFFFFFFFFF
py -X dev
Oh I meant like building python with debug symbols and running it in a debugger like lldb
That's how I normally diagnose stuff
ok
You are still calling Realloc with just the address of the object, not a pointer to the address of the object
@quartz wave ^
Try wrapping id(obj) with c_void_p
So it's c_void_p(id(obj))
>>> x = (1,2,3)
>>> y = "hello world"
>>> replace(x, y, True)
>>> x
'hello world'
>>> y
(1, 2, 3)
>>> ```
^ with the fix
import ctypes
import sys
def replace(to_replace: object, replace_with: object, allow_diff_size: bool = False) -> None:
size_OLD = sys.getsizeof(to_replace)
size_NEW = sys.getsizeof(replace_with)
if not allow_diff_size:
assert size_OLD == size_NEW
elif size_OLD < size_NEW:
res = ctypes.pythonapi.PyObject_Realloc(ctypes.c_void_p(id(to_replace)), size_NEW)
if res == 0:
raise MemoryError
OLD = (ctypes.c_byte * size_NEW).from_address(id(to_replace))
temp = (ctypes.c_byte * size_NEW).from_buffer_copy(OLD)
NEW = (ctypes.c_byte * size_NEW).from_address(id(replace_with))
ctypes.memmove(OLD, NEW, size_NEW)
ctypes.memmove(NEW, temp, size_NEW)
still will crash on exit due to massive memory corruption
that's for swap not for replace
also the exact thing i'm trying to fix is replacing a cached integer with the cached empty tuple
G'day, eso people
This is probably impossible, but if it's possible, how could you extract comments from within a function or within the global scope? Not docstrings, comments
how do i do it with mingw-w64 gdb because it does this ```py
Python path configuration:
PYTHONHOME = 'C:\mingw64\bin..\opt'
PYTHONPATH = (not set)
program name = 'C:\Program Files\Python311\python.exe'
isolated = 0
environment = 1
user site = 1
import site = 1
is in build tree = 0
stdlib dir = 'C:\mingw64\opt\Lib'
sys._base_executable = 'C:\Program Files\Python311\python.exe'
sys.base_prefix = 'C:\mingw64\bin\..\opt'
sys.base_exec_prefix = 'C:\mingw64\bin\..\opt'
sys.platlibdir = 'DLLs'
sys.executable = 'C:\Program Files\Python311\python.exe'
sys.prefix = 'C:\mingw64\bin\..\opt'
sys.exec_prefix = 'C:\mingw64\bin\..\opt'
sys.path = [
'C:\Program Files\Python311\python311.zip',
'C:\mingw64\opt\Lib',
'C:\mingw64\opt\DLLs',
]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'
yes it's impossible
So it's not 'esoteric-possible', just straight-up nope
>>> def foo():
... exec('a = 10')
... print(locals())
... print(a)
...
>>> foo()
{'a': 10}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in foo
NameError: name 'a' is not defined
huh? why? is it looking for a in the global scope?
yes
can't find a definition of a anywhere in the function so it looks for it in the global scope
i c
you can't even do it with a parsed output
>>> from ast import dump, parse
>>> dump(parse("#oh hi"))
'Module(body=[], type_ignores=[])'
you can with a tokenized one though ```py
from tokenize import generate_tokens
[*generate_tokens(iter(["#oh hi"]).next)]
[TokenInfo(type=61 (COMMENT), string='#oh hi', start=(1, 0), end=(1, 6), line='#oh hi'), TokenInfo(type=62 (NL), string='', start=(1, 6), end=(1, 6), line='#oh hi'), TokenInfo(type=0 (ENDMARKER), string='', start=(2, 0), end=(2, 0), line='')]
strings?
I mean, can you have
def f(x):
#comment
...
#code here that extracts the string 'comment', given f as argument
no
can't do it for a parser result and much less for bytecode
so not even by getting the filename and directly reading the file to find the definition of f?
yeah you can do that actually
is generate_tokens() made in python? or is it C like print()
id like to look at the source code of it
!e ```py
from inspect import getsource
from tokenize import generate_tokens, _tokenize
print(getsource(generate_tokens))
print(getsource(_tokenize))
u didnt print
@quartz wave :white_check_mark: Your eval job has completed with return code 0.
001 | def generate_tokens(readline):
002 | """Tokenize a source reading Python code as unicode strings.
003 |
004 | This has the same API as tokenize(), except that it expects the *readline*
005 | callable to return str objects instead of bytes.
006 | """
007 | return _tokenize(readline, None)
008 |
009 | def _tokenize(readline, encoding):
010 | lnum = parenlev = continued = 0
011 | numchars = '0123456789'
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/itusemiriv.txt?noredirect
thats literally unreadable to me ๐ whoever made that is a genius
also regex patterns ๐ค
Whitespace = r'[ \f\t]*'
Comment = r'#[^\r\n]*'
Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment)
Name = r'\w+'
Hexnumber = r'0[xX](?:_?[0-9a-fA-F])+'
Binnumber = r'0[bB](?:_?[01])+'
Octnumber = r'0[oO](?:_?[0-7])+'
Decnumber = r'(?:0(?:_?0)*|[1-9](?:_?[0-9])*)'
Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber)
Exponent = r'[eE][-+]?[0-9](?:_?[0-9])*'
Pointfloat = group(r'[0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?',
r'\.[0-9](?:_?[0-9])*') + maybe(Exponent)
Expfloat = r'[0-9](?:_?[0-9])*' + Exponent
Floatnumber = group(Pointfloat, Expfloat)
Imagnumber = group(r'[0-9](?:_?[0-9])*[jJ]', Floatnumber + r'[jJ]')
Number = group(Imagnumber, Floatnumber, Intnumber)
what is tokenize? i was scrolled up ๐
!e print(dir())
@sick hound :white_check_mark: Your eval job has completed with return code 0.
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
!e print(chr(abs(len(dir(reversed))-131))+chr(abs(len(dir(vars))-134)))
@sick hound :white_check_mark: Your eval job has completed with return code 0.
hi
!e
import builtins
from pprint import pprint
pprint(sorted(dir(builtins), reverse=True, key=lambda x: len(dir(eval(x)))))
@wheat river :white_check_mark: Your eval job has completed with return code 0.
001 | ['bytearray',
002 | '__name__',
003 | 'str',
004 | 'bytes',
005 | 'False',
006 | 'True',
007 | '__debug__',
008 | 'bool',
009 | 'int',
010 | 'float',
011 | 'set',
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/xuwedegubi.txt?noredirect
bytearray wow
what
@wheat river :white_check_mark: Your eval job has completed with return code 0.
87
!e print(len(dir(object)))
@sick hound :white_check_mark: Your eval job has completed with return code 0.
23
and i thought classes with over 20 methods is a lot lmao
23 includes all the preimplemented dunders and mro-related attributes etc
is this the peak of fizzbuzz or is there something more we can do with this?
for i in range(100):print(i%3//2*'Fizz'+i%5//4*'Buzz'or-~i)
it's as good as it gets
if there was anything better someone in CGCC would have posted it
CGCC?
and here is the relevant links for python on the fizzbuzz question
Python 3:https://codegolf.stackexchange.com/questions/58615/1-2-fizz-4-buzz/233121#233121
Python 2:https://codegolf.stackexchange.com/questions/58615/1-2-fizz-4-buzz/58623#58623
ah this
any way of making .replace shorter?
(
guess_word_game := lambda word: (
guessed_word := ["_" for _ in word],
letter_list := list(word.lower()),
correct := set(),
wrong := set(),
print(f"We are searching for a word with {len(letter_list)} characters"),
tries := 0,
(lambda a: lambda: a(a))(
lambda f: (
tries := len(correct) + len(wrong),
letter := input("Letter: ").lower(),
(
(
(
(guessed_word.__setitem__(i, letter), correct.add(letter))
if letter == c
else ()
),
(wrong.add(letter) if letter not in letter_list else ()),
)
for i, c in enumerate(letter_list)
),
print("".join(guessed_word)),
f(f) if guessed_word != letter_list else (),
)
)(),
print(f"End! Correct: {set(correct)} ({len(correct)})"),
print(f"Wrong: {set(wrong)} {len(wrong)} | Total tries {tries}"),
),
guess_word_game("Oneliner-Challenge"),
)
# def guess_word_game(word: str):
# guessed_word = ["_" for _ in word]
# letter_list = list(word.lower())
# correct = set()
# wrong = set()
# print(f"We are searching for a word with {len(letter_list)} characters")
# while guessed_word != letter_list:
# tries = len(correct) + len(wrong)
# letter = input("Letter: ").lower()
# for i, c in enumerate(letter_list):
# if letter == c:
# guessed_word[i] = letter
# correct.add(letter)
# if letter not in letter_list:
# wrong.add(letter)
# print("".join(guessed_word))
# else:
# print(f"End! Correct: {set(correct)} ({len(correct)})")
# print(f"Wrong: {set(wrong)} {len(wrong)} | Total tries {tries}")
# guess_word_game("Oneliner-Challenge")
im clueless as to how i can modify tries or anything, nothing is propegating out of the function
x:x.replace("Green","G").replace("Red","R").replace("Blue","B").replace("Dark","D").replace("Light","L").replace("Medium","M").replace("White","W").replace("Grey","Y").replace("Gray","Y").replace("Turquoise","T")```
use a dict
issue is same as
x = 0
def set_x():
x = 1
print(x)
set_x() # 1
print(x) # 0
pls provide example my good friend ryuga
you could use a dict as ryuga said (making sure not to rebind the name of the dict, only changing its keys), or you could return tries from the function and set tries to the result
i could use locals() actually
actually u dont need to, hold up
you can use an unbounded list comp to implement the while loops in the same scope without recursion
>>> (x:=[1])and[x.append(1)or(y:=len(x)) for _ in x if input() != 'end']
1
2
3
end
[2, 3, 4]
>>> y
4
>>> ```
iterate over a list with one item in it, and add an item if you don't want to exit the loop yet
f = lambda:(x:=[1])and[x.append(1)or(y:=len(x)) for _ in x if input() != 'end']and y
``` example in a lambda
!e
string = 'hello Red Green world'
list_of_words = ['Red', 'Green']
[string:=string.replace(word, word[0]) for word in list_of_words]
print(string)
@wheat river :white_check_mark: Your eval job has completed with return code 0.
hello R G world
@languid hare ^
neat
thank you ryuga you always got us when we need you
guise what exactly is time complexity and how to lower it
was just helping someone in a help channel and figured that this problem seemed pretty apt for golfing. i have no clue how to describe what it's supposed to do so here's some examples
"AaBb" -> ["AB", "Ab", "aB", "ab"]
"AaBbCc" -> ["ABC", "ABc", "AbC", "Abc", "aBC", "aBc", "abC", "abc"]
here was my attempt at golfing a solution: ```py
f=lambda i:["".join(a[int(c)]for a,c in zip([i[x:x+2]for x in range(0,len(i),2)],bin(j)[2:].zfill(len(i)//2)))for j in range(2**(len(i)//2))]
oh dear-
is this a kata or smth-
!e ```py
import itertools
f=lambda s:[''.join(p) for p in itertools.product(*(s[i:i+2] for i in range(0,len(s),2)))]
print(f('AaBbCc'))
@rose beacon :white_check_mark: Your eval job has completed with return code 0.
['ABC', 'ABc', 'AbC', 'Abc', 'aBC', 'aBc', 'abC', 'abc']
f=lambda s:[''.join(s[2*a+i//2**a%2]for a in range(len(s)//2))for i in range(2**(len(s)//2))]
:incoming_envelope: :ok_hand: applied mute to @smoky sleet until <t:1651795717:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
2**a%2?
shouldn't that always produce 0?
oh
2*a + (i//2**a % 2)
Yeah, somehow it gets parsed correctly without brackets
operator precedence
Almost 9k line Python file here and still trying to unpack some long lines https://github.com/TechnoTanuki/Python_BMP/tree/main/Python_BMP
tysm i had no idea how decorators work but now i know
yup, my confidence is now back down to healthy levels after viewing this channels posts, works great when you're overconfident
you could shorten that to ```py
f=lambda s:[''.join(s[2*a+(i>>a&1)]for a in range(len(s)//2))for i in range(1<<len(s)//2)]
what is that supposed to do?
@unreal echo answer to this question
whats golfing-
Trying to tackle a problem in the least amount of characters possible
ah
write a function that prints some message without actually writing the message
maybe even write a generator that generates obfuscated python code to print messages
!e
def foo():
import __hello__
foo()```
@wheat river :white_check_mark: Your eval job has completed with return code 0.
Hello world!
lol
!e py import this
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | The Zen of Python, by Tim Peters
002 |
003 | Beautiful is better than ugly.
004 | Explicit is better than implicit.
005 | Simple is better than complex.
006 | Complex is better than complicated.
007 | Flat is better than nested.
008 | Sparse is better than dense.
009 | Readability counts.
010 | Special cases aren't special enough to break the rules.
011 | Although practicality beats purity.
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/pajolosuxo.txt?noredirect
I don't fully remember, but is there anyway to modify the variables of a closure?
def a():
var = None
def b():
return var
return b
func = a()
What can I do with func() to get access to var?
doesn't func() call b which returns var to you?
oh modify the var. if you want to change what it refers to, there's no way short of messing with cpython internals via ctypes
Okay, thanks! Good ๐
!e ```py
def a():
var = None
def b():
return var
return b
func = a()
func.closure[0].cell_contents = 'hacked'
print(func())```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
hacked
closures are stored in a tuple on the function object
Thank you
I have to decide between closures, or mocks. Do you think closures are safer against tampering?
Either work
wwwwwwoah
Has anyone managed to get the concept of returning early (for/while loops) in lambdas
I'm stuck on this, tried unittest assertRaises and assertTrue to propagate out but variable scopes as it's inside the function for assertRaises fucked me
Maybe I can use it like a ctx manager
If that even works
Anyway I can use semicolons in sets?
true=True;
class console:
def log(self, value):
print(value)
while (true):{
console.log('hmm');
}
``` Tryin to do a cursed loop.
I don't think that's possible, "sadly"
(short of the usual transformative solutions like an import hook or a codec)
U+037E (GREEK QUESTION MARK), the only lookalike I can think of, is not a letter, otherwise you could do console.log('hmm').อพ
good idea, thanks!
It used to be possible to use yield to bail early, but now in order to do early returns you need to restructure your code flow to end the loop naturally early.
#esoteric-python message this is an example of while loops in a lambda (it works by extending a list as you iterate over it)
You can do something similar to end a for loop early ( by clearing the list early inside the loop )
For while loops that work like the above example, you can just skip the extend call
just use a comma
like this
u back now?
u can if u edit ctypes
Nao 9.5 K lines had to revert a few changes lmao breaking up code golfs with \ broke stuff strangely https://github.com/TechnoTanuki/Python_BMP/blob/main/Python_BMP/BITMAPlib.py
even with ctypes it is near impossible to modify syntax because parsing happens before execution. The only way that would moderately work would be like this ```py
code to enable new syntax
import module_with_new_syntax
__init__.py would work right?
if u do it there
the code to modify syntax would need to run before the altered syntax code is even parsed
so ```py
import code_that_changes_syntax
custom::code
So apparently the Python discord bot's eval has os.fork() which means you can spawn multiple processes from !eval. Unfortunately there are no temp files/named pipes as far as I'm aware so I came up with a hacky solution to get IPC: use POSIX signals (like from kill) to send bits from the child process to the parent process.
#bot-commands message
^ this spawns a child process, which then converts "Hello world!" to a stream of bits, and sends them to the parent as SIGUSR1 for 0 and SIGUSR2 for 1. Since POSIX signals are not ordered, the two processes do a little handshake where the parent acknowledges each bit, allowing the child to send the next bit.
I saw this
I was staring at it for a good 10 seconds as it looked like something that should be here
I'm very pleased with this hack
You could legit use it to do a parallel foreach/map, a la multiprocessing
I actually thought i was in esoteric python when i saw you eval it
!e
from lzma import decompress
from base64 import b64decode
c = """
/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AX/AixdADSbSme4Ujxz7TRXz/YuKYOoy6/+/qHJAf2Y
kZ+Tei44AMHe4K+pz733TFmzsTIcdIqSdrob3TqE6OQHmnicrKa0QXNEizjJI/dNNnU2VNgwoWus
bXAA0X9/Q9EDTGrHdCkznHbeu0AsJu136ugjEkcNnrPmMNmHQOsQSPVO6TEy4YVgFrJ63u9WghA+
DB3TpncfiQrGsBZhvi2/lFJOu+igl0404PDRkZtYDLVlWnMR+OFB8QYmA3DaqlWwAY8qPJIp3Dw0
adov/THThzICPCwTqzWaYizZnIAjiUYg5wubfXU9djlAHmMOEUfSWJtDsnang2WonnaLyZ039KSs
RGtFSRWRMDOtP2e4KfJvrRDAcgYZs9WW+Lpxuwx8lGMqVCdjeghIkF1tv5TAgQa3NVOSTxx1k6PC
ny/ZMJdrmhOsu+f8GAS99EV9PJq3UL5a78BLQlZ709srdnV0CPvv9YtLetC+iVY+F/B/YEodB7kj
x9opLF3qTp/VG9TFEEoCpc5b+x41rAz3i5PrqHF4v32mlaWU91O6BFXPwWXtWh0UAMTdnPDaUPpO
nkVW+vO61CQkVdLyuifR70ep0PGRDZJ4/kwcKRInlawkQ2C+Ag6A8RAFp12WkpecN2HpuTCcvyV0
zarwW/9iYM4g3cqpDCOSoqwkvB+edZDZAi4iNG25xnKS9dI5YBgt32zaRBiN6LlPK6XAt55TxYvB
UOMQryWj2qlJA10gfIMUtQAAw9BOqH1bJoMAAcgEgAwAAJuhLS+xxGf7AgAAAAAEWVo=
"""
exec(decompress(b64decode(c)).decode())
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
Hello, world!๏ฟฝ
What in the fuck
My understanding of python is having a stroke
I just took the python from the other channel and compressed it -- this code decompresses it and then runs it haha
How about the code you compressed
How much do you know about signals in Unix/Linux?
Have you written a signal handler?
Literally nothing
No
Hmm, so this is a way that processes can communicate each other that something has happened or changed. e.g. kill process just sends the SIGTERM signal. The default behavior for programs is to exit when they get that
Basically the kill() system call lets a process send a limited range of signals to another process https://man7.org/linux/man-pages/man7/signal.7.html
The two I use are SIGUSR1 and SIGUSR2 which are basically general purpose
Since these are asynchronous, you basically register a callback to handle each signal. When the kernel runs process again (say it's in the sleep part of the loop in my code) it will trigger the signal handlers in some order
These lines register the handler logic to both SIGUSR1 and SIGUSR2:
signal.signal(signal.SIGUSR1, handler)
signal.signal(signal.SIGUSR2, handler)
I do that before the call to os.fork() because after that, I don't know what order the code is going to run in (e.g. the child could finish and send its result before the parent has its handler registered)
Here's the proof. A monte carlo estimation of pi with one worker:
!e
import random
NUM_WORKERS=4
NUM_ITERATIONS=5000000
result = 0
for i in range(NUM_WORKERS * NUM_ITERATIONS):
x, y = random.random(), random.random()
if x * x + y * y < 1:
result += 1
print(f"pi = {4 * result / (NUM_WORKERS * NUM_ITERATIONS)}")
@verbal talon :warning: Your eval job timed out or ran out of memory.
[No output]
With four worker processes:
can you access a lambda within itself?
!e
from lzma import decompress
from base64 import b64decode
NUM_WORKERS=4
NUM_ITERATIONS=5000000
c = """
/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AtFBAFdADSbSme4Ujxz7TRXz/YuKYOoy6/+/qHJAf2Y
kaj5JrjpXHFk4VJJibh/QOHdouojmx1aK6zmJRS7b+EpB6qvEJ1G+Hy8HiQsVmGnx7C23YXKDeyL
X5YCU0I5Y323MFysA/os8HhUtcNjdHjKuvMVtNyNWUl8TOoxr3mrHUwul2kq+WmRIwxPWQAb4R/O
2X6CGHfKp4WbdRxY2jAWrcwbGsJSgLYzdskDM+e69b/p7Fm2puCipScVM+ncbZncUAu4gWuaq3Ez
ipu9VdHQgGin9PPPMBMRfJU4wgN/p6UJpA9iwdxhZp62MQRkYX3Zdh8gtYwS8iMbJ9EwIdAkppul
7cF3LS+j0RIUJQYYSVwa0ddq7XuWux7myKphLqIbWNW9MNkle8ZomHvIcCa2QsZJmj9FASkF/HKm
eOUlUXZRQq5lSlyoSURpB5Xp/4K0+RcbJ+sQyoLhFencaVcBnMbny3LFuSxKoSJ3PrJNh9Avn+yI
HrCYEy1FPsCRi8l/TWKdzkblOwYgTzgR8piLzuewdM3v97zf2jFTNjAI8iuCZRkMQlflbzD8c6LR
WUOOnRYb9u/PaBW1W0F48VuZ9pVKM6sJbX1fB58IClxqx0ob/C8ugtNmbiqqqpINzpITRlMnhemo
7h1pJtFjgR/k13O705ClamLwPNLxObFWv0BuwQyetFO53ujzCWDPZfDvQoq3X5fMGKTkYZ5++S2F
VB7vCBXjxvW6B1teasm12ljGUu4S9GQAk0KA/g6zrBSPd2eRaDOYRRjeeMw08e/sJfMAYImACGGA
nWi32+Zk5yudIF1HXJYQ3ul2AHudqEs0ongOS4SnZggwG06v4eIzNTt3LNVLdll2/mAhLr359GKy
f4Te6RhHoYNBFaALO/5e9h6HL9cemawAL310syEpcRSeqs6zCNdmrmUaIuFJ2YPNrI15ZSRromXF
SOUIq1NfBw/ra+etxzwlCM76BEyd6WnoXiVwodYANH3hBUgY56LMti6dWG70EGXtiAfqw1LIEC0I
pLzjtuQ9d/ok1U1xPKLXPbjUyObdok0DU3yeQ5FGvLy0Z7YKFdSgl9sIzR3cxB9PRVnZk3DIOtA7
/DYg67V4NOoh8q9wGpgcttfhOJ5ZfLu7dMLk3e8dztorijQMUv9QEYLsFVr6GRvC7oZu4qaChTFp
iO71fR9VFn3nUQdB8lvSMCHr9tuai4Vjodp7MZR+aswUsEmEgWk2ZKMTZwklNyCW3+RsGNAM5NWh
uXVdlzQ6zSBGMM08po8Q2LAhkkhZhXspQgC7IqUDQBzyslgmWAaKEn9S0BI73NKFNUaaKooF8bx3
oUQo5RNYcMxXqUfSdQ8DbtVXUT8LYdnRCY6RuE8LAAAAAPJuudUoMDr0AAGdCMYWAACZ9FAZscRn
+wIAAAAABFla
"""
exec(decompress(b64decode(c)).decode())
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
Num processes: 4, total iterations: 20000000, pi ~= 3.14113
lambda:__import__('sys')._getframe().f_code
wait what
you can just do that
Is there a way to do that without imports?
Hmm, could you pass the lambda to itself?
def fix(f):
return f(f)
fix(lambda f: f(f))
You could, but that's cheating
!e ```py
f=lambda:f.code.co_code
print(f())
import dis
print(dis.dis(f))
@severe canyon :white_check_mark: Your eval job has completed with return code 0.
001 | b't\x00j\x01j\x02S\x00'
002 | 1 0 LOAD_GLOBAL 0 (f)
003 | 2 LOAD_ATTR 1 (__code__)
004 | 4 LOAD_ATTR 2 (co_code)
005 | 6 RETURN_VALUE
006 | None
along the lines of this?
Using a fixpoint combinator yes
A what?
fib_lambda=lambda n,cache={0:0,1:1}:(f:=type(lambda:0)(__import__('sys')._getframe().f_code,globals()),a:=cache[n-1] if n-1 in cache else f(n-1,cache),b:=cache[n-2] if n-2 in cache else f(n-2,cache),cache.__setitem__(n,a+b),a+b)[-1]
I made this PoC
yes?
I have just been immensely outgolfed in the esolangs server
I was not aware of the ฮฉ combinator
fact = lambda n: n*fact(n-1) if n > 1 else 1```
fact = lambda self, n: n*self(self, n-1) if n > 1 else 1```
a = fact
fact = lambda n: a(a, n)
f=lambda n:n<2or n*f(n-1)
``` immensely golfed
that'll throw a NameError or an UnboundLocalError
Nao moar than 10k lines https://github.com/TechnoTanuki/Python_BMP/blob/main/Python_BMP/BITMAPlib.py
-e ```py
(lambda: (
[
(a := 1, ret_val := a, (_ for _ in "").throw(StopIteration)) for _ in ""
],
ret_val
)[-1])()
im trying conditional returning early in oneline (expanded for viewing here) but im stuck on the 3.7 behaviour of wrapping `StopIteration` in a `RuntimeError`
using next with a generator has no luck either
oh, i thought about something like this before
my approach was to use any
not sure if it helps you here
yeah, didn't think that far hm
i could always catch an error raised from it, that gets quite long though
have a return value + a temp value that indicates if the loop was returned early?
-e ```py
print((lambda: (
any((
(ret := True, ret_val := None, a := 1, ret_val := a, ret := True, ret)[-1] for _ in "_"
)),
ret_val
)[-1])())
this is an awful example for what im using this for but this might work
!e ```py
print((lambda: (
any((
(ret := True, ret_val := None, a := 1, ret_val := a, ret := True, ret)[-1] for _ in "_"
)),
ret_val
)[-1])())
@pastel sparrow :white_check_mark: Your eval job has completed with return code 0.
1
nice
are you trying to turn any python file into one-liners ๐
maybe
im way far off for and while loops but i keep thinking so far
and, ive got this
!e ```py
(func := lambda a: (
any(
(
(
ret := False,
ret_val := None,
print(f"{i=}"),
(
ret := True,
ret_val := i
) if a and i == 1 else (),
ret
)[-1] for i in range(5)
)
),
ret_val
)[-1]),
print(func(True))
print(func(False))
@sick iris :white_check_mark: Your eval job has completed with return code 0.
001 | i=0
002 | i=1
003 | 1
004 | i=0
005 | i=1
006 | i=2
007 | i=3
008 | i=4
009 | None
which, works as intended
!!!
conditional return in a for loop, which may also be a while loop
of course, this can go to
!e ```py
(func := lambda a:(any(((ret:=False,ret_val:=None,print(f"{i=}"),(ret:=True,ret_val:=i)if a and i==1 else(),ret)[-1]for i in range(5))),ret_val)[-1],print(func(True)),print(func(False)))
@sick iris :white_check_mark: Your eval job has completed with return code 0.
001 | i=0
002 | i=1
003 | 1
004 | i=0
005 | i=1
006 | i=2
007 | i=3
008 | i=4
009 | None
nice!
specifically starred assignments
i mayyyy or may not be using libcst, full programmatic conversion
intended for just a library i work on rn but the hope is for it to work with any sane library that doesnt do immense amount of magic
oh hey, i tried doing it with ast kekw
i hope it goes well
Anyone know of a article/guide on to converting code into true one liners?
I know of the one line loops, if else etc just not sure how to apply them into a true one liner
Actually I think I got it down
Heres a messy one line of rock/paper/scissors
(lambda:(print(((f'Won: {_} beats {__}'if(not(___[_]==__))else(f'Lost: {__} beats {_}'))if(not(_==__))else(f'Tie: {_} is {__}'))if((_:=input('Move: '))and(__:=__import__('random').choice(['rock','paper','scissors']))and(___:={'rock':'paper','paper':'scissors','scissors':'rock'}))else('Invalid input..'))))()
Love it
!e
exec(__import__('lzma').decompress(__import__('base64').b64decode("/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQAWcHJpbnQoIkhlbGxvLCB3b3JsZCEiKQoAAONlhiJ5yzizAAEvF4EISbEftvN9AQAAAAAEWVo=")).decode())
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
Hello, world!
I forgot about __import__. And TIL about :=. Very cool what you can do in expressions haha
yeah, the walrus operator(:=) came in clutch for me lol
!e
(lambda i: exec(i('lzma').decompress(i('base64').b64decode("/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQAWcHJpbnQoIkhlbGxvLCB3b3JsZCEiKQoAAONlhiJ5yzizAAEvF4EISbEftvN9AQAAAAAEWVo="))))(__import__)
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
Hello, world!
I think this is my new pattern for pasting in LZMA-compressed code
and I really like how expressions can be used anywhere.
true=True
(console := lambda:'').log = lambda value:print(value)
i=0
while (true):{
(i := 1+i),
(console.log('hmm') if (i<=5) else (true:=False)),
}
what exactly is lzma-compressed code for?
In some cases I've written more code than can reasonably be pasted into a code block here haha
ah, gotcha
Like my crazy multi-process monte carlo thing I wrote last night
nice nice
I also like that you can change the exec to a print to just get the code itself:
!e
(lambda i: print(i('lzma').decompress(i('base64').b64decode("/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQAWcHJpbnQoIkhlbGxvLCB3b3JsZCEiKQoAAONlhiJ5yzizAAEvF4EISbEftvN9AQAAAAAEWVo="))))(__import__)
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
b'print("Hello, world!")\n'
I use the xz utility: xz < foo.py | base64 -w0
Oh?
if I do:
def test():
return 'r'
test.ok = lambda: 'rrr'
print(test.ok)
x = lambda:'x'
x.x = lambda: 'xxx'
print(x.x)
``` I am allowed to add attributes to them
but if I do it with regular types:
x = 2
x.two = lambda:'222'
print(x.two)
``` I get a attribute error
AttributeError: 'int' object has no attribute 'two'
now these all are classes of their type
!e
class Foo():
pass
f = Foo()
f.x = lambda: 'x'
print(f.x())
so shouldnt it work the same?
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
x
idk why it's different for int. To be honest I'm surprised you're allowed to add arbitrary attributes to functions?
Hmm
I have a weird idea
Can you use this to make f.g represent function composition
!e
z = lambda:print('test')
z.z = lambda:print('ok')
z.z()
x = [1, 2]
x.two = lambda:print(2)
x.two()
I think so?
wdym? like overriding that attribute for all types of that type?
!e
class f:
def __setattr__(x,y,z):
print("python's closed")
h = f()
h.val = 14
@vestal solstice :white_check_mark: Your eval job has completed with return code 0.
python's closed
so I am assuming, with regular variable data types they have a raise put in there for that method
!e
f = lambda x: x
f.__getattr__ = lambda s, name: name
f.x
@verbal talon :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 3, in <module>
003 | AttributeError: 'function' object has no attribute 'x'
!e
class new_int(int):
def __setattr__(self, name, value):
raise Exception('Error...')
x = new_int(5)
x.two = 2
print(x.two)
@short crag :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 6, in <module>
003 | File "<string>", line 3, in __setattr__
004 | Exception: Error...
I'm trying to avoid creating a wrapper class for function haha
I mean I guess it's possible with a wrapper
!e
class test(int):
def __getattr__(self, name):
return 'Test..'
x = test(2)
print(x.two)
@short crag :white_check_mark: Your eval job has completed with return code 0.
Test..
!e
def x():
return 'x'
x.__getattr__ = lambda self, name: 'Test..'
print(x.two)
@short crag :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 5, in <module>
003 | AttributeError: 'function' object has no attribute 'two'
looks like you cant override it without wrapping the type?
Hmm it's interesting that this works:
!e
class Foo():
pass
f = Foo()
f.__getattribute__ = lambda s, name: name
print(f.x)
@verbal talon :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 6, in <module>
003 | AttributeError: 'Foo' object has no attribute 'x'
Wait one sec...
lol
Oh it only worked in my other session because I had already defined __getattr__ in the class, nvm
!e
print(dir(lambda x: x))
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
['__annotations__', '__builtins__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
There is __getattribute__ and __getattr__ and they are subtly different according to the docs https://docs.python.org/3/reference/datamodel.html#object.__getattr__
I've tried overriding both on function though and it doesn't seem to get called.
Yeah I'm a bit stumped here too
It looks like function has a __getattribute__ but setting it to something else doesn't change anything
confusing
__getattribute__ is dangerous and in most cases you only want to override getattr
@magic wraith in this channel we like to live dangerously
(what if you access attributes inside the getattribute? nice recursion lel)
lmao ik
thanks for the heads up, but its kinda pointless here 
With a minifier + LZMA I can get the eval block pretty small
!e
exec((lambda i: i('lzma').decompress(i('base64').b64decode("/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4ASMAo1dACsPRodj/gB+nUa8nWwC2g+4QUdgxFlAPCgO71ujypqzwh+cdGdBER97T6HlEk9cyiyQ9wITsd3Wp5ax2GtOHr0LWY2yzDWmvVWXLyiaG2W1xugCOIsPjsfRhaRtU2EWjJpNYA53k1x9ZrZuvguHB8xYqkVQADOPWU4PTYUBN+G/7iQdQfgjkT9nA3ooWiLVtlY22YoEW5ZZXHX1gXHNe/qKNVBlhAgNNAzwceSk2Zcn2eBG9Ckw+IA0s3cSZr0bTskNY7oPcBnfHI7w11298MCowr16eoZuWFhDgEaH14TStDLfiZzdj2A8fGK2qNrJSs1x5WumaWclm6FesfIae/InIsOkJbl5HXjzD6FZ1r9QeJpTdvcJez9QbqRRxXpGI+t1thYlEJRGxbMFFSd1efXYwKaKMCrnBG/BbIGj82tyOn4fqy2iBWMVMoMYrOGUF7FQWOmcnmqPSU9+4qHkfJLbkZWV2ntYKd/uHQjxW/IQ3h+P63keT8Mw8QRx9cbyTXFSL3wAsWfm9ZbI0gj15iFKaKB6B5mU5edgS88TNxzJhV5n9hxkQtwR16I4BscXg/fqeRy0UkpGRAKSg8Fddnt5ApPxQEv4rsaRx0Lztd5JeqrwCStI1OCbDMJ5cmthsmb/Pr14RNoeYffS4GFtXH+b8r2qgE8UBFJBeMKkppUQI/kgaChoTZwEnmORxZZAVVvb6n5mcJEp+mJeZGmDbTnqjYBEyirmttHoaicTxY5Ut8rRqEaPsV07nI8xovqJxm/ms3z7Jo08KPMEBgR2NYrDeDthgL/F0BP0QZ7tUdoNHiDFa13d1tvpPmG6ZwOhCGG0G5yjeQr/2OOVxP85b3APp3OvUH+QYcGwD0KKAAAAAM0wtZ5r1yNkAAGpBY0JAADiTkQlscRn+wIAAAAABFla")))(__import__))
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
Num processes: 4, total iterations: 20000000, pi ~= 3.1412286
I think that's fun, you can fit some fairly complex programs
huh thats neat
I bet with unicode characters instead of just base64, you could pack a LOT more bits into the text block
You inspired me to try a tail-recursive fibonacci one-liner:
!e
fib = lambda n: (lambda f: f(f, 0, 1, n))(lambda f, a, b, n: f(f, b, a + b, n - 1) if n > 0 else a)
print(fib(100))
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
354224848179261915075
Not sure if you can do while-loops in an expression some other way?
!e
print([(lambda n: (lambda f: f(f, 0, 1, n))(lambda f, a, b, n: f(f, b, a + b, n - 1) if n > 0 else a))(n) for n in range(10)])
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
hah, that looks good
!e
x = 2
print(x.__dir__())
@short crag :white_check_mark: Your eval job has completed with return code 0.
['__new__', '__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__add__', '__radd__', '__sub__', '__rsub__', '__mul__', '__rmul__', '__mod__', '__rmod__', '__divmod__', '__rdivmod__', '__pow__', '__rpow__', '__neg__', '__pos__', '__abs__', '__bool__', '__invert__', '__lshift__', '__rlshift__', '__rshift__', '__rrshift__', '__and__', '__rand__', '__xor__', '__rxor__', '__or__', '__ror__', '__int__', '__float__', '__floordiv__', '__rfloordiv__', '__truediv__', '__rtruediv__', '__index__', 'conjugate', 'bit_length', 'bit_count', 'to_bytes', 'from_bytes', 'as_integer_ratio', '__trunc__', '__floor__', '__ceil__', '__round__', '__getnewargs__', '__format__', '__sizeof__', 'real', 'imag', 'numerator', 'denominator', '__doc__', '__str__', '__setattr__', '__delattr__', '__init__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__dir__', '__class__']
class int(int):
def __setattr__(self, name, value):
confirm = input(f"Are you sure you wanna set {name} to {value} for type {type(self).__name__}(y\\n) ")
if confirm == 'y':
return super().__setattr__(name, value)
raise AttributeError('Attribute not accepted!')
``` Imagine python had you confirm everything you did in the code
Greetings, I am having issues implementing some functions from the cfgmgr32 API on Windows.
Currently, I'm attempting to receive a pointer instance of a device based on its pDeviceID, however, whenever I attempt to convert it into anything that's a pointer, it returns CR_INVALID_POINTER, so I'm currently confused on how I'd be able to convert a regular string to a null-terminated one, and obtain a valid pointer of that.
Here's my current code:
import ctypes
cfgmgr = ctypes.WinDLL("cfgmgr32.dll")
# Let's try to obtain this mouse:
# HID\VID_0B05&PID_18AA&MI_02&COL06\7&2C012244&0&0005
CM_Locate_DevNodeA = cfgmgr.CM_Locate_DevNodeA
CM_Get_DevNode_Property_Keys = cfgmgr.CM_Get_DevNode_Property_Keys
pdnDevInst = ctypes.c_void_p()
pDeviceID = ctypes.c_char_p(
"HID\\VID_0B05&PID_18AA&MI_02&COL06\\7&2C012244&0&0005".encode("UTF-8"))
if CM_Locate_DevNodeA(
pdnDevInst,
pDeviceID,
ctypes.c_ulong(0),
) != 0:
print("ERROR") # It reaches here each time
else:
print(pdnDevInst)
Here's the documentation I'm referencing:
https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_locate_devnodea
Oh and, another cool thing:
__annotations__ = globals()
x: 2
print(x)
hmm.. is that c_ulong supposed to be a pointer to memory
I don't think so
It's merely a flag argument
Here's the header source:
https://github.com/tpn/winsdk-10/blob/master/Include/10.0.10240.0/um/cfgmgr32.h
wow, that's nuts!
@short crag so if I'm reading this right, it assigns the globals() dict to __annotations__ so that when you do x:2 it adds it to the annotations collection, making it a global variable?
what if you do
pdnDevInst = c_ulong()```
then in the call use
```py
ctypes.byref(pdnDevInst)```
yup! It's pretty cool
oh. that worked
Although I'm not sure if it's a valid result returned - it's ulong(1)
I wonder if that's the index to its relative path in the device tree
Hm, it shouldn't be though
A pointer to a device instance handle that CM_Locate_DevNode retrieves. The retrieved handle is bound to the local machine.
I havent experimented around with it, but I think:
globals(), __annotations__ = __annotations__, globals()
``` should swap them entirely(**not sure**)
@verbal talon
hahahahaha
Wait, can that be right? Can globals() be on the left hand side like that?
ยฏ_(ใ)_/ยฏ
__globals__ right?
hmm
__globals__ isnt defined
TypeError: 'builtin_function_or_method' object does not support item assignment
__annotations__, globals = globals, __annotations__
x:2
print(x)
``` @verbal talon looks like we cant do this, sadly.
though
just using __annotations__ = globals() causes weirdness
the annotations take higher priority when making a variable
true
!e
__annotations__ = globals()
x: 2 = 4
print(x)
y: 4
print(y)
z = 6
print(z)
@short crag :white_check_mark: Your eval job has completed with return code 0.
001 | 2
002 | 4
003 | 6
hmm, if it's just a handle, maybe? does it work with whatever other API you're using ?
i love that
same, its so weird lol
!e
x: 2 = 4
y: 4
z = 6
tmp = __annotations__
__annotations__ = globals()
for k in tmp:
globals()[k] = tmp[k]
print(x)
print(y)
print(z)
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
001 | 2
002 | 4
003 | 6
I haven't implemented anything else with c-types before
it's actually a cool way to be explicit with global vs local variables
= is local, : is global
it would be confusing if you didn't know what that one line did, but otherwise it could be useful.
did it return 0 (CR_SUCCESS)?
comments
#HERE X IS ACTUALLY A INT SORRY
x: 2
okay... doc strings are for type annotations, : annotations are for global variables, and globals are for local variables
This should clear it up for beginners
we are gonna invent our own pep guide
pep420
Yes
lol
oh that exists already lol
we need to go back to Hungarian notation
fyi you can do:
open(1, 'w').write('stuff')
``` to print
and
```py
open(0, 'r').readline(1)
``` for input in a more cursed manner
oh interesting, Python is sometimes surprisingly C-like
i forgot to .close on 0, keyboard privileges revoked
I mean its only built on C
Sure but I mean, there's no reason that Python itself has to treat ints as file handles
mistakes have been made xD
true, guess they got a little inspiration
Hm, does None act similarly to C's NULL when using ctypes?
Because I'm getting CR_INVALID_POINTER when I pass None
!e
function = type
main = function("main", (), {'__init__': lambda self, x, y:{print(x+y)}and None})
main(1, 2)
``` @verbal talon cursed way of making a function
@short crag :white_check_mark: Your eval job has completed with return code 0.
3
Hmm, there needs to be a wiki
lmao
@short crag do you know if there is a way to put while loops in one-liners?
I guess I could define a while loop function using exec
And then use that in the rest of my one-liner
you could make an infinite for loop then comprehension over that
any(print(i) for i in range(9999999))
9999999 is basically infinity
basically
oh i wonder if you need to pass it a bytes instead of a string .
thank god python is slow
!e
any(print(i) for i in __import__('itertools').count(0))
@verbal talon :x: Your eval job has completed with return code 143 (SIGTERM).
001 | 0
002 | 1
003 | 2
004 | 3
005 | 4
006 | 5
007 | 6
008 | 7
009 | 8
010 | 9
011 | 10
... (truncated - too many lines)
Full output: too long to upload
A are ascii functions and W are wide char functions?
It would appear that my buffer array is not large enough to hold all the property keys
Seems to be working fine now lol - just have to figure out how I'd allocate the property keys appropriately
You can probably use iter inside of a lambda to make a while loop
!e
any(print(i) if i <= 5 else True for i in __import__('itertools').count(0))
oh ok 
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
001 | 0
002 | 1
003 | 2
004 | 3
005 | 4
006 | 5
Ah I see, any lets you bail out early
Can you explain what you mean?
An example from cpython docs of iter, py from functools import partial with open('mydata.db', 'rb') as f: for block in iter(partial(f.read, 64), b''): process_block(block) here, basically iter calls the partial until it returns b'' here, the sentienl object
It shouldn't be to hard to utilise this in a one-liner inside of a lambda
Although I am interested how I'd replicate a "buffer array of a struct"
Say I have a struct like this:
struct DEVPROPKEY {
DEVPROPGUID fmtid;
DEVPROPID pid;
};
how would I translate this over to Python using ctypes and create a buffer arr of this type?
!e
for i in iter(int, 1):
print(i)
@languid hare :x: Your eval job has completed with return code 143 (SIGTERM).
001 | 0
002 | 0
003 | 0
004 | 0
005 | 0
006 | 0
007 | 0
008 | 0
009 | 0
010 | 0
011 | 0
... (truncated - too many lines)
Full output: too long to upload
looks good
Thanks, I didn't know about that invocation of iter. Very interesting.

lambda and calc, the two things I hate the most
well, at least a very rocky relationship
!e
from itertools import islice
def get_iterator():
x = 0
def next():
nonlocal x
x += 1
return x - 1
return iter(next, None)
for i in islice(get_iterator(), 0, 10):
print(i)
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
001 | 0
002 | 1
003 | 2
004 | 3
005 | 4
006 | 5
007 | 6
008 | 7
009 | 8
010 | 9
([_:=(...)],[__:=({_}|{_})]) I love this expression lol
It's looking at me weird

({}|{})
Hmph. I'm a little stuck.
Say I had a structure called DEVPROPKEY, how would I define a buffer of an array accepting DEVPROPKEY-typed items?
Here's what the structure looks like, if relevant:
class DEVPROPKEY(Structure):
_fields_ = [
("fmtid", c_void_p),
("pid", c_void_p)
]
!e
(lambda N, r: print(f"pi ~= {sum(4 if (lambda x, y: x * x + y * y < 1)(r(),r()) else 0 for i in range(N))/N}"))(1000000, __import__('random').random)
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
pi ~= 3.141396
Changed the implementation a bit - I think it should be ok now.
class GUID(Structure):
_fields_ = [
("Data1", c_ulong),
("Data2", c_ushort),
("Data3", c_ushort),
("Data4", c_byte*8)
]
class DEVPROPKEY(Structure):
_fields_ = [
("fmtid", GUID),
("pid", c_ulong)
]
This is where I'm currently stuck:
buf = c_buffer(b"", sizeof(DEVPROPKEY) * 256)
count = c_ulonglong(0)
stat = CM_Get_DevNode_Property_Keys(
pdnDevInst,
buf,
byref(count),
c_ulong(0)
)
if stat != 0x0:
print("STATUS #2: " + str(stat))
print(buf, buf.value, count)
else:
print(buf, buf.value, count)
The stat value is 0x1A, which is, CR_BUFFER_SMALL - I must've declared the DEVPROPKEY structure improperly.
The function in question:
https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_get_devnode_property_keys
lambda _:(__)if(any(('...'if(__:=False)else'...'if((_) %___==0)else'...' if(__:=True)else'...')for(___)in(range(2, _)))if((__:=True)and(_) >0)else('...'if(__:=False)else'...'))else(__)
``` Can't be bothered to test it more, or clean up the shitty code. but I think its a working prime checker.
lmao
I'm actually trying to convert a Sieve of Eratosthenes implementation to a one liner
!e
a = [*range(100)]
a[0] := 1
@verbal talon :x: Your eval job has completed with return code 1.
001 | File "<string>", line 2
002 | a[0] := 1
003 | ^^^^
004 | SyntaxError: cannot use assignment expressions with subscript
Running into a hitch though, can't assign into my array as an expression
it has to be a array?
Hmm the algorithm is usually implemented as an array
What else did you have in mind?
It seems like only variables support := right?
Hmm for now I'm going to ignore this and do my old trick of "take in the solution to the problem as a parameter"
yeah
not sure, maybe you could use a dict and swap out the values?
#list
[item_1, item_2, item_3}
#dict
{1:item_1, 2:item_2, item_3}
!e
stuff = {1: '1'}
stuff[1] := '2'
@short crag :x: Your eval job has completed with return code 1.
001 | File "<string>", line 2
002 | stuff[1] := '2'
003 | ^^^^^^^^
004 | SyntaxError: cannot use assignment expressions with subscript
!e
def s(a, i, v): a[i] = v
print((lambda N, s: (lambda arr: (any(any(s(arr, j, False) for j in range(2 * i + 2, N, i + 2)) for i in range(N)), [i+2 for i in range(N-1) if arr[i]]))([True for i in range(N-1)])[1])(100, s))
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
!e
print((lambda N,s:(lambda arr: (any(any(s(arr,j,False) for j in range(2*i+2, N, i+2)) for i in range(N)), [i+2 for i in range(N-1) if arr[i]]))([True for i in range(N-1)])[1])(100, lambda a,i,v:a.__setitem__(i, v)))
i didnt take my brainpower to think
it's a dunder
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
Got it
Okay I think this is cleaned up a bit:
!e
print((lambda N:(lambda arr: (any(any(arr.__setitem__(j,False) for j in range(2*i+2,N,i+2)) for i in range(N)), [i+2 for i in range(N-1) if arr[i]]))([True for i in range(N-1)])[1])(100))
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
I should also change it to iterate only up to math.sqrt(N)
!e ```py
print([2,3,5,7,*(i for i in range(2,100)if all((i%6in(1,5),i%5,i%7)))])
@quartz wave :white_check_mark: Your eval job has completed with return code 0.
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
lol
Hah now do 1000
!e ```py
print([2,3,5,7,*(i for i in range(2,1000)if all((i%6in(1,5),i%5,i%7)))])
@quartz wave :white_check_mark: Your eval job has completed with return code 0.
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 121, 127, 131, 137, 139, 143, 149, 151, 157, 163, 167, 169, 173, 179, 181, 187, 191, 193, 197, 199, 209, 211, 221, 223, 227, 229, 233, 239, 241, 247, 251, 253, 257, 263, 269, 271, 277, 281, 283, 289, 293, 299, 307, 311, 313, 317, 319, 323, 331, 337, 341, 347, 349, 353, 359, 361, 367, 373, 377, 379, 383, 389, 391, 397, 401, 403, 407, 409, 419, 421, 431, 433, 437, 439, 443, 449, 451, 457, 461, 463, 467, 473, 479, 481, 487, 491, 493, 499, 503, 509, 517, 521, 523, 527, 529, 533, 541, 547, 551, 557, 559, 563, 569, 571, 577, 583, 587, 589, 593, 599, 601, 607, 611, 613, 617, 619, 629, 631, 641, 643, 647, 649, 653, 659, 661, 667, 671, 673, 677, 683, 689, 691, 697, 701, 703, 709, 713, 719, 727, 731, 733, 737, 739, 743, 751, 757, 761, 767, 769, 773, 779, 781, 787, 793, 797, 799, 803, 809, 811, 817, 821, 823, 827, 829, 839, 841, 851, 853, 857, 859, 863, 869, 871, 877, 881, 883
... (truncated - too long)
Full output: https://paste.pythondiscord.com/aleseyiyab.txt?noredirect
correct?
lol
my prime number code is giving me 5 errors bruh
those are warnings
!e
print((lambda N:(lambda a: (any(any(a.__setitem__(j,0) for j in range(2*i+2,N-1,i+2)) for i in range(__import__('math').isqrt(N)-1)), [i+2 for i in range(N-1) if a[i]]))([1 for i in range(N-1)])[1])(1000))
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
Hmm those all look like numbers to me. Most of them odd, too.

5 is prime number

mission accomplished 
i wonder how many prime numbers it takes so that an AI/ML doesn't just spit out odd numbers
You mean like if you asked GPT-3 what the next prime number in the sequence:
[2, 3, 5, 7, ...]
was?
more like here's some prime numbers, give me a whole bunch more
ah yeah
@umbral heron youll like this place
lol thx
i wanna compress something into 1 line but ik im tired and fuck it up greatly
what is it?
idk
1 line disc bot
discord_bot = (lambda: client.run('TOKEN') if(client:=__import__('discord.ext', fromlist=['commands']).commands.Bot(command_prefix='!', intents=__import__('discord.ext').Intents.all())) else '...')()
``` Got this so far @umbral heron
just need to a ping command

i'm not familiar with python for discord so......
it uses decorators
@client.command()
async def ping(ctx):
await ctx.send('Pong!')
``` @umbral heron
I gotta compress those 3 lines into 1
not sure if that's even possable
im gonna try
!e
2="sa"
print(2)
!e
A="s"
print (A)
!e
A="s"
print (A)
!e
def exercise53(capital, interest_rate, target):
year =
while capital < target:
year =
capital =
print("La premiรจre annรฉe oรน son capital a dรฉpassรฉ", target ......,"est :", ......)
!e
!e
import random
print(random.choice(('A', 'B')))
print(random.choices(('A', 'B'), (50, 50)))
@sick hound :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | !e
003 | ^
004 | SyntaxError: invalid syntax
!e
!e
import random
print(random.choice(('A', 'B')))
print(random.choices(('A', 'B'), (50, 50)))
@sick hound :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | !e
003 | ^
004 | SyntaxError: invalid syntax
!e
import random
print(random.choice(('A', 'B')))
print(random.choices(('A', 'B'), (50, 50)))
@sick hound :white_check_mark: Your eval job has completed with return code 0.
001 | B
002 | ['B']
(getattr((bot:=getattr(__import__("importlib").import_module("discord.ext.commands"),'Bot')(command_prefix='^',intents=getattr(__import__('discord'),'Intents').all())), 'command')(name='ping')(__import__('asyncio').coroutine(lambda ctx:(await ctx.send('pong')for _ in '_').__anext__())));bot.run(token)```
discord_bot = (lambda: (client.run('TOKEN') or client.command()(ping)) if(ping:=lambda ctx: ctx.send('test'), client:=__import__('discord.ext', fromlist=['commands']).commands.Bot(command_prefix='!', intents=__import__('discord.ext').Intents.all())) else '...')()
``` So I am trying this, the bot runs and everything is fine. but its not reccognizing my ping command
yeah we had diff approaches
!e
_2="s"
print (_2)
@sick hound :white_check_mark: Your eval job has completed with return code 0.
s
#bot-commands theres this place for testing
Sorry
its ok
''.join(map(str, []))
thanks
looking at that, in the command definition. why do you need to do a loop, with for _ in '_'? What exactly is that doing
because async lanbda doesn't exists, we have to call __anext__ manually for that we need a generator for (... for _ in '_') makes a generator and then we can call __anext__
ah, gotcha. Thanks.
wonder why we dont have async lambdas 
async lambda ctx: await ctx.send('I am async') would be so much better
it doesn't really makes sense to have it
why would someone ever use it (except here)
true, but arent lambdas handled the same way as (regular)functions? So couldnt they just add the check if its lambda or def after async?
oh yeah new idea to implement
broooo.
remember a decorator is just a wrapper function, so you can make a one liner decorator and a lambda, just dont know abt async lambda
async lambda is like __import__('asyncio').coroutine(lambda *args,**kwargs:...)
>>> foo = async lambda a: await a
>>> foo
<function <lambda> at 0x0000026846595BD0>
>>> async def bar(a):
... return await a
...
>>> from dis import dis
>>> dis(bar)
1 0 RETURN_GENERATOR
2 POP_TOP
4 RESUME 0
2 6 LOAD_FAST 0 (a)
8 GET_AWAITABLE 0
10 LOAD_CONST 0 (None)
>> 12 SEND 3 (to 20)
14 YIELD_VALUE
16 RESUME 3
18 JUMP_BACKWARD_NO_INTERRUPT 4 (to 12)
>> 20 RETURN_VALUE
>>> dis(foo)
1 0 RETURN_GENERATOR
2 POP_TOP
4 RESUME 0
6 LOAD_FAST 0 (a)
8 GET_AWAITABLE 0
10 LOAD_CONST 0 (None)
>> 12 SEND 3 (to 20)
14 YIELD_VALUE
16 RESUME 3
18 JUMP_BACKWARD_NO_INTERRUPT 4 (to 12)
>> 20 RETURN_VALUE
>>> baz = async lambda: 5
>>> main = async lambda: await foo(bar(baz()))
>>> from asyncio import run
>>> run(main())
5
implemented async lambda
fire
how???
modified cpython
:0 found someone else who tried doing it
I know this isn't technically esoteric python per se, but is anyone interested in esoteric versioning schemes?
Semver is pretty boring, it would be much more exciting to publish version {{{}}{}} of your ctypes-heckery library...
Its possible but you have to look into the decorator function source code and just copy paste it to get rid of the decorator , instead of it you would have another function that you call with the ping function as first argument
Anything is possible as long as it isn't a syntax error :)
Heya esoteric people
Question for you
I'm writing a library to enforce privacy and type annotations at runtime
So far so good!
The syntax looks a bit like this...
interpret major.minor as a float then publish it as the cast 32 bit integer
from <library> import Object
from <library> import Attribute
class ThingWithPrivateAttributes(Object):
private = Attribute(int, access=False)
readonly = Attribute(str, access=None)
public = Attribute(bool, access=True)
def __init__(self, arg1: int, arg2: str, arg3: bool) -> None:
self.private = arg1
self.readonly = arg2
self.public = arg3
And then a bunch of descriptor magic takes over
Cool! So here's my question
With a normal object, which has no attributes of its own by default, it makes sense to just throw an error if someone tries to set an attribute on the object that doesn't have a corresponding Attribute descriptor declared in the class
But if I extend this to class attributes, well, things get uglier
Classes have lots of attributes by default. __name__, __bases__, __itemsize__ โ some of them quite general use, others yucky implementation details
What do I do about setting an attribute on a class that enabled with this privacy-and-enforcement protocol if that attribute is something other than an attribute explicitly delcared using the library
You can define __name__ on the metaclass, and do whatever you want with it there (e.g. make it a property). But I hope it's clear to you that your library is esoteric indeed, unpythonic, and can't possibly truly work.
Oh yeah
You'd have to gut the language like a fish and rebuild it pretty much from scratch to do it properly
They goal, though, well its two fold
Its a good demonstration of where my abilities stand with python and hence, a good portfolio piece
And beyond that, it isn't about installing privacy in the traditional sense so much as in the philosophical sense. Privacy != security. Its meant be an unambiguous Berlin-Wall between the public and private APIs which is nontrivial enough to get around that it states unequivocally "here be dragons"
and can't possibly truly work
That is bold xD
I didn't want to say anything, but I feel a bit the same
The principal is simple, and seems to be working fine
It's possible to make a class that's attribute model is near impossible to modify (unless the user uses ctypes). You have to toggle some class flags yourself with ctypes
(Or any other way to do memory corruption)
Using ctypes, you can make objects that can only be accessed with ctypes
!e ```py
from ctypes import *
from _ctypes import PyObj_FromPtr
BYTES_HEADER = bytes.basicsize - 1
PTR_SIZE = tuple.itemsize
ENDIAN = ['big','little'][memoryview(b'\1\0').cast('h')[0]&0xff]
class container:
slots = 'value'
def ptr_to_bytes(p):
return p.to_bytes(PTR_SIZE, ENDIAN)
def make_container(init_val=(sentinel:=object())):
raw = ptr_to_bytes(0xffffffff)
+ ptr_to_bytes(id(container))
+ bytes(PTR_SIZE * 2)
fake = PyObj_FromPtr(id(raw) + BYTES_HEADER)
if init_val is not sentinel:
fake.value = init_val
return raw
def get_value(raw):
return PyObj_FromPtr(id(raw) + BYTES_HEADER).value
def set_value(raw, new_val):
PyObj_FromPtr(id(raw) + BYTES_HEADER).value = new_val
def clear_value(raw):
del PyObj_FromPtr(id(raw) + BYTES_HEADER).value
raw_container = make_container('abc')
print(raw_container)
print(get_value(raw_container))
clear_value(raw_container)
print(raw_container)``` this example makes a bytes object that contains the real container object (thus making it only accessible through ctypes
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | b'\xff\xff\xff\xff\x00\x00\x00\x00\x103\x1cX\xd6U\x00\x000Dt\x81%\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
002 | abc
003 | b'\xff\xff\xff\xff\x00\x00\x00\x00\x103\x1cX\xd6U\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Could you explain to me what ctypes is?
It lets you call c functions from python, but only using primitive types?
*as arguments
how is it that PyObj_FromPtr requires ```py
id(
ptr_to_bytes(0xffffffff)
- ptr_to_bytes(id(container))
- bytes(PTR_SIZE * 2)
) + BYTES_HEADER
but `py_object.from_address` requirespy
id(
ptr_to_bytes(id(container)) # swapped - ptr_to_bytes(0xffffffff) # swapped
- bytes(PTR_SIZE * 2)
) + BYTES_HEADER
that second block of code, if passed into py_object.from_address i think would return the container class, not an instance of the container class
!e ```py
from ctypes import *
from _ctypes import PyObj_FromPtr
BYTES_HEADER = bytes.basicsize - 1
PTR_SIZE = tuple.itemsize
ENDIAN = ['big','little'][memoryview(b'\1\0').cast('h')[0]&0xff]
class container:
slots = 'value'
def ptr_to_bytes(p):
return p.to_bytes(PTR_SIZE, ENDIAN)
addr = id(
s := ptr_to_bytes(id(container)) \
- ptr_to_bytes(0xffffffff) \
- bytes(PTR_SIZE * 2)
) + BYTES_HEADER
print(py_object.from_address(addr))```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
py_object(<class '__main__.container'>)
!e yea cause that code is the same as this: ```py
from ctypes import *
from _ctypes import PyObj_FromPtr
BYTES_HEADER = bytes.basicsize - 1
PTR_SIZE = tuple.itemsize
ENDIAN = ['big','little'][memoryview(b'\1\0').cast('h')[0]&0xff]
class container:
slots = 'value'
def ptr_to_bytes(p):
return p.to_bytes(PTR_SIZE, ENDIAN)
addr = id(
s := ptr_to_bytes(id(container))
) + BYTES_HEADER
print(py_object.from_address(addr))```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
py_object(<class '__main__.container'>)
ok i guess
had a cursed idea, but im not sure if its possible. it would need:
automatic function currying (maybe hooking function
__init__if thats a thing)
replacing@onobjectwith an elixir-style|>
object called_that returns operators, so_+_returnsoperator.add
Then you could do functional pipeline programming :) ```py[3, 4, 5] @ map (+) @ reversed
[6, 5, 4]
I've thought about something similar before but using * -- rationale being that function composition is a (non-commutative) monoid so you'd usually use the times symbol anyway
I'm trying to turn this code into a one-liner but a bit stuck because I don't know how to move the nonlocal bit into the lambda:
def get_mock_input(user_input):
x = -1
def input(prompt):
nonlocal x
return user_input[(x := x + 1)]
return input
input = get_mock_input(["foo", "bar"])
Like normally I'd work from the inside and turn this into:
def get_mock_input(user_input):
x = -1
return lambda prompt: user_input[(x := x + 1)]
and then proceed from there, but I can't because x is no longer accessible from that scope...
I think for now I'm going to work around this by using a different type anyway:
def get_mock_input(user_input):
q = __import__('collections').deque(user_input)
return lambda prompt: q.popleft()
!e ```py
get_mock_input = lambda ui:iter(ui).next
input = get_mock_input(l:=[])
l.extend(['a', 'b', 'c'])
print(input())```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
a
just use an iterator
ah, of course
Because ultimately I wanted this to just be one line
input = iter(["foo"], ["bar"]).__next__
Should make it easier to test some interactive scripts...
input = iter(["foo", "bar"]).__next__ should be this
yeah that
Except that's not right either, because it should accept one argument, and ignore it
input = lambda _: iter(["foo", "bar"]).__next__()
I don't think this is right either because it will make a new iter on every call
This seems to do the trick:
input = (lambda f: lambda _: f())(iter(["foo", "bar"]).__next__)
!e
input = (lambda f: lambda _: f())(iter(["foo", "bar"]).__next__)
print(input("ignored1"))
print(input("ignored2"))
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
001 | foo
002 | bar
Thanks for your help!
definitely doable
!e
o = object()
o.x = "foo"
@verbal talon :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 2, in <module>
003 | AttributeError: 'object' object has no attribute 'x'
!e
o = lambda: None
o.x = "foo"
@verbal talon :warning: Your eval job has completed with return code 0.
[No output]
What explains the difference in behavior?
Functions allow you to set attributes on instances
Hmm, explicitly functions and not other types of objects?
Well that's very useful for my purposes haha
!e
(lambda c,s,seq,run:(lambda ipc:any((__import__('sys').exit(0)if s.pc>=len(c)else{'+':lambda:run(s.arr.__setitem__(s.ptr, s.arr[s.ptr]+1),ipc()),'-':lambda:run(s.arr.__setitem__(s.ptr, s.arr[s.ptr]-1),ipc()),'>':lambda:run(setattr(s,"ptr", s.ptr+1),ipc()),'<':lambda:run(setattr(s, "ptr", s.ptr-1),ipc()),',':lambda: run(s.arr.__setitem__(s.ptr, ord(__import__('sys').stdin.read(1))),ipc()),'.':lambda:run(print(chr(s.arr[s.ptr]),end=''),ipc()),'[':lambda:run(s.rs.append(s.pc),ipc()),']':lambda:setattr(s,"pc",(lambda ppc:ppc if s.arr[s.ptr] != 0 else s.pc + 1)(s.rs.pop()))}[c[s.pc]]())for _ in __import__('itertools').count(0)))(lambda:setattr(s,"pc",s.pc+1)))(">++++++++[<+++++++++>-]<.>++++[<+++++++>-]<+.+++++++..+++.>>++++++[<+++++++>-]<++.------------.>++++++[<+++++++++>-]<+.<.+++.------.--------.>>>++++[<++++++++>-]<+.",(lambda x:(x,setattr(x,"arr",[0]*1024),setattr(x,"ptr",0),setattr(x,"pc",0),setattr(x,"rs",[]))[0])(lambda _:None),lambda x,y:y,lambda *x:None)
@verbal talon :white_check_mark: Your eval job has completed with return code 0.
Hello, World!
This was my project for the evening -- learning how to write hello world in python
The fact that you can stick arbitrary attributes on functions was helpful here. just create lambda:None and then start assigning key-value pairs to it lol
a brainfuck interpreter for a hello world ๐
we all gotta start somewhere man
any shorter ?
!e
c=12
while c>0:d=("*"*c).center(12);print(d,d);c-=2
@onyx jacinth :white_check_mark: Your eval job has completed with return code 0.
001 | ************ ************
002 | ********** **********
003 | ******** ********
004 | ****** ******
005 | **** ****
006 | ** **
use fstrings
u can replace ("*"*c).center(12) with f'{"*"*c:^12}'
!e
c=13
while c>0:print(f'{"*"*(c:=c-2):^12}'*2)
@wheat river :white_check_mark: Your eval job has completed with return code 0.
001 | *********** ***********
002 | ********* *********
003 | ******* *******
004 | ***** *****
005 | *** ***
006 | * *
007 |
!e
c=12
while c>0:print(f'{"*"*c:^12} '*2);c-=2
@wheat river :white_check_mark: Your eval job has completed with return code 0.
001 | ************ ************
002 | ********** **********
003 | ******** ********
004 | ****** ******
005 | **** ****
006 | ** **
ohh i did not know about align in f strings nice
how in the fuck does my man ryuga do it
my guy looks at a 35 line program
and goes
"heres the same exact program but in 99% less characters"
when you know python syntax, that's possible
how does he do this though like i never knew you could do this
is this like a mega golfed lambda inside an f string
if i see str.center i'd think "hmm, that same functionality is in f-strings isn't it"
btw check out https://github.com/AFK-debug-9/test
def rot13(message): return ''.join(map(lambda x: chr(ord(x) + 13) if x.isalpha() and ord(x) < 96 - 13 else (chr(ord(x) - (96 - ord(x))) if x.isalpha() and ord(x) < 96 - 13 else x), message))```
whats the problem with this-
!e py exec(''.join(['c3\nhl >:rn("\'\'c^1";-2\nrn("n\'ee on ieYuU ):3})wiec3:rn("\'\'c^1";+2'[i//2] if i%2==0 else '=1wiec0pitf{1*:3})c=\npitf\\{NvrGnaGv o p:\'^0"\nhl <2pitf{1*:3})c=;'[i//2]for i in range(128)]))
@split salmon :white_check_mark: Your eval job has completed with return code 0.
001 | 1111111111111111111111111111111
002 | 11111111111111111111111111111
003 | 111111111111111111111111111
004 | 1111111111111111111111111
005 | 11111111111111111111111
006 | 111111111111111111111
007 | 1111111111111111111
008 | 11111111111111111
009 | 111111111111111
010 | 1111111111111
011 | 11111111111
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/ikicakajup.txt?noredirect
YS!!!!
no its just
while c>0:d=("*"*c).center(12);print(d,d);c-=2
in a fstring
center method???
!e
print('a'.center(10))
print(f'{"a":^10}')
@wheat river :white_check_mark: Your eval job has completed with return code 0.
001 | a
002 | a
How does that work???
!e ```py
print("0.".format("0<10"))
print("1".format("0>10"))
print("^".format(" ^10"))
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
001 | 0.00000000
002 | 0000000001
003 | ^
except f-strings do all that within {:} inside the strings.
what????
the string has an internal method __format__ that does these things, and it comes with syntax sugar to abbreviate it
!e ```py
print(f"0{'.':0<9}")
print(f"{'1':0>10}")
print(f"{'^': ^10}")
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
001 | 0.00000000
002 | 0000000001
003 | ^
what an f string does is it looks for the {:} characters and replaces them and the characters between them with calling str.__format__ with the arguments between as arguments and inserts them back into the "main" f-string
there are some parts to an fstring
f'{some-object:<format-specifier>}'
some-object is the object u want to format (u can also add flags (starts with !) like !r(repr of the obj)
format-specifier the format specifier ........
so its like a mini lang
some format specifiers
^ centers some text
< left aligns
> right aligns
and so on
i looked it up and its a special string formatting thing
so like
code
!e py print(f"{10:.2f}")
@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.
10.00
@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.
10.00
indent not working as i hoped but i think thats discord
anyhow
!e py print(f"{10:>10.2f}")
@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.
10.00
@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.
10.00
@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.
..10.00...
!e I likes symmetry ```py
print(f"0{10:0^10.2f}")
@floral meteor :white_check_mark: Your eval job has completed with return code 0.
00010.00000
@split salmon :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | ValueError: Invalid format specifier
thanks!
wrong
it would be
!e py print(f"{10:.^10.2f}")
@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.
..10.00...
!e py print(f".{10:.^10.2f}")
@upbeat sonnet :white_check_mark: Your eval job has completed with return code 0.
...10.00...
๐
lol me dum
!e
@lambda m:(f:=lambda*a,**k:(a or k)and print(m(*a,**k))or f)
def factorial(lim):
from functools import reduce
return reduce(lambda x,y:x*y,range(1,lim+1))
factorial(10)(3)(4)()()(2)
@wheat river :white_check_mark: Your eval job has completed with return code 0.
001 | 3628800
002 | 6
003 | 24
004 | 2
!e ```py
factorial=type("e",(),{"new":lambda c,i=():[print(import("math").factorial(i))if i!=()else 1,factorial][1]})
factorial(10)(3)(4)()()(2)
@pastel sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | 3628800
002 | 6
003 | 24
004 | 2
wait dammit mine is still longer than a one line version of yours
!e ```py
factorial=lambda i=():[print(import("math").factorial(i))if i!=()else 1,factorial][1]
factorial(10)(3)(4)()()(2)
@pastel sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | 3628800
002 | 6
003 | 24
004 | 2
what is esoteric python?
code gore, code golf, and other headache inducing shenanigans.
"gore" ๐
Python should have some special div and maybe sqrt ops that return integer values when the inputs and outputs are precisely integer
is there a golfed method of getting the first X letters of a string
so like 4.0 / 2 = 2.0, that's fine, but they should make it so that 4 / 2 = 2
and sqrt(4) should be 2 instead of 2.0
omg he who floats among us?
sus! impostor! vent!
nvm im actually dumb
"string"[:3]
something like this
def fancy_div(a, b):
"""
Returns quotient as an integer if a and b are integers, and a is divisible
by b, otherwise returns quotient as a float
"""
div, mod = divmod(a, b)
return div if mod == 0 else a / b
>>> fancy_div(4,2)
2
>>> fancy_div(4.0,2)
2.0
>>> fancy_div(5,2)
2.5
def fancy_sqrt(n):
"""
Returns the โn as an integer if n is an integer and perfect square,
otherwise calculate and return sqrt(n) as a float
"""
if isinstance(n, int):
isqrt = math.isqrt(n)
if isqrt ** 2 == n:
return isqrt
else:
return math.sqrt(n)
its better to be consistent in what type of data you return
you dont know if some big application relies on it being a float everytime
T = TypeVar("T", bound=float)
def fancy_div(a: T, b: T) -> T: ...
:>
I like it, but I'm not sure where I'd use it outside of contexts where the next step is making things human readable.
intermediate calculations of anything to prevent from moving over to float for as long as possible
keep perfect precision; this wouldn't help make things readable generally if you've already got float numbers since it would keep them float
!e if it's an integer and not a perfect square, return None ```py
import math
def fancy_sqrt(n):
"""
Returns the โn as an integer if n is an integer and perfect square,
otherwise calculate and return sqrt(n) as a float
"""
if isinstance(n, int):
isqrt = math.isqrt(n)
if isqrt ** 2 == n:
return isqrt
else:
return math.sqrt(n)
print(fancy_sqrt(5))
@quartz wave :white_check_mark: Your eval job has completed with return code 0.
None
Why?
!e got it shorter, and removed the import ```py
factorial=lambda i=():[i==()or print([i:=i*n for n in range(1,i)][-1]),factorial][1]
factorial(10)(3)(4)()()(2)```
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | 3628800
002 | 6
003 | 24
004 | 2
why'd you do it like that?
like what?
i noticed there was a flaw in your code in which if it's an integer and not a perfect square, it returns None
oh you're right, the logic is broken; should just delete the else line
import math
def fancy_sqrt(n):
"""
Returns the โn as an integer if n is an integer and perfect square,
otherwise calculate and return sqrt(n) as a float
"""
if isinstance(n, int):
isqrt = math.isqrt(n)
if isqrt ** 2 == n:
return isqrt
return math.sqrt(n)
something like that
@quartz wave :white_check_mark: Your eval job has completed with return code 0.
001 | 4
002 | 2.23606797749979
003 | 4.0
!e ```py
import math
fancy_sqrt=lambda n:int(s)if(type(n)==int)==(not(s:=math.sqrt(n))%1)else s
print(fancy_sqrt(16))
print(fancy_sqrt(5))
print(fancy_sqrt(16.))
@quartz wave :white_check_mark: Your eval job has completed with return code 0.
001 | 4
002 | 2.23606797749979
003 | 4.0
Why not call int(sq) instead of sq.__trunc__
ok
!e py fancy_sqrt = lambda n:[sq:=n**.5,int(sq)][(type(n)==int)and(sq**2==n)] print(fancy_sqrt(16)) print(fancy_sqrt(5)) print(fancy_sqrt(16.)) golfed it more
@rugged sparrow :white_check_mark: Your eval job has completed with return code 0.
001 | 4
002 | 2.23606797749979
003 | 4.0
!e
fancy_sqrt = lambda n:[sq:=n**.5,int(sq)][(type(n)==int)&(sq**2==n)]
print(fancy_sqrt(16))
print(fancy_sqrt(5))
print(fancy_sqrt(16.))
@wheat river :white_check_mark: Your eval job has completed with return code 0.
001 | 4
002 | 2.23606797749979
003 | 4.0
i don't know if this will work the same way for all inputs, the math.isqrt() function is doing something very different than n**.5
!e
from math import isqrt as ii
for i in range(1, 100):
if (a:=int(i**.5)) != (b:=ii(i)):
print(a, b)
@wheat river :warning: Your eval job has completed with return code 0.
[No output]
a python script I made outputted this abomination when I fed it my desktop background.
Reminds me of The Amazing World of Gumball's the void
wait- why is (x**.5)**2 != x for non-perfect squares
sadge
~~!e
print((5 ** .5) ** 2 == 5)
```~~, misread it.... idk, floating point error maybe.
@wheat river :white_check_mark: Your eval job has completed with return code 0.
False
"why is"
!e
locals = {}
exec("""
import typing
from tokenize import Token
def f() -> typing.List[Token]:
pass
f()
"""
{}, locals)
print(locals)
@near gust :x: Your eval job has completed with return code 1.
001 | File "<string>", line 2
002 | exec("""
003 | ^^
004 | SyntaxError: invalid syntax. Perhaps you forgot a comma?
!e
locals = {}
code = """
import typing
from tokenize import Token
def f() -> typing.List[Token]:
pass
f()
"""
exec(code, {}, locals)
print(locals)
@near gust :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/usr/local/lib/python3.10/typing.py", line 665, in __init__
003 | code = compile(arg, '<string>', 'eval')
004 | File "<string>", line 1
005 | [ \f\t]*(\\\r?\n[ \f\t]*)*(#[^\r\n]*)?((([0-9](?:_?[0-9])*[jJ]|(([0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?|\.[0-9](?:_?[0-9])*)([eE][-+]?[0-9](?:_?[0-9])*)?|[0-9](?:_?[0-9])*[eE][-+]?[0-9](?:_?[0-9])*)[jJ])|(([0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?|\.[0-9](?:_?[0-9])*)([eE][-+]?[0-9](?:_?[0-9])*)?|[0-9](?:_?[0-9])*[eE][-+]?[0-9](?:_?[0-9])*)|(0[xX](?:_?[0-9a-fA-F])+|0[bB](?:_?[01])+|0[oO](?:_?[0-7])+|(?:0(?:_?0)*|[1-9](?:_?[0-9])*)))|(\r?\n|(\~|\}|\|=|\||\{|\^=|\^|\]|\[|@=|@|>>=|>>|>=|>|==|=|<=|<<=|<<|<|;|:=|:|/=|//=|//|/|\.\.\.|\.|\->|\-=|\-|,|\+=|\+|\*=|\*\*=|\*\*|\*|\)|\(|\&=|\&|%=|%|!=))|((|U|RB|BR|F|rF|u|R|r|fr|B|b|bR|rf|rb|Fr|rB|br|Br|Rb|Rf|f|fR|FR|RF)'[^\n'\\]*(?:\\.[^\n'\\]*)*'|(|U|RB|BR|F|rF|u|R|r|fr|B|b|bR|rf|rb|Fr|rB|br|Br|Rb|Rf|f|fR|FR|RF)"[^\n"\\]*(?:\\.[^\n"\\]*)*")|
... (truncated - too long, too many lines)
Full output: https://paste.pythondiscord.com/urajajever.txt?noredirect
yep that's the problem
lemme look into this
i need flag ast.PyCF_TYPE_COMMENTS
I need to run compile and then exec
!e
locals = {}
code = """
import typing
from tokenize import Token
def f() -> typing.List[Token]:
pass
f()
"""
import ast
code = compile(code, '<string>', 'exec', flags=ast.PyCF_TYPE_COMMENTS)
exec(code, {}, locals)
print(locals)
@near gust :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "/usr/local/lib/python3.10/typing.py", line 665, in __init__
003 | code = compile(arg, '<string>', 'eval')
004 | File "<string>", line 1
005 | [ \f\t]*(\\\r?\n[ \f\t]*)*(#[^\r\n]*)?((([0-9](?:_?[0-9])*[jJ]|(([0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?|\.[0-9](?:_?[0-9])*)([eE][-+]?[0-9](?:_?[0-9])*)?|[0-9](?:_?[0-9])*[eE][-+]?[0-9](?:_?[0-9])*)[jJ])|(([0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?|\.[0-9](?:_?[0-9])*)([eE][-+]?[0-9](?:_?[0-9])*)?|[0-9](?:_?[0-9])*[eE][-+]?[0-9](?:_?[0-9])*)|(0[xX](?:_?[0-9a-fA-F])+|0[bB](?:_?[01])+|0[oO](?:_?[0-7])+|(?:0(?:_?0)*|[1-9](?:_?[0-9])*)))|(\r?\n|(\~|\}|\|=|\||\{|\^=|\^|\]|\[|@=|@|>>=|>>|>=|>|==|=|<=|<<=|<<|<|;|:=|:|/=|//=|//|/|\.\.\.|\.|\->|\-=|\-|,|\+=|\+|\*=|\*\*=|\*\*|\*|\)|\(|\&=|\&|%=|%|!=))|((|U|rb|RB|br|F|rf|FR|u|rF|b|RF|R|BR|rB|Br|fr|f|fR|B|Fr|r|Rb|Rf|bR)'[^\n'\\]*(?:\\.[^\n'\\]*)*'|(|U|rb|RB|br|F|rf|FR|u|rF|b|RF|R|BR|rB|Br|fr|f|fR|B|Fr|r|Rb|Rf|bR)"[^\n"\\]*(?:\\.[^\n"\\]*)*")|
... (truncated - too long, too many lines)
Full output: https://paste.pythondiscord.com/fucepigada.txt?noredirect
nah I was just testing something
!e
locals = {}
code = """
import typing
from tokenize import TokenInfo
def f() -> typing.List[TokenInfo]:
pass
f()
"""
import ast
code = compile(code, '<string>', 'exec', flags=ast.PyCF_TYPE_COMMENTS)
exec(code, {}, locals)
print(locals)
@near gust :white_check_mark: Your eval job has completed with return code 0.
{'typing': <module 'typing' from '/usr/local/lib/python3.10/typing.py'>, 'TokenInfo': <class 'tokenize.TokenInfo'>, 'f': <function f at 0x7f67465a4ca0>}
oh
I'm dumb
!e
locals = {}
code = """
import typing
from tokenize import TokenInfo
def f() -> typing.List[TokenInfo]:
pass
f()
"""
import ast
code = compile(code, '<string>', 'exec')
exec(code, {}, locals)
print(locals)
@near gust :white_check_mark: Your eval job has completed with return code 0.
{'typing': <module 'typing' from '/usr/local/lib/python3.10/typing.py'>, 'TokenInfo': <class 'tokenize.TokenInfo'>, 'f': <function f at 0x7f9e55214ca0>}
the naming is a bit misleading but yeah Token (and all the specific token types) are just the actual regex patterns
Just why
old code
gvanrossum committed on Jan 2, 1992
how long has github been around for
Given that Git itself is from 2005, not that long
tf how
idfk
Python was initially developed with some other version control software (CVS?). When the repository was converted to Git, the old commits were translated into Git commits, including commits older than Git.
Since Git is decentralized, GitHub doesn't know when a commit really was created anyways; I can push a commit from before 1900, too, I think.
ah intresting