1
0
mirror of https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git synced 2025-08-14 00:25:46 +02:00

Проверка 09.02.2025

This commit is contained in:
MoonTestUse1
2025-02-09 01:11:49 +06:00
parent ce52f8a23a
commit 0aa3ef8fc2
5827 changed files with 14316 additions and 1906434 deletions

View File

@@ -8,6 +8,7 @@ from ._core._eventloop import sleep as sleep
from ._core._eventloop import sleep_forever as sleep_forever
from ._core._eventloop import sleep_until as sleep_until
from ._core._exceptions import BrokenResourceError as BrokenResourceError
from ._core._exceptions import BrokenWorkerIntepreter as BrokenWorkerIntepreter
from ._core._exceptions import BrokenWorkerProcess as BrokenWorkerProcess
from ._core._exceptions import BusyResourceError as BusyResourceError
from ._core._exceptions import ClosedResourceError as ClosedResourceError

View File

@@ -28,8 +28,6 @@ from collections.abc import (
Collection,
Coroutine,
Iterable,
Iterator,
MutableMapping,
Sequence,
)
from concurrent.futures import Future
@@ -49,7 +47,7 @@ from queue import Queue
from signal import Signals
from socket import AddressFamily, SocketKind
from threading import Thread
from types import TracebackType
from types import CodeType, TracebackType
from typing import (
IO,
TYPE_CHECKING,
@@ -449,7 +447,7 @@ class CancelScope(BaseCancelScope):
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
) -> bool | None:
) -> bool:
del exc_tb
if not self._active:
@@ -677,45 +675,7 @@ class TaskState:
self.cancel_scope = cancel_scope
class TaskStateStore(MutableMapping["Awaitable[Any] | asyncio.Task", TaskState]):
def __init__(self) -> None:
self._task_states = WeakKeyDictionary[asyncio.Task, TaskState]()
self._preliminary_task_states: dict[Awaitable[Any], TaskState] = {}
def __getitem__(self, key: Awaitable[Any] | asyncio.Task, /) -> TaskState:
assert isinstance(key, asyncio.Task)
try:
return self._task_states[key]
except KeyError:
if coro := key.get_coro():
if state := self._preliminary_task_states.get(coro):
return state
raise KeyError(key)
def __setitem__(
self, key: asyncio.Task | Awaitable[Any], value: TaskState, /
) -> None:
if isinstance(key, asyncio.Task):
self._task_states[key] = value
else:
self._preliminary_task_states[key] = value
def __delitem__(self, key: asyncio.Task | Awaitable[Any], /) -> None:
if isinstance(key, asyncio.Task):
del self._task_states[key]
else:
del self._preliminary_task_states[key]
def __len__(self) -> int:
return len(self._task_states) + len(self._preliminary_task_states)
def __iter__(self) -> Iterator[Awaitable[Any] | asyncio.Task]:
yield from self._task_states
yield from self._preliminary_task_states
_task_states = TaskStateStore()
_task_states: WeakKeyDictionary[asyncio.Task, TaskState] = WeakKeyDictionary()
#
@@ -741,24 +701,10 @@ class _AsyncioTaskStatus(abc.TaskStatus):
_task_states[task].parent_id = self._parent_id
async def _wait(tasks: Iterable[asyncio.Task[object]]) -> None:
tasks = set(tasks)
waiter = get_running_loop().create_future()
def on_completion(task: asyncio.Task[object]) -> None:
tasks.discard(task)
if not tasks and not waiter.done():
waiter.set_result(None)
for task in tasks:
task.add_done_callback(on_completion)
del task
try:
await waiter
finally:
while tasks:
tasks.pop().remove_done_callback(on_completion)
if sys.version_info >= (3, 12):
_eager_task_factory_code: CodeType | None = asyncio.eager_task_factory.__code__
else:
_eager_task_factory_code = None
class TaskGroup(abc.TaskGroup):
@@ -767,6 +713,7 @@ class TaskGroup(abc.TaskGroup):
self._active = False
self._exceptions: list[BaseException] = []
self._tasks: set[asyncio.Task] = set()
self._on_completed_fut: asyncio.Future[None] | None = None
async def __aenter__(self) -> TaskGroup:
self.cancel_scope.__enter__()
@@ -785,12 +732,15 @@ class TaskGroup(abc.TaskGroup):
if not isinstance(exc_val, CancelledError):
self._exceptions.append(exc_val)
loop = get_running_loop()
try:
if self._tasks:
with CancelScope() as wait_scope:
while self._tasks:
self._on_completed_fut = loop.create_future()
try:
await _wait(self._tasks)
await self._on_completed_fut
except CancelledError as exc:
# Shield the scope against further cancellation attempts,
# as they're not productive (#695)
@@ -805,6 +755,8 @@ class TaskGroup(abc.TaskGroup):
and not is_anyio_cancellation(exc)
):
exc_val = exc
self._on_completed_fut = None
else:
# If there are no child tasks to wait on, run at least one checkpoint
# anyway
@@ -835,13 +787,19 @@ class TaskGroup(abc.TaskGroup):
task_status_future: asyncio.Future | None = None,
) -> asyncio.Task:
def task_done(_task: asyncio.Task) -> None:
# task_state = _task_states[_task]
task_state = _task_states[_task]
assert task_state.cancel_scope is not None
assert _task in task_state.cancel_scope._tasks
task_state.cancel_scope._tasks.remove(_task)
self._tasks.remove(task)
del _task_states[_task]
if self._on_completed_fut is not None and not self._tasks:
try:
self._on_completed_fut.set_result(None)
except asyncio.InvalidStateError:
pass
try:
exc = _task.exception()
except CancelledError as e:
@@ -892,26 +850,25 @@ class TaskGroup(abc.TaskGroup):
f"the return value ({coro!r}) is not a coroutine object"
)
name = get_callable_name(func) if name is None else str(name)
loop = asyncio.get_running_loop()
if (
(factory := loop.get_task_factory())
and getattr(factory, "__code__", None) is _eager_task_factory_code
and (closure := getattr(factory, "__closure__", None))
):
custom_task_constructor = closure[0].cell_contents
task = custom_task_constructor(coro, loop=loop, name=name)
else:
task = create_task(coro, name=name)
# Make the spawned task inherit the task group's cancel scope
_task_states[coro] = task_state = TaskState(
_task_states[task] = TaskState(
parent_id=parent_id, cancel_scope=self.cancel_scope
)
name = get_callable_name(func) if name is None else str(name)
try:
task = create_task(coro, name=name)
finally:
del _task_states[coro]
_task_states[task] = task_state
self.cancel_scope._tasks.add(task)
self._tasks.add(task)
if task.done():
# This can happen with eager task factories
task_done(task)
else:
task.add_done_callback(task_done)
task.add_done_callback(task_done)
return task
def start_soon(
@@ -2114,10 +2071,9 @@ class _SignalReceiver:
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
) -> bool | None:
) -> None:
for sig in self._handled_signals:
self._loop.remove_signal_handler(sig)
return None
def __aiter__(self) -> _SignalReceiver:
return self
@@ -2446,7 +2402,7 @@ class AsyncIOBackend(AsyncBackend):
return CapacityLimiter(total_tokens)
@classmethod
async def run_sync_in_worker_thread(
async def run_sync_in_worker_thread( # type: ignore[return]
cls,
func: Callable[[Unpack[PosArgsT]], T_Retval],
args: tuple[Unpack[PosArgsT]],
@@ -2468,7 +2424,7 @@ class AsyncIOBackend(AsyncBackend):
async with limiter or cls.current_default_thread_limiter():
with CancelScope(shield=not abandon_on_cancel) as scope:
future: asyncio.Future = asyncio.Future()
future = asyncio.Future[T_Retval]()
root_task = find_root_task()
if not idle_workers:
worker = WorkerThread(root_task, workers, idle_workers)

View File

@@ -132,8 +132,7 @@ class CancelScope(BaseCancelScope):
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
) -> bool | None:
# https://github.com/python-trio/trio-typing/pull/79
) -> bool:
return self.__original.__exit__(exc_type, exc_val, exc_tb)
def cancel(self) -> None:
@@ -186,9 +185,10 @@ class TaskGroup(abc.TaskGroup):
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
) -> bool | None:
) -> bool:
try:
return await self._nursery_manager.__aexit__(exc_type, exc_val, exc_tb)
# trio.Nursery.__exit__ returns bool; .open_nursery has wrong type
return await self._nursery_manager.__aexit__(exc_type, exc_val, exc_tb) # type: ignore[return-value]
except BaseExceptionGroup as exc:
if not exc.split(trio.Cancelled)[1]:
raise trio.Cancelled._create() from exc

View File

@@ -21,6 +21,23 @@ class Selector:
self._send, self._receive = socket.socketpair()
self._send.setblocking(False)
self._receive.setblocking(False)
# This somewhat reduces the amount of memory wasted queueing up data
# for wakeups. With these settings, maximum number of 1-byte sends
# before getting BlockingIOError:
# Linux 4.8: 6
# macOS (darwin 15.5): 1
# Windows 10: 525347
# Windows you're weird. (And on Windows setting SNDBUF to 0 makes send
# blocking, even on non-blocking sockets, so don't do that.)
self._receive.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1)
self._send.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1)
# On Windows this is a TCP socket so this might matter. On other
# platforms this fails b/c AF_UNIX sockets aren't actually TCP.
try:
self._send.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
except OSError:
pass
self._selector.register(self._receive, EVENT_READ)
self._closed = False

View File

@@ -2,6 +2,8 @@ from __future__ import annotations
import sys
from collections.abc import Generator
from textwrap import dedent
from typing import Any
if sys.version_info < (3, 11):
from exceptiongroup import BaseExceptionGroup
@@ -21,6 +23,41 @@ class BrokenWorkerProcess(Exception):
"""
class BrokenWorkerIntepreter(Exception):
"""
Raised by :meth:`~anyio.to_interpreter.run_sync` if an unexpected exception is
raised in the subinterpreter.
"""
def __init__(self, excinfo: Any):
# This was adapted from concurrent.futures.interpreter.ExecutionFailed
msg = excinfo.formatted
if not msg:
if excinfo.type and excinfo.msg:
msg = f"{excinfo.type.__name__}: {excinfo.msg}"
else:
msg = excinfo.type.__name__ or excinfo.msg
super().__init__(msg)
self.excinfo = excinfo
def __str__(self) -> str:
try:
formatted = self.excinfo.errdisplay
except Exception:
return super().__str__()
else:
return dedent(
f"""
{super().__str__()}
Uncaught in the interpreter:
{formatted}
""".strip()
)
class BusyResourceError(Exception):
"""
Raised when two tasks are trying to read from or write to the same resource

View File

@@ -3,7 +3,13 @@ from __future__ import annotations
import os
import pathlib
import sys
from collections.abc import AsyncIterator, Callable, Iterable, Iterator, Sequence
from collections.abc import (
AsyncIterator,
Callable,
Iterable,
Iterator,
Sequence,
)
from dataclasses import dataclass
from functools import partial
from os import PathLike
@@ -220,11 +226,15 @@ class Path:
Some methods may be unavailable or have limited functionality, based on the Python
version:
* :meth:`~pathlib.Path.copy` (available on Python 3.14 or later)
* :meth:`~pathlib.Path.copy_into` (available on Python 3.14 or later)
* :meth:`~pathlib.Path.from_uri` (available on Python 3.13 or later)
* :meth:`~pathlib.Path.full_match` (available on Python 3.13 or later)
* :meth:`~pathlib.Path.is_junction` (available on Python 3.12 or later)
* :meth:`~pathlib.Path.match` (the ``case_sensitive`` paramater is only available on
Python 3.13 or later)
* :meth:`~pathlib.Path.move` (available on Python 3.14 or later)
* :meth:`~pathlib.Path.move_into` (available on Python 3.14 or later)
* :meth:`~pathlib.Path.relative_to` (the ``walk_up`` parameter is only available on
Python 3.12 or later)
* :meth:`~pathlib.Path.walk` (available on Python 3.12 or later)
@@ -396,6 +406,51 @@ class Path:
def match(self, path_pattern: str) -> bool:
return self._path.match(path_pattern)
if sys.version_info >= (3, 14):
async def copy(
self,
target: str | os.PathLike[str],
*,
follow_symlinks: bool = True,
dirs_exist_ok: bool = False,
preserve_metadata: bool = False,
) -> Path:
func = partial(
self._path.copy,
follow_symlinks=follow_symlinks,
dirs_exist_ok=dirs_exist_ok,
preserve_metadata=preserve_metadata,
)
return Path(await to_thread.run_sync(func, target))
async def copy_into(
self,
target_dir: str | os.PathLike[str],
*,
follow_symlinks: bool = True,
dirs_exist_ok: bool = False,
preserve_metadata: bool = False,
) -> Path:
func = partial(
self._path.copy_into,
follow_symlinks=follow_symlinks,
dirs_exist_ok=dirs_exist_ok,
preserve_metadata=preserve_metadata,
)
return Path(await to_thread.run_sync(func, target_dir))
async def move(self, target: str | os.PathLike[str]) -> Path:
# Upstream does not handle anyio.Path properly as a PathLike
target = pathlib.Path(target)
return Path(await to_thread.run_sync(self._path.move, target))
async def move_into(
self,
target_dir: str | os.PathLike[str],
) -> Path:
return Path(await to_thread.run_sync(self._path.move_into, target_dir))
def is_relative_to(self, other: str | PathLike[str]) -> bool:
try:
self.relative_to(other)

View File

@@ -728,6 +728,5 @@ class ResourceGuard:
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
) -> bool | None:
) -> None:
self._guarded = False
return None

View File

@@ -88,7 +88,7 @@ class CancelScope:
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
) -> bool | None:
) -> bool:
raise NotImplementedError

View File

@@ -35,7 +35,7 @@ _process_pool_idle_workers: RunVar[deque[tuple[Process, float]]] = RunVar(
_default_process_limiter: RunVar[CapacityLimiter] = RunVar("_default_process_limiter")
async def run_sync(
async def run_sync( # type: ignore[return]
func: Callable[[Unpack[PosArgsT]], T_Retval],
*args: Unpack[PosArgsT],
cancellable: bool = False,