eventsourcing 9.4.0b1__py3-none-any.whl → 9.4.0b3__py3-none-any.whl

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.

Potentially problematic release.


This version of eventsourcing might be problematic. Click here for more details.

eventsourcing/system.py CHANGED
@@ -6,11 +6,12 @@ import traceback
6
6
  from abc import ABC, abstractmethod
7
7
  from collections import defaultdict
8
8
  from queue import Full, Queue
9
- from types import FrameType, ModuleType
10
9
  from typing import TYPE_CHECKING, Any, ClassVar, Optional, Union, cast
11
10
 
12
11
  if TYPE_CHECKING:
13
12
  from collections.abc import Iterable, Iterator, Sequence
13
+ from types import FrameType, ModuleType
14
+
14
15
  from typing_extensions import Self
15
16
 
16
17
  from eventsourcing.application import (
@@ -52,8 +53,7 @@ ConvertingJob = Optional[Union[RecordingEvent, list[Notification]]]
52
53
 
53
54
 
54
55
  class Follower(Application):
55
- """
56
- Extends the :class:`~eventsourcing.application.Application` class
56
+ """Extends the :class:`~eventsourcing.application.Application` class
57
57
  by using a process recorder as its application recorder, by keeping
58
58
  track of the applications it is following, and pulling and processing
59
59
  new domain event notifications through its :func:`policy` method.
@@ -71,15 +71,13 @@ class Follower(Application):
71
71
  self.processing_lock = threading.Lock()
72
72
 
73
73
  def construct_recorder(self) -> ProcessRecorder:
74
- """
75
- Constructs and returns a :class:`~eventsourcing.persistence.ProcessRecorder`
74
+ """Constructs and returns a :class:`~eventsourcing.persistence.ProcessRecorder`
76
75
  for the application to use as its application recorder.
77
76
  """
78
77
  return self.factory.process_recorder()
79
78
 
80
79
  def follow(self, name: str, log: NotificationLog) -> None:
81
- """
82
- Constructs a notification log reader and a mapper for
80
+ """Constructs a notification log reader and a mapper for
83
81
  the named application, and adds them to its collections
84
82
  of readers and mappers.
85
83
  """
@@ -97,9 +95,7 @@ class Follower(Application):
97
95
  def pull_and_process(
98
96
  self, leader_name: str, start: int | None = None, stop: int | None = None
99
97
  ) -> None:
100
- """
101
- Pull and process new domain event notifications.
102
- """
98
+ """Pull and process new domain event notifications."""
103
99
  if start is None:
104
100
  start = self.recorder.max_tracking_id(leader_name)
105
101
  for notifications in self.pull_notifications(
@@ -119,8 +115,7 @@ class Follower(Application):
119
115
  *,
120
116
  inclusive_of_start: bool = True,
121
117
  ) -> Iterator[list[Notification]]:
122
- """
123
- Pulls batches of unseen :class:`~eventsourcing.persistence.Notification`
118
+ """Pulls batches of unseen :class:`~eventsourcing.persistence.Notification`
124
119
  objects from the notification log reader of the named application.
125
120
  """
126
121
  return self.readers[leader_name].select(
@@ -140,8 +135,7 @@ class Follower(Application):
140
135
  def convert_notifications(
141
136
  self, leader_name: str, notifications: Iterable[Notification]
142
137
  ) -> list[ProcessingJob]:
143
- """
144
- Uses the given :class:`~eventsourcing.persistence.Mapper` to convert
138
+ """Uses the given :class:`~eventsourcing.persistence.Mapper` to convert
145
139
  each received :class:`~eventsourcing.persistence.Notification`
146
140
  object to an :class:`~eventsourcing.domain.AggregateEvent` object
147
141
  paired with a :class:`~eventsourcing.persistence.Tracking` object.
@@ -161,8 +155,7 @@ class Follower(Application):
161
155
  def process_event(
162
156
  self, domain_event: DomainEventProtocol, tracking: Tracking
163
157
  ) -> None:
164
- """
165
- Calls :func:`~eventsourcing.system.Follower.policy` method with
158
+ """Calls :func:`~eventsourcing.system.Follower.policy` method with
166
159
  the given :class:`~eventsourcing.domain.AggregateEvent` and a
167
160
  new :class:`~eventsourcing.application.ProcessingEvent` created from
168
161
  the given :class:`~eventsourcing.persistence.Tracking` object.
@@ -204,8 +197,7 @@ class Follower(Application):
204
197
  domain_event: DomainEventProtocol,
205
198
  processing_event: ProcessingEvent,
206
199
  ) -> None:
207
- """
208
- Abstract domain event processing policy method. Must be
200
+ """Abstract domain event processing policy method. Must be
209
201
  implemented by event processing applications. When
210
202
  processing the given domain event, event processing
211
203
  applications must use the :func:`~ProcessingEvent.collect_events`
@@ -219,20 +211,15 @@ class Follower(Application):
219
211
 
220
212
 
221
213
  class RecordingEventReceiver(ABC):
222
- """
223
- Abstract base class for objects that may receive recording events.
224
- """
214
+ """Abstract base class for objects that may receive recording events."""
225
215
 
226
216
  @abstractmethod
227
- def receive_recording_event(self, recording_event: RecordingEvent) -> None:
228
- """
229
- Receives a recording event.
230
- """
217
+ def receive_recording_event(self, new_recording_event: RecordingEvent) -> None:
218
+ """Receives a recording event."""
231
219
 
232
220
 
233
221
  class Leader(Application):
234
- """
235
- Extends the :class:`~eventsourcing.application.Application`
222
+ """Extends the :class:`~eventsourcing.application.Application`
236
223
  class by also being responsible for keeping track of
237
224
  followers, and prompting followers when there are new
238
225
  domain event notifications to be pulled and processed.
@@ -244,9 +231,7 @@ class Leader(Application):
244
231
  self.followers: list[RecordingEventReceiver] = []
245
232
 
246
233
  def lead(self, follower: RecordingEventReceiver) -> None:
247
- """
248
- Adds given follower to a list of followers.
249
- """
234
+ """Adds given follower to a list of followers."""
250
235
  self.followers.append(follower)
251
236
 
252
237
  def save(
@@ -259,8 +244,7 @@ class Leader(Application):
259
244
  return super().save(*objs, **kwargs)
260
245
 
261
246
  def _notify(self, recordings: list[Recording]) -> None:
262
- """
263
- Calls :func:`receive_recording_event` on each follower
247
+ """Calls :func:`receive_recording_event` on each follower
264
248
  whenever new events have just been saved.
265
249
  """
266
250
  super()._notify(recordings)
@@ -280,16 +264,13 @@ class Leader(Application):
280
264
 
281
265
 
282
266
  class ProcessApplication(Leader, Follower):
283
- """
284
- Base class for event processing applications
267
+ """Base class for event processing applications
285
268
  that are both "leaders" and followers".
286
269
  """
287
270
 
288
271
 
289
272
  class System:
290
- """
291
- Defines a system of applications.
292
- """
273
+ """Defines a system of applications."""
293
274
 
294
275
  __caller_modules: ClassVar[dict[int, ModuleType]] = {}
295
276
 
@@ -298,9 +279,9 @@ class System:
298
279
  pipes: Iterable[Iterable[type[Application]]],
299
280
  ):
300
281
  # Remember the caller frame's module, so that we might identify a topic.
301
- caller_frame = cast(FrameType, cast(FrameType, inspect.currentframe()).f_back)
302
- module = cast(ModuleType, inspect.getmodule(caller_frame))
303
- type(self).__caller_modules[id(self)] = module
282
+ caller_frame = cast("FrameType", inspect.currentframe()).f_back
283
+ module = cast("ModuleType", inspect.getmodule(caller_frame))
284
+ type(self).__caller_modules[id(self)] = module # noqa: SLF001
304
285
 
305
286
  # Build nodes and edges.
306
287
  self.edges: list[tuple[str, str]] = []
@@ -319,9 +300,8 @@ class System:
319
300
  self.edges.append(edge)
320
301
 
321
302
  self.nodes: dict[str, str] = {}
322
- for name in classes:
323
- topic = get_topic(classes[name])
324
- self.nodes[name] = topic
303
+ for name, cls in classes.items():
304
+ self.nodes[name] = get_topic(cls)
325
305
 
326
306
  # Identify leaders and followers.
327
307
  self.follows: dict[str, list[str]] = defaultdict(list)
@@ -339,12 +319,14 @@ class System:
339
319
  # Check followers are followers.
340
320
  for name in self.follows:
341
321
  if not issubclass(classes[name], Follower):
342
- raise TypeError("Not a follower class: %s" % classes[name])
322
+ msg = f"Not a follower class: {classes[name]}"
323
+ raise TypeError(msg)
343
324
 
344
325
  # Check each process is a process application class.
345
326
  for name in self.processors:
346
327
  if not issubclass(classes[name], ProcessApplication):
347
- raise TypeError("Not a process application class: %s" % classes[name])
328
+ msg = f"Not a process application class: {classes[name]}"
329
+ raise TypeError(msg)
348
330
 
349
331
  @property
350
332
  def leaders(self) -> list[str]:
@@ -392,15 +374,13 @@ class System:
392
374
  topic = module.__name__ + ":" + name
393
375
  assert resolve_topic(topic) is self
394
376
  if topic is None:
395
- msg = "Unable to compute topic for system object: %s" % self
377
+ msg = f"Unable to compute topic for system object: {self}"
396
378
  raise ProgrammingError(msg)
397
379
  return topic
398
380
 
399
381
 
400
382
  class Runner(ABC):
401
- """
402
- Abstract base class for system runners.
403
- """
383
+ """Abstract base class for system runners."""
404
384
 
405
385
  def __init__(self, system: System, env: EnvType | None = None):
406
386
  self.system = system
@@ -409,24 +389,18 @@ class Runner(ABC):
409
389
 
410
390
  @abstractmethod
411
391
  def start(self) -> None:
412
- """
413
- Starts the runner.
414
- """
392
+ """Starts the runner."""
415
393
  if self.is_started:
416
394
  raise RunnerAlreadyStartedError
417
395
  self.is_started = True
418
396
 
419
397
  @abstractmethod
420
398
  def stop(self) -> None:
421
- """
422
- Stops the runner.
423
- """
399
+ """Stops the runner."""
424
400
 
425
401
  @abstractmethod
426
402
  def get(self, cls: type[TApplication]) -> TApplication:
427
- """
428
- Returns an application instance for given application class.
429
- """
403
+ """Returns an application instance for given application class."""
430
404
 
431
405
  def __enter__(self) -> Self:
432
406
  self.start()
@@ -437,38 +411,26 @@ class Runner(ABC):
437
411
 
438
412
 
439
413
  class RunnerAlreadyStartedError(Exception):
440
- """
441
- Raised when runner is already started.
442
- """
414
+ """Raised when runner is already started."""
443
415
 
444
416
 
445
417
  class NotificationPullingError(Exception):
446
- """
447
- Raised when pulling notifications fails.
448
- """
418
+ """Raised when pulling notifications fails."""
449
419
 
450
420
 
451
421
  class NotificationConvertingError(Exception):
452
- """
453
- Raised when converting notifications fails.
454
- """
422
+ """Raised when converting notifications fails."""
455
423
 
456
424
 
457
425
  class EventProcessingError(Exception):
458
- """
459
- Raised when event processing fails.
460
- """
426
+ """Raised when event processing fails."""
461
427
 
462
428
 
463
429
  class SingleThreadedRunner(Runner, RecordingEventReceiver):
464
- """
465
- Runs a :class:`System` in a single thread.
466
- """
430
+ """Runs a :class:`System` in a single thread."""
467
431
 
468
432
  def __init__(self, system: System, env: EnvType | None = None):
469
- """
470
- Initialises runner with the given :class:`System`.
471
- """
433
+ """Initialises runner with the given :class:`System`."""
472
434
  super().__init__(system=system, env=env)
473
435
  self.apps: dict[str, Application] = {}
474
436
  self._recording_events_received: list[RecordingEvent] = []
@@ -491,34 +453,31 @@ class SingleThreadedRunner(Runner, RecordingEventReceiver):
491
453
  self.apps[name] = single
492
454
 
493
455
  def start(self) -> None:
494
- """
495
- Starts the runner. The applications mentioned in the system definition
456
+ """Starts the runner. The applications mentioned in the system definition
496
457
  are constructed. The followers are set up to follow the applications
497
458
  they are defined as following in the system definition. And the leaders
498
459
  are set up to lead the runner itself.
499
460
  """
500
-
501
461
  super().start()
502
462
 
503
463
  # Setup followers to follow leaders.
504
464
  for edge in self.system.edges:
505
465
  leader_name = edge[0]
506
466
  follower_name = edge[1]
507
- leader = cast(Leader, self.apps[leader_name])
508
- follower = cast(Follower, self.apps[follower_name])
467
+ leader = cast("Leader", self.apps[leader_name])
468
+ follower = cast("Follower", self.apps[follower_name])
509
469
  assert isinstance(leader, Leader)
510
470
  assert isinstance(follower, Follower)
511
471
  follower.follow(leader_name, leader.notification_log)
512
472
 
513
473
  # Setup leaders to lead this runner.
514
474
  for name in self.system.leaders:
515
- leader = cast(Leader, self.apps[name])
475
+ leader = cast("Leader", self.apps[name])
516
476
  assert isinstance(leader, Leader)
517
477
  leader.lead(self)
518
478
 
519
- def receive_recording_event(self, recording_event: RecordingEvent) -> None:
520
- """
521
- Receives recording event by appending the name of the leader
479
+ def receive_recording_event(self, new_recording_event: RecordingEvent) -> None:
480
+ """Receives recording event by appending the name of the leader
522
481
  to a list of prompted names.
523
482
 
524
483
  Then, unless this method has previously been called and not yet returned,
@@ -528,7 +487,7 @@ class SingleThreadedRunner(Runner, RecordingEventReceiver):
528
487
  continues until there are no more prompted names. In this way, a system
529
488
  of applications will process all events in a single thread.
530
489
  """
531
- leader_name = recording_event.application_name
490
+ leader_name = new_recording_event.application_name
532
491
  with self._prompted_names_lock:
533
492
  self._prompted_names.add(leader_name)
534
493
 
@@ -544,7 +503,7 @@ class SingleThreadedRunner(Runner, RecordingEventReceiver):
544
503
 
545
504
  for leader_name in prompted_names:
546
505
  for follower_name in self.system.leads[leader_name]:
547
- follower = cast(Follower, self.apps[follower_name])
506
+ follower = cast("Follower", self.apps[follower_name])
548
507
  follower.pull_and_process(leader_name)
549
508
 
550
509
  finally:
@@ -562,14 +521,10 @@ class SingleThreadedRunner(Runner, RecordingEventReceiver):
562
521
 
563
522
 
564
523
  class NewSingleThreadedRunner(Runner, RecordingEventReceiver):
565
- """
566
- Runs a :class:`System` in a single thread.
567
- """
524
+ """Runs a :class:`System` in a single thread."""
568
525
 
569
526
  def __init__(self, system: System, env: EnvType | None = None):
570
- """
571
- Initialises runner with the given :class:`System`.
572
- """
527
+ """Initialises runner with the given :class:`System`."""
573
528
  super().__init__(system=system, env=env)
574
529
  self.apps: dict[str, Application] = {}
575
530
  self._recording_events_received: list[RecordingEvent] = []
@@ -592,8 +547,7 @@ class NewSingleThreadedRunner(Runner, RecordingEventReceiver):
592
547
  self.apps[name] = single
593
548
 
594
549
  def start(self) -> None:
595
- """
596
- Starts the runner.
550
+ """Starts the runner.
597
551
  The applications are constructed, and setup to lead and follow
598
552
  each other, according to the system definition.
599
553
  The followers are setup to follow the applications they follow
@@ -601,28 +555,26 @@ class NewSingleThreadedRunner(Runner, RecordingEventReceiver):
601
555
  leader), and their leaders are setup to lead the runner itself
602
556
  (send prompts).
603
557
  """
604
-
605
558
  super().start()
606
559
 
607
560
  # Setup followers to follow leaders.
608
561
  for edge in self.system.edges:
609
562
  leader_name = edge[0]
610
563
  follower_name = edge[1]
611
- leader = cast(Leader, self.apps[leader_name])
612
- follower = cast(Follower, self.apps[follower_name])
564
+ leader = cast("Leader", self.apps[leader_name])
565
+ follower = cast("Follower", self.apps[follower_name])
613
566
  assert isinstance(leader, Leader)
614
567
  assert isinstance(follower, Follower)
615
568
  follower.follow(leader_name, leader.notification_log)
616
569
 
617
570
  # Setup leaders to notify followers.
618
571
  for name in self.system.leaders:
619
- leader = cast(Leader, self.apps[name])
572
+ leader = cast("Leader", self.apps[name])
620
573
  assert isinstance(leader, Leader)
621
574
  leader.lead(self)
622
575
 
623
- def receive_recording_event(self, recording_event: RecordingEvent) -> None:
624
- """
625
- Receives recording event by appending it to list of received recording
576
+ def receive_recording_event(self, new_recording_event: RecordingEvent) -> None:
577
+ """Receives recording event by appending it to list of received recording
626
578
  events.
627
579
 
628
580
  Unless this method has previously been called and not yet returned, it
@@ -630,19 +582,19 @@ class NewSingleThreadedRunner(Runner, RecordingEventReceiver):
630
582
  events, until there are none remaining.
631
583
  """
632
584
  with self._recording_events_received_lock:
633
- self._recording_events_received.append(recording_event)
585
+ self._recording_events_received.append(new_recording_event)
634
586
 
635
587
  if self._processing_lock.acquire(blocking=False):
636
588
  try:
637
589
  while True:
638
590
  with self._recording_events_received_lock:
639
- recording_events_received = self._recording_events_received
591
+ recording_events = self._recording_events_received
640
592
  self._recording_events_received = []
641
593
 
642
- if not recording_events_received:
594
+ if not recording_events:
643
595
  break
644
596
 
645
- for recording_event in recording_events_received:
597
+ for recording_event in recording_events:
646
598
  leader_name = recording_event.application_name
647
599
  previous_max_notification_id = (
648
600
  self._previous_max_notification_ids.get(leader_name, 0)
@@ -709,15 +661,12 @@ class NewSingleThreadedRunner(Runner, RecordingEventReceiver):
709
661
 
710
662
 
711
663
  class MultiThreadedRunner(Runner):
712
- """
713
- Runs a :class:`System` with one :class:`MultiThreadedRunnerThread`
664
+ """Runs a :class:`System` with one :class:`MultiThreadedRunnerThread`
714
665
  for each :class:`Follower` in the system definition.
715
666
  """
716
667
 
717
668
  def __init__(self, system: System, env: EnvType | None = None):
718
- """
719
- Initialises runner with the given :class:`System`.
720
- """
669
+ """Initialises runner with the given :class:`System`."""
721
670
  super().__init__(system=system, env=env)
722
671
  self.apps: dict[str, Application] = {}
723
672
  self.threads: dict[str, MultiThreadedRunnerThread] = {}
@@ -743,8 +692,7 @@ class MultiThreadedRunner(Runner):
743
692
  self.apps[name] = single
744
693
 
745
694
  def start(self) -> None:
746
- """
747
- Starts the runner.
695
+ """Starts the runner.
748
696
  A multi-threaded runner thread is started for each
749
697
  'follower' application in the system, and constructs
750
698
  an instance of each non-follower leader application in
@@ -757,7 +705,7 @@ class MultiThreadedRunner(Runner):
757
705
 
758
706
  # Construct followers.
759
707
  for follower_name in self.system.followers:
760
- follower = cast(Follower, self.apps[follower_name])
708
+ follower = cast("Follower", self.apps[follower_name])
761
709
 
762
710
  thread = MultiThreadedRunnerThread(
763
711
  follower=follower,
@@ -772,8 +720,8 @@ class MultiThreadedRunner(Runner):
772
720
 
773
721
  # Lead and follow.
774
722
  for edge in self.system.edges:
775
- leader = cast(Leader, self.apps[edge[0]])
776
- follower = cast(Follower, self.apps[edge[1]])
723
+ leader = cast("Leader", self.apps[edge[0]])
724
+ follower = cast("Follower", self.apps[edge[1]])
777
725
  follower.follow(leader.name, leader.notification_log)
778
726
  thread = self.threads[follower.name]
779
727
  leader.lead(thread)
@@ -806,8 +754,7 @@ class MultiThreadedRunner(Runner):
806
754
 
807
755
 
808
756
  class MultiThreadedRunnerThread(RecordingEventReceiver, threading.Thread):
809
- """
810
- Runs one :class:`~eventsourcing.system.Follower` application in
757
+ """Runs one :class:`~eventsourcing.system.Follower` application in
811
758
  a :class:`~eventsourcing.system.MultiThreadedRunner`.
812
759
  """
813
760
 
@@ -828,8 +775,7 @@ class MultiThreadedRunnerThread(RecordingEventReceiver, threading.Thread):
828
775
  self.is_running = threading.Event()
829
776
 
830
777
  def run(self) -> None:
831
- """
832
- Loops forever until stopped. The loop blocks on waiting
778
+ """Loops forever until stopped. The loop blocks on waiting
833
779
  for the 'is_prompted' event to be set, then calls
834
780
  :func:`~Follower.pull_and_process` method for each
835
781
  prompted name.
@@ -851,12 +797,11 @@ class MultiThreadedRunnerThread(RecordingEventReceiver, threading.Thread):
851
797
  self.error.__cause__ = e
852
798
  self.has_errored.set()
853
799
 
854
- def receive_recording_event(self, recording_event: RecordingEvent) -> None:
855
- """
856
- Receives prompt by appending name of
800
+ def receive_recording_event(self, new_recording_event: RecordingEvent) -> None:
801
+ """Receives prompt by appending name of
857
802
  leader to list of prompted names.
858
803
  """
859
- leader_name = recording_event.application_name
804
+ leader_name = new_recording_event.application_name
860
805
  with self.prompted_names_lock:
861
806
  if leader_name not in self.prompted_names:
862
807
  self.prompted_names.append(leader_name)
@@ -868,9 +813,7 @@ class MultiThreadedRunnerThread(RecordingEventReceiver, threading.Thread):
868
813
 
869
814
 
870
815
  class NewMultiThreadedRunner(Runner, RecordingEventReceiver):
871
- """
872
- Runs a :class:`System` with multiple threads in a new way.
873
- """
816
+ """Runs a :class:`System` with multiple threads in a new way."""
874
817
 
875
818
  QUEUE_MAX_SIZE: int = 0
876
819
 
@@ -879,9 +822,7 @@ class NewMultiThreadedRunner(Runner, RecordingEventReceiver):
879
822
  system: System,
880
823
  env: EnvType | None = None,
881
824
  ):
882
- """
883
- Initialises runner with the given :class:`System`.
884
- """
825
+ """Initialises runner with the given :class:`System`."""
885
826
  super().__init__(system=system, env=env)
886
827
  self.apps: dict[str, Application] = {}
887
828
  self.pulling_threads: dict[str, list[PullingThread]] = {}
@@ -909,8 +850,7 @@ class NewMultiThreadedRunner(Runner, RecordingEventReceiver):
909
850
  self.apps[name] = single
910
851
 
911
852
  def start(self) -> None:
912
- """
913
- Starts the runner.
853
+ """Starts the runner.
914
854
 
915
855
  A multi-threaded runner thread is started for each
916
856
  'follower' application in the system, and constructs
@@ -924,7 +864,7 @@ class NewMultiThreadedRunner(Runner, RecordingEventReceiver):
924
864
 
925
865
  # Start the processing threads.
926
866
  for follower_name in self.system.followers:
927
- follower = cast(Follower, self.apps[follower_name])
867
+ follower = cast("Follower", self.apps[follower_name])
928
868
  processing_queue: Queue[list[ProcessingJob] | None] = Queue(
929
869
  maxsize=self.QUEUE_MAX_SIZE
930
870
  )
@@ -940,9 +880,9 @@ class NewMultiThreadedRunner(Runner, RecordingEventReceiver):
940
880
  for edge in self.system.edges:
941
881
  # Set up follower to pull notifications from leader.
942
882
  leader_name = edge[0]
943
- leader = cast(Leader, self.apps[leader_name])
883
+ leader = cast("Leader", self.apps[leader_name])
944
884
  follower_name = edge[1]
945
- follower = cast(Follower, self.apps[follower_name])
885
+ follower = cast("Follower", self.apps[follower_name])
946
886
  follower.follow(leader.name, leader.notification_log)
947
887
 
948
888
  # Create converting queue.
@@ -978,7 +918,7 @@ class NewMultiThreadedRunner(Runner, RecordingEventReceiver):
978
918
 
979
919
  # Subscribe for notifications from leaders.
980
920
  for leader_name in self.system.leaders:
981
- leader = cast(Leader, self.apps[leader_name])
921
+ leader = cast("Leader", self.apps[leader_name])
982
922
  assert isinstance(leader, Leader)
983
923
  leader.lead(self)
984
924
 
@@ -1007,14 +947,15 @@ class NewMultiThreadedRunner(Runner, RecordingEventReceiver):
1007
947
  assert isinstance(app, cls)
1008
948
  return app
1009
949
 
1010
- def receive_recording_event(self, recording_event: RecordingEvent) -> None:
1011
- for pulling_thread in self.pulling_threads[recording_event.application_name]:
1012
- pulling_thread.receive_recording_event(recording_event)
950
+ def receive_recording_event(self, new_recording_event: RecordingEvent) -> None:
951
+ for pulling_thread in self.pulling_threads[
952
+ new_recording_event.application_name
953
+ ]:
954
+ pulling_thread.receive_recording_event(new_recording_event)
1013
955
 
1014
956
 
1015
957
  class PullingThread(threading.Thread):
1016
- """
1017
- Receives or pulls notifications from the given leader, and
958
+ """Receives or pulls notifications from the given leader, and
1018
959
  puts them on a queue for conversion into processing jobs.
1019
960
  """
1020
961
 
@@ -1096,9 +1037,7 @@ class PullingThread(threading.Thread):
1096
1037
 
1097
1038
 
1098
1039
  class ConvertingThread(threading.Thread):
1099
- """
1100
- Converts notifications into processing jobs.
1101
- """
1040
+ """Converts notifications into processing jobs."""
1102
1041
 
1103
1042
  def __init__(
1104
1043
  self,
@@ -1155,7 +1094,7 @@ class ConvertingThread(threading.Thread):
1155
1094
  if processing_jobs:
1156
1095
  self.processing_queue.put(processing_jobs)
1157
1096
  except Exception as e:
1158
- print(traceback.format_exc())
1097
+ print(traceback.format_exc()) # noqa: T201
1159
1098
  self.error = NotificationConvertingError(str(e))
1160
1099
  self.error.__cause__ = e
1161
1100
  self.has_errored.set()
@@ -1166,8 +1105,7 @@ class ConvertingThread(threading.Thread):
1166
1105
 
1167
1106
 
1168
1107
  class ProcessingThread(threading.Thread):
1169
- """
1170
- A processing thread gets events from a processing queue, and
1108
+ """A processing thread gets events from a processing queue, and
1171
1109
  calls the application's process_event() method.
1172
1110
  """
1173
1111
 
@@ -1206,9 +1144,7 @@ class ProcessingThread(threading.Thread):
1206
1144
 
1207
1145
 
1208
1146
  class NotificationLogReader:
1209
- """
1210
- Reads domain event notifications from a notification log.
1211
- """
1147
+ """Reads domain event notifications from a notification log."""
1212
1148
 
1213
1149
  DEFAULT_SECTION_SIZE = 10
1214
1150
 
@@ -1217,8 +1153,7 @@ class NotificationLogReader:
1217
1153
  notification_log: NotificationLog,
1218
1154
  section_size: int = DEFAULT_SECTION_SIZE,
1219
1155
  ):
1220
- """
1221
- Initialises a reader with the given notification log,
1156
+ """Initialises a reader with the given notification log,
1222
1157
  and optionally a section size integer which determines
1223
1158
  the requested number of domain event notifications in
1224
1159
  each section retrieved from the notification log.
@@ -1227,8 +1162,7 @@ class NotificationLogReader:
1227
1162
  self.section_size = section_size
1228
1163
 
1229
1164
  def read(self, *, start: int) -> Iterator[Notification]:
1230
- """
1231
- Returns a generator that yields event notifications
1165
+ """Returns a generator that yields event notifications
1232
1166
  from the reader's notification log, starting from
1233
1167
  given start position (a notification ID).
1234
1168
 
@@ -1257,8 +1191,7 @@ class NotificationLogReader:
1257
1191
  topics: Sequence[str] = (),
1258
1192
  inclusive_of_start: bool = True,
1259
1193
  ) -> Iterator[list[Notification]]:
1260
- """
1261
- Returns a generator that yields lists of event notifications
1194
+ """Returns a generator that yields lists of event notifications
1262
1195
  from the reader's notification log, starting from given start
1263
1196
  position (a notification ID).
1264
1197