[issue30718] [doc] open builtin function: specifying the size of buffer has no effect for text files
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 4.0 -> 5.0 pull_requests: +30403 stage: -> patch review pull_request: https://github.com/python/cpython/pull/32351 ___ Python tracker <https://bugs.python.org/issue30718> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46168] Incorrect format specified for the "style" key in the configuration file format formatter example
Stanley added the comment: Samriddhi, are you still working on this? -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue46168> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44158] Clarify documentation for redirected stdout/stderr when using subprocess in Linux
Stanley added the comment: Hmm, I'm not quite following - when you say that the subproccess-ed command should also inherit the redirection, which subprocess command are you referring to, and nested or unnested? I gave it a ran and everything seems to run how I'd expected it, so maybe put another way, what's the expected output from the files and stdout/stderr? -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue44158> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47207] Switch datetime docstrings / documentation to using "Returns" rather than "Return"?
Stanley added the comment: Is there a bpo page or some sort that discusses why the imperative mood is used over the indicative mood other than convention of PEP 257? I found this (https://mail.python.org/pipermail/tutor/2012-May/089584.html) question and answer that seems to make sense, but it's not quite an official source. If the reason for using imperative mood in docstrings doesn't apply to documentation, then I think there wouldn't be any problems in changing it. One thing raised in the mail thread was that 'Returns ...' isn't strictly grammatical, so perhaps that's something to consider. -- ___ Python tracker <https://bugs.python.org/issue47207> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue32658] Metacharacter (\) documentation suggestion
Stanley added the comment: Feel free, it's all yours -- ___ Python tracker <https://bugs.python.org/issue32658> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue32658] Metacharacter (\) documentation suggestion
Stanley added the comment: Mike, are you still working on this issue? -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue32658> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39971] [doc] Error in functional how-to example
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 4.0 -> 5.0 pull_requests: +30250 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/32172 ___ Python tracker <https://bugs.python.org/issue39971> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37430] [doc] range is not a built-in function
Stanley added the comment: Terry, how do you think the example/paragraph should be improved? I notice that the previous paragraphs talk about continue/break/else, so were you looking for some new example with all those? And I think the indexing's been fixed by now, but a clickable link to the range() documentation (https://docs.python.org/3/library/stdtypes.html#range) might still be a good idea just for convenience. -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue37430> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47031] math.nan should note that NANs do not compare equal to anything
Stanley added the comment: Then perhaps saying that it's *never* equal is too strong, and instead we just say it's *not* equal. Not too sure how to phrase the behavior difference between `==` and `is` though, if that's something that should be noted. -- ___ Python tracker <https://bugs.python.org/issue47031> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47031] math.nan should note that NANs do not compare equal to anything
Stanley added the comment: Vedran's got a good point, as existing documentation for math.nan already says "... Equivalent to the output of float('nan')." so it does seem a bit redundant to say both, though I wonder if we should still be explicit since >>> import math >>> math.nan is math.nan True >>> float('nan') is float('nan') False so they don't have the exact same behavior. Serhiy also has a good point, so maybe instead say that Math.nan/float('nan') is *generally* not equal to any other value? -- ___ Python tracker <https://bugs.python.org/issue47031> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue33028] [doc] tempfile.TemporaryDirectory documentation improvements
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 4.0 -> 5.0 pull_requests: +30104 stage: -> patch review pull_request: https://github.com/python/cpython/pull/32016 ___ Python tracker <https://bugs.python.org/issue33028> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47031] math.nan should note that NANs do not compare equal to anything
Stanley added the comment: How does this sound instead? The unequalness is pushed to the front and the IEEE part back so it's less likely missed: Math.nan and float('nan') are never equal to any other value, including themselves, as per IEEE 754. Use math.isnan to test for NANs. -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue47031> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue9182] document “--” as a way to distinguish option w/ narg='+' from positional argument in argparse
Change by Stanley : -- nosy: +slateny nosy_count: 13.0 -> 14.0 pull_requests: +29908 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/31810 ___ Python tracker <https://bugs.python.org/issue9182> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue9305] Don't use east/west of UTC in date/time documentation
Change by Stanley : -- nosy: +slateny nosy_count: 14.0 -> 15.0 pull_requests: +29817 pull_request: https://github.com/python/cpython/pull/31697 ___ Python tracker <https://bugs.python.org/issue9305> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26545] [doc] os.walk is limited by python's recursion limit
Stanley added the comment: I'm not too sure about documenting the recursive limit here. There's a few other recursive functions in the os library (such as makedirs()) and if we note the recursive limit for os.walk then all of them should be noted too, but that doesn't seem quite right to me. -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue26545> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue18534] [doc] State clearly that open() 'file' param is "name" attr of the result
Stanley added the comment: Would it be fine to modify FileIO.name like this: "... given in the constructor. Depending on the type of *name* that was passed into the constructor, this may not necessarily e a string." -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue18534> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23323] [doc] mention that flags arg to imaplib's append should be a string
Stanley added the comment: How would this sound as clarification for the flags argument? *flags* is a space-separated string containing IMAP flags tokens. Must start with ``\``. Perhaps optionally also provide the list of system flags as given in https://datatracker.ietf.org/doc/html/rfc3501#section-2.3.2 -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue23323> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25415] [doc] "there is no public constructor" should be reworded in io module documentation
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 5.0 -> 6.0 pull_requests: +29753 pull_request: https://github.com/python/cpython/pull/31631 ___ Python tracker <https://bugs.python.org/issue25415> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue10149] [doc] Data truncation in expat parser
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 6.0 -> 7.0 pull_requests: +29752 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/31629 ___ Python tracker <https://bugs.python.org/issue10149> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45991] Improve ambiguous docstrings in pkgutil
Stanley added the comment: I feel like there might be some backwards compatibility issues if pkgutil wraps it like that, but similarly I'm not at all familiar with how common the package is used and whether it'd be fine to make that change, so I'll also differ judgement here. -- ___ Python tracker <https://bugs.python.org/issue45991> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23453] [doc] Clarify bytes vs text with non-seeking tarfile stream
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 3.0 -> 4.0 pull_requests: +29733 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/31610 ___ Python tracker <https://bugs.python.org/issue23453> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25743] [doc] Clarify exactly what \w matches in UNICODE mode
Stanley added the comment: Would a change like this be accurate? Matches Unicode word characters; this includes most alphanumeric characters as well as the underscore. In Unicode, alphanumeric characters are defined to be the general categories L + N (see https://unicode.org/reports/tr44/#General_Category_Values). If the :const:`ASCII` flag is used, only ``[a-zA-Z0-9_]`` is matched. -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue25743> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue20970] [doc] contradictory documentation for prog option of argparse
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 6.0 -> 7.0 pull_requests: +29725 stage: -> patch review pull_request: https://github.com/python/cpython/pull/31602 ___ Python tracker <https://bugs.python.org/issue20970> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue29251] [doc] Class __dict__ is only a mapping proxy
Stanley added the comment: >From what I can see, the original patch changed ... and the *dict* dictionary is the namespace containing definitions for class body and is copied to a standard dictionary to become the __dict__ attribute into this ... and the *dict* dictionary is copied to the namespace containing definitions for the class body, which is referenced by the __dict__ attribute so that the documentation avoids saying that the attribute is a dictionary, instead saying it just references a dictionary. However, current documentation says that ... it may be copied or wrapped before becoming the __dict__ attribute which implies some sort of change already. In this case, is the patch for the functions page still applicable? -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue29251> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue13821] [doc] misleading return from isidentifier
Stanley added the comment: For clarification then, would it be accurate to add a sentence like this in the documentation? "Note that isidentifier() still returns True even if the string may not be normalized." -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue13821> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21761] [doc] language reference describes the role of module.__file__ inaccurately
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 6.0 -> 7.0 pull_requests: +29687 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/31565 ___ Python tracker <https://bugs.python.org/issue21761> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27583] [doc ] configparser: modifying default_section at runtime
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 5.0 -> 6.0 pull_requests: +29685 stage: -> patch review pull_request: https://github.com/python/cpython/pull/31562 ___ Python tracker <https://bugs.python.org/issue27583> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45991] Improve ambiguous docstrings in pkgutil
Stanley added the comment: While it is ambiguous, when there's a path parameter I would default it to string unless otherwise specified. Maybe instead a note could be put in the Pathlib doc noting functions that accept path arguments might not accept Path objects? -- ___ Python tracker <https://bugs.python.org/issue45991> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue12165] [doc] clarify documentation of nonlocal
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 6.0 -> 7.0 pull_requests: +29672 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/31551 ___ Python tracker <https://bugs.python.org/issue12165> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue30677] [doc] mention that os.mkdir() raises FileNotFound if path does not exist
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 3.0 -> 4.0 pull_requests: +29669 stage: -> patch review pull_request: https://github.com/python/cpython/pull/31548 ___ Python tracker <https://bugs.python.org/issue30677> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45991] Improve ambiguous docstrings in pkgutil
Stanley added the comment: Could you expand a bit on why 'list of paths' in pkgutil is understood by default to be 'list of PosixPath paths'? I would interpret it by default to be string paths if I saw it somewhere without context -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue45991> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34429] [doc] On Windows tempfile.TemporaryFile behaves like NamedTemporaryFile
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 4.0 -> 5.0 pull_requests: +29668 stage: -> patch review pull_request: https://github.com/python/cpython/pull/31547 ___ Python tracker <https://bugs.python.org/issue34429> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23747] [doc] platform module exposes win32_ver function on posix systems
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 4.0 -> 5.0 pull_requests: +29591 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/31462 ___ Python tracker <https://bugs.python.org/issue23747> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue31327] [doc] Add example of platform-specific support for negative timestamps to the time doc
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 8.0 -> 9.0 pull_requests: +29589 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/31460 ___ Python tracker <https://bugs.python.org/issue31327> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36557] [doc] Clarify the meaning of /uninstall in windows cli
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 7.0 -> 8.0 pull_requests: +29586 stage: -> patch review pull_request: https://github.com/python/cpython/pull/31457 ___ Python tracker <https://bugs.python.org/issue36557> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45492] stdlib inspect documentation on code.co_names is incorrect
Change by Stanley : -- keywords: +patch nosy: +slateny nosy_count: 2.0 -> 3.0 pull_requests: +29585 stage: -> patch review pull_request: https://github.com/python/cpython/pull/31456 ___ Python tracker <https://bugs.python.org/issue45492> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21910] [doc] File protocol should document if writelines must handle generators sensibly
Change by Stanley : -- keywords: +patch pull_requests: +29414 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/31245 ___ Python tracker <https://bugs.python.org/issue21910> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21910] [doc] File protocol should document if writelines must handle generators sensibly
Stanley added the comment: I'd be interested in taking a look at this - would these changes clarify things? Current (https://docs.python.org/3/library/codecs.html#codecs.StreamWriter): Writes the concatenated list of strings to the stream (possibly by reusing the write() method). The standard bytes-to-bytes codecs do not support this method. Proposed: Writes the concatenated list of strings to the stream by reusing the write() method, and thus does not support infinite or very large generators. The standard bytes-to-bytes codecs do not support this method. -- nosy: +slateny ___ Python tracker <https://bugs.python.org/issue21910> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44697] Memory leak when asyncio.open_connection raise
Kyle Stanley added the comment: Thank you Arteem, that should help indicate where the memory leak is present. -- ___ Python tracker <https://bugs.python.org/issue44697> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39529] Deprecate get_event_loop()
Kyle Stanley added the comment: > But why does `asyncio.run` unconditionally create a new event loop instead of > running on `asyncio.get_event_loop`? AFAIK, it does so for purposes of compatibility in programs that need multiple separate event loops and providing a degree of self-dependency. asyncio.run() is entirely self-reliant in that it creates all needed resources at the start and closes them in finalization, rather than depending on existing resources. I believe this to be significantly safer and better guaranteed to function as intended, although perhaps at some cost to convenience in cases like your own where there only needs to be one event loop. -- ___ Python tracker <https://bugs.python.org/issue39529> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39995] test_concurrent_futures: ProcessPoolSpawnExecutorDeadlockTest.test_crash() fails with OSError: [Errno 9] Bad file descriptor
Kyle Stanley added the comment: Thanks for closing up the issue, Victor :) -- ___ Python tracker <https://bugs.python.org/issue39995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37228] UDP sockets created by create_datagram_endpoint() allow by default multiple processes to bind the same port
Kyle Stanley added the comment: > Thanks, Ned <3 (For following up and closing the issue) -- ___ Python tracker <https://bugs.python.org/issue37228> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37228] UDP sockets created by create_datagram_endpoint() allow by default multiple processes to bind the same port
Kyle Stanley added the comment: > Since 3.5 has now reached end-of-life, this issue will not be fixed there so > it looks like it can be closed. Thanks, Ned <3 -- ___ Python tracker <https://bugs.python.org/issue37228> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42647] Unable to use concurrent.futures in atexit hook
Kyle Stanley added the comment: Thanks for bringing attention to this, Julien. While the regression is definitely unfortunate, I'm uncertain about whether the behavior is *correct* to allow in the first place. Specifically, allowing the registration of an atexit hook which uses a ThreadPoolExecutor within it means that the finalization of the executor will be done *after* thread finalization occurs, leaving dangling threads which will have to be abruptly killed upon interpreter exit instead of being safely joined. From my perspective at least, this doesn't seem like something to be encouraged. Is there a real-world situation where it's specifically necessary or even beneficial to utilize ThreadPoolExecutor at this point after thread finalization rather than earlier in the program? Not that it doesn't exist, but to me it intuitively seems very odd to utilize an executor within an atexit hook, which are intended to just be resource finalization/cleanup functions called at interpreter shutdown. Assuming there is a genuine use case I'm not seeing, it may be worth weighing against the decision to convert the executors to not use daemon threads, as I presently don't think there's a way to (safely) allow that behavior without reverting back to using daemon threads. That said, I'll admit that I'm more than a bit biased as the author of the commit which introduced the regression, so I'll CC Antoine Pitrou (active expert for threading and concurrent.futures) to help make the final decision. -- nosy: +pitrou ___ Python tracker <https://bugs.python.org/issue42647> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41962] Make threading._register_atexit public?
Kyle Stanley added the comment: > I'm dealing with a subtle deadlock involving > concurrent.futures.ThreadPoolExecutor, and my solution that worked in Python > 3.8 broke with 3.9. I'm running some long-running (possibly infinite) tasks > in the thread pool, and I cancel them in an `atexit` callback so that > everything can shut down cleanly (before ThreadPoolExecutor joins all worker > threads in its own `atexit` hook). IMO, a better practice would be providing those potentially infinite running tasks a direct method of escape and invoking it before calling executor.shutdown(), it would be a more reliable approach. But, perhaps there is some convenience utility in being able to provide custom atexit hooks. It also might help the user to separate the shutdown logic from the rest of the program. Since you worked with me in adding threading._register_atexit(), Do you have any thoughts, Antoine? I would personally not be opposed to it being made public assuming there's real utility present in doing so. My only concern is that it might be a potential foot-gun. If the user submits an atexit hook that deadlocks, it might prevent threads from shutting down safely prior to interpreter finalization. I'm presently undecided if explicitly mentioning that it in the docs would be sufficient warning. -- nosy: +pitrou ___ Python tracker <https://bugs.python.org/issue41962> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42611] PEP 594
New submission from Kyle Stanley : This issue was created for the purpose of tracking any changes related to PEP 594 (Removing dead batteries from stdlib), and any relevant discussions about the modules being removed. -- components: Library (Lib) messages: 382815 nosy: aeros, christian.heimes priority: normal pull_requests: 22588 severity: normal status: open title: PEP 594 type: enhancement versions: Python 3.10 ___ Python tracker <https://bugs.python.org/issue42611> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42392] remove the 'loop' parameter from __init__ in all classes in asyncio.locks
Kyle Stanley added the comment: New changeset b9127dd6eedd693cfd716a648864e2e00186 by Yurii Karabas in branch 'master': bpo-42392: Improve removal of *loop* parameter in asyncio primitives (GH-23499) https://github.com/python/cpython/commit/b9127dd6eedd693cfd716a648864e2e00186 -- ___ Python tracker <https://bugs.python.org/issue42392> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42392] remove the 'loop' parameter from __init__ in all classes in asyncio.locks
Kyle Stanley added the comment: > Is there anyone who is assigned to removing the deprecated `loop` parameter > from `asyncio` codebase? > If not I can take this task, I believe I have enough free time and curiosity > to do that :) You can certainly feel free to work on that and it would definitely be appreciated! However, I would recommend splitting it into several PRs, basically as "Remove *loop* parameter from x` rather than doing a massive PR that removes it from everywhere that it was deprecated. This makes the review process easier. Also, keep in mind that there are some uses of *loop* that are still perfectly valid and will remain so, such as in `asyncio.run_coroutine_threadsafe()`. It should only be removed in locations where there was a deprecation warning from 3.8 or sooner present (as we give two major versions of deprecation notice before most breaking changes are made -- this has been made official policy as of PEP 387). -- ___ Python tracker <https://bugs.python.org/issue42392> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42392] remove the 'loop' parameter from __init__ in all classes in asyncio.locks
Kyle Stanley added the comment: Regarding the example _get_loop(): ``` def _get_loop(self): loop = asyncio.get_running_loop() if self._loop is None: self._loop = loop if loop is not self._loop: raise if not loop.is_running(): raise ``` Would this be added to all asyncio primitives to be called anytime a reference to the loop is needed within a coroutine? Also, regarding the last line "if not loop.is_running(): raise" I'm not 100% certain that I understand the purpose. Wouldn't it already raise a RuntimeError from `asyncio.get_running_loop()` if the event loop wasn't running? The only thing I can think of where it would have an effect is if somehow the event loop was running at the start of `_get_loop()` and then the event loop was stopped (e.g. a loop in an alternative thread was stopped by the main thread while the alternative thread was in the middle of executing `_get_loop()`). But to me, that seems to be enough of an edge case to simplify it to the following: ``` def _get_loop(self): loop = asyncio.get_running_loop() if self._loop is None: self._loop = loop if loop is not self._loop: raise ``` (Unless you intended for the first line `loop = asyncio.get_running_loop()` to instead be using the private `asyncio._get_running_loop()`, which returns None and doesn't raise. In that case, the original would be good to me.) Other than that, I think the approach seems solid. -- ___ Python tracker <https://bugs.python.org/issue42392> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42392] remove the 'loop' parameter from __init__ in all classes in asyncio.locks
Kyle Stanley added the comment: > Oh my. FWIW I think that we need to implement this differently. I don't > think it matters where, say, an asyncio.Lock was instantiated. It can be > created anywhere. So IMO its __init__ shouldn't try to capture the current > loop -- there's no need for that. The loop can be and should be captured when > the first `await lock.acquire()` is called. That's good to know and I think more convenient to work with, so +1 from me. I guess my remaining question though is whether it's okay to `await lock.acquire()` on a single lock instance from multiple different running event loops (presumably each in their own separate threads) or if there's a need to restrict it to only one event loop. > I'm writing a piece of code right now that would need to jump through the > hoops to simply create a new `asyncio.Lock()` in a place where there's no > asyncio loop yet. >From what I've seen of asyncio user code, it seems reasonably common to create >async primitives (lock, semaphore, queue, etc.) in the __init__ for some class >prior to using the event loop, which would fail with usage of >`get_running_loop()` in the __init__ for the primitives. So, if it's not an >issue to wait until accessing the event loop until it's actually needed (e.g. >in the lock.acquire() or queue.get/put()), I think we should definitely try to >be conscious about when we call `get_running_loop()` going forward to ensure >we're not imposing arbitrary inconveniences on users. -- ___ Python tracker <https://bugs.python.org/issue42392> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42392] remove the 'loop' parameter from __init__ in all classes in asyncio.locks
Kyle Stanley added the comment: Sure, I would be interested in helping with this. Although if a newer contributor takes it up before I'm able to, I wouldn't be opposed to that either (my main priority at the moment is helping with PEP 594 since it's a concrete goal of my internship w/ the PSF, but I should have some time to work on this as well). As far as I can tell though, there's currently a similar PR open: https://github.com/python/cpython/pull/18195 . This attempts to deprecate the loop argument and creating primitives such as asyncio.Lock outside of a running event loop with the following approach: ``` def __init__(self, *, loop=None): self._waiters = None self._locked = False if loop is None: self._loop = events._get_running_loop() if self._loop is None: warnings.warn("The creation of asyncio objects without a running " "event loop is deprecated as of Python 3.9.", DeprecationWarning, stacklevel=2) self._loop = events.get_event_loop() else: warnings.warn("The loop argument is deprecated since Python 3.8, " "and scheduled for removal in Python 3.10.", DeprecationWarning, stacklevel=2) ``` So, do we want to add more strictness to that with always using `get_running_loop()` to access the event loop each time instead of accessing self._loop, and effectively ignore the user-supplied one? Presumably, this would start with a warning for passing a *loop* arg and then be removed entirely as a parameter ~two versions later. > (or alternatively they can cache the running `loop`, but the first loop > lookup should be performed with `asyncio.get_running_loop()`) AFAIK, at the C-API extension level, get_running_loop() already caches the running loop in `cached_running_holder`. (https://github.com/python/cpython/blob/9c98e8cc3ebf56d01183c67adbc000ed19b8e0f4/Modules/_asynciomodule.c#L232). So from a performance perspective, wouldn't it effectively be the same if we repeatedly use `get_running_loop()` to access the same event loop? I think it also adds a nice integrity check to be certain that the primitive wasn't initially created within a running event loop, and then later accessed outside of one. The only concern that I can see with this approach is that users could potentially create a primitive in one running event loop and then access it in a separate loop running in a different thread (without using something like self._loop, the primitive would no longer be associated with a specific event loop and could potentially used within *any* running event loop). I'm not entirely certain if that is a real problem though, and if anything, it seems like it could prove to be useful in some multi-loop environment. I just want to make sure that it's intended. -- ___ Python tracker <https://bugs.python.org/issue42392> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41699] Potential memory leak with asyncio and run_in_executor
Kyle Stanley added the comment: > Regularly calling executor.shutdown() and then instantiating a new > ThreadPoolExecutor in order to run an asyncio program does not seem like a > good API to me. Clarification: you're typically only supposed to instantiate a single ThreadPoolExecutor or ProcessPoolExecutor per program (sometimes one of each depending on use case), and continuously submit jobs to it rather than creating multiple executor instances. Otherwise, it's generally unneeded overhead. (I'll take a look at the other parts once I find the time, just wanted to briefly mention the above in the meantime.) -- ___ Python tracker <https://bugs.python.org/issue41699> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41699] Potential memory leak with asyncio and run_in_executor
Kyle Stanley added the comment: Also note that the difference in memory is much higher when an exception occurs (presumably because the exception is stored on future._exception and not cleaned up?): ``` [aeros:~/repos/cpython]$ ./python ~/programming/python/asyncio_run_in_exec_leak.py -n=1 --asyncio start RSS memory: VmRSS: 16976 kB after 10_000 iterations of 1 element lists: VmRSS: 64132 kB ``` -- ___ Python tracker <https://bugs.python.org/issue41699> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41699] Potential memory leak with asyncio and run_in_executor
Kyle Stanley added the comment: In the snippet provided, at least part of the resources are not finalized because executor.shutdown() was not called in the program (which should be done when creating a local instance of the executors, either explicitly or using the context manager). For the event loop's default threadpool (used w/ loop.run_in_executor(None, ...), I added a coroutine function loop.shutdown_default_executor() in 3.9+ handles this (called in asyncio.run()). Without ever calling executor.shutdown(), the worker threads/processes and their associated resources are not finalized until interpreter shutdown. There's also some additional finalization that occurs in `_python_exit()` for both TPE and PPE (see https://github.com/python/cpython/blob/3317466061509c83dce257caab3661d52571cab1/Lib/concurrent/futures/thread.py#L23 or https://github.com/python/cpython/blob/3317466061509c83dce257caab3661d52571cab1/Lib/concurrent/futures/process.py#L87), which is called just before all non-daemon threads are joined just before interpreter shutdown occurs. However, even considering the above, there still seems to be a significant additional difference in RSS compared to using ThreadPoolExecutor vs loop.run_in_executor() that I can't seem to account for (before and after asyncio.run()): ``` import asyncio import concurrent.futures as cf import os import gc import argparse from concurrent.futures.thread import _python_exit def leaker(n): list(range(n)) def func_TPE(n): with cf.ThreadPoolExecutor() as executor: for i in range(10_000): executor.submit(leaker, n) async def func_run_in_executor(n): loop = asyncio.get_running_loop() for i in range(10_000): loop.run_in_executor(None, leaker, n) def display_rss(): os.system(f"grep ^VmRSS /proc/{os.getpid()}/status") def main(n=100, asyncio_=False): try: if asyncio_: asyncio.run(func_run_in_executor(n)) else: func_TPE(n) finally: _python_exit() gc.collect() print(f"after 10_000 iterations of {n} element lists:") display_rss() if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-n", type=int, default=100) parser.add_argument("--asyncio", action=argparse.BooleanOptionalAction) print("start RSS memory:") display_rss() args = parser.parse_args() main(args.n, args.asyncio) ``` Results (on latest commit to master, 3.10): asyncio - ``` [aeros:~/repos/cpython]$ ./python ~/programming/python/asyncio_run_in_exec_leak.py -n=1 --asyncio start RSS memory: VmRSS: 16948 kB after 10_000 iterations of 1 element lists: VmRSS: 27080 kB ``` concurrent.futures - ``` [aeros:~/repos/cpython]$ ./python ~/programming/python/asyncio_run_in_exec_leak.py -n=1 --no-asyncio start RSS memory: VmRSS: 17024 kB after 10_000 iterations of 1 element lists: VmRSS: 19572 kB ``` When using await before loop.run_in_executor(), the results are more similar to using ThreadPoolExecutor directly: ``` [aeros:~/repos/cpython]$ ./python ~/programming/python/asyncio_run_in_exec_leak.py -n=1 --asyncio start RSS memory: VmRSS: 16940 kB after 10_000 iterations of 1 element lists: VmRSS: 17756 kB ``` However, as mentioned by the OP, if stored in a container and awaited later (such as w/ asyncio.gather()), a substantial memory difference is present (increases with list size): ``` [aeros:~/repos/cpython]$ ./python ~/programming/python/asyncio_run_in_exec_leak.py -n=1 --asyncio start RSS memory: VmRSS: 16980 kB after 10_000 iterations of 1 element lists: VmRSS: 29744 kB ``` Based on the above results, I think there may be a smaller leak occurring in concurrent.futures (potentially related to the linked bpo-41588) and a bit of a larger leak occurring in loop.run_in_executor(). So they can remain as separate issues IMO. At the moment, my best guess is that there's some memory leak that occurs from the future not being fully cleaned up, but I'm not certain about that. This will likely require some further investigation. Input from Yury and/or Andrew would definitely be appreciated. Is there something that I'm potentially missing here? -- ___ Python tracker <https://bugs.python.org/issue41699> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41588] Potential Memory leak with concurrent.futures.ThreadPoolExecutor's map
Change by Kyle Stanley : -- nosy: +aeros, bquinlan, pitrou ___ Python tracker <https://bugs.python.org/issue41588> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue28533] Replace asyncore
Kyle Stanley added the comment: Since this issue is now a significant blocker for PEP 594 (remove stdlib dead batteries, which includes asyncore and asynchat), I'm going to prioritize working on this and assign it to myself. -- assignee: -> aeros ___ Python tracker <https://bugs.python.org/issue28533> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38912] test_asyncio altered the execution environment
Kyle Stanley added the comment: I've applied Justin's patch, and opened PRs for backporting to 3.9 and 3.8 (currently waiting on CI). Based on my local testing and buildbot fleet results, it definitely reduces the rate at which the failure occurs, but does not 100% resolve the ENV CHANGED failure (from the transport being closed). As a result, I'll leave the issue open for further investigation. -- ___ Python tracker <https://bugs.python.org/issue38912> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38912] test_asyncio altered the execution environment
Kyle Stanley added the comment: New changeset de73d432bb29f6439f2db16cb991e15e09c70c26 by Justin Turner Arthur in branch 'master': bpo-38912: fix close before connect callback in test_asyncio SSL tests (GH-22691) https://github.com/python/cpython/commit/de73d432bb29f6439f2db16cb991e15e09c70c26 -- ___ Python tracker <https://bugs.python.org/issue38912> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue29127] Incorrect reference names in asyncio.subprocess documentation
Kyle Stanley added the comment: I can confirm that both on the latest version of the docs (for 3.8) and for the version mentioned in the issue (3.6), the issue mentioned with asyncio.subprocess.PIPE is no longer present. (It was likely fixed in the asyncio documentation overhaul that happened within the last couple of years). As a result, I'll proceed with closing this issue. Thanks for checking, Carl. -- nosy: +aeros resolution: -> fixed stage: -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue29127> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37294] concurrent.futures.ProcessPoolExecutor state=finished raised error
Kyle Stanley added the comment: DanilZ, could you take a look at the superseding issue (https://bugs.python.org/issue37297) and see if your exception raised within the job is the same? If it's not, I would suggest opening a separate issue (and linking to it in a comment here), as I don't think it's necessarily related to this one. "state=finished raised error" doesn't indicate the specific exception that occurred. A good format for the name would be something along the lines of: "ProcessPoolExecutor.submit() while reading large object (4GB)" It'd also be helpful in the separate issue to paste the full exception stack trace, specify OS, and multiprocessing start method used (spawn, fork, or forkserver). This is necessary to know for replicating the issue on our end. In the meantime, I workaround I would suggest trying would be to use the *chunksize* parameter (or *Iterator*) in pandas.read_csv(), and split it across several jobs (at least 4+, more if you have additional cores) instead of within a single one. It'd also be generally helpful to see if that alleviates the problem, as it could possibly indicate an issue with running out of memory when the dataframe is converted to pickle format (which often increases the total size) within the process associated with the job. -- nosy: +aeros ___ Python tracker <https://bugs.python.org/issue37294> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41815] SQLite: segfault if backup called on closed database
Kyle Stanley added the comment: I've received approval from Lukasz to backport to 3.9 and 3.8, and have now merged the PRs. It could use a post-commit review from a core dev that has some additional experience with SQLite3, but it can be de-escalated from release blocker. -- priority: release blocker -> normal stage: patch review -> commit review status: open -> closed ___ Python tracker <https://bugs.python.org/issue41815> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41815] SQLite: segfault if backup called on closed database
Change by Kyle Stanley : -- nosy: +ghaering ___ Python tracker <https://bugs.python.org/issue41815> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41815] SQLite: segfault if backup called on closed database
Kyle Stanley added the comment: With this being a segfault that's simple to replicate under normal circumstances, I've elevated the priority to release blocker. I'll wait on the release manager (Lukasz) for explicit approval for backporting to 3.9 and 3.8, with both branches being in the release candidate phase. (The attached PR looks to be ready to be merged as well, after a Misc/NEWS entry is added by the author. See https://github.com/python/cpython/pull/22322#pullrequestreview-492167467 for details.) -- nosy: +aeros, lukasz.langa priority: normal -> release blocker versions: -Python 3.7 ___ Python tracker <https://bugs.python.org/issue41815> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41818] Lib/pty.py major revision
Kyle Stanley added the comment: In addition to the above, if a major revision is made to pty, I'd suggest also addressing the issue of "master/slave" terminology, and replace it with something comparable like "parent/child". There's an open devguide issue (https://github.com/python/devguide/issues/605) to more explicitly state terms to avoid, and support for avoiding usage of "slave/master" seems uncontroversial (especially in any new code). -- nosy: +aeros ___ Python tracker <https://bugs.python.org/issue41818> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39349] Add "cancel_futures" parameter to concurrent.futures.Executor.shutdown()
Kyle Stanley added the comment: Thanks for bringing attention to cancel_futures being missing in the base Executor class and for the PR, Shantanu! -- ___ Python tracker <https://bugs.python.org/issue39349> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39349] Add "cancel_futures" parameter to concurrent.futures.Executor.shutdown()
Kyle Stanley added the comment: New changeset a763ee3c583e6a2dfe1b1ac0600a48e8a978ed50 by Shantanu in branch '3.9': [3.9] bpo-39349: Add cancel_futures to Executor.shutdown base class (GH-22023) (GH-22048) https://github.com/python/cpython/commit/a763ee3c583e6a2dfe1b1ac0600a48e8a978ed50 -- ___ Python tracker <https://bugs.python.org/issue39349> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39349] Add "cancel_futures" parameter to concurrent.futures.Executor.shutdown()
Kyle Stanley added the comment: New changeset 17dc1b789ecc33b4a254eb3b799085f4b3624ca5 by Shantanu in branch 'master': bpo-39349: Add cancel_futures to Executor.shutdown base class (GH-22023) https://github.com/python/cpython/commit/17dc1b789ecc33b4a254eb3b799085f4b3624ca5 -- ___ Python tracker <https://bugs.python.org/issue39349> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41682] test_asyncio: Proactor test_sendfile_close_peer_in_the_middle_of_receiving failure
Change by Kyle Stanley : -- nosy: -paul.moore, steve.dower, tim.golden, zach.ware ___ Python tracker <https://bugs.python.org/issue41682> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41682] test_asyncio: Proactor test_sendfile_close_peer_in_the_middle_of_receiving failure
Change by Kyle Stanley : -- components: +Windows, asyncio nosy: +paul.moore, steve.dower, tim.golden, zach.ware ___ Python tracker <https://bugs.python.org/issue41682> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41682] test_asyncio: Proactor test_sendfile_close_peer_in_the_middle_of_receiving failure
Kyle Stanley added the comment: In case the link to the logs are lost from closing and reopening the PR, it was a Windows CI test (GitHub actions) ran with the following configuration: D:\a\cpython\cpython>"D:\a\cpython\cpython\PCbuild\amd64\python.exe" -u -Wd -E -bb -m test -uall -u-cpu -rwW --slowest --timeout 1200 -j0 == CPython 3.10.0a0 (remotes/pull/22023/merge:992cc27, Aug 31 2020, 06:11:21) [MSC v.1927 64 bit (AMD64)] == Windows-10-10.0.17763-SP0 little-endian == cwd: D:\a\cpython\cpython\build\test_python_6372� == CPU count: 2 == encodings: locale=cp1252, FS=utf-8 Using random seed 491155 0:00:00 Run tests in parallel using 4 child processes (timeout: 20 min, worker timeout: 25 min) -- ___ Python tracker <https://bugs.python.org/issue41682> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41682] test_asyncio: Proactor test_sendfile_close_peer_in_the_middle_of_receiving failure
Change by Kyle Stanley : -- components: +Tests nosy: +asvetlov, yselivanov type: -> behavior versions: +Python 3.10 ___ Python tracker <https://bugs.python.org/issue41682> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41682] test_asyncio: Proactor test_sendfile_close_peer_in_the_middle_of_receiving failure
New submission from Kyle Stanley : In an unrelated PR to add a new argument to the base Executor class for concurrent.futures, there was a test_asyncio failure in test_sendfile for the ProactorEventLoop tests: == FAIL: test_sendfile_close_peer_in_the_middle_of_receiving (test.test_asyncio.test_sendfile.ProactorEventLoopTests) -- Traceback (most recent call last): File "D:\a\cpython\cpython\lib\test\test_asyncio\test_sendfile.py", line 452, in test_sendfile_close_peer_in_the_middle_of_receiving self.run_loop( AssertionError: ConnectionError not raised -- https://github.com/python/cpython/pull/22023/checks?check_run_id=1049760805#step:5:2373 -- title: test_asyncio: Proactor -> test_asyncio: Proactor test_sendfile_close_peer_in_the_middle_of_receiving failure ___ Python tracker <https://bugs.python.org/issue41682> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41682] test_asyncio: Proactor
Change by Kyle Stanley : -- nosy: aeros priority: normal severity: normal status: open title: test_asyncio: Proactor ___ Python tracker <https://bugs.python.org/issue41682> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39349] Add "cancel_futures" parameter to concurrent.futures.Executor.shutdown()
Kyle Stanley added the comment: Good catch, Shantanu. It was not intentional on my part, and it would make sense to include *cancel_futures* in the base Executor class as documented. If you'd like to submit a PR to add it (attaching it to this issue), I should be able to review it within a reasonable period. -- ___ Python tracker <https://bugs.python.org/issue39349> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41577] Cannot use ProcessPoolExecutor if in a decorator?
Kyle Stanley added the comment: Due to the way pickle works, it's not presently possible to serialize wrapped functions directly, at least not in a way that allows you to pass it to executor.submit() within the inner function (AFAICT). I'm also not certain what it would involve to provide that, or if it would be feasible to do so in a manner that would be backwards compatible. In the meantime, this is a decent work-around: ``` from concurrent import futures import random class PPEWrapper: def __init__(self, func, num_proc=4): self.fn = func self.num_proc = num_proc def __call__(self, *args, **kwargs): with futures.ProcessPoolExecutor() as executor: fs = [] for i in range(self.num_proc): fut = executor.submit(self.fn, *args, **kwargs) fs.append(fut) result = [] for f in futures.as_completed(fs): result.append(f.result()) return result def _get_random_int(): return random.randint(0, 100) # it's often quite useful anyways to have a parallel and non-parallel version # (for testing and devices that don't support MP) get_random_int = PPEWrapper(_get_random_int, num_proc=4) if __name__ == "__main__": result = get_random_int() print(result) ``` This doesn't allow you to use the decorator syntax, but it largely provides the same functionality. That being said, my familiarity with the pickle protocol isn't overly strong, so the above is mostly based on my own recent investigation. There could very well be a way to accomplish what you're looking for in a way that I was unable to determine. -- nosy: +aeros, alexandre.vassalotti, pitrou ___ Python tracker <https://bugs.python.org/issue41577> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41202] Allow to provide custom exception handler to asyncio.run()
Kyle Stanley added the comment: > Should I set status for this issue for closed with resolution rejected ? I'll proceed with closing the issue. > Should I delete branch on my forked git repo ? > Can I delete my forked git repo ? Might as well delete the branch, but the forked repo might be useful to keep around should you choose to open a PR to CPython in the future (although you can also just create a new one later). If you are interested in working on something else in the future, I'd recommend looking at the "newcomer friendly"/"easy" issues, or just looking for an existing open issue that you're interested in helping with. In most cases, working with a clearly defined issue is much easier than trying to propose a new one and getting it merged. -- resolution: -> wont fix stage: patch review -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue41202> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41202] Allow to provide custom exception handler to asyncio.run()
Kyle Stanley added the comment: Yep, having to set a custom exception handler definitely constitutes as needing "finer control over the event loop behavior". There's absolute nothing wrong with using the low-level API when you need further customization, but we try to minimize the high-level API as much as possible to make it simple for the average user. I suspect that the majority of asyncio users don't have a need to customize the exception handler beyond the default settings. -- nosy: +aeros ___ Python tracker <https://bugs.python.org/issue41202> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40967] asyncio.Task.all_tasks() and asyncio.Task.current_task() must be removed in 3.9
Kyle Stanley added the comment: Thanks Rémi for working on this. -- priority: release blocker -> normal stage: patch review -> commit review ___ Python tracker <https://bugs.python.org/issue40967> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40967] asyncio.Task.all_tasks() and asyncio.Task.current_task() must be removed in 3.9
Kyle Stanley added the comment: > With beta 4 coming in 2 days it would perhaps good to choose now whether this > must be done for 3.9 or 3.10 Agreed. I'm definitely leaning towards 3.10 with it being decently well into the beta, but I'll try to bring this to Yury's attention to make a final decision on the matter. Optimally, we want to do removals before the beta so that users can prepare accordingly rather than deal with breakage in the final release. -- ___ Python tracker <https://bugs.python.org/issue40967> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue30064] BaseSelectorEventLoop.sock_{recv, sendall}() don't remove their callbacks when canceled
Kyle Stanley added the comment: Thanks again for working on this @Fantix, and for the continued vigilance on the issue after the test failures occurred in the buildbots. I think this recent PR-20868 will do the trick. At the very least, it will make the failure much more rare than before, which is definitely an improvement. -- stage: patch review -> commit review versions: +Python 3.10, Python 3.9 -Python 3.8 ___ Python tracker <https://bugs.python.org/issue30064> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40973] platform.platform() in Python 3.8 does not report detailed Linux platform information
Change by Kyle Stanley : -- nosy: +aeros ___ Python tracker <https://bugs.python.org/issue40973> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40973] platform.platform() in Python 3.8 does not report detailed Linux platform information
Change by Kyle Stanley : -- nosy: +jaraco, lemburg ___ Python tracker <https://bugs.python.org/issue40973> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue30064] BaseSelectorEventLoop.sock_{recv, sendall}() don't remove their callbacks when canceled
Kyle Stanley added the comment: > Last question before PR pls: given the fact that this test is to cover a > fixed case when loop.sock_*() was hanging forever, should I keep the > wait_for(..., timeout=10)? For now, I think we can keep the asyncio.wait_for() w/ 10 the sec timeout. I'll have to run the tests locally though w/ the patch to double check (once the PR is opened), and it may still end up needing to be increased if the test fails again in the future. It should be okay though. -- ___ Python tracker <https://bugs.python.org/issue30064> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue30064] BaseSelectorEventLoop.sock_{recv, sendall}() don't remove their callbacks when canceled
Kyle Stanley added the comment: No problem at all, and thanks for clarifying. > If enlarging the timeout works in some of your cases, that really inspires me > on a potential cause of the issue in the test. To simulate the race condition > specifically for loop.sock_sendall(), I needed a connected socket with a full > send buffer so that the next sock_sendall() call would block. To achieve > this, I wrote something like this: > It might be that it cost too much time in these loops (especially the 2nd one > because the logs showed that it was blocked on calling sock_sendall()). But > that's just a guess yet, let me add some more debug logs and test locally. That seems reasonable to me and would make the most sense at a glance. If this is confirmed to be the source of the issue, we should be able to just reduce the size of the socket's send buffer via SO_SNDBUF before sending to it so that it fills up much more quickly. -- ___ Python tracker <https://bugs.python.org/issue30064> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue30064] BaseSelectorEventLoop.sock_{recv, sendall}() don't remove their callbacks when canceled
Kyle Stanley added the comment: I believe that I might have identified a simple fix for the issue, but first I'd like to clarify on something: What exactly is the reason that we need to use asyncio.wait_for() with a timeout of 10 seconds in these tests? We typically avoid using short duration timeouts on individual tests, largely because we don't want them to fail based on the performance of the device they're ran on. This can be a concern for slower devices running the test suite w/ parallel jobs. If asyncio.wait_for() is necessary in this case, I'd advise increasing the timeout substantially. I didn't experiment with a wide variety of numbers, but increasing the duration from 10 to 60 seconds seems to have fixed the failure locally, so that might be a decent starting point. If it's not necessary, I'd prefer to simply remove the asyncio.wait_for()s in test_sock_client_racing. -- ___ Python tracker <https://bugs.python.org/issue30064> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue30064] BaseSelectorEventLoop.sock_{recv, sendall}() don't remove their callbacks when canceled
Kyle Stanley added the comment: I was able to replicate the failure locally by running the large number of jobs in parallel. We typically use this to test for tricky race conditions, to simulate maximum load: [aeros:~/repos/cpython]$ ./python -m test test_asyncio.test_sock_lowlevel --match test_sock_client_racing -j100 -F -v # [snip] == ERROR: test_sock_client_racing (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests) -- Traceback (most recent call last): File "/home/aeros/repos/cpython/Lib/test/test_asyncio/test_sock_lowlevel.py", line 200, in _basetest_sock_send_racing await self.loop.sock_sendall(sock, b'world') File "/home/aeros/repos/cpython/Lib/asyncio/selector_events.py", line 460, in sock_sendall return await fut asyncio.exceptions.CancelledError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/aeros/repos/cpython/Lib/asyncio/tasks.py", line 507, in wait_for fut.result() asyncio.exceptions.CancelledError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/home/aeros/repos/cpython/Lib/test/test_asyncio/test_sock_lowlevel.py", line 256, in test_sock_client_racing self.loop.run_until_complete(asyncio.wait_for( File "/home/aeros/repos/cpython/Lib/asyncio/base_events.py", line 642, in run_until_complete return future.result() File "/home/aeros/repos/cpython/Lib/asyncio/tasks.py", line 509, in wait_for raise exceptions.TimeoutError() from exc asyncio.exceptions.TimeoutError == ERROR: test_sock_client_racing (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests) -- Traceback (most recent call last): File "/home/aeros/repos/cpython/Lib/test/test_asyncio/test_sock_lowlevel.py", line 200, in _basetest_sock_send_racing await self.loop.sock_sendall(sock, b'world') File "/home/aeros/repos/cpython/Lib/asyncio/selector_events.py", line 460, in sock_sendall return await fut asyncio.exceptions.CancelledError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/aeros/repos/cpython/Lib/asyncio/tasks.py", line 507, in wait_for fut.result() asyncio.exceptions.CancelledError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/home/aeros/repos/cpython/Lib/test/test_asyncio/test_sock_lowlevel.py", line 256, in test_sock_client_racing self.loop.run_until_complete(asyncio.wait_for( File "/home/aeros/repos/cpython/Lib/asyncio/base_events.py", line 642, in run_until_complete return future.result() File "/home/aeros/repos/cpython/Lib/asyncio/tasks.py", line 509, in wait_for raise exceptions.TimeoutError() from exc asyncio.exceptions.TimeoutError == ERROR: test_sock_client_racing (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests) -- Traceback (most recent call last): File "/home/aeros/repos/cpython/Lib/test/test_asyncio/test_sock_lowlevel.py", line 256, in test_sock_client_racing self.loop.run_until_complete(asyncio.wait_for( File "/home/aeros/repos/cpython/Lib/asyncio/base_events.py", line 629, in run_until_complete self.run_forever() File "/home/aeros/repos/cpython/Lib/asyncio/base_events.py", line 596, in run_forever self._run_once() File "/home/aeros/repos/cpython/Lib/asyncio/base_events.py", line 1854, in _run_once event_list = self._selector.select(timeout) File "/home/aeros/repos/cpython/Lib/selectors.py", line 323, in select r, w, _ = self._select(self._readers, self._writers, [], timeout) OSError: [Errno 9] Bad file descriptor I'll try to add some debug lugs to find the source of the failure(s). This one might be a bit tricky to assess though. @Fantix I'd recommend trying to run the local test with the above command, and increasing the parallel job count until it occurs. If it takes more than a minute or two for the tests to run, slowly lower the number. At the moment, the failure has only occurred once in the buildbots, but we might need to temporarily disable it if it occurs repeatedly or find some form of workaround (as it will potentially mask other bugs). -- ___ Python tracker <https://bugs.python.org/issue30064> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40967] asyncio.Task.all_tasks() and asyncio.Task.current_task() must be removed in 3.9
Kyle Stanley added the comment: Thanks for bringing attention to this Rémi. I'm a bit concerned that it might be a bit late into the 3.9 beta to incorporate a removal and that we might need to consider delaying to 3.10, but I'll leave that up to Lukasz. Feel free to open a PR in the meantime since it will need to be removed either way, the only main difference is whether or not it gets backported to 3.9. (I elevated the priority to "release blocker", as I think it should be a blocker for 3.10 if it's not for 3.9. The version should be updated accordingly.) -- nosy: +aeros, lukasz.langa priority: normal -> release blocker ___ Python tracker <https://bugs.python.org/issue40967> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40894] asyncio.gather() cancelled() always False
Kyle Stanley added the comment: Thanks for the additional feedback, Caleb. > I think `gather()` should work the same. It would be confusing if > `future_gather.cancelled()` is false if a child is cancelled, while a plain > old outer future returns `future.cancelled() == true` if futures that it > waits on are cancelled. Agreed, I think it would make the most sense IMO for the behavior of .cancelled() to be similar for tasks, futures, and for gather itself. So, I'm still inclined towards checking the exception to see if CancelledError occurred for _GatheringFuture.cancelled(), as I think that would result in the most similar behavior. Currently waiting on feedback from Yury and/or Andrew about the current long-term plans for asyncio.gather(), and their general thoughts on this issue. Unless it is realistically going to be deprecated and effectively replaced with task groups in 3.10, I think the change would make sense. -- ___ Python tracker <https://bugs.python.org/issue40894> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40894] asyncio.gather() cancelled() always False
Kyle Stanley added the comment: Upon further investigation, I've realized that the issue is just that the cancel() override for `_GatheringFuture` never sets its state to CANCELLED at any point (unlike its parent), and is instead going to always be set to FINISHED because of the `outer.set_exception()` (https://github.com/python/cpython/blob/b8f67c0923ac85468dfbfd43375e0bbfb6ca50ea/Lib/asyncio/tasks.py#L826 or https://github.com/python/cpython/blob/b8f67c0923ac85468dfbfd43375e0bbfb6ca50ea/Lib/asyncio/tasks.py#L791, depending on the arg for *return_exceptions*). Since we are unable to set the state of `_GatheringFuture` (at least not without causing side effects), I'm starting to agree that it makes sense to override the behavior for `cancelled()`. However, it might make more sense to replace the `self._cancel_requested` check with `isinstance(self.exception(), exceptions.CancelledError)`, as this more accurately indicates if and when the gather() was cancelled. I don't think we should rely on `self._cancel_requested` since it would be true before the future is actually cancelled and not always be correct since the gather() can be cancelled without setting `self._cancel_requested`. Here's one case where relying on `self._cancel_requested` for future_gather.cancelled() wouldn't work, based on a slight modification of the reproducer example: ``` async def main(): """Cancel a gather() future and child and return it.""" task_child = ensure_future(sleep(1.0)) future_gather = gather(task_child) task_child.cancel() try: await future_gather except asyncio.CancelledError: pass return future_gather, task_child ``` (Despite `await future_gather` raising a CancelError and effectively being cancelled, `future_gather.cancelled()` would return false since `self._cancel_requested` was never set to true.) -- ___ Python tracker <https://bugs.python.org/issue40894> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40894] asyncio.gather() cancelled() always False
Kyle Stanley added the comment: > So, we can't rely on checking ``self.done() and self._cancel_requested`` for > future.cancelled() as this would mean that future.cancelled() would return > true for a future that fully completed if `future.cancel()` was called after > it finished (which is incorrect). This should be "was called *as* it finished", not "was called *after* it was finished". If gather_future.cancel() is called after the future is `FINISHED`, it will immediately return false since it checks `self.done()` first (https://github.com/python/cpython/blob/b8f67c0923ac85468dfbfd43375e0bbfb6ca50ea/Lib/asyncio/tasks.py#L727). -- ___ Python tracker <https://bugs.python.org/issue40894> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40894] asyncio.gather() cancelled() always False
Kyle Stanley added the comment: > Specifically a future can't be cancelled once it reaches the PENDING state, > this is indicated when future.cancel() returns false; see > https://github.com/python/cpython/blob/0e96c419d7287c3c7f155c9f2de3c61020386256/Lib/asyncio/futures.py#L152 > for the source code Actually, I was mistaken in my previous message; sorry about that. It can *only* be cancelled when the state is PENDING. So, I suspect there's a race condition where the state is `PENDING` when future.cancel() is called, but transitions to `FINISHED` before the future is actually cancelled. I'll insert some logging in `future.cancel()` to verify this locally. The approach in PR-20686 has a fundamental problem though: simply because cancellation was requested does not mean the future was cancelled. So, we can't rely on checking ``self.done() and self._cancel_requested`` for future.cancelled() as this would mean that future.cancelled() would return true for a future that fully completed if `future.cancel()` was called after it finished (which is incorrect). I'll have to do some further investigation to determine the cause and a potential fix of the race condition. Thanks again for reporting it, and my apologies for the earlier mixup. -- ___ Python tracker <https://bugs.python.org/issue40894> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40894] asyncio.gather() cancelled() always False
Kyle Stanley added the comment: Thank you for the bug report Timm. While I can certainly understand the source of the confusion here, I think you may be misunderstanding an important part of cancellation for futures. Specifically a future can't be cancelled once it reaches the PENDING state, this is indicated when future.cancel() returns false; see https://github.com/python/cpython/blob/0e96c419d7287c3c7f155c9f2de3c61020386256/Lib/asyncio/futures.py#L152 for the source code. In your example code snippet, you can also see this if you replace the line: ``` future_gather.cancel() ``` with the following: ``` if not future_gather.cancel(): logger.info("future_gather could not be cancelled") ``` Also, to clarify on something else: > However, my understanding is that asyncio.gather() is scheduled for > deprecation, so maybe changes in this area are on halt anyways!? asyncio.gather() is not deprecated or scheduled for deprecation, it is simply the loop argument being deprecated. -- nosy: +aeros ___ Python tracker <https://bugs.python.org/issue40894> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40802] AbstractEventLoop.shutdown_default_executor breaks backwards compatibility
Kyle Stanley added the comment: The main issue is that shutdown_default_executor() (or something that does the same thing) is necessary to ensure the resources of the event loop's ThreadPoolExecutor are finalized in a safe manner. Otherwise, it frequently results in dangling threads when run_in_executor() is used with the default executor, and was regularly doing so in the buildbots. So, I think this is a case where we ultimately have to break backwards compatibility in an upcoming version to fix a bug. Also, the implementation of shutdown_default_executor() is fairly straightforward, and as far as I'm aware it's not incompatible with any of the listed projects that would need to implement it for 3.9. While inconvenient, I don't think the burden to address the compatibility break is at all high in this case. > Since asyncio is no longer provisional, should it break backwards > compatibility with just a What's New entry? Do you have an alternative suggestion? Personally, I don't think a deprecation warning (or other) would make much sense here since it would be effectively leaving a resource leak bug as long as it isn't implemented. -- nosy: +aeros ___ Python tracker <https://bugs.python.org/issue40802> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40061] Possible refleak in _asynciomodule.c future_add_done_callback()
Kyle Stanley added the comment: Thanks for the PR, Zackery. -- resolution: -> fixed stage: patch review -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue40061> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35621] asyncio.create_subprocess_exec() only works with main event loop
Kyle Stanley added the comment: > is there a workaround for earlier Python versions that does not involve > patching the standard library? You could potentially try using the new default watcher, `ThreadedChildWatcher`, by implementing it locally and setting it as the child watcher to use (instead of `SafeChildWatcher`) with `set_child_watcher()`. AFAICT, the current implementation should work well for earlier versions of Python that don't have it, we just can't include it earlier than 3.8 since it's a new feature. See https://github.com/python/cpython/blob/4649202ea75d48e1496e99911709824ca2d3170e/Lib/asyncio/unix_events.py#L1326 for reference. -- nosy: +aeros ___ Python tracker <https://bugs.python.org/issue35621> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue30064] BaseSelectorEventLoop.sock_{recv, sendall}() don't remove their callbacks when canceled
Kyle Stanley added the comment: > The new test_sock_client_racing() test seems to have... a race condition... I'm also a bit skeptical about relying on `time.sleep(0.01)` at the end of the loop in `_basetest_sock_recv_racing()`, but I don't have an idea for a better approach at the moment. -- ___ Python tracker <https://bugs.python.org/issue30064> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40782] AbstactEventLoop.run_in_executor is listed as an async method, but should actually return a Futrue
Kyle Stanley added the comment: >From looking at the commit history of AbstactEventLoop.run_in_executor(), it >seems that it was previously be a non-coroutine method prior to the conversion >from the `@asyncio.coroutine` decorator to `async def` (PR-4753). See >https://github.com/python/cpython/blame/ede157331b4f9e550334900b3b4de1c8590688de/Lib/asyncio/events.py#L305. The only context for the change I can find is the following conversation between Andrew and Yury: https://github.com/python/cpython/pull/4753#issuecomment-350114336. However, the example provided of `connect_read_pipe()` had already been a coroutine at the time for the BaseEventLoop implementation, which makes sense in that case. So, it's not clear to me as to why `run_in_executor()` was also converted to "async def" when its main implementation is not a coroutine. Furthermore, it's documented as an awaitable rather than a coroutine (https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor). @Andrew do you have any additional context to provide that I'm potentially missing? -- nosy: +aeros, asvetlov, yselivanov ___ Python tracker <https://bugs.python.org/issue40782> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40160] documentation example of os.walk should be less destructive
Kyle Stanley added the comment: > I made the suggested change to just print the os.remove() statements (instead > of executing them) and also removed the 'skip news'. I think you may have misunderstood the suggestion. Specifically, the key part was "I would suggest adding succinct comments or a note that very briefly explains how one could see a visual demonstration...". This would mean the actual code in the example would be *unchanged*, but with a new code comment or separate note after the example that explains how one could replace ``os.remove(os.path.join(root, name))`` with ``print(f"os.remove({os.path.join(root, name)})")`` for a purely visual demonstration that doesn't affect any local files. -- ___ Python tracker <https://bugs.python.org/issue40160> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40405] asyncio.as_completed documentation misleading
Kyle Stanley added the comment: Thanks for bring this to our attention and working on this Bar Harel, and thanks to Yury for the suggestions. -- resolution: -> fixed stage: patch review -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue40405> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40405] asyncio.as_completed documentation misleading
Kyle Stanley added the comment: New changeset 13206b52d16c2489f4c7dd2dce2a7f48a554b5ed by Bar Harel in branch 'master': bpo-40405: Fix asyncio.as_completed docs (GH-19753) https://github.com/python/cpython/commit/13206b52d16c2489f4c7dd2dce2a7f48a554b5ed -- ___ Python tracker <https://bugs.python.org/issue40405> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com