Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into enable-flake8-commas
Browse files Browse the repository at this point in the history
  • Loading branch information
CoolCat467 committed Aug 29, 2024
2 parents 69f1635 + 4ae737a commit 351f6ca
Show file tree
Hide file tree
Showing 16 changed files with 165 additions and 54 deletions.
19 changes: 14 additions & 5 deletions .github/workflows/autodeps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,35 @@ jobs:
issues: write
repository-projects: write
contents: write

steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup python
uses: actions/setup-python@v5
with:
python-version: "3.8"

- name: Bump dependencies
run: |
python -m pip install -U pip pre-commit
python -m pip install -r test-requirements.txt
uv pip compile --universal --python-version=3.8 --upgrade test-requirements.in -o test-requirements.txt
uv pip compile --universal --python-version=3.8 --upgrade docs-requirements.in -o docs-requirements.txt
uv pip compile --universal --python-version=3.11 --upgrade docs-requirements.in -o docs-requirements.txt
pre-commit autoupdate --jobs 0
- name: Install new requirements
run: python -m pip install -r test-requirements.txt

# apply newer versions' formatting
- name: Black
run: black src/trio

- name: uv
run: |
# The new dependencies may contain a new black version.
# Commit any changes immediately.
python -m pip install -r test-requirements.txt
black src/trio
uv pip compile --universal --python-version=3.8 test-requirements.in -o test-requirements.txt
uv pip compile --universal --python-version=3.11 docs-requirements.in -o docs-requirements.txt
- name: Commit changes and create automerge PR
env:
GH_TOKEN: ${{ github.token }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ['pypy-3.9', 'pypy-3.10', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
python: ['pypy-3.10', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
check_formatting: ['0']
no_test_requirements: ['0']
extra_name: ['']
Expand Down
11 changes: 10 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ ci:
autoupdate_commit_msg: "[pre-commit.ci] pre-commit autoupdate"
autoupdate_schedule: weekly
submodules: false
skip: [regenerate-files]

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
Expand All @@ -23,7 +24,7 @@ repos:
hooks:
- id: black
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.1
rev: v0.6.2
hooks:
- id: ruff
types: [file]
Expand All @@ -33,3 +34,11 @@ repos:
rev: v2.3.0
hooks:
- id: codespell
- repo: local
hooks:
- id: regenerate-files
name: regenerate generated files
language: system
entry: python src/trio/_tools/gen_exports.py
pass_filenames: false
files: ^src\/trio\/_core\/(_run|(_i(o_(common|epoll|kqueue|windows)|nstrumentation)))\.py$
2 changes: 1 addition & 1 deletion check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ echo "::group::Pip Compile - Tests"
uv pip compile --universal --python-version=3.8 test-requirements.in -o test-requirements.txt
echo "::endgroup::"
echo "::group::Pip Compile - Docs"
uv pip compile --universal --python-version=3.8 docs-requirements.in -o docs-requirements.txt
uv pip compile --universal --python-version=3.11 docs-requirements.in -o docs-requirements.txt
echo "::endgroup::"

if git status --porcelain | grep -q "requirements.txt"; then
Expand Down
3 changes: 2 additions & 1 deletion docs-requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# sphinx 5.3 doesn't work with our _NoValue workaround
sphinx >= 6.0
jinja2
sphinx_rtd_theme
# >= is necessary to prevent `uv` from selecting a `Sphinx` version this does not support
sphinx_rtd_theme >= 2
sphinxcontrib-jquery
sphinxcontrib-trio
towncrier
Expand Down
30 changes: 8 additions & 22 deletions docs-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file was autogenerated by uv via the following command:
# uv pip compile --universal --python-version=3.8 docs-requirements.in -o docs-requirements.txt
alabaster==0.7.13
# uv pip compile --universal --python-version=3.11 docs-requirements.in -o docs-requirements.txt
alabaster==0.7.16
# via sphinx
attrs==24.2.0
# via
Expand Down Expand Up @@ -40,12 +40,6 @@ imagesize==1.4.1
# via sphinx
immutables==0.20
# via -r docs-requirements.in
importlib-metadata==8.4.0 ; python_full_version < '3.10'
# via
# sphinx
# towncrier
importlib-resources==6.4.3 ; python_full_version < '3.10'
# via towncrier
jinja2==3.1.4
# via
# -r docs-requirements.in
Expand All @@ -63,8 +57,6 @@ pygments==2.18.0
# via sphinx
pyopenssl==24.2.1
# via -r docs-requirements.in
pytz==2024.1 ; python_full_version < '3.9'
# via babel
requests==2.32.3
# via sphinx
sniffio==1.3.1
Expand All @@ -75,7 +67,7 @@ sortedcontainers==2.4.0
# via -r docs-requirements.in
soupsieve==2.6
# via beautifulsoup4
sphinx==7.1.2
sphinx==7.4.7
# via
# -r docs-requirements.in
# sphinx-codeautolink
Expand All @@ -89,11 +81,11 @@ sphinx-hoverxref==1.4.0
# via -r docs-requirements.in
sphinx-rtd-theme==2.0.0
# via -r docs-requirements.in
sphinxcontrib-applehelp==1.0.4
sphinxcontrib-applehelp==2.0.0
# via sphinx
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-devhelp==2.0.0
# via sphinx
sphinxcontrib-htmlhelp==2.0.1
sphinxcontrib-htmlhelp==2.1.0
# via sphinx
sphinxcontrib-jquery==4.1
# via
Expand All @@ -102,19 +94,13 @@ sphinxcontrib-jquery==4.1
# sphinx-rtd-theme
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-qthelp==2.0.0
# via sphinx
sphinxcontrib-serializinghtml==1.1.5
sphinxcontrib-serializinghtml==2.0.0
# via sphinx
sphinxcontrib-trio==1.1.2
# via -r docs-requirements.in
tomli==2.0.1 ; python_full_version < '3.11'
# via towncrier
towncrier==24.7.1
# via -r docs-requirements.in
urllib3==2.2.2
# via requests
zipp==3.20.0 ; python_full_version < '3.10'
# via
# importlib-metadata
# importlib-resources
8 changes: 5 additions & 3 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,14 @@ def add_mapping(

# This has been removed in Py3.12, so add a link to the 3.11 version with deprecation warnings.
add_mapping("method", "pathlib", "Path.link_to", "3.11")

# defined in py:data in objects.inv, but sphinx looks for a py:class
# see https://github.com/sphinx-doc/sphinx/issues/10974
# to dump the objects.inv for the stdlib, you can run
# python -m sphinx.ext.intersphinx http://docs.python.org/3/objects.inv
add_mapping("class", "math", "inf")
# `types.FrameType.__module__` is "builtins", so sphinx looks for
# builtins.FrameType.
# See https://github.com/sphinx-doc/sphinx/issues/11802
add_mapping("class", "types", "FrameType")

# new in py3.12, and need target because sphinx is unable to look up
# the module of the object if compiling on <3.12
if not hasattr(collections.abc, "Buffer"):
Expand Down
35 changes: 29 additions & 6 deletions docs/source/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,24 @@ This keeps us closer to the desired state where each open issue reflects some
work that still needs to be done.


Environment
~~~~~~~~~~~
We strongly suggest using a virtual environment for managing dependencies,
for example with `venv <https://docs.python.org/3/library/venv.html>`__. So to
set up your environment and install dependencies, you should run something like:

.. code-block:: shell
cd path/to/trio/checkout/
python -m venv .venv # create virtual env in .venv
source .venv/bin/activate # activate it
pip install -e . # install trio, needed for pytest plugin
pip install -r test-requirements.txt # install test requirements
you rarely need to recreate the virtual environment, but you need to re-activate it
in future terminals. You might also need to re-install from test-requirements.txt if
the versions in it get updated.

.. _pull-request-tests:

Tests
Expand All @@ -186,12 +204,11 @@ locally, you should run:

.. code-block:: shell
cd path/to/trio/checkout/
pip install -r test-requirements.txt # possibly using a virtualenv
pytest trio
source .venv/bin/activate # if not already activated
pytest src
This doesn't try to be completely exhaustive – it only checks that
things work on your machine, and it may skip some slow tests. But it's
things work on your machine, and it will skip some slow tests. But it's
a good way to quickly check that things seem to be working, and we'll
automatically run the full test suite when your PR is submitted, so
you'll have a chance to see and fix any remaining issues then.
Expand All @@ -211,8 +228,14 @@ it being merely hard to fix). For example:
We use Codecov to track coverage, because it makes it easy to combine
coverage from running in different configurations. Running coverage
locally can be useful
(``pytest --cov=PACKAGENAME --cov-report=html``), but don't be
surprised if you get lower coverage than when looking at Codecov

.. code-block:: shell
coverage run -m pytest
coverage combine
coverage report
but don't be surprised if you get lower coverage than when looking at Codecov
reports, because there are some lines that are only executed on
Windows, or macOS, or PyPy, or CPython, or... you get the idea. After
you create a PR, Codecov will automatically report back with the
Expand Down
3 changes: 1 addition & 2 deletions docs/source/reference-core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,7 @@ attribute to :data:`True`:
try:
await conn.send_hello_msg()
finally:
with trio.move_on_after(CLEANUP_TIMEOUT) as cleanup_scope:
cleanup_scope.shield = True
with trio.move_on_after(CLEANUP_TIMEOUT, shield=True) as cleanup_scope:
await conn.send_goodbye_msg()
So long as you're inside a scope with ``shield = True`` set, then
Expand Down
1 change: 1 addition & 0 deletions newsfragments/3052.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`trio.move_on_at`, `trio.move_on_after`, `trio.fail_at` and `trio.fail_after` now accept *shield* as a keyword argument. If specified, it provides an initial value for the `~trio.CancelScope.shield` attribute of the `trio.CancelScope` object created by the context manager.
12 changes: 12 additions & 0 deletions src/trio/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,14 @@ async def __anext__(self) -> ReceiveType:
raise StopAsyncIteration from None


# these are necessary for Sphinx's :show-inheritance: with type args.
# (this should be removed if possible)
# see: https://github.com/python/cpython/issues/123250
SendChannel.__module__ = SendChannel.__module__.replace("_abc", "abc")
ReceiveChannel.__module__ = ReceiveChannel.__module__.replace("_abc", "abc")
Listener.__module__ = Listener.__module__.replace("_abc", "abc")


class Channel(SendChannel[T], ReceiveChannel[T]):
"""A standard interface for interacting with bidirectional channels.
Expand All @@ -702,3 +710,7 @@ class Channel(SendChannel[T], ReceiveChannel[T]):
"""

__slots__ = ()


# see above
Channel.__module__ = Channel.__module__.replace("_abc", "abc")
4 changes: 4 additions & 0 deletions src/trio/_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,10 @@ async def wait_send_all_might_not_block(self) -> None:
await self.transport_stream.wait_send_all_might_not_block()


# this is necessary for Sphinx, see also `_abc.py`
SSLStream.__module__ = SSLStream.__module__.replace("._ssl", "")


@final
class SSLListener(Listener[SSLStream[T_Stream]]):
"""A :class:`~trio.abc.Listener` for SSL/TLS-encrypted servers.
Expand Down
45 changes: 44 additions & 1 deletion src/trio/_tests/test_timeouts.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import time
from typing import Awaitable, Callable, TypeVar
from typing import Awaitable, Callable, Protocol, TypeVar

import outcome
import pytest
Expand Down Expand Up @@ -75,6 +75,49 @@ async def sleep_3() -> None:
await check_takes_about(sleep_3, TARGET)


class TimeoutScope(Protocol):
def __call__(self, seconds: float, *, shield: bool) -> trio.CancelScope: ...


@pytest.mark.parametrize("scope", [move_on_after, fail_after])
async def test_context_shields_from_outer(scope: TimeoutScope) -> None:
with _core.CancelScope() as outer, scope(TARGET, shield=True) as inner:
outer.cancel()
try:
await trio.lowlevel.checkpoint()
except trio.Cancelled:
pytest.fail("shield didn't work")
inner.shield = False
with pytest.raises(trio.Cancelled):
await trio.lowlevel.checkpoint()


@slow
async def test_move_on_after_moves_on_even_if_shielded() -> None:
async def task() -> None:
with _core.CancelScope() as outer, move_on_after(TARGET, shield=True):
outer.cancel()
# The outer scope is cancelled, but this task is protected by the
# shield, so it manages to get to sleep until deadline is met
await sleep_forever()

await check_takes_about(task, TARGET)


@slow
async def test_fail_after_fails_even_if_shielded() -> None:
async def task() -> None:
with pytest.raises(TooSlowError), _core.CancelScope() as outer, fail_after(
TARGET, shield=True
):
outer.cancel()
# The outer scope is cancelled, but this task is protected by the
# shield, so it manages to get to sleep until deadline is met
await sleep_forever()

await check_takes_about(task, TARGET)


@slow
async def test_fail() -> None:
async def sleep_4() -> None:
Expand Down
12 changes: 10 additions & 2 deletions src/trio/_tests/tools/test_gen_exports.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ def test_create_pass_through_args() -> None:

@skip_lints
@pytest.mark.parametrize("imports", [IMPORT_1, IMPORT_2, IMPORT_3])
def test_process(tmp_path: Path, imports: str) -> None:
def test_process(
tmp_path: Path, imports: str, capsys: pytest.CaptureFixture[str]
) -> None:
try:
import black # noqa: F401
# there's no dedicated CI run that has astor+isort, but lacks black.
Expand All @@ -106,7 +108,13 @@ def test_process(tmp_path: Path, imports: str) -> None:
with pytest.raises(SystemExit) as excinfo:
process([file], do_test=True)
assert excinfo.value.code == 1
process([file], do_test=False)
captured = capsys.readouterr()
assert "Generated sources are outdated. Please regenerate." in captured.out
with pytest.raises(SystemExit) as excinfo:
process([file], do_test=False)
assert excinfo.value.code == 1
captured = capsys.readouterr()
assert "Regenerated sources successfully." in captured.out
assert genpath.exists()
process([file], do_test=True)
# But if we change the lookup path it notices
Expand Down
Loading

0 comments on commit 351f6ca

Please sign in to comment.