Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into add_tox
Browse files Browse the repository at this point in the history
  • Loading branch information
jakkdl committed Feb 14, 2025
2 parents 130ff64 + 5eb5afb commit bc0ed8d
Show file tree
Hide file tree
Showing 39 changed files with 244 additions and 292 deletions.
15 changes: 9 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,33 @@ repos:
- id: sort-simple-yaml
files: .pre-commit-config.yaml
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.10.0
rev: 25.1.0
hooks:
- id: black
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.3
rev: v0.9.6
hooks:
- id: ruff
types: [file]
types_or: [python, pyi, toml]
args: ["--show-fixes"]
- repo: https://github.com/codespell-project/codespell
rev: v2.4.0
rev: v2.4.1
hooks:
- id: codespell
additional_dependencies:
# tomli needed on 3.10. tomllib is available in stdlib on 3.11+
- tomli
- repo: https://github.com/crate-ci/typos
rev: dictgen-v0.3.1
rev: typos-dict-v0.12.4
hooks:
- id: typos
- repo: https://github.com/sphinx-contrib/sphinx-lint
rev: v1.0.0
hooks:
- id: sphinx-lint
- repo: https://github.com/woodruffw/zizmor-pre-commit
rev: v1.2.2
rev: v1.3.1
hooks:
- id: zizmor
- repo: local
Expand All @@ -56,7 +59,7 @@ repos:
additional_dependencies: ["astor", "attrs", "black", "ruff"]
files: ^src\/trio\/_core\/(_run|(_i(o_(common|epoll|kqueue|windows)|nstrumentation)))\.py$
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.5.24
rev: 0.5.30
hooks:
# Compile requirements
- id: pip-compile
Expand Down
3 changes: 2 additions & 1 deletion docs-requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ exceptiongroup >= 1.0.0rc9
immutables >= 0.6

# types used in annotations
pyOpenSSL
# TODO: fix support for importing typing-extensions
pyOpenSSL < 25.0.0
12 changes: 6 additions & 6 deletions docs-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
# uv pip compile --universal --python-version=3.11 docs-requirements.in -o docs-requirements.txt
alabaster==1.0.0
# via sphinx
attrs==24.3.0
attrs==25.1.0
# via
# -r docs-requirements.in
# outcome
babel==2.16.0
babel==2.17.0
# via sphinx
beautifulsoup4==4.12.3
# via sphinx-codeautolink
certifi==2024.12.14
certifi==2025.1.31
# via requests
cffi==1.17.1 ; os_name == 'nt' or platform_python_implementation != 'PyPy'
# via
Expand All @@ -24,7 +24,7 @@ colorama==0.4.6 ; sys_platform == 'win32'
# via
# click
# sphinx
cryptography==44.0.0
cryptography==44.0.1
# via pyopenssl
docutils==0.21.2
# via
Expand Down Expand Up @@ -53,7 +53,7 @@ packaging==24.2
# via sphinx
pycparser==2.22 ; os_name == 'nt' or platform_python_implementation != 'PyPy'
# via cffi
pygments==2.18.0
pygments==2.19.1
# via sphinx
pyopenssl==24.3.0
# via -r docs-requirements.in
Expand All @@ -75,7 +75,7 @@ sphinx==8.1.3
# sphinx-rtd-theme
# sphinxcontrib-jquery
# sphinxcontrib-trio
sphinx-codeautolink==0.15.2
sphinx-codeautolink==0.16.2
# via -r docs-requirements.in
sphinx-hoverxref==1.4.2
# via -r docs-requirements.in
Expand Down
33 changes: 33 additions & 0 deletions docs/source/history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ Release history

.. towncrier release notes start
Trio 0.29.0 (2025-02-14)
------------------------

Features
~~~~~~~~

- Add :func:`trio.lowlevel.in_trio_run` and :func:`trio.lowlevel.in_trio_task` and document the semantics (and differences) thereof. See :ref:`the documentation <trio_contexts>`. (`#2757 <https://github.com/python-trio/trio/issues/2757>`__)
- If `trio.testing.RaisesGroup` does not get the expected exceptions it now raises an `AssertionError` with a helpful message, instead of letting the raised exception/group fall through. The raised exception is available in the ``__context__`` of the `AssertionError` and can be seen in the traceback. (`#3145 <https://github.com/python-trio/trio/issues/3145>`__)


Bugfixes
~~~~~~~~

- Clear Trio's cache of worker threads upon `os.fork`. (`#2764 <https://github.com/python-trio/trio/issues/2764>`__)


Miscellaneous internal changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- Stop using ctypes to mutate tracebacks for ``strict_exception_groups=False``'s exception collapsing. (`#405 <https://github.com/python-trio/trio/issues/405>`__)
- Fixed spelling error in Windows error code enum for ``ERROR_INVALID_PARAMETER``. (`#3166 <https://github.com/python-trio/trio/issues/3166>`__)
- Publicly re-export ``__version__`` for type checking purposes. (`#3186 <https://github.com/python-trio/trio/issues/3186>`__)
- The typing of :func:`trio.abc.HostnameResolver.getaddrinfo` has been corrected to
match that of the stdlib `socket.getaddrinfo`, which was updated in mypy 1.15 (via
a typeshed update) to include the possibility of ``tuple[int, bytes]`` for the
``sockaddr`` field of the result. This happens in situations where Python was compiled
with ``--disable-ipv6``.

Additionally, the static typing of :func:`trio.to_thread.run_sync`,
:func:`trio.from_thread.run` and :func:`trio.from_thread.run_sync` has been
improved and should reflect the underlying function being run. (`#3201 <https://github.com/python-trio/trio/issues/3201>`__)


Trio 0.28.0 (2024-12-25)
------------------------

Expand Down
1 change: 0 additions & 1 deletion newsfragments/2757.feature.rst

This file was deleted.

1 change: 0 additions & 1 deletion newsfragments/3145.feature.rst

This file was deleted.

1 change: 0 additions & 1 deletion newsfragments/3166.breaking.rst

This file was deleted.

1 change: 0 additions & 1 deletion newsfragments/3186.misc.rst

This file was deleted.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ combine-as-imports = true
fixture-parentheses = false

[tool.mypy]
python_version = "3.9"
python_version = "3.10"
files = ["src/trio/", "docs/source/*.py"]

# Be flexible about dependencies that don't have stubs yet (like pytest)
Expand Down
3 changes: 1 addition & 2 deletions src/trio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Trio - A friendly Python library for async concurrency and I/O
"""
"""Trio - A friendly Python library for async concurrency and I/O"""

from __future__ import annotations

Expand Down
2 changes: 1 addition & 1 deletion src/trio/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ async def getaddrinfo(
socket.SocketKind,
int,
str,
tuple[str, int] | tuple[str, int, int, int],
tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes],
]
]:
"""A custom implementation of :func:`~trio.socket.getaddrinfo`.
Expand Down
119 changes: 5 additions & 114 deletions src/trio/_core/_concat_tb.py
Original file line number Diff line number Diff line change
@@ -1,121 +1,10 @@
from __future__ import annotations

from typing import TYPE_CHECKING, ClassVar, cast

if TYPE_CHECKING:
from types import TracebackType

################################################################
# concat_tb
################################################################

# We need to compute a new traceback that is the concatenation of two existing
# tracebacks. This requires copying the entries in 'head' and then pointing
# the final tb_next to 'tail'.
#
# NB: 'tail' might be None, which requires some special handling in the ctypes
# version.
#
# The complication here is that Python doesn't actually support copying or
# modifying traceback objects, so we have to get creative...
#
# On CPython, we use ctypes. On PyPy, we use "transparent proxies".
#
# Jinja2 is a useful source of inspiration:
# https://github.com/pallets/jinja/blob/main/src/jinja2/debug.py

try:
import tputil
except ImportError:
# ctypes it is
# How to handle refcounting? I don't want to use ctypes.py_object because
# I don't understand or trust it, and I don't want to use
# ctypes.pythonapi.Py_{Inc,Dec}Ref because we might clash with user code
# that also tries to use them but with different types. So private _ctypes
# APIs it is!
import _ctypes
import ctypes

class CTraceback(ctypes.Structure):
_fields_: ClassVar = [
("PyObject_HEAD", ctypes.c_byte * object().__sizeof__()),
("tb_next", ctypes.c_void_p),
("tb_frame", ctypes.c_void_p),
("tb_lasti", ctypes.c_int),
("tb_lineno", ctypes.c_int),
]

def copy_tb(base_tb: TracebackType, tb_next: TracebackType | None) -> TracebackType:
# TracebackType has no public constructor, so allocate one the hard way
try:
raise ValueError
except ValueError as exc:
new_tb = exc.__traceback__
assert new_tb is not None
c_new_tb = CTraceback.from_address(id(new_tb))

# At the C level, tb_next either points to the next traceback or is
# NULL. c_void_p and the .tb_next accessor both convert NULL to None,
# but we shouldn't DECREF None just because we assigned to a NULL
# pointer! Here we know that our new traceback has only 1 frame in it,
# so we can assume the tb_next field is NULL.
assert c_new_tb.tb_next is None
# If tb_next is None, then we want to set c_new_tb.tb_next to NULL,
# which it already is, so we're done. Otherwise, we have to actually
# do some work:
if tb_next is not None:
_ctypes.Py_INCREF(tb_next)
c_new_tb.tb_next = id(tb_next)

assert c_new_tb.tb_frame is not None
_ctypes.Py_INCREF(base_tb.tb_frame)
old_tb_frame = new_tb.tb_frame
c_new_tb.tb_frame = id(base_tb.tb_frame)
_ctypes.Py_DECREF(old_tb_frame)

c_new_tb.tb_lasti = base_tb.tb_lasti
c_new_tb.tb_lineno = base_tb.tb_lineno

try:
return new_tb
finally:
# delete references from locals to avoid creating cycles
# see test_cancel_scope_exit_doesnt_create_cyclic_garbage
del new_tb, old_tb_frame

else:
# http://doc.pypy.org/en/latest/objspace-proxies.html
def copy_tb(base_tb: TracebackType, tb_next: TracebackType | None) -> TracebackType:
# tputil.ProxyOperation is PyPy-only, and there's no way to specify
# cpython/pypy in current type checkers.
def controller( # type: ignore[no-any-unimported]
operation: tputil.ProxyOperation,
) -> TracebackType | None:
# Rationale for pragma: I looked fairly carefully and tried a few
# things, and AFAICT it's not actually possible to get any
# 'opname' that isn't __getattr__ or __getattribute__. So there's
# no missing test we could add, and no value in coverage nagging
# us about adding one.
if (
operation.opname
in {
"__getattribute__",
"__getattr__",
}
and operation.args[0] == "tb_next"
) or TYPE_CHECKING: # pragma: no cover
return tb_next
# Delegate is reverting to original behaviour
return operation.delegate() # type: ignore[no-any-return]

return cast(
"TracebackType",
tputil.make_proxy(controller, type(base_tb), base_tb),
) # Returns proxy to traceback
from types import TracebackType


# this is used for collapsing single-exception ExceptionGroups when using
# `strict_exception_groups=False`. Once that is retired this function and its helper can
# `strict_exception_groups=False`. Once that is retired this function can
# be removed as well.
def concat_tb(
head: TracebackType | None,
Expand All @@ -131,5 +20,7 @@ def concat_tb(
pointer = pointer.tb_next
current_head = tail
for head_tb in reversed(head_tbs):
current_head = copy_tb(head_tb, tb_next=current_head)
current_head = TracebackType(
current_head, head_tb.tb_frame, head_tb.tb_lasti, head_tb.tb_lineno
)
return current_head
3 changes: 1 addition & 2 deletions src/trio/_core/_entry_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

PosArgsT = TypeVarTuple("PosArgsT")

# Explicit "Any" is not allowed
Function = Callable[..., object] # type: ignore[misc]
Function = Callable[..., object] # type: ignore[explicit-any]
Job = tuple[Function, tuple[object, ...]]


Expand Down
11 changes: 5 additions & 6 deletions src/trio/_core/_instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@

import logging
import types
from collections.abc import Callable, Sequence
from typing import TypeVar
from typing import TYPE_CHECKING, TypeVar

from .._abc import Instrument

# Used to log exceptions in instruments
INSTRUMENT_LOGGER = logging.getLogger("trio.abc.Instrument")

if TYPE_CHECKING:
from collections.abc import Sequence

# Explicit "Any" is not allowed
F = TypeVar("F", bound=Callable[..., object]) # type: ignore[misc]
T = TypeVar("T")


# Decorator to mark methods public. This does nothing by itself, but
# trio/_tools/gen_exports.py looks for it.
# Explicit "Any" is not allowed
def _public(fn: F) -> F: # type: ignore[misc]
def _public(fn: T) -> T:
return fn


Expand Down
Loading

0 comments on commit bc0ed8d

Please sign in to comment.