[issue44807] typing.Protocol silently overrides __init__ method of delivered class
Adrian Garcia Badaracco added the comment: I am not sure if that solves anything (other than the fact that __new__ is much less common to implement than __init__), but I may just be slow to pick up the implications of moving the check to __new__ -- ___ Python tracker <https://bugs.python.org/issue44807> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44807] typing.Protocol silently overrides __init__ method of delivered class
Adrian Garcia Badaracco added the comment: Guido, it looks like you replied while I was typing my reply out. Yurii can correct me here but I believe PR #27543 was an attempt to disallow defining `__init__` on a Protocol completely. What I proposed above is the opposite behavior, while still fixing the issue of `__init__` getting silently overridden (which is the crux / title of this issue). I'm not sure which approach is right. -- ___ Python tracker <https://bugs.python.org/issue44807> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44807] typing.Protocol silently overrides __init__ method of delivered class
Adrian Garcia Badaracco added the comment: Agreed. What if we allow protocols that implement `__init__` but still disallow instantiating a protocol that does not? It's a 1 line change, all existing tests pass and it would still catch what I think was the original intention (trying to instantiate a Protocol class with no __init__): https://github.com/python/cpython/pull/31628/files#diff-ddb987fca5f5df0c9a2f5521ed687919d70bb3d64eaeb8021f98833a2a716887 -- ___ Python tracker <https://bugs.python.org/issue44807> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44807] typing.Protocol silently overrides __init__ method of delivered class
Change by Adrian Garcia Badaracco : -- pull_requests: +29750 stage: test needed -> patch review pull_request: https://github.com/python/cpython/pull/31628 ___ Python tracker <https://bugs.python.org/issue44807> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44807] typing.Protocol silently overrides __init__ method of delivered class
Adrian Garcia Badaracco added the comment: Apologies if that was noise, I filed an issue on the MyPy issue tracker: https://github.com/python/mypy/issues/12261 -- ___ Python tracker <https://bugs.python.org/issue44807> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44807] typing.Protocol silently overrides __init__ method of delivered class
Adrian Garcia Badaracco added the comment: While this is figured out, would it be possible to remove the silent overriding? This seems like something type checkers should be doing, not silent runtime modification of classes. Pyright already (correctly) checks this, so I think it would just need to be added to MyPy. >>> class C(Protocol): ... def __init__(self) -> None: ... print('init!') ... >>> c = C() # Pyright error, MyPy says it's okay I came across this while trying to create a class that requires concrete subclasses to define a specific field, and it seems like Protocol is the only thing that can pull this off because of how type checkers special case it: https://gist.github.com/adriangb/6c1a001ee7035bad5bd56df70e0cf5e6 I don't particularly like this use of Protocol, but it works (aside from the overriding issue). I don't know if this usage of implementing `__init__` on a protocol class should be valid or not, but I do think it's interesting that `__init__` is never called on the protocol class itself, even if the protocol class is the one defining it. It is only called on `MyAPIKey`, which is a concrete class that happens to inherit the implementation from a protocol class. So maybe that should be valid? I'm not sure. But I do know that making type checkers enforce this instead runtime would allow this use case to work while still prohibiting the (in my opinion invalid) use case of calling `__init__` on the protocol class itself. -- nosy: +adriangb status: pending -> open ___ Python tracker <https://bugs.python.org/issue44807> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17005] Add a topological sort algorithm
Adrian Garcia Badaracco added the comment: As part of working on a tool that deals with dependencies, I was building my own topological sort. I iterated through various APIs (iterable of tasks, iterable of parallelizable groups of tasks, etc.) until I found the (now stdlib) version which ended up being exactly the API I needed to most efficiently execute dependencies. So, kudos on the design! I actually ended up re-writing it in Rust, partly because I wanted a good project to learn Rust, partly because I wanted to be able to modify the API a bit. Namely: 1. I needed the ability to re-execute the same DAG multiple times without re-checking for cycles and re-adding all nodes (so basically copying `npredecessors` before executing). 2. I needed the ability to remove nodes from the graph. The real-world application is removing pruning subgraphs corresponding to cached dependencies. Again, I wanted to do this without rebuilding the entire thing (removing nodes can never lead to a cycle, and it is possible to keep track of new leaf nodes as you remove them instead of iterating over the entire graph again to find leaf nodes). Here's the implementation in case anyone is interested: https://github.com/adriangb/graphlib2 The algorithm is the same, but I had to change the data structures somewhat to cope w/ Rusts' borrowing rules (namely I can't hold a mutable reference to two values in `node2nodeinfo` at the same time, which the current implementation does here https://github.com/python/cpython/blob/32f1491a9770b7f2989507ecf8f13ef35dd95b0b/Lib/graphlib.py#L190, so I split them out into two separate mappings). -- nosy: +adriangb ___ Python tracker <https://bugs.python.org/issue17005> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26175] Fully implement IOBase abstract on SpooledTemporaryFile
Change by Adrian Garcia Badaracco : -- nosy: +adriangb ___ Python tracker <https://bugs.python.org/issue26175> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44834] contextvars.Context.run w/ coroutines gives inconsistent behavior
Change by Adrian Garcia Badaracco : -- nosy: +yselivanov ___ Python tracker <https://bugs.python.org/issue44834> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42815] new thread doesn't copy context of the parent thread
Change by Adrian Garcia Badaracco : -- nosy: +adriangb ___ Python tracker <https://bugs.python.org/issue42815> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44834] contextvars.Context.run w/ coroutines gives inconsistent behavior
New submission from Adrian Garcia Badaracco : I recently tried to use `contextvars.Context.run` w/ coroutines, expecting the same behavior as with regular functions, but it seems that `contextvars.Context.run` does not work w/ coroutines. I'm sorry if this is something obvious to do with how coroutines work under the hood, if so I'd appreciate some help in understanding why this is the expected behavior. ```python import asyncio import contextvars ctxvar = contextvars.ContextVar("ctxvar", default="spam") def func(): assert ctxvar.get() == "spam" async def coro(): func() async def main(): ctx = contextvars.copy_context() ctxvar.set("ham") ctx.run(func) # works await ctx.run(coro) # breaks asyncio.run(main()) ``` Thanks! -- components: Library (Lib) messages: 398924 nosy: adriangb priority: normal severity: normal status: open title: contextvars.Context.run w/ coroutines gives inconsistent behavior type: behavior versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue44834> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com