#internals-and-peps
1 messages Β· Page 141 of 1
can someone help in #help-cookie? pls
This feature was going to be default in 3.10, but that was reverted and the core devs haven't decided exactly how annotations should be handled in 3.11. It's still in alpha so any features can be added/removed without notice.
Variable annotations for attributes are only allowed on local variable definitions, since those are discarded. Global variable annotations are stored in __annotations__, but there's nowhere to put your attribute annotation. You should just annotate the original definition of this class.
As an aside, __names are not syntax for "private" names, that's just a single underscore. Two are indented for the specific case of multiple classes inheriting from each other, so their attributes don't stomp on each other.
True, but it's not that important, it should be set to a proper value by the time of release.
can you show TimeState?
Oh, I see
actually, no, let's move to #type-hinting
any particular reason why you're asking about this on a python server? π
You can't modify a type after defining it. That doesn't play nicely with static type checking.
Why bother though
Guys guys how do i di oython
Is that a hacker tool?
Yall working in fbi!?!!
Cool
How do i hack also
Woahh cool hacker thing
Youre doing right there
Soo how do i do it?
Python is an interpreted high-level general-purpose programming language. Its design philosophy emphasizes code readability with its use of significant indentation. Its language constructs as well as its object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.Python is dynamically-typed and g...
amongst other things, yes - https://www.thepythoncode.com/topic/ethical-hacking
if you're seriously interested in the topic #cybersecurity
some might be, most probably not
def main() -> None:
while True:
collection_handler = CollectionHandler()
document_handler = DocumentHandler()
data_handler = DataHandler()
command_list = {
'new collection': collection_handler.create,
'del collection': collection_handler.delete,
'use collection': collection_handler.use,
'see collection': collection_handler.read,
'new document': document_handler.create,
'del document': document_handler.delete,
'use document': document_handler.use,
'see document': document_handler.read,
'new data': data_handler.create,
'del data': data_handler.delete,
'upd data': data_handler.update,
'see data': data_handler.read
}
command = input(">> ")
for cmd in command_list:
if command.startswith(cmd):
data = command.removeprefix(cmd)
try:
command_list[cmd](eval(data))
except NameError:
try:
command_list[cmd](data)
except SyntaxError:
command_list[cmd]()
break
there's some way to avoid these try except???
can u show me how?
You could parse that in two parts
You have a lot of repetition going on, so instead of specifying each particular action subject case you could generalize it to something like
actions = {
'new': 'create',
'del': 'delete',
'use': 'use',
'see': 'read'
}
handlers = {
'data': data_handler,
'document': document_handler,
'collection': collection_handler
}
action, subject, data = input('>> ').split(maxsplit=2)
handler = handlers[subject]
method = getattr(handler, actions[action])
method(data)```
that's soo good
Does anyone know why _ is handled as a soft keyword and not an identifier?
!e
import keyword
print(keyword.softkwlist)
@surreal sun :white_check_mark: Your eval job has completed with return code 0.
['_', 'case', 'match']
because it doesnt act like other identifiers in case _:
!e
x = 5
match x:
case aaa:
print(aaa)
@native flame :white_check_mark: Your eval job has completed with return code 0.
5
!e
x = 5
match x:
case _:
print(_)
@native flame :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 4, in <module>
003 | NameError: name '_' is not defined
Ohh so it was changed to a soft keyword recently?
Ah alright
Tbh I still think * would be a better wildcard
it doesn't even have to be a regular variable, so yeah
when i print the result of this i get <generator obj at 0x....>
so how do i do what i want here
That's how it works yeah
Exactly, that's why the type is a function that creates a generator
the type of the result of the function is a generator
If that's all the generator is you could also just use itertools.cycle
which is itself a function?
f
i think i get it now
i was trying to last night
but it was doing the same shit
ty
but now
i'm getting "itertools.cycle obj is not callable"
TIME.advance = itertools.cycle([ts for ts in TIME.values() if isinstance(ts, TimeState)])
...
if __name__ == '__main__':
while True:
print(TIME.advance())
so if the function returns a generator you would just call that again wouldn't you
im definitely misunderstanding something here
No, to use a generator you step through it in some way
cycle returns an iterator so if you want a single value from it you can use next on the cycle object, or iterate through it with a for loop
makes sense
people often use imprecise terminology which I don't really like
When you do (x**2 for x in range(10)) or _advance(), you get a generator or a generator object.
But _advance itself isn't a generator, it's a function. So the right way to call it is generator function.
A function with yield is a generator function. It returns a generator
yep
same with async. some people call an async def function(...) a coroutine, but it's a coroutine function. It returns a coroutine.
some people includes the python docs π
If I remember correctly
Are coroutines just asynchronous generators?
They represent a different concept, but they are implemented as generators IIRC
Ahh
Wasnt the concept of asynchronous programming introduced into Python itself with async generators?
Besides stackless python and what not
At first, before async def and await were a thing, you'd use a decorator on a generator
Ah
The main semantic difference is that a generator's purpose is to produce values, while a coroutine's purpose is to allow for asynchronous programming. The underlying mechanics that generators use do allow to conveniently achieve async programming, and although very similar (if not the same under the hood) in their implementation, generators and coroutines are used in different contexts
await does return a value, but what matters most is that it hands the control back to the event loop. yield can be used to give the control back to the event loop, but the main idea behind it is that it returns a value
Are you sure? I think they distinguish, but they don't properly emphasize the distinction, nor do they have distinct glossary entries
Like how there's no clear definition of a "file object"
This knowledge is communicated tribally, not via structured documentation
IIRC they mention at the top of the page that they use the word coroutine to refer both to actual coroutines and coroutine functions
pretty sure the glossary has both
I specifically had this portion in mind https://docs.python.org/3/library/asyncio-task.html#coroutines
"Note that simply calling a coroutine will not schedule it to be executed"
Oh yuck
coroutines are not callable
π€¦ββοΈ
You can have a callable awaitable!
That would actually be an interesting trick
You could have it call asyncio.run on itself
Or you could have two different implementations
Or the available version would run itself in a thread
Probably confusing to end users
Generators mainly pull data. Coroutines push data
@verbal escarp re: p2p package distribution, https://pretalx.com/packagingcon-2021/talk/RWR89G/
This talk will first briefly discuss the wheel package format and the current state of PyPI in the Python packaging ecosystem, focusing on a few shortcoming and relevant recent efforts. It will then introduce IPWHL from the motivating philosophy to real-world properties, before showing the current process and a demo usage. As this happens, the...
if you're on libera.chat, this is the user cnx
uh!
hu.. last time i talked to the ipfs guys, they didn't recommend using it for python packages, i might have ignited something there
i'm a bit skeptical now
were the talks recorded?
it hasn't happened yet!
you might want to connect w/ them on irc
i told them about you, too
oh, right.. still october
you did? oh man :p
π
ok, i'm on libera
i don't see any cnx on libera #python..
how to submit a fix for a typo on the python documentation?
#pypa @verbal escarp
hypothetically*
There is a docs contributing guide somewhere in the docs... i can try to find it if you don't see it
don't worry bout it
its actually an intentional typo and the docs explain it
hm, you seem confused
Oh that, yep
ye
are there other languages where the coroutines are callable?
exactly what it sounds like
try a regular coro
forget it π€£
hey guys, i have a random time complexity question:
if there is an if loop in a nested for loop in a for loop, the time complexity would be O(n^2 + n) right?
but you dont write O(n^2 + n), so you just write O(n^2)?
Can someone help me in #help-candy ?
I just spent like a good hour trying to implement PEP 660 - editable installations in setuptools. Turns out I completely misunderstood the way build_editable is supposed to work >.<
The editable wheel should basically just contain .dist-info and support files that actually make it "editable", in this case being a .pth file. I originally thought you could just reuse a normal wheel and stick the extra .pth file in there π€¦
!pep 660
Can someone help me in #help-cupcake
Are editable wheels a security risk
E.g. can you upload an editable wheel on pypi that links to some malicious payload?
Or is that no worse than just uploading the payload directly as a wheel
the pep states that an editable wheel MUST not be distributed, so no?
although I'm not sure if say PyPI would block it
but they could and it'd be spec-compliant
I can't imagine it being worse than just uploading a payload directly as a wheel
right
a non-editable wheel could already contain a .pth file, and .pth files are evaluated whenever the interpreter starts, regardless of whether the installed module is imported or not
oh huh
I'm not surprised as the install operation is usually unpack + entry_point scripts but I never considered that
yeah, but the things that are unpacked can include .pth files, which will be used by the next run of the interpreter automatically
in other words, even with a regular wheel, ```py
python -m pip install some_lib && python -c 'print("hello world")'
Indeed
finally, I hacked up a functional build_editable, it's very specific to my setup but at least it works =p
https://paste.pythondiscord.com/ovusorafov.py - this is the most sketchy thing I've written in a while
How does __future__ work? like before python 3 released, it wouldn't have existed in python 2 right?
it did? but it didnt have the print_function right?
Hey @still torrent, please claim an help channel like said in #βο½how-to-get-help 
Sorry for deleting your message, that was a missclick. Lmk if you want me to DM you the original content.
:ok_hand: applied mute to @unkempt rock until <t:1634559849:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).
How do you fix a bug which does not occur when run from source but happens only when you run it from binary/installed package?
Like what can be said about the nature of the bug?
Depends what the bug is
thats what i want to know
how do you approach to debug?
I ran the program(from source) using different shells but none of them reproduces it.
you can try to aspectize all functions and methods
that is, decorate everything with log.debug to log all function calls and their parameters
hmmm
decorating everything manually usually is too much trouble, but you can do it programmatically
advantage is that decorating stuff doesn't care about interpreters and runtimes
disadvantage is that some decorators don't play nice with others
i've had good success with that approach, though
i will try it!
performance implication is also limited which makes it suitable to debug "realtime" applications like pyqt
if you need help with it, just poke
i will
(shameless plug: if you were using justuse, you could do that in the future with mod = use(your_thing) @ (use.isfunction, "", decorator) π )
ok. now its really weird
Bug does not reproduce when its compiled using make. It happens only when installed through a package manager
tried with the aspectizing?
Is there a way to prevent an instance of python.exe from being able to open files or certain libraries? The current train of thought is to run the "sandboxed" instance of the interpreter via subprocess and do whatever shenanigans to prevent it from doing certain things. I would have to have a whitelist of imports that would be allowed and only allow those.
IE: allow numpy, configparser, but not sys, os, ctypes, importlib, etc.
@heady mauve not easily
As my research thus far has shown
@heady mauve even if you block all those imports it's not actually hard to execute arbitrary things.
The generally correct way to do what you want is to limit the user which Python is running as to access only certain things on the system.
I.e, create a new user with basically no privileges, and then give that user privileges on only what your program needs
You can do more advanced configurations but this is the simple way
Or use containerization to give the process its own private system to abuse.
That too
windows group policy has a ton of options but that's kind of a big ball of wax worth studying entirely on its own
plus you generally don't and shouldn't work directly with group policy as an application developer. You define what permissions your application needs and then it's up to the sysadmin to configure the policy however they want within those parameters.
I was about to post this to the Stanford server: "My nineteen year old daughter is enamored of Harvard. Please help me show her the error of her ways."
!e Hmm py print(124849745640593184256214502788000232711984346194239284918599169775251467106591187580476305077269760425019686159071753053924227569816588462643229463821875763427430576080998505780547826368760514503807579784278708008217584939464444237989070811887584423210788916656247499281**0.5)
@unkempt rock :white_check_mark: Your eval job has completed with return code 0.
3.5334083494636332e+134
On my pc (win10 64bit, py 3.9.6) the exact same code gives 3.5334083494636337e+134 (last 7 vs 2). Anyone know why this might be?
Number constructed with <#ot0-psvmβs-eternal-disapproval message> code
float precision is platform dependent
Really I though it was a standard
isn't that the point
windows py2.7.18
3.53340834946e+134
windows py3.9.5
3.5334083494636337e+134
ubuntu py3.6.9
3.5334083494636332e+134
ok well py2 wasn't very helpful there
i want to assume it's due to difference in rounding modes for the platforms? I can't think of another reason, the hardware representation should be the same (both platforms are x86_64 and use IEEE754 64bit double afaik)
and PyFloat just has an double fval member to store the double as is
hmm
!e more digits may help ```py
x = 124849745640593184256214502788000232711984346194239284918599169775251467106591187580476305077269760425019686159071753053924227569816588462643229463821875763427430576080998505780547826368760514503807579784278708008217584939464444237989070811887584423210788916656247499281
print(f'{x**0.5:.1000}')
my pc gives: 353340834946363365023871148628525120617391104199092003518319856057556622071902666612556464998161371385578049019244746510418552744312832.0```
@unkempt rock :white_check_mark: Your eval job has completed with return code 0.
353340834946363324676216803520578407243654041652031467116666843100939234092850220664937370985017705297369404017091130324431490670133248.0
I don't know if this is what's causing that or not, but modern CPUs have 80 bit floating point registers that are used for intermediate results, so that operations with 2 64-bit floats can be performed with less loss of precision, even though the final result needs to be rounded back down to 64 bits.
Floating-point contractions, machine instructions that combine floating-point operations, may be generated under /fp:precise.
What u said?
(Maybe gcc doesnβt do this with the flags cpython gets compiled with?)
/fp:precise is the default for msvc
According to mathematica the result is 353340834946363345257473017597911079933781446508208388719162940497886257062411267034976578524965264261618554821962433800999907190674409 but idk whether to trust it 
That's one of the leading reasons for differences of the sort that you're showing, anyway. It could be that in one case the generated machine code is able to keep the result in the 80 bit register longer, and is able to get slightly better precision.
!e oh it works exactlypy y = 353340834946363345257473017597911079933781446508208388719162940497886257062411267034976578524965264261618554821962433800999907190674409 x = 124849745640593184256214502788000232711984346194239284918599169775251467106591187580476305077269760425019686159071753053924227569816588462643229463821875763427430576080998505780547826368760514503807579784278708008217584939464444237989070811887584423210788916656247499281 print(y*y == x)
@unkempt rock :white_check_mark: Your eval job has completed with return code 0.
True
But also, floats only have 17 significant digits of precision, anyway. You shouldn't expect accuracy with numbers this large
I know 
What initially confused me is that sqrt methods differ #ot0-psvmβs-eternal-disapproval message
Interesting report from Εukasz Langa, our Developer in Residance with statistics about the CPython codebase:
https://lukasz.langa.pl/f15a8851-af26-4e94-a4b1-c146c57c9d20/
lukasz.langa.pl
One of the tasks given me by the Python Software Foundation as part of the Developer in Residence job was to look at the state of CPython as an active software development project. What are people working on? Which standard libraries require most work? Who are the active experts behind which libraries? Those were just some of the questions asked...
Quite interesting indeed
Try it with the Decimal or fractals module?
!e Decimal works given enough precision ```py
import decimal as d
y = 353340834946363345257473017597911079933781446508208388719162940497886257062411267034976578524965264261618554821962433800999907190674409
x = 124849745640593184256214502788000232711984346194239284918599169775251467106591187580476305077269760425019686159071753053924227569816588462643229463821875763427430576080998505780547826368760514503807579784278708008217584939464444237989070811887584423210788916656247499281
d.getcontext().prec = len(str(y))
s = d.Decimal(x)**d.Decimal(1/2)
print(f"{s:f}")
print(y)
print(y == s)
@unkempt rock :white_check_mark: Your eval job has completed with return code 0.
001 | 353340834946363345257473017597911079933781446508208388719162940497886257062411267034976578524965264261618554821962433800999907190674409
002 | 353340834946363345257473017597911079933781446508208388719162940497886257062411267034976578524965264261618554821962433800999907190674409
003 | True
Fractions got off pretty quickly
Isn't that an integer? I am confused
Yeah but sqrt needs floaty stuff I guess?
So you're just creating a decimal with no decimals?
Oh I though you were asking about fractions
the goal was to take sqrt of x which is where the floats come in
but it is a perfect square
I think that may be the way to go. Windows 10 1903 and up apparently comes with sandboxing. If I were to have my app subprocess another interpreter in Windows sandbox then that might work.
Are you reinventing subinterpreters lmao
there is the mysql.connector thing for ur responses in python to mysql is there something like that for csv files
this isn't a good topic for this channel. but you might want to look into the Pandas library. we discuss it often in #data-science-and-ml
the c-api provides a way to give members their own docstring
is it possible to do this in Python too? all i could find was giving functions/methods and classes docstrings
i don't think so unfortunately
sphinx supports it with
class Thing:
x : float
"""The 'x'."""
but python itself doesn't
is x an instance or static member there?
it's an instance member, if it were a class member you'd write x : ClassVar[float]
(i don't think there's any sensible distinction to be made between a class attribute and a static attribute)
>>> a = Thing()
>>> a.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Thing' object has no attribute 'x'
i haven't done python in a while, but what am i missing here?
the type annotation just says what its type should be if it exists
there are no uninitialized variables in python
it declares the type, but doesn't make it exist
oh, i need x: float = 5 for it to actually exist?
you still have to assign to it, e.g. in __init__
yes:
class Thing:
x: ClassVar[float] = 5.0
y : float
def __init__(self):
self.y = 0.0
wym by ClassVar? (i get that it's a type annotation, but i thought we said x was still part of the instance?)
>>> class Thing:
... x: float = 5
...
>>> Thing.x
5
>>> a = Thing()
>>> b = Thing()
>>> a.x
5
>>> b.x
5
>>> a.x = 4
>>> a.x
4
>>> b.x
5
but it's an annotation? annotations can actually affect things?
nope, that's why you need a static type checker to check these things
without a type checker like mypy, annotations are just suggestions / documentation
ah ok
everything after the : is ignored at runtime, and in 3.10 they aren't even evaluated, they're just left as strings
Python 3.10.0 (default, Oct 5 2021, 01:38:49) [Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a:print(1)
1
>>> class a:
... x: print(1)
...
1
>>> ``` i think they are still evaluated
huh
i thought that was the whole point of from __future__ import annotations
maybe it's just a repl thing?
i guess you still need from __future__ import annotations in 3.10
i thought it was on by default in 3.10+
i just tried it, that seems to be the case
the pep didn't make it to the release because of libs that use annotations for non type hinting purposes
ty, didn't realize
Actually, how are they going to solve things like this?
def make_foo():
Item = GenericItem[int, str]
def foo(item: Item) -> str:
return item.name
return foo
inspect_annotations(make_foo())
There is an another PEP proposed that I think handles that for the evaluation
Nah it was pushed to 3.11
typing.get_type_hints() i think just evals the annotations
so mypy knows that Item is a type alias, python at runtime knows you're just assigning something opaque to something opaque
but that's why you can't do TypeVar('T', bound=str | bytes) in 3.8 even with from __future__ import annotations, because that isn't on the RHS of : so it still has to get evaluated
Yes, that's what I meant
because stringly annotations are just that - strings - my example will break
It does in 3.10 (because it uses get_annotations() from inspect I believe) which was added in 3.10
Sucks if you're trying to support anything older than that though :/
For those visiting this channel for the first time, please refer to the channel description. If you're looking for help with a specific problem, see #βο½how-to-get-help.
This is more of a question about low-level and OS code, but with current process affinity and scheduling, the core layout is homogenous
With existing ARM big.LITTLE CPU's and upcoming Intel versions of big.LITTLE, the core layout is heterogeneous with a set of high performance and a set of high efficiency cores, some of which may or may not have simultaneous multithreading
Are there existing or planned ways to get and set the CPU core affinity and scheduling for processes on these CPU's?
I know the general idea is to let the OS handle scheduling, but the other recommendation I've heard is to set the affinity for programs to either the high performance or the high efficiency cores, rather than setting the affinity on a per-core basis
Why do I feel like iβve seen this question asked before?
Did u ask it on a Python mailing list?
hi fellas
i want to develop a program which can identify difference between 'ideal image" and 'difference image' . can anybody help
Ah here https://mail.python.org/archives/list/python-ideas@python.org/thread/C3BYESZBZT2PNQSWCW3HGD25AGABJGOJ/#C3BYESZBZT2PNQSWCW3HGD25AGABJGOJ I think this is the latest thought on the topic (so afaik no oneβs planning anything?)
Wrong channel - try #data-science-and-ml
thanks buddy
Tbh iβm of the opinion that if you need such fine control over your cpu, Python probably isnβt the right language for what youβre doing
Thank you for the link to the mailing list post! I'm pretty I've never posted this question on any Python mailing list
I'm less about super fine control like setting individual cores to a task and more about "this task is a priority and should be scheduled into the high performance core" or "this task is less CPU-bound and can sit on a high efficiency core"
We're both in the Raspberry Pi discord server, and I think I posted a similar question there before they purged their programming channel and made a new one
It's already possible to set specific CPU core affinities with either os.sched_setaffinity and os.sched_getaffinity for Unix systems, or with the pywin32 library for Windows, and the psutil works on pretty much all operating systems.
There just isn't a specific way to see that core A is different in performance/power draw than core B.
Comparing CPU frequency is one thing, but you can have situations where a higher frequency doesn't mean that the core is faster when it comes to things like IPC and such
Hey guys this might be easy but for me it is advanced topic: Can anyone tell me which programing path comes natively when you use a MacBook Pro with M1 chip?
hasn't there been any progress on that? that subject came up a while ago in here, didn't it?
Hello! How do you type your packages? Do you create a types.py module? For example, do I create a T = TypeVar("T") in every module?
"type my packages"?
you mean add type annotations to python code or something else?
Yeah, sorry, I mean the former.
is it your own code?
Yes, a personal project.
then just add the annotations right inside your code
you write your python code as a prototype. when you're confident about the code structure, you start adding annotations everywhere, maybe use beartype and icontract while you're at it
Thanks, just looked at beartype. I only knew of pydantic. For repeated types, though, do you create a module where you define the types and just import it or do you define it in every module like T = TypeVar("T")?
what do you mean by "repeated types"? if you have a class you want to use across your project, you annotate it once in a module and import it everywhere else
So for example, you only define T = TypeVar("T") once and just import it anywhere you need it?
why do you need a TypeVar? can you give some concrete code?
I've read typing.Any should be avoided so for variables or paramaters that can be any type, I thought I'll use T = TypeVar("T").
my point is that you shouldn't use those placeholders if you can avoid them - just write your code until you're happy with the structure and nail down things with concrete types
there's no point in using placeholders if you only do it to make some nitpicking typechecker happy
there are some cases where you can't avoid them, but those are rare
are you sure you need TypeVar?
As a learner, honestly I have doubts. For example, I have a function like this:
def f(x: T) -> str, that is, any type is ok because they're turned into strings anyway.
well, what are "any types" in your case? π
is that function supposed to be called by a user from an outside library?
or is it internal to your own code? in that case you could specify the exact types as a union
personally, I think inline annotations are clean and the best way even if its not just your own code
i was talking about code you don't have control over, imported as a library
I mean, literally anything: So the full function is like def f(x: T) -> str: return str(x). It's internal :)
even if you could in theory pass in anything, it doesn't mean you will pass in anything - in practice you'll pass in one two different types of objects, which, at this point, you might not be able to pin down just yet
so - don't annotate, write your code and when you know which types are passed in, you can pin it down
but if you know it doesn't hurt to annotate, you could always change it
I mean in other languages people don't even have the luxury of choosing
it's List<? externds Entry<? super T>> right off the bat π€£
guess that's part of the the benefit of the dynamic typing
Thanks :) And yep, I'm doing this to make a nitpicking typechecker happy lol
mypy ? π
you got it lol
yeah it's quite an effort to appease it. I sort of see @verbal escarp 's point. if you have to get it by mypy, it would be quite a bit of extra work during development
the insistence on explicit Optional made me stop using it
yeah, using Any wherever it was unclear did it for me
if you need to resort to those, your code just isn't ready for actual typechecking yet
isn't that the same as just not typing it
huh, I thought it just checked stuff you had typed
usually you can't clearly separate those
ic
im working on my own language, need opinion for something. Should i enforce indent blocks for conditions, loops and things alike or just have end keyword instead
if it's your own language, why are you asking in a python channel? π
i'm not even sure how if statments with else looks like?
if condiiton
do_something
else
do_nothing
end
- or is it -
if condition
do something
end
else
do_more
end```
because im writing the compiler and interpreter in python
LMAO
end is not a keyword in Python
if condition:
do_stuff()
else:
do_other_stuff()
That is all.
Also, please refer to the channel description for this channel.
thats not supposed to be python lol
ooo
ok
<@&831776746206265384>
!mute 894585668771139674
:incoming_envelope: :ok_hand: applied mute to @crimson plaza until <t:1634736511:f> (59 minutes and 58 seconds).
How are your scopes defined?
Well if youβre creating your own lang try to make it minimalistic
i am. still trying to decide if end is better than enforcing indent blocks
Compare memory consumption
Then donβt bother
Is this a project or for production?
Personally I prefer typing less
The backend should be able to determine the scope by indentation.
Anyone working on a project that would like a contributor?
we could use help with debugging and refactoring in https://github.com/amogorkon/justuse, if you're up to it
Finally a project and not someone needing help googling
its just for fun. for anyone to use. but i needed to know because typing preference matters. we all like typing less however some people do not like being forced to indent for getting inside a scope
I would say neither indent nor begin/end are the way to go, but braces. But this is a long discussion on language design that only touches somewhat on python
why not both braces and indents π
because what purpose do the indents serve at that point?
Readability?
err, nobody is saying that the code wouldn't be nicely indented?
Oh
this is just the definition of the language grammar
Ok nvm
hah I see now why you reacted that way, the rolling eyes seemed a bit harsh π
LMAOO
Thatβs rolling eyes? I thought it was just looking up maybe slightly exasperated
im just tryna figure out what people prefer π
I just put my mouse over it and saw what popped up π
uh, does python do loop unrolling and if yes, does the bytecode reflect that unrolling (where can i see it)
honestly, it makes no difference, syntax is quite insignificant compared to other properties of a language
no loop unrolling
Eh, I don't really agree, python's delimitation by whitespace has definitely had consequences for the language
alright well that solves a whole bunch of questions i guess haha
Isnβt there a niche case of unrolling with strings somewhere?
it's been oft-cited as the reason why it's so hard to come up with a multi-line lambda syntax
yeah, I wouldn't go with indents personally, since it makes the grammar really hard to express sensibly.
and multiline lambdas are also an issue
My $0.02 is that at this point in time, it's been more-or-less-proven that braces + auto-formatters are the way to go
but in the end, nim has multiline lambdas and indentation based syntax
when python was created good auto-formatters didn't exist
but yeah, braces are probably the way to go
so python's take was a reasonable solution on solving the problem of "how do we ensure that the what the code does and what the code appears to do agree?"
Python was developed in like 1990. "production level" auto formatters weren't a thing until like 15+ years later.
when google said "we want to just run this auto formatter on a billion lines of C++" and they developed clang-format, and that kicked off the trend
the irony is that not only does the whitespace put python in a tougher position parsing wise, but python still wants/needs auto-formatters, and then they end up not working as well in python as in many brace-based languages
compared to begin/end?
eh, it's a lot more intrusive than braces
Kotlin/Swift have done some really amazing things with braces in their syntax
which is one of the reasons why i was suggesting both
But there's no reason to have both in a new language....
braces are more or less the standard, you would be hardpressed to improve on them
^
Hmmm
If you want to write a new language with nice syntax, I'd really start by looking at Kotlin/Swift, they're two of the newest mainstream languages, they allow you to do very slick things with their approach to creating and passing lambdas
I just don't think braces suit the language style. My language is more python like
i don't like braces either, it's more to type and more visual noise
So end > forced indents?
forced indents I wouldn't hate, but they do have issues and with automatic formatting, they are a lot less needed
Fair
also they are a damn pain to implement
i guess it really depends what you want your language to look like
END seems fine when you are mostly thinking about basic constructs like loops, if
Loops, ifs and macros/functions
there is a case to be made for forced indents being easier to read, simply because even with braces we've seen indentation make things nicer
ruby has end and does just fine being one of the most expressive languages
Less fun when you start thinking about lambdas
Anything that requires its own scope
Thing is you can still use indents with end it's just not required
so then the thought goes: if we have to* indent anyways to make things easier, then why have extra syntax on top
i like braces
It doesn't really make things easier to read though if it ends up properly indented either way
Kinda my point
π
the issue with forced indents is when you need a block as part of an expression
i would like to have braces with lambdas, simply because indents don't work well inline
but END is not more minimal than braces
Originally went enforcing indents but maybe that's annoying
which is something a modern language should always do
this should be solved on it's own merits, no?
and whitespace-only has a lot of practical issues once you go beyond the basics
End is just one word as supposed to a brace before and after the scope
nim has that syntax, and it gets confusing
sounds like, just have braces for scope, forced indentation for indents, win win? or no good.
end is definitely the worst of all worlds though
still 3 characters instead of 2. and END to me looks very bizarre at the end of a line as opposed to on its own line
end with an optional tag could work
end is just fine
opening braces aren't exactly needed
Not doing braces
they are in C because of the way C syntax works
needed for sanity π
end with no begin π π
but they don't actually help the syntax over just not being there
I think END is ok though, kidna ugly but eh. Still better than whitespace. If you want end then look at Ruby.
Never planned on adding a begin lmao. Just the keyword followed by end. If that was a joke I'm dumb LMAO
like an implied comment - something like ```
foobar for ...:
...
end foobar
thinking of sql server's ugly
end else begin
you have to label every for loop in Ada?
ah no, it just does it for procedures and a few other constructs
no reason to have end if
Just end, not end if
Yeah so what's the tag?
it's not ambiguous with no tag right
there's no reason we couldn't have multi-line lambdas by wrapping the entire thing in parens. There's no reason that Python couldn't have:
def sort_the_list(lst):
lst.sort(key=def lambda elem: (
field1 = elem.field1
field2 = elem.field2
return (field1, field2)
))
Python has multi-line lambdas today. What it doesn't have today are multi-statement lambdas. (My def lambda here is pseudocode for "a lambda that allows statements")
not ambiguous but harder to parse visually
also, afaics that is still whitespace dependent
how do you know where the if clause ends and the body begins?
Using indent levels
Check if the indent level is greater by one then the If statement
so now you dependent on whitespace and use end
so this is pretty much the worst of both worlds tbh
in cmake they're optional
well, right now indentation in expression doesn't exist
Nono I said originally I was using enforced indents
this is a nitpick, we all know what is meant by python not having multiline lambdas
Without end
well, if you're determined to use whitespace, then just use that? Why ask here?
I'm confused.
I'm rewriting my code. Originally it was white space only. Now I'm asking should I stick to whitespace or use end instead
I'm just curious about people's preferences
I will not make a decision about a language based on their block syntax
sure, but people pretend that the problem is a parsing one, and it isn't. multi-line lambdas work fine. You wrap the code in parentheses, and leading indent gets ignored. What doesn't work is multi-statement lambdas. And that could work fine, and be parsed unambiguously - it just needs new syntax to define a new, entirely different type of anonymous function.
I like pascal despite their insanity
It's not based on blocked syntax. I'm tryna dΓ©cide on a syntax lol
well, right now the parser ignores indentation in an expression entirely
it could be parsed, no problem, if stuff was added to the language, changing how the language is parsed?
fortunately
So it can't be parsed, unless how it's parsed is changed, so that it can be parsed?
you are currently deciding on your block syntax
Yeah I think we agree π
yes, exactly.
End counts as block?
lol
Lmaoo
this is called a "distinction without a difference"
well, we had the discussion a while ago about an experiment with just def (): as lambda, a clearly anonymous function definition, but currently you'd need to work around the limitation that python doesn't allow inline defs and then no multi-statement lambdas..
yes, it is possible, look at nim
it's not a fundamental limitation of using indents rather than braces. It's just a limitation of Python as it exists today.
yes, that is not in question
but honestly, it gets really messy in nim
good to know
I stopped reading about nim after I saw the whole foo_bar will automatically call fooBar thing or whatever it was
I still argue that it is great in a glue language
maybe in theory, but it has minimal traction, and if there's one crazy decision like that, there's going to be others, and it's probably not going to get traction
if you have 2 libraries, where one is in C and one is in python, they will use different conventions, and you can still use the same one in your code using both
but yes, nim is more or less useless
when you see a decision like that you immediately know 99% of the decisions in the language are made by one person because the odds of two randomly sampled software engineers thinking that's a good idea are 0
the same is true with Pony's divide by 0 = 0 thing
Why is that? nim has always looked appealing to me, but I never dug into it very deeply - what limits its utility?
somebody didn't pay attention in maths there
undefined is so much better than 0 /s
it doesn't do enough to be worth adopting
well, pony has 3 division operators
but yes, trying to be a theoretically sound language while focusing on performance is silly
should've just not been cowards and gone with / is a partial function
in a language without exceptions, making x / 0 return 0 doesn't seem crazy to me. Why return a sentinel value like undefined or an error return code that the user will have to check, when the user could just check the divisor before calling /?
that's true for 0/0, but x/0 with x > 0, it's inf.. very ugly and very hard to work with if you want to do it properly
because 0 is a nonsense value... when a function gets nonsense input, it shouldn't guarantee that it returns a specific nonsense value
0 is also reachable by division in other ways, so it doesn't work well as a sentinel
it's just terrible
I stopped reading about Pony after learning about divide by /
there's so many languages that are actually good and in use that I know much less about than I want to
The C++ "undefined behavior" approach, where you say "if you do X, then the rest of the program is ill-formed, and no rules apply to what the compiler can generate whatsoever", isn't exactly nice for developers, either.
semi-predicate problem π
Pony has this really cool actor model runtime thing with insanely strong guarantees, atop which a wonky language is written
it's nice for performance, but really, really bad for correctness.
But in JavaScript they're the same thing :p
I mean, pony also has /!, which does UB given 0 as a divisor
yes, but C++ is performance focused? I don't know what else to say.
if you don't handle the edge cases properly, you can't make any guarantees about the rest of the program though
yeah. I'd be willing to bet that >90% of real-life C++ programs are ill-formed.
C++ is not only performance focused, but it's only very focused on running on a very wide variety of hardware
which means that the fact that they work is just dumb luck.
if this teaches anything it's that language design is a minefield
undefined is bad behaviour in my opinion. But the benefit of an exception is that it will ensure that the actual error will be raised from where it happened (and not 5 calls deeper where you have no idea why something happened).
like idk, I don't really care about minor problems like picking a bad / default
there's a lot of UB that is in practice guaranteed on a specific implementation, that people end up depending on
for sure developing for C++ is a headache relative to most languages but it's not dumb luck
That's cool and disappointing
there are more useful ways to do division than just /
You can get the same performance in rust though right
in a language that has exceptions, I agree 100%. In a language that doesn't... Β―_(γ)_/Β―
Nim doesn't?!
in a language that doesn't have exceptions, you will have to cover every goddamn corner case properly
Segfault or-?
yeah, I would argue that pony shouldn't have / at all and force you to choose between /? which is more or less a checked exception and /!, which is the raw LLVM instruction
we were talking about Pony, which doesn't, AFAIK
More or less, but e.g. division in Rust, will apparently always check if the denominator is 0, which adds instructions
So what happens when things go wrong?
things don't go wrong
and returning undefined is proper behaviour for some operations in math
that's a sad fact
you are forced to handle all erroring states
except signals
the language will not crash except by running out of memory or being killed by the OS
that's an alternative way that it could have been handled. divide by zero could trigger a SIGFPE signal.
the actual problem is probably simply that integers don't have representations for NaN/Inf/-Inf like float do, and they don't have built-in handling of these things the way that floating point does
(on modern hardware)
so the buck gets passed to the programming languages
and there is no great solution, but there are some terrible ones
I want to ask how this works, but I take it that errors aren't used the same way.
One issue I would have would be difficult RuntimeErrors, but I guess that whole situation doesn't even exist in Pony?
you have to catch all runtime errors and handle them somehow. Be it accessing out of bounds, division by 0 (when you use the correct operator to do that), opening a file etc
there is no panic
So the compiler enforces all calls that are documented to raise errors to handle those?
yes
except you can of course bypass it with C interop
AFAIK, that's not a correct nitpick. UB is a special case of "ill-formed, no diagnostic required". But regardless, it is absolutely true that programs depend on how their current compiler behaves in the presence of UB - which means that compiler upgrades frequently break C++ programs, because those programs have always been incorrect.
couldn't exceptions be handled in a seperate overwatcher thread?
so that when something happens there's a way to resolve and return?
Is there an equivalent to RuntimeError because it seems awfully annoying to having to deal with that in a program like asyncio where get_running_loop() may raise RuntimeError if the event loop isn't running... even though you are in a task/coroutine which has to have an event loop running to execute.
if something goes wrong, just let it burn
no. Though it isn't super annoying since it's not exception, and there is only a function that can have some error, or a function that can't have an error
like, that wasn't really an inconvenience for me
IFNDR is usually discussed in relation to compile/build time
UB in general depends on runtime
But you still need code which is basically equivalent to an try/except yeah?
yes
it's not at all a nitpick, I wasn't trying to nitpick
this is how C++ engineers use these terms, day to day
or declare the caller as partial, at which point it can call partial functions without an explicit check
Hm? No, UB is entirely about what the compiler is allowed to emit. And I am a C++ engineer.
UB is not entirely about what the compiler is allowed to emit, no
that's just wrong
UB affects what the compiler is allowed to emit, yes
whether your program actually has UB or not can depend on runtime values
true.
So what happens if you want to make a function call inside of an except, and this can raise an error? Handle that as well?
I think I feel satisfied with this conversation though because I know that APIs will be designed differently to account for this annoyance
yup
Anyhow, I honestly did not mean to turn this into nitpicking. IFNDR is most commonly a think when you have some kind of error between TU's that only the linker could in theory diagnose but it cannot because the linker is shit.
the program either has undefined behavior or not, though, I thought.
yes. And when the program has undefined behavior in any one part of it, the behavior of any other part of the program is no longer guaranteed.
IFNDR can cause UB, e.g. ODR, but there are many other ways of causing UB, most commonly having to do with things that happen at runtime e.g. dereferencing a null pointer
"the program" in the sense of the whole run of the program, including its inputs, is technically what has UB or not
in practice some programs will have UB every time they're run, regardless of inputs, so then we might just say "this code has UB" which is essentially shorthand
the compiler would be allowed to make whatever assumptions ut wants, if, say, you forget to check before dereferencing somewhere, I think
correct
the compiler assumes that UB never happens
so if you dereference a pointer, afterwards the compiler can assume it's not null
fun things like that
including removing your checks
yep
which was the cause of a recent-ish Linux kernel security vulnerability.
it seems crazy, because people think "why would I write checks only to have them removed"
people tend to not consider how much inlining happens in a real program
and when inlining happens, you end up with code next to each other that's silly and redundant, so these optimizations make sense
even across TUs, with LTO.
yeah
ODR violation counts as UB?
i'm sympathetic to people who find all the UB and edge cases in C++ rough, I do too.
Not sympathetic to people who want the compiler not to optimize UB.
yeah I'm pretty sure
One and only one definition of every non-inline function or variable that is odr-used (see below) is required to appear in the entire program (including any standard and user-defined libraries). The compiler is not required to diagnose this violation, but the behavior of the program that violates it is undefined.
the same people who think "why would the compiler remove that check, I wrote it for a reason" are the people who otherwise would say "oh, that's OK, that will get optimized out", and not realize that it's exactly the same process that's allowing one bit of clearly useless code to be optimized out as another.
that's pretty clear
hah, it is? π
I've been tripped up by ODR rules many times
literally yesterday in fact
that you're screwed π€£
yes, same
Being a C++ engineer is like being a well paid Sisyphus
yeah, you ain't wrong.
you don't really get warned for it in the situations that matter
because, remember, the linker is 50 year old dogshit
It doesn't know anything about C++
or even C
it just knows symbols
with LTO i guess you do at times
C++'s build stack is the craziest thing imaginable by modern standards
Yeah, that could be true, perhaps LTO allows issuing extra diagnostics, I can't speak to that
we don't really use LTO, the way our application is structured it's not that useful
then we got modules
I'm withholding judgement π
any day now..
but yeah, C++ pretty much decided exception specifications are junk
the prognosis for compiler-verified error handling doesn't seem bright
another feather in the cap of "don't save the user from themselves"
I think you should save the user from themselves, but you shouldn't protect them from themselves
Though guess it's hard to differentiate with a compiler like that
what's the difference?
Well, you can only compiler verify up to a certain point really
trying to really have the compiler verify error handling was tried... it's called checked exceptions
and it was a disaster
if you look at more modern languages, what they mostly tend to veriffy at the compiler level is "can this function error or not" but in many/most cases they don't try to verify "did you handle all the possible errors" outside of the immediate context
You should simplify API and raise errors and warnings (saving them from normal mistakes made), but if someone wants to get down into the internals and do some advanced stuff you should allow them to do so (meaning that you don't protect them from it).
reminds me of.. python? ^^
eh I mean python is nice in that it's simple and readable but definitely goes way too far in not even trying to protect users from many kinds of errors, unnecessarily.
but then it's dynamically typed so what do you expect
a long standing requests.Session seems to drop connections, i think due to linux not enabling TCP keep alive, I've seen some suggestions that altering the HTTPConnection socket options in urllib can alleviate this error. anybody have experience in the area?
and even if you go to great lengths to require handling possible errors, you can still crash because of a runtime error π€£
why do we create class inside a class?
it is quite rare to see this. One case I can remember is django using a nested class for metadata about a model, but it is very rarely the correct thing to do
it's usually a bad idea. nested functions often makes sense because when a function is nested it can capture some nested state, which is useful
but classes already are designed to capture state, in another way, explicitly. So when you have a nested class, now you potentially have both explicit, and implicit state, being used inside the class.
sqlalchemy moment
@halcyon trail by nested functions you mean decorator functions right?
No I mean like defining a function inside a function generally
!e Functions enclosed in other functions, like this: ```py
def adder_maker(num):
def adder(other_num):
return num + other_num
return adder
add5 = adder_maker(5)
print(add5(10))```
Often when you write decorators you do implement them that way
@spice pecan :white_check_mark: Your eval job has completed with return code 0.
15
ah
if it's worth anything, the solution seems to be subclassing HTTPAdapter from requests..adapters, specifying socket_options , and mounting the adapter on the session
that probably warrants a github issue
does that always work? the local state is reliably captured?
that's how most decorators are implemented
so yeah, it is reliable
nice
some languages have broken closures, is why I asked
it's OS specific, perhaps you're right. it just turns out linux and TCP keep-alive aren't the best of friends.
Can you give an example of what you mean?
well maybe it doesn't count, but in java variables can only be captured if they're "effectively final"
@lusty scroll can you give a code example or a link explaining it?
afaics Java is actually doing this to save you from shooting yourself in the foot, in a way that is easy to do in python
seems like a mix of that and also language limitations re heap and stack π keep in mind that python will prevent you from trying to re-seat capture variables as well, a restriction with some of the same motivations. that's what nonlocal is for
I see.. still, it's nice to have the option if you do decide shooting your foot is in order
yeah I suppose. on the flipside Java lambdas actually suck less than python's... who would have thought that would happen twenty years ago
it's hard to do worse than lambda as a keyword π
^
what's bad about lambda as a keyword?
compared to other symbols like: ->, \, it just looks terrible
this, and it's also quite an obscure word that is named after lambda calculus which a lot of people aren't familiar with, making the choice for the keyword even less intuitive
I was really confused when I learned about lambda, as compared to other things in python, the name for the keyword wasn't that intuitive. It took me a while to realize it was just an anonymous function
i remember in a talk, raymond hettinger said it could have just been named makefunction
Why was it named lambda, a design choice from Guido?
IIRC it was copied from scheme or other lisp dialect
Ah
Yeah true
there's never something where you absolutely need them (I think)
they just make some things easier
I think def x: 42 would definitely make them easier to explain π
Exactly, I think salt rock said that a nicer notation for lambda would be
def (x, y): return x + y
lambda looks bad, and also the fact you can't have multiple lines
but that's also because python has evolved with shitty lambdas, so obviously you don't really feel their lack at present
I feel like lambdas are made to be discouraging
Possibly
they are in python
I really hope a core dev takes on PEP 505 soon
I would really love none aware operators
if that's the case though, why even put them in
Why would they exist in the first place then?
idk, you could say the same thing about map
map is pretty nice
possibly mostly backwards compatibility at this point
why map instead of list comp?
I prefer map(int, iterable) rather than [int(j) for j in iterable]
applying callables to each item in an iterable looks much nicer with map
personal preference ofc
sure it's personal preference but also pretty explicitly against the grain of python
not something I have an answer too
define 'grain of python', cause I'm not sure if you mean PEP8 or something else
I mean list comprehensions are clearly the preferred way of doing things, by the language
they're much more common in real code, they extend better to the case of not having the exact callable you already need
they were introduced explicitly as a feature to the language when map already existed
so it's pretty obvious that was done because they think LC's are a better solution
You shouldn't use map for everything ofc, but I do love map for conversions and what not
eh it's just a loss of consistency with no real benefit
something something only one way things should be done
? wdym
from the zen
you still need nice lambdas for map to be cool
I never used map, I always find comprehension way more readable
same
I can understand it for reduce and stuff like that, along with checks
that's true, some languages like js do use them more
LC's are nice but the fact that you have to first class it into the language has all kinds of downsides
map(f, map(g, map(h, iterable)) 
and also the fact that it can just be one expression is pretty lame
if you have more complex logic then in python you either define a function locally and then use an LC, or you create an empty list and append into it. both of these feel lame.
My eyes after seeing this
it would be nice to be able to write stuff like
new_list = old_list.map {
first line of logic...
second line of logic...
third line of logic...
}
map(lambda x: f(g(h(x))), iterable)
that is not point-free smh @sand python
what does that mean
what would yo uall think would be better function composition syntax, assuming f and g are callables
f @ g
or f + g
"pointful" is when you name the argument, like lambda x: f(g(h(x))). "point-free" is the opposite - you don't name the argument, like compose(f, g, h)
interesting
neither π I don't think function composition is worth having special syntax for
There's a utility that converts Haskell code to point-free version https://http://pointfree.io/:
that's a whole new level of esoteric
imo python having more functional features would be pretty nice, like function composition and the likes
i might learn haskell sometime soon
Python already has function composition, you can write a function that does it
but yeah, it's not as nice as .
Yeah fair, I meant something like __matmul__implementation for functions that would allow you to compose functions together, however there would need to be a special implementation for builtin methods and what not to allow that
"point-free" smh
speaking of new syntax, what about this? ```py
@EXPR1
with EXPR2 as TARGET:
BODY
<=>
with EXPR2 as __x:
TARGET = (EXPR1)(__x)
BODY
or maybe?
with EXPR2 as __x:
with (EXPR1)(__x) as TARGET:
BODY
Not sure where it would be useful... but that's a thought
using context managers for decorating? that looks interesting
oh wait
decorating context managers**
how would that work with multiple items in the with statement?
apply to each one, I guess?
does anyone know c# and familiar with pyobjc? I'm trying to use the pyobjc-framework-Quartz to get the toupe of a window location in osx in python3. I found this script written in python that uses obj-c quartz wrapper but it lists info on all open windows. I'm trying to get toupe coordinate of specific window to feed to mss to take a screenshot for opencv/OCR. https://github.com/drksun/ocr-gspro-interface/blob/main/ListWindow_osx.py trying to get kCGWindowBounds by giving a kCGWindowName
the issue is the pyobjc-framework-Quartz documentation says see apple's doc and that's all in obj-c I'm confused
sweet i figured it out https://github.com/drksun/ocr-gspro-interface/blob/main/CaptureWindow_osx.py
Hi, can someone help me figure out how to use functions in python?
I just started programming π
does PyPy have a buffer class? i keep seeing it referenced but I can't find it anywhere
or at least it doesn't appear on my pypy interpreter
ok nvm apparently i can do this:
from pypy.module.cpyext.api import (
cpython_api, Py_buffer, Py_ssize_t, Py_ssize_tP, CONST_STRINGP, cts,
generic_cpy_call,
PyBUF_WRITABLE, PyBUF_FORMAT, PyBUF_ND, PyBUF_STRIDES)
or not :/ time to figure out how i can do that
I like @ bc it more closely resembles the composition operator in math
I do wish we had a compose and pipe operator
Like pipe would create a closure that called the functions in order, automatically feeding ones output to the other
why would it create a closure that does that instead of just doing it
I guess
f(x)|g
But if you did f|g then it would delay the operation
Like maybe you don't want to execute it immediately
then you'd make a lambda out of it
a better solution if you don't want something to execute immediately is to just have a good lambda syntax, and then that works for everything
the problem is that f | g can't delay the operation, because when you have pipe that already means something
it means g(f)
how about f * g
For function composition?
I think it's somewhat of a lost cause because lots of things are callable
yea
as a hypothetical operator
i guess whatever issue f | g has, any binary operator might also have
@lusty scroll :white_check_mark: Your eval job has completed with return code 0.
001 | 40
002 | 49
!e
def f(x): return x * 10
def g(x): return x - 1
def fun___mul__(self, f2):
def apply(*args, **kwargs):
return f2(self(*args, **kwargs))
return apply
from forbiddenfruit import curse
from types import FunctionType
curse(FunctionType, "__mul__", fun___mul__)
print(f"{(f * g)(5)=}")
print(f"{(g * f)(5)=}")
@lusty scroll :white_check_mark: Your eval job has completed with return code 0.
001 | (f * g)(5)=49
002 | (g * f)(5)=40
@surreal sun π
can some one briefly explain to me what is Metaclass
it's literally the class of a class
if a class is a blueprint for objects, a metaclass is a blueprint for classes
oh okay thanks
type is the default metaclass, I believe
actually, i know how it could work in practice
replace * by @ for consistency with decorator syntax and then rewrite the functions that are essential to functional programming like map, reduce etc. with a variant that returns a closure
then you'd write (map(f) @ reduce(g))(list)
downside would be the changed signature in normal situations
like map(lambda x: x**2)(range(10))
on the upside, it would be explicit which params are used for "configuration" of the function and which param is iterated over
i had just realized i used that pattern in my fuzzylogic library, somehow never relating it to function composition
hmm but if you use operators that already exist, what would happen for f @ g if they had both __matmul__ and __call__ implemented
i don't think i've ever seen pure functions implement __matmul__
nobody does that, for obvious reasons
but __call__ is a problem for backwards compatibility, yeah
replacing map and reduce with those variants is breaking
but it actually might enhance performance in many cases to consider two phases
in fuzzylogic, i use this pattern not just because it's nice to work with. in some cases it's useful to prepare heavy math ops in the first (initialization) phase and then reuse the results in the second (work) phase
so you don't have to repeatedily calculate exponentials and whatnot
for general purposes, the initial phase could be used to prepare a JIT of sorts
there could be a hook in __matmul__ that triggers a JIT - "hey, something's about to happen, look!"
just contemplating
yeah, kind of fearing we might run into the same issue that forced pipes to provide both << and >>
exactly that
but with an explicit initialization phase for those complex functions that could be remedied
(map(func) @ filter(lambda x: x > 2) @ list)(iterator) doesn't even have a direct simple list comprehension to compare to
it would require a comprehension-comprehension
[x for x in (func(y) for y in iterator) if x > 2] i think?
ugly as hell
the ugliest part in the composition is the lambda, imo
let's replace that by a hypothetical (map(func) @ filter({x => x > 2}) @ list)
that looks nicer
that's pretty awful
might have to special-case stuff like classmethod too
You can do that in a non-breaking fashion
def map(func, iterable=None):
if iterable is None:
return composable_map(func)
return regular_map(func, iterable)
i like!
i had thought of some kind of dispatch, yeah
nice and simple
Although I guess that's not exactly correct yet
This should be equivalent to map's current behavior, given that you do define regular_map and composable_map
def map(func, *iterables):
if iterables:
return regular_map(func, iterables)
return composable_map(func)
But yeah, there are ways to achieve this without introducing a breaking change
i think composable complex functions like that could help with comprehension-comprehension situations
Thatβs true
tbh i find comprehension-comprehensions very hard to write correctly, i almost never get them right in one go
having a clean and simple alternative to plug stuff together would help greatly in those cases
i'm just pondering, if generators supported __matmul__, we could actually plug comprehensions together like that.. maybe forbidden fruit can do that?
with a bit of wrapping you can achieve that without dark magic
gen @ composable(other_gen) @ function @ whatever_else_you_want_im_not_sure
if composable implements __matmul__ and __rmatmul__, this should be functioning
that could work. a bit of dark magic would make it a bit more elegant, though π
Having this out of the box would be convenient, but having a lack of dark magic makes this a significantly more stable solution that you can use in production environments without a feeling of guilt
true
You could opt in for a slightly-less-magical wrapping value that would make this more elegant, something like
makepipe @ gen @ func @ ...```
actually, that whole approach would easily be PEP-able. no AST-fiddling necessary, backwards compatible..
would have to build an actual prototype for it and test it a while though, i guess
This leaves some consistency questions in the air. As fix said, lots of things are callable, but you can't auto-force composition onto each and every one of those automatically, since they just implement __call__ and don't have a common callable ancestor
You can soften it with reflected operators, but if you try to compose several things that don't support it themselves, you'd either have to patch them beforehand or force a blank in there just to convert to composables
And lots of things that pretend to be functions aren't actual functions
can't really make an educated guess as to how hard it would be to catch those without some actual examples
and i don't know how often people try to call stuff that isn't a function in a functional way
maybe the most prominent example of that would be something like list()
Every class (mostly applicable to built-ins such as int, range, str and so forth), classmethods, singledispatch objects, map and filter (perhaps reduce as well, not sure there), etc
map isn't a function?
nop
@spice pecan :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 1, in <module>
003 | NameError: name 'help' is not defined
Oh wow
Since all of them use class constructors, you could technically patch type
Since, after all, calling any of those is equivalent to calling their __new__
But that still falls short for static/classmethods, which are classes used as decorators that return callable instances, same for singledispatch
Partial might actually return functions, not sure about that one
Oh, attr/itemgetter and methodcaller... There are lots, to say the least
Cases like these make me feel a bit bitter about duck-typing, since this would be a lot easier in a language with extension methods on interfaces
It would be a matter of overloading @ for some abstract Callable that every callable type inherits from
got a point there
This is why it would be significantly cheaper to just shove a blank in front that would wrap the chain into composable of some sorts
functools.partial? iirc that is a class
I think so too, can't check right now
but it could be easily implemented as a wrapped function
Yeah I can confirm, I think I was messing with functools source code the other day and saw that
Yeah
maybe all it takes is a little helper function that people can wrap their callables with if they run into a situation with AttributeError: foobar has no __matmul__
It really is, yeah
I though / after means that parameters before it are positional only
@surreal sun :white_check_mark: Your eval job has completed with return code 0.
hi,test
All it needs is a / after function so you can still have function as a kwarg
I thought / after meant positional only
For parameters before
It does
And having that allows you to receive kwargs that are named like pos-only args
!e ```py
def f(a, /, **kw):
print(a, kw)
def g(a, **kw):
print(a, kw)
f(10, a=20)
g(a=20)
g(10, a=20) # This one's going to crash
@spice pecan :x: Your eval job has completed with return code 1.
001 | 10 {'a': 20}
002 | 20 {}
003 | Traceback (most recent call last):
004 | File "<string>", line 9, in <module>
005 | TypeError: g() got multiple values for argument 'a'
Ohh
that is left as exercise to the curious reader
@stable grail Just letting you know I've updated the repo for PyPacker, it's sorta-kinda useable outside of my own test cases now.
I want to make a ListenerFuncABC that would pass the isinstance(func, ListenerFuncABC) check if the function object has certain attributes and meets some other defined conditions in the ABC, I know that there's __subclasshook__ that can override issubclass, but how would I override isinstance function?
metaclass with __instancecheck__ would work
do I need a metaclass? can't I just override something when inheriting from abc.ABC?
what I'm essentially trying to achieve is a structure like this: ```py
class Foo(Controller):
@Controller.listener(name="bar")
async def my_listener_func(self, *args, **kwargs):
...
the `Controller.listener` decorator will set certain attributes for the `my_listener_func` object itself for which I then want to perform a simple `isinstance(function_object, ListenerFuncABC)` check within the metaclass `__new__` so that I can know whether it's a listener function or not. Alternatively, I could probably just make a standalone function that checks these, but I think the ABC makes more sense here, or should I go with the standalone check function approach instead (something like `is_listener(function_object)`)
(Controller is inheriting from ControllerMeta that defines that __new__)
Nvm, you do need a metaclass__instancecheck__ on your class should be sufficient I believe
Does anyone knows hot to do video stitching using python ??
i know from podcasts with professionals in the media area that python is used for such pipelines, but i'd have to search which packages are used specifically..
hmm, I could swear I've seen this done with a class that simply inherits from abc.ABC by just overriding some method, since abc.ABC already inherits from abc.ABCMeta
Sir!! If you can share some resource links!! That would be helpful
https://github.com/topics/video-editing?l=python&o=asc&s=forks <- there's that
All i can find is having a classmethod decorated __subclasshook__. Perhaps ABCMeta uses that in __instancecheck__ calls as well?
Something like if issubclass(type(instance), cls): return True would make a lot of sense in virtual subclass context
so you're suggesting something like this? ```py
@classmethod
def subclasshook(cls, other: Type[type]):
# We're dealing with an instance, use the instancecheck
if isinstance(other, FunctionType):
return cls.instancecheck(other)
# The function's class itself cann never be a listener fucntion
else:
return False
is other always a type? or could it be some metaclass like ABCMeta
totally agree .. there's no connection between any of these afaik except having __call__
maybe if python aded extension methods that could be enough
well ABCMeta is a type, so disregard
I'm not sure how that would work, honestly
I guess some aspect-type feature would be necessary
you're right, it wouldn't work if we just had extension methods, pretty sure
probably simpler to retrofit the callables with some kind of common base type, and some more unlikely magic
maybe by overriding __get__ somehow
Retroactively making them actually inherit from ABCs would be the optimal solution IMO
Though that won't fix the issue of new types with __call__ not being registered, hmm
thanks π
well, it could probably even be Any, the user can pass anything in there the checks happen internally without any prerequisite for what the object that it's comparing is. I figured Type[type] will essentially cover anything since it's just an object created from type, which should include type itself since that class is a bit weird, type(type) is type # true
yeah, that's the contract I suppose, not everything anyone could possibly pass in
can i not have a class in test.py, put from _impl.test import MyClass inside __init__.py, and then outside of the package do from test import MyClass?
(to hide the fact that it's in its own file)
You can
hmm it gave me a module not found error tho
wonder if i can create an MRE on repl.it or something
basically want to create a package that appears as a module
Why?
because i want multiple files, but i like the convenience of being able to do from mdl import cls
https://replit.com/@doodspav1/ModuleMRE#main.py wonder if that's public
Then just put from ._private_submodule import cls in mdl/__init__.py
The globals in mdl/__init__.py are the things that show up in, and are importable from, the mdl module
that breaks too
https://replit.com/@doodspav1/ModuleMRE#main.py are you able to modify stuff on this link?
ah you're on mobile :/ nvm
ahhhh i didn't have the .
it works now, yay π thanks
i mean, my code doesn't, but the import does π
you put the code in __init__.py?
oh you did ```python
from _impl.my_cls import MyClass
all = [MyClass]
yeah i realised once it complained lol
Does any linux distribution not come with a compiler?
Seems easier to just compile something required for a package on install rather than deal with multi linux and stuff? (And have precompiled versions for windows and Mac)
try /kill all
is there any internal name for dunder/magic method
because i cant find anything on searching dunder in python docs
dayum thanks
"special" indeed, they make up 90% of the attributes on any simple class π
depends on the context. if you use a class as a wrapper/API for stuff in other languages like pyqt, almost no dunder methods are involved
in fuzzylogic on the other hand it's almost 99% of all methods because i'm wrapping stuff with additional logic, which is nice if you can use python syntax
at least they are "special" in terms of unique behaviour regarding the syntax
what are you trying to compare in this example?
the first three bytes of a Python string are not the characters in the string.
Tbf itβs a bytes object
ok, same point
Anyone have any idea for mini project using Python ?
that's a good question for #python-discussion
does ctypes.c_char_p(b'hah') keep around a reference to the bytes object once the call is evaluated?