flpit 0.2.2__tar.gz → 0.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: flpit
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Fluent LINQ for Python — flip your iterables
5
5
  Project-URL: Homepage, https://github.com/riemar/flpit
6
6
  Project-URL: Repository, https://github.com/riemar/flpit
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "flpit"
3
- version = "0.2.2"
3
+ version = "0.2.4"
4
4
  description = "Fluent LINQ for Python — flip your iterables"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -55,7 +55,7 @@ include = ["src/flp", "src/flpit"]
55
55
  [tool.pyrefly]
56
56
  project-includes = ["src"]
57
57
  project-excludes = ["**/__pycache__", "tests"]
58
- search-path = ["src"]
58
+ search-path = ["src", "typing"]
59
59
  preset = "strict"
60
60
 
61
61
  [tool.pytest.ini_options]
@@ -14,7 +14,6 @@ from itertools import islice
14
14
  from typing import (
15
15
  Any,
16
16
  Callable,
17
- Generic,
18
17
  Iterable,
19
18
  Iterator,
20
19
  Collection,
@@ -27,14 +26,14 @@ from typing import (
27
26
  Union,
28
27
  override,
29
28
  overload,
30
- cast as typing_cast, BinaryIO,
29
+ cast as typing_cast,
30
+ BinaryIO,
31
+ Concatenate,
32
+ Sized
31
33
  )
32
34
 
33
- import flpit.json
34
35
  from flpit.json import JsonConvert, JsonSerializerOptions
35
36
 
36
- TItem = TypeVar("TItem")
37
- TResult = TypeVar("TResult")
38
37
  TKey = TypeVar("TKey")
39
38
  TOther = TypeVar("TOther")
40
39
  TAccumulate = TypeVar("TAccumulate")
@@ -114,16 +113,24 @@ class ArgumentOutOfBoundsError(ArgumentError):
114
113
  super().__init__("Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.")
115
114
 
116
115
 
117
- def _guard_empty(func: Callable[..., Any]) -> Callable[..., Any]:
118
- """Catches Python's native empty-sequence ValueError and re-raises LINQ-compliant error."""
116
+ def _guard_empty[SelfT: Sized, R, **P](
117
+ func: Callable[Concatenate[SelfT, P], R],
118
+ ) -> Callable[Concatenate[SelfT, P], R]:
119
+ """Translate empty-sequence ValueError into EmptySequenceError."""
120
+
119
121
  @wraps(func)
120
- def wrapper(self: Any, *args: Any, **kwargs: Any) -> Any:
122
+ def wrapper(
123
+ self: SelfT,
124
+ *args: P.args,
125
+ **kwargs: P.kwargs,
126
+ ) -> R:
121
127
  try:
122
128
  return func(self, *args, **kwargs)
123
129
  except ValueError as e:
124
- if not self._FlpList__list.data:
130
+ if len(self) == 0:
125
131
  raise EmptySequenceError() from e
126
132
  raise
133
+
127
134
  return wrapper
128
135
 
129
136
 
@@ -137,7 +144,7 @@ def dotnet_context() -> AbstractContextManager[decimal.Context]:
137
144
  return decimal.localcontext(ctx)
138
145
 
139
146
 
140
- class _FactoryIterable(Iterable[TItem], Generic[TItem]):
147
+ class _FactoryIterable[TItem](Iterable[TItem]):
141
148
  """
142
149
  Wraps a generator factory function into a clean Iterable[T].
143
150
  Ensures __iter__ produces a brand-new iterator instance on every call
@@ -152,7 +159,7 @@ class _FactoryIterable(Iterable[TItem], Generic[TItem]):
152
159
  return self._factory()
153
160
 
154
161
 
155
- class FlpIt(Iterable[TItem], Generic[TItem]):
162
+ class FlpIt[TItem](Iterable[TItem]):
156
163
  """
157
164
  | Fluent Iterable
158
165
  Lazy evaluation wrapper around an iterable, inspired by .NET LINQ's
@@ -173,7 +180,7 @@ class FlpIt(Iterable[TItem], Generic[TItem]):
173
180
  return iter(self._iterable)
174
181
 
175
182
  # noinspection unused-parameter
176
- def as_type(self, target_type: Type[TResult]) -> FlpIt[TResult]:
183
+ def as_type[TResult](self, target_type: Type[TResult]) -> FlpIt[TResult]:
177
184
  """Zero-cost static type hint update returning self directly without checks or allocations."""
178
185
  return self # type: ignore[return-value]
179
186
 
@@ -257,7 +264,7 @@ class FlpIt(Iterable[TItem], Generic[TItem]):
257
264
  # return typing_cast(FlpIt[TItem], FlpIt[TItem](_FactoryIterable(_generator)))
258
265
  return FlpIt[TItem](_FactoryIterable(_generator))
259
266
 
260
- def select(self, selector: Callable[[TItem], TResult]) -> FlpIt[TResult]:
267
+ def select[TResult](self, selector: Callable[[TItem], TResult]) -> FlpIt[TResult]:
261
268
  """Projects each element into a new form."""
262
269
  def _generator() -> Iterator[TResult]:
263
270
  for item in self:
@@ -265,7 +272,7 @@ class FlpIt(Iterable[TItem], Generic[TItem]):
265
272
 
266
273
  return FlpIt(_FactoryIterable(_generator))
267
274
 
268
- def select_many(
275
+ def select_many[TResult](
269
276
  self, selector: Callable[[TItem], Iterable[TResult]]
270
277
  ) -> FlpIt[TResult]:
271
278
  """Flattens sequence projections."""
@@ -310,7 +317,7 @@ class FlpIt(Iterable[TItem], Generic[TItem]):
310
317
 
311
318
  return FlpIt(_FactoryIterable(_generator))
312
319
 
313
- def cast(self, target_type: Type[TResult]) -> FlpIt[TResult]:
320
+ def cast[TResult](self, target_type: Type[TResult]) -> FlpIt[TResult]:
314
321
  """Casts elements to a specified type or raises TypeError if cast fails."""
315
322
  def _generator() -> Iterator[TResult]:
316
323
  for item in self:
@@ -322,7 +329,7 @@ class FlpIt(Iterable[TItem], Generic[TItem]):
322
329
 
323
330
  return FlpIt(_FactoryIterable(_generator))
324
331
 
325
- def of_type(self, target_type: Type[TResult]) -> FlpIt[TResult]:
332
+ def of_type[TResult](self, target_type: Type[TResult]) -> FlpIt[TResult]:
326
333
  """Filters the elements of an Iterable based on a specified type."""
327
334
  def _generator() -> Iterator[TResult]:
328
335
  for item in self:
@@ -360,7 +367,7 @@ class FlpIt(Iterable[TItem], Generic[TItem]):
360
367
  def zip(self, second: Iterable[TOther]) -> FlpIt[tuple[TItem, TOther]]: ...
361
368
 
362
369
  @overload
363
- def zip(
370
+ def zip[TResult, TOther](
364
371
  self,
365
372
  second: Iterable[TOther],
366
373
  result_selector: Callable[[TItem, TOther], TResult],
@@ -598,7 +605,7 @@ class FlpIt(Iterable[TItem], Generic[TItem]):
598
605
  return item
599
606
  raise EmptySequenceError() if predicate is _SENTINEL else NoMatchError()
600
607
 
601
- def first_or_default(
608
+ def first_or_default[TResult](
602
609
  self, default: TResult, predicate: Callable[[TItem], bool] | _Sentinel = _SENTINEL
603
610
  ) -> Union[TItem, TResult]:
604
611
  """Returns the first element matching a predicate, or a default value."""
@@ -673,14 +680,7 @@ class _NoneOrderKey:
673
680
 
674
681
  _NONE_ORDER_KEY = _NoneOrderKey()
675
682
 
676
- def _none_aware_key(
677
- selector: Callable[[TItem], Any],
678
- item: TItem,
679
- ) -> Any:
680
- key = selector(item)
681
- return _NONE_ORDER_KEY if key is None else key
682
-
683
- class OrderedIt(FlpIt[TItem]):
683
+ class OrderedIt[TItem](FlpIt[TItem]):
684
684
  __slots__ = ("_criteria",)
685
685
 
686
686
  def __init__(
@@ -701,13 +701,21 @@ class OrderedIt(FlpIt[TItem]):
701
701
  else:
702
702
  self._criteria = _criteria + ((selector, descending),)
703
703
 
704
+ @staticmethod
705
+ def __none_aware_key(
706
+ selector: Callable[[TItem], Any],
707
+ item: TItem,
708
+ ) -> Any:
709
+ key = selector(item)
710
+ return _NONE_ORDER_KEY if key is None else key
711
+
704
712
  @override
705
713
  def __iter__(self) -> Iterator[TItem]:
706
714
  items = list(self._iterable)
707
715
 
708
716
  for selector, descending in reversed(self._criteria):
709
717
  items.sort(
710
- key=partial(_none_aware_key, selector),
718
+ key=partial(self.__none_aware_key, selector),
711
719
  reverse=descending,
712
720
  )
713
721
 
@@ -736,7 +744,7 @@ class OrderedIt(FlpIt[TItem]):
736
744
  )
737
745
 
738
746
 
739
- class Grouping(FlpIt[TItem], Generic[TKey, TItem]):
747
+ class Grouping[TKey, TItem](FlpIt[TItem]):
740
748
  """Represents a collection of elements sharing a common key (.NET IGrouping<TKey, TElement>)."""
741
749
  __slots__ = ("_key", )
742
750
 
@@ -760,7 +768,7 @@ class Grouping(FlpIt[TItem], Generic[TKey, TItem]):
760
768
  return self.key == other.key and self.to_list() == other.to_list()
761
769
 
762
770
 
763
- class FlpList(Collection[TItem], Generic[TItem]):
771
+ class FlpList[TItem](Collection[TItem]):
764
772
  """
765
773
  | Fluent List
766
774
  A materialized list extending UserList that yields lazy FlpIt instances for query operations.
@@ -781,7 +789,7 @@ class FlpList(Collection[TItem], Generic[TItem]):
781
789
  # =====================================================================
782
790
  # 1. THE ABC CONTRACT
783
791
  # =====================================================================
784
- def __iter__(self) -> Iterator[Any]:
792
+ def __iter__(self) -> Iterator[TItem]:
785
793
  return self.__list.__iter__()
786
794
 
787
795
  def __len__(self) -> int:
@@ -1032,17 +1040,16 @@ class FlpList(Collection[TItem], Generic[TItem]):
1032
1040
  def concat(self, second: Iterable[TItem]) -> FlpIt[TItem]:
1033
1041
  return FlpIt(self.__list.data).concat(second)
1034
1042
 
1035
- # noinspection unused-parameter
1036
- def as_type(self, target_type: Type[TResult]) -> FlpList[TResult]:
1037
- return self # type: ignore[return-value]
1043
+ def as_type[TResult](self, target_type: Type[TResult]) -> FlpList[TResult]:
1044
+ return typing_cast(FlpList[TResult], self)
1038
1045
 
1039
1046
  def where(self, predicate: Callable[[TItem], bool]) -> FlpIt[TItem]:
1040
1047
  return FlpIt[TItem](self.__list.data).where(predicate)
1041
1048
 
1042
- def select(self, selector: Callable[[TItem], TResult]) -> FlpIt[TResult]:
1049
+ def select[TResult](self, selector: Callable[[TItem], TResult]) -> FlpIt[TResult]:
1043
1050
  return FlpIt(self.__list.data).select(selector)
1044
1051
 
1045
- def select_many(
1052
+ def select_many[TResult](
1046
1053
  self, selector: Callable[[TItem], Iterable[TResult]]
1047
1054
  ) -> FlpIt[TResult]:
1048
1055
  return FlpIt(self.__list.data).select_many(selector)
@@ -1053,10 +1060,10 @@ class FlpList(Collection[TItem], Generic[TItem]):
1053
1060
  def take(self, count: int) -> FlpIt[TItem]:
1054
1061
  return FlpIt(self.__list.data).take(count)
1055
1062
 
1056
- def cast(self, target_type: Type[TResult]) -> FlpIt[TResult]:
1063
+ def cast[TResult](self, target_type: Type[TResult]) -> FlpIt[TResult]:
1057
1064
  return FlpIt(self.__list.data).cast(target_type)
1058
1065
 
1059
- def of_type(self, target_type: Type[TResult]) -> FlpIt[TResult]:
1066
+ def of_type[TResult](self, target_type: Type[TResult]) -> FlpIt[TResult]:
1060
1067
  return FlpIt(self.__list.data).of_type(target_type)
1061
1068
 
1062
1069
  def distinct(self) -> FlpIt[TItem]:
@@ -1071,7 +1078,7 @@ class FlpList(Collection[TItem], Generic[TItem]):
1071
1078
  def zip(self, second: Iterable[TOther]) -> FlpIt[tuple[TItem, TOther]]: ...
1072
1079
 
1073
1080
  @overload
1074
- def zip(
1081
+ def zip[TResult, TOther](
1075
1082
  self,
1076
1083
  second: Iterable[TOther],
1077
1084
  result_selector: Callable[[TItem, TOther], TResult],
@@ -1204,7 +1211,7 @@ class FlpList(Collection[TItem], Generic[TItem]):
1204
1211
 
1205
1212
  raise EmptySequenceError() if predicate is _SENTINEL else NoMatchError()
1206
1213
 
1207
- def first_or_default(
1214
+ def first_or_default[TResult](
1208
1215
  self, default: TResult, predicate: Callable[[TItem], bool] | _Sentinel = _SENTINEL
1209
1216
  ) -> TItem | TResult:
1210
1217
  return FlpIt(self.__list.data).first_or_default(default, predicate)
@@ -49,7 +49,7 @@ from collections.abc import Awaitable, Callable, Coroutine
49
49
  import flpit
50
50
 
51
51
  T = TypeVar("T")
52
- _LOG = logging.getLogger("tinytask")
52
+ _LOG = logging.getLogger("task")
53
53
  _MISSING = object()
54
54
  _WAKE = object()
55
55
 
@@ -71,7 +71,7 @@ class OperationCanceledError(Exception):
71
71
  super().__init__(message)
72
72
 
73
73
 
74
- # Backwards-compatible spelling used by the first TinyTask prototype.
74
+ # Backwards-compatible spelling used by the first Task prototype.
75
75
  CancelledError = OperationCanceledError
76
76
 
77
77
 
@@ -236,7 +236,7 @@ class CancellationToken:
236
236
 
237
237
  def throw_if_cancellation_requested(self) -> None:
238
238
  if self.is_cancellation_requested:
239
- raise OperationCanceledError("Cancellation was requested")
239
+ raise OperationCanceledError("Cancellation was requested", token=self)
240
240
 
241
241
  def register(self, callback: Callable[[], Any]) -> CancellationTokenRegistration:
242
242
  if not callable(callback):
@@ -393,8 +393,13 @@ class _Operation:
393
393
 
394
394
 
395
395
  class _Sleep(_Operation):
396
- def __init__(self, runtime: "_Runtime", delay: float) -> None:
397
- super().__init__(runtime)
396
+ def __init__(
397
+ self,
398
+ runtime: "_Runtime",
399
+ delay: float,
400
+ token: CancellationToken | None = None,
401
+ ) -> None:
402
+ super().__init__(runtime, token)
398
403
  self.delay = delay
399
404
  self.deadline = time.monotonic() + delay
400
405
 
@@ -471,8 +476,12 @@ async def _invoke_background(
471
476
  return result
472
477
 
473
478
 
474
- async def _delay_coroutine(runtime: "_Runtime", delay: float) -> None:
475
- await _Sleep(runtime, delay)
479
+ async def _delay_coroutine(
480
+ runtime: "_Runtime",
481
+ delay: float,
482
+ token: CancellationToken | None = None,
483
+ ) -> None:
484
+ await _Sleep(runtime, delay, token=token)
476
485
 
477
486
 
478
487
  class Task(Generic[T]):
@@ -487,11 +496,10 @@ class Task(Generic[T]):
487
496
  self,
488
497
  runtime: "_Runtime",
489
498
  *,
490
- name: str | None = None,
491
499
  token: CancellationToken | None = None,
492
500
  ) -> None:
493
501
  self._runtime = runtime
494
- self.name = name or f"Task-{id(self):x}"
502
+ self.name = f"Task-{id(self):x}"
495
503
  self._state = self.PENDING
496
504
  self._result: Any = None
497
505
  self._exception: BaseException | None = None
@@ -560,17 +568,42 @@ class Task(Generic[T]):
560
568
  raise TypeError("handler must be callable or None")
561
569
  _get_runtime().set_exception_handler(handler)
562
570
 
571
+ @overload
572
+ @classmethod
573
+ def run[R](
574
+ cls,
575
+ work: Callable[..., Coroutine[Any, Any, R]],
576
+ /,
577
+ *args: Any,
578
+ token: CancellationToken | None = None,
579
+ pass_token: bool = False,
580
+ **kwargs: Any,
581
+ ) -> Task[R]: ...
582
+
583
+ @overload
584
+ @classmethod
585
+ def run[R](
586
+ cls,
587
+ work: Callable[..., R],
588
+ /,
589
+ *args: Any,
590
+ token: CancellationToken | None = None,
591
+ pass_token: bool = False,
592
+ **kwargs: Any,
593
+ ) -> Task[R]: ...
594
+
563
595
  @classmethod
564
596
  def run(
565
597
  cls,
566
- work: Callable[..., T],
598
+ work: Callable[..., Any],
567
599
  /,
568
600
  *args: Any,
569
- name: str | None = None,
570
601
  token: CancellationToken | None = None,
571
602
  pass_token: bool = False,
572
603
  **kwargs: Any,
573
- ) -> "Task[T]":
604
+ ) -> Task[Any]:
605
+ # Keep your existing implementation here.
606
+ ...
574
607
  """Schedule a coroutine/awaitable or ordinary callable.
575
608
 
576
609
  Ordinary functions run in the bounded worker pool. ``token`` controls
@@ -594,7 +627,7 @@ class Task(Generic[T]):
594
627
  work.close()
595
628
  raise ValueError("pass_token=True requires an explicit token")
596
629
  runtime = _get_runtime()
597
- task = cls(runtime, name=name, token=token)
630
+ task = cls(runtime, token=token)
598
631
  task._pass_token = pass_token
599
632
  runtime._submit(task, work, args, kwargs)
600
633
  return task
@@ -602,9 +635,7 @@ class Task(Generic[T]):
602
635
  @classmethod
603
636
  def when_all(
604
637
  cls,
605
- *tasks: Any,
606
- name: str | None = None,
607
- token: CancellationToken | None = None,
638
+ *tasks: Awaitable[T]
608
639
  ) -> "Task[list[Any]]":
609
640
  """Complete when every supplied task completes, preserving input order.
610
641
 
@@ -615,22 +646,16 @@ class Task(Generic[T]):
615
646
  several children fail, TaskAggregateError exposes all their exceptions.
616
647
  If there are no tasks, the result is an empty list.
617
648
  """
618
- if token is not None and not isinstance(token, CancellationToken):
619
- raise TypeError("token must be a CancellationToken")
620
649
  normalized = _normalize_tasks(tasks, allow_empty=True)
621
650
  return cast(
622
651
  "Task[list[Any]]",
623
- # todo: make run type compatible via Generator[Y, S, R]
624
- # pyrefly: ignore [bad-argument-type]
625
- cls.run(_when_all_coroutine, normalized, name=name, token=token),
652
+ cls.run(_when_all_coroutine, normalized),
626
653
  )
627
654
 
628
655
  @classmethod
629
656
  def when_any(
630
657
  cls,
631
658
  *tasks: Any,
632
- name: str | None = None,
633
- token: CancellationToken | None = None,
634
659
  ) -> "Task[Task[Any]]":
635
660
  """Complete when one supplied task completes and return that task.
636
661
 
@@ -642,14 +667,10 @@ class Task(Generic[T]):
642
667
  If multiple tasks are already complete at observation time, input order
643
668
  breaks the tie deterministically.
644
669
  """
645
- if token is not None and not isinstance(token, CancellationToken):
646
- raise TypeError("token must be a CancellationToken")
647
670
  normalized = _normalize_tasks(tasks, allow_empty=False)
648
671
  return cast(
649
672
  "Task[Task[Any]]",
650
- # todo: make run type compatible via Generator[Y, S, R]
651
- # pyrefly: ignore [bad-argument-type]
652
- cls.run(_when_any_coroutine, normalized, name=name, token=token),
673
+ cls.run(_when_any_coroutine, normalized),
653
674
  )
654
675
 
655
676
  @staticmethod
@@ -674,7 +695,6 @@ class Task(Generic[T]):
674
695
  seconds: float,
675
696
  *,
676
697
  token: CancellationToken | None = None,
677
- name: str | None = None,
678
698
  ) -> "Task[None]":
679
699
  """Return a task completed after seconds without blocking a worker."""
680
700
  if seconds < 0:
@@ -682,12 +702,12 @@ class Task(Generic[T]):
682
702
  if token is not None and not isinstance(token, CancellationToken):
683
703
  raise TypeError("token must be a CancellationToken")
684
704
  runtime = _get_runtime()
685
- task: Task[None] = cls(runtime, name=name or f"Delay({seconds:g}s)", token=token)
705
+ task: Task[None] = cls(runtime, token=token)
686
706
  # During graceful cancellation, allow an already-running coroutine to
687
707
  # create a delay for async cleanup. External callers are still rejected.
688
708
  runtime._submit_coroutine(
689
709
  task,
690
- _delay_coroutine(runtime, seconds),
710
+ _delay_coroutine(runtime, seconds, token),
691
711
  allow_during_shutdown=runtime.is_runtime_thread(),
692
712
  )
693
713
  return task
@@ -754,16 +774,6 @@ class Task(Generic[T]):
754
774
  return self._exception
755
775
  return OperationCanceledError(f"{self.name} was cancelled")
756
776
 
757
- def cancel(self) -> bool:
758
- """Request cancellation of this Task, independently of other token users."""
759
- if self.done():
760
- return False
761
- try:
762
- self._runtime._post(lambda: self._cancel_on_runtime(), internal=True)
763
- except RuntimeShutdownError:
764
- return False
765
- return True
766
-
767
777
  def __await__(self) -> Generator[Any, T, T]:
768
778
  if self.done():
769
779
  return self._raise_or_return()
@@ -780,11 +790,6 @@ class Task(Generic[T]):
780
790
  raise InvalidStateError(f"{self.name} has not completed")
781
791
  return cast(T, self._result)
782
792
 
783
- def _bind_token(self) -> None:
784
- if not self._token.can_be_cancelled or self._token_registration is not None:
785
- return
786
- self._token_registration = self._token.register(self.cancel)
787
-
788
793
  def _cancel_on_runtime(self) -> None:
789
794
  if self.done():
790
795
  return
@@ -1152,7 +1157,7 @@ class _Runtime:
1152
1157
  self._max_pending_background = max_pending_background
1153
1158
  self._pending_background: deque[tuple[Task[Any], _BackgroundCall]] = deque()
1154
1159
  self._background_active = 0 # scheduler-thread-owned submitted call count
1155
- self._executor = ThreadPoolExecutor(max_workers=max_workers, thread_name_prefix="tinytask-io")
1160
+ self._executor = ThreadPoolExecutor(max_workers=max_workers, thread_name_prefix="Thread")
1156
1161
  self._inflight_lock = threading.Condition()
1157
1162
  self._inflight_futures: set[Future[Any]] = set()
1158
1163
  self._current_task: Task[Any] | None = None
@@ -1181,8 +1186,8 @@ class _Runtime:
1181
1186
  return
1182
1187
  with self._state_lock:
1183
1188
  if self._closed or self._shutdown_requested:
1184
- raise RuntimeShutdownError("TinyTask runtime is shutting down")
1185
- self._thread = threading.Thread(target=self._loop, name="TinyTask-runtime", daemon=True)
1189
+ raise RuntimeShutdownError("Task runtime is shutting down")
1190
+ self._thread = threading.Thread(target=self._loop, name="Task-runtime", daemon=True)
1186
1191
  self._thread.start()
1187
1192
  self._started.wait()
1188
1193
 
@@ -1199,8 +1204,8 @@ class _Runtime:
1199
1204
  handler({**context, "exception": error})
1200
1205
  return
1201
1206
  except Exception:
1202
- _LOG.exception("TinyTask exception handler itself failed")
1203
- message = str(context.get("message", "Unexpected TinyTask runtime error"))
1207
+ _LOG.exception("Task exception handler itself failed")
1208
+ message = str(context.get("message", "Unexpected Task runtime error"))
1204
1209
  _LOG.error("%s", message, exc_info=(type(error), error, error.__traceback__))
1205
1210
 
1206
1211
  def _call_sync(self, callback: Callable[[], T], *, internal: bool = False) -> T:
@@ -1230,7 +1235,7 @@ class _Runtime:
1230
1235
  thread = self._thread
1231
1236
  if thread is None or not thread.is_alive():
1232
1237
  raise RuntimeShutdownError(
1233
- "TinyTask runtime stopped before the scheduled operation ran"
1238
+ "Task runtime stopped before the scheduled operation ran"
1234
1239
  )
1235
1240
  if "error" in outcome:
1236
1241
  raise outcome["error"]
@@ -1241,7 +1246,7 @@ class _Runtime:
1241
1246
  execute_inline = False
1242
1247
  with self._state_lock:
1243
1248
  if self._closed or self._stopping or (self._shutdown_requested and not internal):
1244
- raise RuntimeShutdownError("TinyTask runtime is shutting down")
1249
+ raise RuntimeShutdownError("Task runtime is shutting down")
1245
1250
  if self.is_runtime_thread():
1246
1251
  execute_inline = True
1247
1252
  else:
@@ -1312,7 +1317,6 @@ class _Runtime:
1312
1317
  return
1313
1318
  task._coroutine = coroutine
1314
1319
  self._tasks.add(task)
1315
- task._bind_token()
1316
1320
  self._schedule(task)
1317
1321
 
1318
1322
  def _schedule(
@@ -1361,7 +1365,7 @@ class _Runtime:
1361
1365
  if not isinstance(yielded, _Operation):
1362
1366
  raise RuntimeError(
1363
1367
  f"{task.name} yielded unsupported object {yielded!r}; "
1364
- "this runtime only supports TinyTask awaitables"
1368
+ "this runtime only supports Task awaitables"
1365
1369
  )
1366
1370
  if yielded.runtime is not self:
1367
1371
  raise RuntimeError("awaitable belongs to a different runtime")
@@ -1614,7 +1618,7 @@ class _Runtime:
1614
1618
  callback()
1615
1619
  except BaseException as error:
1616
1620
  self._report_exception(
1617
- {"message": "Unhandled exception in TinyTask scheduler callback", "callback": callback},
1621
+ {"message": "Unhandled exception in Task scheduler callback", "callback": callback},
1618
1622
  error,
1619
1623
  )
1620
1624
 
@@ -1704,7 +1708,7 @@ class _Runtime:
1704
1708
  if self._stopping or self.closed:
1705
1709
  break
1706
1710
  self._report_exception(
1707
- {"message": "Selector failed; stopping TinyTask runtime"}, error
1711
+ {"message": "Selector failed; stopping Task runtime"}, error
1708
1712
  )
1709
1713
  self._stopping = True
1710
1714
  break
@@ -1716,7 +1720,7 @@ class _Runtime:
1716
1720
  )
1717
1721
  self._stopping = True
1718
1722
  except BaseException as error:
1719
- self._report_exception({"message": "Fatal error in TinyTask scheduler loop"}, error)
1723
+ self._report_exception({"message": "Fatal error in Task scheduler loop"}, error)
1720
1724
  self._stopping = True
1721
1725
  finally:
1722
1726
  # Stop accepting work before releasing scheduler resources. The
@@ -1771,7 +1775,7 @@ class _Runtime:
1771
1775
  runtime_stopped = thread is None or not thread.is_alive()
1772
1776
  if not runtime_stopped:
1773
1777
  self._report_exception(
1774
- {"message": "TinyTask scheduler thread did not stop before timeout"},
1778
+ {"message": "Task scheduler thread did not stop before timeout"},
1775
1779
  TimeoutError("scheduler shutdown timed out"),
1776
1780
  )
1777
1781
 
@@ -1825,7 +1829,7 @@ def _shutdown_at_exit() -> None:
1825
1829
  try:
1826
1830
  Task.shutdown(grace_timeout=0.2, worker_timeout=0.2)
1827
1831
  except BaseException:
1828
- _LOG.exception("Error during TinyTask interpreter shutdown")
1832
+ _LOG.exception("Error during Task interpreter shutdown")
1829
1833
 
1830
1834
 
1831
1835
  atexit.register(_shutdown_at_exit)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes