[issue45995] string formatting: normalize negative zero
Change by John Belmonte : -- keywords: +patch nosy: +jbelmonte nosy_count: 5.0 -> 6.0 pull_requests: +28274 stage: -> patch review pull_request: https://github.com/python/cpython/pull/30049 ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: > For Decimal, we'd need to "own" the string formatting, taking that > responsibility away from mpdecimal, but there are already other reasons to do > that. After some digging, I believe this is the background on forking pieces of mpdecimal (and why the existing source copy inside Python doesn't count as a fork): https://bugs.python.org/issue45708#msg405895 https://github.com/python/cpython/pull/29438 If I understand correctly, the PR for supporting underscore separators in Decimal formatting is only taking control of generating a mpd_spec_t from the spec string. Formatting itself is still done by mpd_qformat_spec(). So there's outstanding work to also pull the formatting code itself into _decimal.c. (And this is wanted anyway to reconcile existing libmpdec formatting modifications: https://github.com/python/cpython/commit/298131a44896a4fec1ea829814ad52409d59aba5) And this is all because vendors have the crazy practice of unbundling libmpdec from Python. (If a project is bundling the source of another, there may be some reason...?) -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: potential short-term solution for Decimal: if negative zero option is set and sign is negative: pre-round into a temp using mpd_qrescale() if mpd_iszero(temp): change sign to positive -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: implemented float and Decimal-- PR is ready for review -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: Mark, would you give it a review this month? (PR has been marked stale.) -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: Thank you Mark and Eric. > I'll note that the paper is proposing a 'z' modifier to the sign, so I guess > for us that would translate to: [sign[optional-z]] instead of just sign. I'd > have to noodle through the differences between that the proposed [sign][~]. The C++ paper proposes [sign][z] (i.e. you can have the `z` alone without an explicit +/-), and this is what I implemented in the Python PR. My original proposal with tilde was discarded. > My only reservation is Mark's comment: """For Decimal, we'd need to "own" > the string formatting, taking that responsibility away from mpdecimal, but > there are already other reasons to do that.""" In the PR I was able to avoid taking that on by preprocessing the format string before handing it to mpdecimal. The code was already doing such things to handle the NULL fill character. -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: PEP at https://github.com/python/peps/pull/2295 -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38250] enum.Flag should be more set-like
New submission from John Belmonte : I would like Flag class instances to have more set-like abilities: 1. iteration, to walk through each set bit of the value 2. len corresponding to #1 3. subset operator I may be told "implement it yourself as instance methods", or that #3 has an idiom (a & b is b). Ideally though, every Flag user should be able to rely on these being implemented consistently. When trying to implement #1 without devolving into bit fiddling, naturally one might try to use the class iterator. Unfortunately the semantics of that enumeration include 0, aliases, and compound values. I've used Flag in several situations and projects, and so far there hasn't been a case where that was the desired semantics. Interesting though, if #1 were implemented in the standard library, then we could enumerate all bits of the Flag via iteration of `~MyFlag(0)`... though that's obscuring things behind another idiom. Thank you for considering. -- components: Library (Lib) messages: 352967 nosy: John Belmonte priority: normal severity: normal status: open title: enum.Flag should be more set-like type: enhancement versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue38250> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42194] Docs for argparse.BooleanOptionalAction missing "New in version 3.9"
John Belmonte added the comment: A PR was opened over a year ago, but the author never signed CLA. How can we proceed with this doc fix? -- nosy: +John Belmonte ___ Python tracker <https://bugs.python.org/issue42194> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42194] Docs for argparse.BooleanOptionalAction missing "New in version 3.9"
Change by John Belmonte : -- nosy: +jbelmonte nosy_count: 6.0 -> 7.0 pull_requests: +24938 pull_request: https://github.com/python/cpython/pull/26348 ___ Python tracker <https://bugs.python.org/issue42194> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42194] Docs for argparse.BooleanOptionalAction missing "New in version 3.9"
John Belmonte added the comment: I've opened a new PR, please review. -- ___ Python tracker <https://bugs.python.org/issue42194> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44242] enum.IntFlag regression: missing values cause TypeError
John Belmonte added the comment: To clarify, it's caused by these mask entries in the enum: NPTS_MASK = 0xF DEL_S_MASK = 0xF0 AZIS_MASK = 0xF00 Since the masks are not an aggregation of individual bits defined in the enum, it's an error. > I'm inclined to go with [removing the check], since `boundary` is designed to > answer the question of what to do when Flag.A | Flag.B does not exist in Flag. I think that would cause various problems in the API and implementation. For example, without underlying individual bits, repr() may be nonsensical. -- ___ Python tracker <https://bugs.python.org/issue44242> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44242] enum.IntFlag regression: missing values cause TypeError
John Belmonte added the comment: I wonder if CONFORM could tolerate these, since it's ultimately going to discard invalid bits. And then perhaps CONFORM is the default. -- ___ Python tracker <https://bugs.python.org/issue44242> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44242] enum.IntFlag regression: missing values cause TypeError
John Belmonte added the comment: Rather than make such masks containing unknown bits, this would be best practice if you want to use STRICT, correct? NPTS_ROUND = 0x0 NPTS_CEIL = 0x1 NPTS_TRUNC = 0x2 NPTS_MASK = NPTS_ROUND | NPTS_CEIL | NPTS_TRUNC Otherwise, if your input may have unknown bits, use CONFORM. -- ___ Python tracker <https://bugs.python.org/issue44242> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44242] enum.IntFlag regression: missing values cause TypeError
John Belmonte added the comment: > However, if the user is interfacing with other software/hardware, they may > not have a choice on which bits make up the mask. I think it's the same as saying "unknown bits may come on the input". An important use case is for forward compatibility, where new bits may be added but you don't want to break existing code. That is what CONFORM is for. The cited code should either declare the masks as I've shown if STRICT is desired, or use CONFORM if forward compatibility is desired. -- ___ Python tracker <https://bugs.python.org/issue44242> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44242] enum.IntFlag regression: missing values cause TypeError
John Belmonte added the comment: > Do you agree that simply removing the unnamed member check that takes place > at Flag creation is a good way forward? It's uncomfortable, because then STRICT is not actually strict, and it's going to be show raw values in str/repr. > CONFORM -> unnamed bits are discarded (so the DEFAULT flag would be returned) This behavior of CONFORM is a little dubious. I expect it to conform new values after the class is constructed. But the class members themselves should not have that transform applied, and raise an error on invalid bits. -- ___ Python tracker <https://bugs.python.org/issue44242> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44242] enum.IntFlag regression: missing values cause TypeError
John Belmonte added the comment: > Either [...] we should lose the creation time check (not apply the > transform), or we should still have the check (raise an error on invalid > bits) which would still leave us in this situation. That is only one option (which undesirable consequences are already identified). We should consider a few options carefully. >From the start, if default Enum declarations are going to be subject to new >runtime exceptions, it's certain that they'll be hit in some existing code. >Anything other than the default being legacy-compatible, or defining the new >stuff as Enum2, or deferring all the changes to Python 4, is going to lead to >bug reports and disgruntled users. I don't think that suggests we should >remove the runtime exceptions-- they are what supports the new API and >implementation. Perhaps KEEP should be renamed to LEGACY, that should be the default, and there should be guidance on how to get the KEEP use cases you've found migrated to one of the other modes. (And changing the default could be considered for Python 4.) >> But the [CONFORM] class members themselves should not have that transform >> applied, and raise >> an error on invalid bits. > > But I'm not sure I understand that. It's an important point that should be fixed in the code. CONFORM should be regarding transforming external values into valid member instances. The enum author's declaration itself should be coherent and not rely on such transforms. Users will be surprised when they define a "FOO = 0xFF" and they read the value back as 0x1F or something. The runtime exception lets the enum author know about the issue in the declaration, and normalize it. -- ___ Python tracker <https://bugs.python.org/issue44242> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40213] contextlib.aclosing()
John Belmonte added the comment: merged for Python 3.10 -- resolution: -> fixed stage: patch review -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue40213> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37398] contextlib.ContextDecorator decorating async functions
John Belmonte added the comment: > bpo-40816 took the much simpler approach of introducing a separate > contextlib.AsyncContextDecorator class How do I apply AsyncContextDecorator to the use case of wrapping either a sync or async function with a synchronous context manager? -- ___ Python tracker <https://bugs.python.org/issue37398> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44594] AsyncExitStack.enter_async_context() is mishandling exception __context__
New submission from John Belmonte : Over at the Trio project, we have evidence that `AsyncExitStack.enter_async_context(foo())` is not actually equivalent to `async with foo()` regarding raised exception context. The symptom is a very long, unhelpful tracebacks because the __context__ of raised exceptions is not set to the expected object. https://github.com/python-trio/trio/issues/2001 I can't speak to this solution myself, but njsmith suggests this amendment to contextlib: saved_context = exc_details[1].__context__ try: raise exc_details[1] finally: exc_details[1].__context__ = saved_context -- components: Library (Lib) messages: 397230 nosy: John Belmonte, njs priority: normal severity: normal status: open title: AsyncExitStack.enter_async_context() is mishandling exception __context__ ___ Python tracker <https://bugs.python.org/issue44594> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44594] AsyncExitStack.enter_async_context() is mishandling exception __context__
Change by John Belmonte : -- keywords: +patch nosy: +jbelmonte nosy_count: 3.0 -> 4.0 pull_requests: +25637 stage: -> patch review pull_request: https://github.com/python/cpython/pull/27089 ___ Python tracker <https://bugs.python.org/issue44594> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44594] AsyncExitStack.enter_async_context() is mishandling exception __context__
John Belmonte added the comment: demonstrating the difference for async case: import contextlib import trio async def background(): assert False async def main1(): async with trio.open_nursery() as nursery: nursery.start_soon(background) await trio.sleep_forever() async def main2(): async with contextlib.AsyncExitStack() as stack: nursery = await stack.enter_async_context(trio.open_nursery()) nursery.start_soon(background) await trio.sleep_forever() try: trio.run(main1) except BaseException as e: print('main1, context:', e.__context__) try: trio.run(main2) except BaseException as e: print('main2, context:', e.__context__) main1, context: None main2, context: Cancelled -- ___ Python tracker <https://bugs.python.org/issue44594> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44594] AsyncExitStack.enter_async_context() is mishandling exception __context__
John Belmonte added the comment: To clarify the problem case, I believe the discrepancy is seen when raising exceptions as follows: exc = foo() try: raise exc finally: exc.__context__ = None (From my understanding, Trio has valid use cases for doing this since it wants to control complex exception chaining, and this is beyond the scope of __suppress_context__.) Neither ExitStack nor AsyncExcitStack are preserving the None context in the case above. === `with` statement === Traceback (most recent call last): File "exit_stack_test.py", line 251, in assert False File "/.../python3.7/contextlib.py", line 130, in __exit__ self.gen.throw(type, value, traceback) File "exit_stack_test.py", line 244, in my_cm raise exc MyException === enter_context() === Traceback (most recent call last): File "exit_stack_test.py", line 240, in my_cm yield File "exit_stack_test.py", line 259, in assert False AssertionError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "exit_stack_test.py", line 259, in assert False File "/.../python3.7/contextlib.py", line 524, in __exit__ raise exc_details[1] File "/.../python3.7/contextlib.py", line 509, in __exit__ if cb(*exc_details): File "/.../python3.7/contextlib.py", line 377, in _exit_wrapper return cm_exit(cm, exc_type, exc, tb) File "/.../python3.7/contextlib.py", line 130, in __exit__ self.gen.throw(type, value, traceback) File "exit_stack_test.py", line 244, in my_cm raise exc MyException -- ___ Python tracker <https://bugs.python.org/issue44594> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44594] AsyncExitStack.enter_async_context() is mishandling exception __context__
John Belmonte added the comment: [reposting the example, with source] example: class MyException(Exception): pass @contextmanager def my_cm(): try: yield except BaseException: exc = MyException() try: raise exc finally: exc.__context__ = None print('\n=== `with` statement ===') try: with my_cm(): assert False except BaseException as e: traceback.print_exc() print('\n=== enter_context() ===') try: with ExitStack() as stack: stack.enter_context(my_cm()) assert False except BaseException as e: traceback.print_exc() output: === `with` statement === Traceback (most recent call last): File "exit_stack_test.py", line 251, in assert False File "/.../python3.7/contextlib.py", line 130, in __exit__ self.gen.throw(type, value, traceback) File "exit_stack_test.py", line 244, in my_cm raise exc MyException === enter_context() === Traceback (most recent call last): File "exit_stack_test.py", line 240, in my_cm yield File "exit_stack_test.py", line 259, in assert False AssertionError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "exit_stack_test.py", line 259, in assert False File "/.../python3.7/contextlib.py", line 524, in __exit__ raise exc_details[1] File "/.../python3.7/contextlib.py", line 509, in __exit__ if cb(*exc_details): File "/.../python3.7/contextlib.py", line 377, in _exit_wrapper return cm_exit(cm, exc_type, exc, tb) File "/.../python3.7/contextlib.py", line 130, in __exit__ self.gen.throw(type, value, traceback) File "exit_stack_test.py", line 244, in my_cm raise exc MyException -- ___ Python tracker <https://bugs.python.org/issue44594> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44594] AsyncExitStack.enter_async_context() is mishandling exception __context__
John Belmonte added the comment: cc: ncoghlan for help with ExitStack exception context -- nosy: +ncoghlan ___ Python tracker <https://bugs.python.org/issue44594> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44594] AsyncExitStack.enter_async_context() is mishandling exception __context__
Change by John Belmonte : -- type: -> behavior versions: +Python 3.10, Python 3.11, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue44594> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44594] AsyncExitStack.enter_async_context() is mishandling exception __context__
Change by John Belmonte : -- pull_requests: +27078 pull_request: https://github.com/python/cpython/pull/28730 ___ Python tracker <https://bugs.python.org/issue44594> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44594] AsyncExitStack.enter_async_context() is mishandling exception __context__
Change by John Belmonte : -- pull_requests: +27079 pull_request: https://github.com/python/cpython/pull/28731 ___ Python tracker <https://bugs.python.org/issue44594> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
New submission from John Belmonte : proposal: add a string formatting option to normalize negative 0 values to 0 use case: rounded display of a float that is nominally 0, where the distraction of a flashing minus sign from minute changes around 0 is unwanted example: >>> '%~5.1f' % -.1 ' 0.0' format spec before: format_spec ::= [[fill]align][sign][#][0][width][grouping_option][.precision][type] after: format_spec ::= [[fill]align][sign][~][#][0][width][grouping_option][.precision][type] where '~' is only allowed for number types implementation: if '~' is present in the spec, add 0 to the value after applying precision -- components: Library (Lib) messages: 407792 nosy: John Belmonte priority: normal severity: normal status: open title: string formatting: normalize negative zero type: enhancement ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: > To normalize negative 0.0 to 0.0 you can just add 0.0. yes, I'm aware-- see "implementation" in the original post > there is no need to change all formatting specifications For adding 0 to work, it must be done after the rounding. That means if you want make use of anything in the current formatting spec regarding precision, normalizing negative zero would need to be a proper option of the formatting spec. -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: Here is the same proposal made for C++ `std::format`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1496r2.pdf It makes fair arguments for the feature's use, and explains why the problem is hard to work around. It was withdrawn by the author for C++20, but a consensus proposal is promised for C++23. -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: > changing %-formatting doesn't seem viable I'm concerned about treating %-formatting specially. As far as float/complex, the logical and efficient place to put this change seems to be PyOS_double_to_string(), which affects all three formatting options. For example, the dtoa case is as simple as this change to format_float_short(): /* coerce negative zero to positive */ if (sign == 1 && ((digits_len == 0 && decpt == -1) || (digits_len == 1 && digits[0] == '0'))) { sign = 0; } -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: I see now. PyOS_double_to_string() could gain the extra flag to coerce negative zero but, out of the three formatting methods, only format() and f-string would use the flag. -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45995] string formatting: normalize negative zero
John Belmonte added the comment: I'll share a draft PR soon (excluding Decimal), so far it's still looking straightforward. > Maybe old versions would correctly ignore the new bit being set. That's one of the benefits of using bit flags in an ABI: backward-compatible extensibility. (An implementation can defeat it by intentionally failing if unknown bits are encountered, but the code in question doesn't appear to be doing this.) > You can round explicitly before formatting > >>>> '%5.1f' % (round(-.1, 1) + 0.0) Yes, I have experience with it. 1. even as a one-off, it's questionable. If someone accidentally changes the precision in only one of the spec string or round call, that's a bug. 2. since applications and libraries may pass around format specs, and because of (1), you'll try to make a programmatic solution. Now you're parsing format spec strings. 3. while a programmatic solution can be done for a function API like format() that takes a separate spec and value, there is no sane way to wrap f-strings -- ___ Python tracker <https://bugs.python.org/issue45995> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38753] AsyncMock not cited as new in 3.8
New submission from John Belmonte : AsyncMock appears to be new in Python 3.8, but doc is missing info on when it was introduced. https://docs.python.org/3.8/library/unittest.mock.html#unittest.mock.AsyncMock -- assignee: docs@python components: Documentation messages: 356290 nosy: John Belmonte, docs@python priority: normal severity: normal status: open title: AsyncMock not cited as new in 3.8 versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue38753> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38753] AsyncMock not cited as new in 3.8
John Belmonte added the comment: yes, will do -- ___ Python tracker <https://bugs.python.org/issue38753> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38753] AsyncMock not cited as new in 3.8
Change by John Belmonte : -- keywords: +patch pull_requests: +16608 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/17102 ___ Python tracker <https://bugs.python.org/issue38753> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40213] contextlib.aclosing()
New submission from John Belmonte : Please add aclosing() to contextlib, the async equivalent of closing(). It's needed to ensure deterministic call of aclose() on the resource object at block exit. It's been available in the async_generator module for some time. However that module is intended to provide async generators to Python 3.5, so it's odd for apps using modern Python versions to depend on it only for aclosing(). https://github.com/python-trio/async_generator/blob/22eddc191c2ae3fc152ca13cf2d6fa55ac3f1568/async_generator/_util.py#L6 -- components: Library (Lib) messages: 365885 nosy: John Belmonte, njs priority: normal severity: normal status: open title: contextlib.aclosing() type: enhancement versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue40213> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43370] thread_time not available on python.org OS X builds
New submission from John Belmonte : time.thread_time is supposed to be available on OS X 10.12 and newer. Yet it's reported to raise ImportError on macOS Big Sur (11.2.1) on Python 3.9.2 (python.org download). (Reported by Quentin Pradet.) It is available in other OS X Python builds, such as published by Home Brew. (I confirm it's available on macOS 10.13, Python 3.7.7.) -- components: Build messages: 387925 nosy: John Belmonte priority: normal severity: normal status: open title: thread_time not available on python.org OS X builds type: behavior ___ Python tracker <https://bugs.python.org/issue43370> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40213] contextlib.aclosing()
John Belmonte added the comment: Given the lack of deterministic cleanup for iterators (https://www.python.org/dev/peps/pep-0533/), aclosing() is the way to ensure deterministic cleanup given any API using async iteration. -- ___ Python tracker <https://bugs.python.org/issue40213> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40213] contextlib.aclosing()
John Belmonte added the comment: highlighting from PEP 533: > Async generators cannot do cleanup at all without some mechanism for > deterministic cleanup that people will actually use, and async generators are > particularly likely to hold resources like file descriptors. -- ___ Python tracker <https://bugs.python.org/issue40213> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40816] Add missed AsyncContextDecorator to contextlib
John Belmonte added the comment: Thank you heckad! I'm in need of a decorating asynccontextmanager, and glad that an implementation is in the works that I can copy from in the meantime. I hope Yuri reviews the PR before long. -- nosy: +John Belmonte ___ Python tracker <https://bugs.python.org/issue40816> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40213] contextlib.aclosing()
Change by John Belmonte : -- keywords: +patch nosy: +jbelmonte nosy_count: 9.0 -> 10.0 pull_requests: +21613 stage: -> patch review pull_request: https://github.com/python/cpython/pull/22640 ___ Python tracker <https://bugs.python.org/issue40213> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38250] enum.Flag should be more set-like
John Belmonte added the comment: Part of this issue (#1) was intended to be addressed by https://github.com/python/cpython/pull/1 which added an `__iter__` implementation to Flag and IntFlag. (The PR did not reference this issue, and was already merged last month.) However that PR seems problematic on several counts: 1. `__iter__` diverges from the existing `__contains__`. The latter includes 0 and compound values 2. the implementation is fairly heavy 3. len() on an enum instance is going to be O(n) I've put post-merge comments on the PR. I think it would be safer to have an explicitly named `bits()` iterator on flag instances, rather than use `__iter__()`. -- keywords: +patch message_count: 3.0 -> 4.0 pull_requests: +21621 stage: -> patch review versions: +Python 3.10 -Python 3.9 pull_request: https://github.com/python/cpython/pull/1 ___ Python tracker <https://bugs.python.org/issue38250> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38250] enum.Flag should be more set-like
John Belmonte added the comment: > Just a comment, (1) is analogous to str. iter('abc') gives only 'a', 'b' and > 'c', while contains accepts '', 'ab', 'bc', and 'abc' too. At least in my > mind, it's a pretty strong analogy. I don't agree. The "zero" bit does not exist, so having __contains__ return True on `Foo(0) in x` is misaligned with the iterator. And having __contains__ return True for specific compound values just because they happen to be explicitly defined, while returning False for others, is arbitrary. __contains__ seems to be of very little use, and moreover a trap for the unwary. Assuming we have to live with that until Python 4, it's better to make an explicit iterator like `bits()` so that the API doesn't contradict itself. -- ___ Python tracker <https://bugs.python.org/issue38250> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38250] enum.Flag should be more set-like
John Belmonte added the comment: I think https://github.com/python/cpython/pull/1 should be reverted (considering the design issue, performance issue, and bugs), and lets have a proper design and review. While just reading the code, I found an existing bug in Flag. And the new __iter__ uses the buggy internal function, and so itself has bugs. https://github.com/python/cpython/pull/1#issuecomment-706776441 -- ___ Python tracker <https://bugs.python.org/issue38250> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40213] contextlib.aclosing()
Change by John Belmonte : -- pull_requests: +21633 versions: +Python 3.10 -Python 3.9 pull_request: https://github.com/python/cpython/pull/21545 ___ Python tracker <https://bugs.python.org/issue40213> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38250] enum.Flag should be more set-like
John Belmonte added the comment: It's completely undocumented, but today I noticed that Flag.__contains__() is actually a subset operation. def __contains__(self, other): ... return other._value_ & self._value_ == other._value_ It's an unfortunate departure from the `set` type, which uses `in` for membership test and issubset() / `<=` for subset test. For set operations, the Flag individual bits should be considered the members of a set (not Flag compound values, which are themselves equivalent to a set). -- ___ Python tracker <https://bugs.python.org/issue38250> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38250] enum.Flag should be more set-like
John Belmonte added the comment: I agree that a bit and one-bit flag are the same. > only 'x' was in 'xyz', not 'xy I don't understand the comparison, because str 'a in b' tests if 'a' is a subsequence of 'b'. It is not a subset operation ('xz' in 'xyz' is false). I can understand the argument that Flag has a subset operator (currently __contains__), and given that one-bit flags can be used freely with the subset operator, there is no reason to add a bit membership operator. However, since flag values are arguably a set of enabled bits, I think the use of `in` for subset is a confusing departure from the `set` API. -- ___ Python tracker <https://bugs.python.org/issue38250> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38250] enum.Flag should be more set-like
Change by John Belmonte : -- nosy: +jbelmonte nosy_count: 4.0 -> 5.0 pull_requests: +21698 pull_request: https://github.com/python/cpython/pull/22734 ___ Python tracker <https://bugs.python.org/issue38250> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue31861] add aiter() and anext() functions to operator module
John Belmonte added the comment: Adding this would be a nice compliment to aclosing(), which was already merged for 3.10. Otherwise, witness the ugliness of using aclosing() with an async iterable object: async with aclosing(foo.__aiter__()) as agen: async for item in agen: ... I'd like: async with aclosing(aiter(foo)) as agen: async for item in agen: ... -- nosy: +John Belmonte ___ Python tracker <https://bugs.python.org/issue31861> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37398] contextlib.ContextDecorator decorating async functions
New submission from John Belmonte : A case came up where I'd like a non-async context manager to be able to decorate both regular and async functions. I wonder why contextlib.ContextDecorator doesn't just support both cases. The implementation seems straightforward, switching on iscoroutinefunction(). -- components: Library (Lib) messages: 346485 nosy: John Belmonte priority: normal severity: normal status: open title: contextlib.ContextDecorator decorating async functions type: enhancement ___ Python tracker <https://bugs.python.org/issue37398> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37398] contextlib.ContextDecorator decorating async functions
John Belmonte added the comment: I have a context manager used for timing sections of code or whole functions (when used as a decorator). It's aware of the Trio async/await scheduler and is able to exclude periods of time where the task is not executing. The context manager itself is not async. Synopsis of decorator case: @PerfTimer('query') async def query_or_throw(self, q): return _parse_result(await self._send_query(q)) I'd like to just use the existing ContextDecorator to define the PerfTimer context manager, and have it wrap coroutine functions properly. New API is not required. -- ___ Python tracker <https://bugs.python.org/issue37398> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37398] contextlib.ContextDecorator decorating async functions
John Belmonte added the comment: PerfTimer is a reusable, non-reentrant context manager implemented as a class. There are already use cases of ContextDecorator described in the contextlib documentation, such as the track_entry_and_exit logger. What reason would you have for such context managers to *not* wrap async functions properly? -- ___ Python tracker <https://bugs.python.org/issue37398> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37398] contextlib.ContextDecorator decorating async functions
John Belmonte added the comment: My use case is for a non-async context manager, and if we take track_entry_and_exit as an example that's non-async as well. The explicit approach (e.g. separate base class for decorators applied to sync vs. async functions) doesn't seem ideal, because it precludes having a single context manager for both cases. track_entry_and_exit is an example where a context manager would want to decorate both types of functions. I'm not sure how big of a problem the iscoroutinefunction() limitation is-- in Trio style we don't pass around coroutines by normal functions. The `async` qualifier exists to make it clear when a function returns a coroutine, and ContextDecorator already doesn't work for the case of a regular function returning a coroutine. I think the scope here is to enhance ContextDecorator to work with async functions which are properly qualified with `async`. -- ___ Python tracker <https://bugs.python.org/issue37398> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37398] contextlib.ContextDecorator decorating async functions
John Belmonte added the comment: I was caught by this again, indirectly via @contextmanager. If I define a non-async context manager using @contextmanager, I expect the decorator support to work on async functions. I.e. the following should be equivalent: ``` async def foo(): with non_async_cm: ... ``` ``` @non_async_cm async def foo(): ... ``` Not only does the 2nd case not work, but the decorator is (effectively) silently ignored :( -- ___ Python tracker <https://bugs.python.org/issue37398> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36857] bisect should support descending order
New submission from John Belmonte : because "list.pop()" use case: maintain large ordered list and efficiently remove min item list.pop() is O(1) but yields the max item. There is no efficient removal of the min item. list is by far the fastest collection to use with insort(). While deque offers O(1) popleft(), insort() performance with deque is not acceptable. Lack of descending support in bisect necessitates workarounds such as using negative-valued items, which hurts code readability and moreover assumes that values are numbers. -- components: Library (Lib) messages: 341921 nosy: John Belmonte priority: normal severity: normal status: open title: bisect should support descending order type: enhancement ___ Python tracker <https://bugs.python.org/issue36857> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com