Python 3.13 support #18

Merged
goodboy merged 29 commits from py313_support into main 2025-03-27 19:50:43 +00:00

Bumping to latest minor release with some refinements and wart fixes along the way!


Main breaking/unexpected changes due to deps

Those requiring attention are detailed in #8 and i’ll briefly re-list here,

  1. trio’s release schedule requires we bump to at least trio>0.27 which flips on strict egs (ExceptionGroups) by default. This originally broke most of our test suite an generally internal RemoteActorError relay and propagation as per the surgery completed in #8..
  • required either of,
    • setting (the soon to be removed/already deprecated) strict_exception_groups=False in various core-runtime and test-suite trio.open_nursery() usage
      • de91ca7 Flip to strict_exception_groups=False in core tns
      • 3e37508 A couple more loose-egs flag flips
      • 0af83bd Go to loose egs in Actor root & service nurseries (for now..)
    • forcing a move in some spots to explicit except*: handlers for topical/manual eg “loosify-ing”.
      • 67c6834 Handle egs on failed request_root_stdio_lock()
      • 539ae7d Draft some eg collapsing helpers (this adds a new trionics._beg mod FYI)
  • various test suite adjustments include,
    • b6e4e58 Another loose-egs flag in test_child_manages_service_nursery
    • ea29a1c Various test tweaks related to 3.13 egs
    • 1a0e631 Another couple loose-ifies for discovery and advanced fault suites
    • 8027746 Fix docs tests with yet another loosie-goosie
    • 42389f8 Use collapse_eg() in broadcaster suite
    • 307e3cf Another loosie in the trioisms suite
  1. asyncio re-mucking its SIGINT machinery; all the miserable details of which can be found in #2..
  • #2 fixes all of this including some 3.13 specific augmentations,
    • 3.13’s asyncio.Queue provides for more explicit aio-side graceful teardown detection using the new asyncio.Queue.shutdown()/.QueueShutDown feats delivered in,
      • 680501a Add per-side graceful-exit/cancel excs-as-signals
      • dc19659 Continue supporting py3.11+
    • avoiding calls to asyncio.Task.cancel() and instead hackily checking for and doing,
      • 5a9a3a4 Hm, asyncio.Task._fut_waiter.set_exception()
  1. cpython deciding to render colored console output in tracebacks which completely rekts pattern matching in the tests/devx/test_debugger.py suite(s).
  • obvi we need to disable that for tests as per
    • 149b75 Unset $PYTHON_COLORS for test debugger suite.. which lands in #2, and
    • 934f453 Disable tb colors in ._testing.mk_cmd()
  1. the stdlib getting a readline.backend: str and seemingly cpython itself being more commonly built (definitely with our move to uv for pking) to use libedit meaning our use of pdbp gets REPL UX issues (tab complete, vi mode) without specially configuring.
    • backported and landed in #14,
      • 9324d82 Handle cpython builds with libedit for readline

  • prefer the system python in the uv config, choose the linux distro’s cpython over those distributed by astral.
  • pinning to msgspec>=0.19.0 release which supports 3.13+
  • 9681406 Bump up to pytest>=8.3.5 to match “GH actions”

Miscellaneous refinements,

various minor .devx related repairs/adjustments,

  • 68784a8 Match maybe_open_crash_handler() to non-maybe version
  • fd6d250 Unpack errors from pdb.bdb
  • 0696e7d Fix roundtripped ref error in validate_payload_msg()
  • e42bc33 Move bp to-match-comments on same line for py3.13

RE frame-hiding on internal errors,

  • 0e76a2d Expose hide_tb: bool from .open_nursery()
  • d6ed798 Hide open_nursery() frame by def
  • 78028ca Show frames when decode is handed bad input
  • 4d865b8 Bind another _bexc for debuggin

changes in namespacing,

  • 030a9b5 Expose ._state.debug_mode() predicate at top level

To-cherry into #2

  • 34ce5fd Drop asyncio-canc error from ._exceptions
  • 66bc38f Add equiv of AsyncioCancelled for aio side
  • 38497fa Comment-tag pause points in asycnio_bp.py
Bumping to latest minor release with some refinements and wart fixes along the way! --- Main breaking/unexpected changes due to deps -------------------------------------------- Those requiring attention are detailed in #8 and i'll briefly re-list here, 1. `trio`'s release schedule requires we bump to at least `trio>0.27` which flips on strict egs (`ExceptionGroup`s) by default. This originally broke most of our test suite an generally internal `RemoteActorError` relay and propagation as per the surgery completed in #8.. - [x] required either of, - setting (the soon to be removed/already deprecated) `strict_exception_groups=False` in various core-runtime and test-suite `trio.open_nursery()` usage - de91ca7 Flip to `strict_exception_groups=False` in core tns - 3e37508 A couple more loose-egs flag flips - 0af83bd Go to loose egs in `Actor` root & service nurseries (for now..) - forcing a move in some spots to explicit `except*:` handlers for topical/manual eg "loosify-ing". - 67c6834 Handle egs on failed `request_root_stdio_lock()` - 539ae7d Draft some eg collapsing helpers (this adds a new `trionics._beg` mod FYI) - various test suite adjustments include, - b6e4e58 Another loose-egs flag in `test_child_manages_service_nursery` - ea29a1c Various test tweaks related to 3.13 egs - 1a0e631 Another couple loose-ifies for discovery and advanced fault suites - 8027746 Fix docs tests with yet another loosie-goosie - 42389f8 Use `collapse_eg()` in broadcaster suite - 307e3cf Another loosie in the trioisms suite 2. `asyncio` re-mucking its SIGINT machinery; all the miserable details of which can be found in #2.. - [x] https://pikers.dev/goodboy/tractor/pulls/2 fixes all of this including some 3.13 specific augmentations, - 3.13's `asyncio.Queue` provides for more explicit aio-side graceful teardown detection using the new `asyncio.Queue.shutdown()`/`.QueueShutDown` feats delivered in, - 680501a Add per-side graceful-exit/cancel excs-as-signals - dc19659 Continue supporting py3.11+ - avoiding calls to `asyncio.Task.cancel()` and instead hackily checking for and doing, - 5a9a3a4 Hm, `asyncio.Task._fut_waiter.set_exception()` 3. cpython deciding to render colored console output in tracebacks which completely rekts pattern matching in the `tests/devx/test_debugger.py` suite(s). - [x] obvi we need to disable that for tests as per - 149b75 Unset `$PYTHON_COLORS` for test debugger suite.. which lands in #2, and - 934f453 Disable tb colors in `._testing.mk_cmd()` 4. the stdlib getting a `readline.backend: str` and seemingly cpython itself being more commonly built (definitely with our move to `uv` for pking) to use `libedit` meaning our use of `pdbp` gets REPL UX issues (tab complete, vi mode) without specially configuring. - [x] backported and landed in #14, - 9324d82 Handle cpython builds with `libedit` for `readline` --- Additional dep related changes include, --------------------------------------- - prefer the system python in the `uv` config, choose the linux distro's `cpython` over those distributed by astral. - pinning to `msgspec>=0.19.0` release which supports 3.13+ - 9681406 Bump up to `pytest>=8.3.5` to match "GH actions" --- Miscellaneous refinements, -------------------------- various minor `.devx` related repairs/adjustments, - 68784a8 Match `maybe_open_crash_handler()` to non-maybe version - fd6d250 Unpack errors from `pdb.bdb` - 0696e7d Fix `roundtripped` ref error in `validate_payload_msg()` - e42bc33 Move bp to-match-comments on same line for py3.13 RE frame-hiding on internal errors, - 0e76a2d Expose `hide_tb: bool` from `.open_nursery()` - d6ed798 Hide `open_nursery()` frame by def - 78028ca Show frames when decode is handed bad input - 4d865b8 Bind another `_bexc` for debuggin changes in namespacing, - 030a9b5 Expose `._state.debug_mode()` predicate at top level --- To-cherry into #2 ----------------- - [x] 34ce5fd Drop `asyncio`-canc error from `._exceptions` - [x] 66bc38f Add equiv of `AsyncioCancelled` for aio side - [x] 38497fa Comment-tag pause points in `asycnio_bp.py`
goodboy force-pushed py313_support from d97e426bca to 4a6bac2fb1 2025-03-25 16:08:39 +00:00 Compare
goodboy force-pushed py313_support from 4a6bac2fb1 to e42bc33bd6 2025-03-25 20:00:30 +00:00 Compare
goodboy requested review from guille 2025-03-27 17:39:22 +00:00
goodboy requested review from jc211 2025-03-27 17:39:22 +00:00
goodboy reviewed 2025-03-27 17:41:40 +00:00
tractor/_root.py Outdated
@ -81,3 +81,3 @@
# enables the multi-process debugger support
debug_mode: bool = False,
maybe_enable_greenback: bool = False, # `.pause_from_sync()/breakpoint()` support
maybe_enable_greenback: bool = True, # `.pause_from_sync()/breakpoint()` support
Poster
Owner

Not sure if this is the right choice, seems like it can’t hurt since we consider greenback a --dev dep?

Not sure if this is the right choice, seems like it can't hurt since we consider `greenback` a `--dev` dep?
goodboy reviewed 2025-03-27 17:45:53 +00:00
@ -83,0 +100,4 @@
# TODO, ask ronny how to impl this .. XD
# ids='unmask_from_canc={0}, canc_from_finally={1}',#.format,
)
def test_acm_embedded_nursery_propagates_enter_err(
Poster
Owner

This test demonstrates a footgun i recently discovered debugging silent process tree cancellation in modden.

Turns out if you raise trio.Cancelled from a finally it’ll suppress any underlying error raised from the cancel scope.. This is actually expected behavior but definitely unexpected IHMO.

I spoke to core trio about it over chat but noone seemed that concerned XD

So i’ve replicated the condition as well as attempted to provide a devx-y solution to unwrap the underlying error for the user if detected in any BaseException.__context__ and then use .add_note() to report that the cancellation’s suppression.

This test demonstrates a footgun i recently discovered debugging silent process tree cancellation in `modden`. Turns out if you raise `trio.Cancelled` from a finally it'll suppress any underlying error raised from the cancel scope.. This is actually expected behavior but **definitely unexpected** IHMO. I spoke to core `trio` about it over chat but noone seemed **that concerned** XD So i've replicated the condition as well as attempted to provide a devx-y solution to unwrap the underlying error for the user if detected in any `BaseException.__context__` and then use `.add_note()` to report that the cancellation's suppression.
goodboy reviewed 2025-03-27 17:48:46 +00:00
@ -66,3 +67,4 @@ from ._root import (
from ._ipc import Channel as Channel
from ._portal import Portal as Portal
from ._runtime import Actor as Actor
from . import hilevel as hilevel
Poster
Owner

woof, this should be removed since that subpkg won’t land until #12 ?

woof, this should be removed since that subpkg won't land until #12 ?
goodboy reviewed 2025-03-27 17:51:53 +00:00
@ -64,2 +64,3 @@
ctx.open_stream() as stream,
trio.open_nursery() as n,
trio.open_nursery(
strict_exception_groups=False,
Poster
Owner

You’ll find the bulk of the strict-eg-style “sidestepping” is just this for now..

XD

I know that it’ll set to be removed in an upcoming trio release, but we’re likely just going to have to delivery our own version for a variety of remote-error relaying cases, particularly pertaining to RPC semantics.

It’s something to be followed up in #22

You'll find the bulk of the strict-eg-style "sidestepping" is just this for now.. XD I know that it'll set to be removed in an upcoming `trio` release, but we're likely just going to have to delivery our own version for a variety of remote-error relaying cases, particularly pertaining to RPC semantics. It's something to be followed up in #22
goodboy reviewed 2025-03-27 17:59:19 +00:00
@ -199,2 +255,2 @@
)
await trio.sleep_forever()
# TODO, factor this into a `trionics.collapse()`?
except* BaseException as beg:
Poster
Owner

prolly coulda also used ._beg.collapse_eg() here too..

Ahh well someone will swap it eventually, at least whenever we have to solve #22

prolly coulda also used `._beg.collapse_eg()` here too.. Ahh well someone will swap it eventually, at least whenever we have to solve #22
goodboy reviewed 2025-03-27 18:00:10 +00:00
@ -289,3 +351,3 @@
def test_aio_cancelled_from_aio_causes_trio_cancelled(reg_addr):
def test_aio_cancelled_from_aio_causes_trio_cancelled(
Poster
Owner

Ahh i guess this was a aio related refinement of a test discovered while working through strict egs alongside using to_asyncio stuff.

Prolly woulda been better landed in #2 but, meh.

Nm, was all todo with egs again.

~~Ahh i guess this was a aio related refinement of a test discovered while working through strict egs alongside using `to_asyncio` stuff.~~ ~~Prolly woulda been better landed in #2 but, meh.~~ Nm, was all todo with egs again.
goodboy marked this conversation as resolved
goodboy changed title from Python 3.13 support to Python 3.13 support 2025-03-27 18:31:35 +00:00
goodboy changed target branch from aio_abandons to main 2025-03-27 18:31:36 +00:00
goodboy force-pushed py313_support from e42bc33bd6 to eda48c8021 2025-03-27 18:32:38 +00:00 Compare
guille approved these changes 2025-03-27 19:08:22 +00:00
guille left a comment
Collaborator

Looking forward to #22 in order to get rid of all the strict_exceptions=False warnings

Looking forward to #22 in order to get rid of all the `strict_exceptions=False` warnings
Poster
Owner

Looking forward to #22 in order to get rid of all the strict_exceptions=False warnings

Indeed!

I’m just holding off on doing it now bc i’d like to take a look at their original implementation and then really think about where we want to keep to the original .trionics._beg.collapse_eg() style.

> Looking forward to #22 in order to get rid of all the `strict_exceptions=False` warnings Indeed! I'm just holding off on doing it now bc i'd like to take a look at their original implementation and then really think about where we want to keep to the original `.trionics._beg.collapse_eg()` style.
goodboy merged commit 1e86722357 into main 2025-03-27 19:50:43 +00:00
Sign in to join this conversation.
No reviewers
No Label
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: goodboy/tractor#18
There is no content yet.