You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+11
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
4
4
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
7
+
## [0.4.0] - 2024-12-21
8
+
9
+
### Added
10
+
-**Weak Reference Support**: Introduced `weak=True` for signal connections to allow automatic disconnection when the receiver is garbage-collected.
11
+
-**One-Shot Connections**: Added `one_shot=True` in `connect(...)` to enable automatically disconnecting a slot after its first successful emission call.
12
+
- Extended integration tests to cover new `weak` and `one_shot` functionality.
13
+
14
+
### Improved
15
+
-**Thread Safety**: Strengthened internal locking and concurrency patterns to reduce race conditions in high-load or multi-threaded environments.
16
+
-**Documentation**: Updated `readme.md`, `api.md`, and example code sections to explain weak references, one-shot usage, and improved thread-safety details.
Copy file name to clipboardExpand all lines: README.md
+3
Original file line number
Diff line number
Diff line change
@@ -10,6 +10,8 @@ TSignal is a lightweight, pure-Python signal/slot library that provides thread-s
10
10
-**Flexible Connection Types**: Direct or queued connections, automatically chosen based on the caller and callee threads.
11
11
-**Worker Thread Pattern**: Simplify background task execution with a built-in worker pattern that provides an event loop and task queue in a dedicated thread.
12
12
-**Familiar Decorators**: Inspired by Qt’s pattern, `@t_with_signals`, `@t_signal`, and `@t_slot` let you define signals and slots declaratively.
13
+
-**Weak Reference**:
14
+
- By setting `weak=True` when connecting a slot, the library holds a weak reference to the receiver object. This allows the receiver to be garbage-collected if there are no other strong references to it. Once garbage-collected, the connection is automatically removed, preventing stale references.
13
15
14
16
## Why TSignal?
15
17
@@ -100,6 +102,7 @@ asyncio.run(main())
100
102
### Thread Safety and Connection Types
101
103
TSignal automatically detects whether the signal emission and slot execution occur in the same thread or different threads:
102
104
105
+
-**Auto Connection**: When connection_type is AUTO_CONNECTION (default), TSignal checks whether the slot is a coroutine function or whether the caller and callee share the same thread affinity. If they are the same thread and slot is synchronous, it uses direct connection. Otherwise, it uses queued connection.
103
106
-**Direct Connection**: If signal and slot share the same thread affinity, the slot is invoked directly.
104
107
-**Queued Connection**: If they differ, the call is queued to the slot’s thread/event loop, ensuring thread safety.
Copy file name to clipboardExpand all lines: docs/api.md
+27-5
Original file line number
Diff line number
Diff line change
@@ -126,10 +126,12 @@ Represents a signal. Signals are created by `@t_signal` and accessed as class at
126
126
Connects the signal to a slot.
127
127
128
128
-**Parameters:**
129
-
- receiver_or_slot: Either the receiver object and slot method, or just a callable (function/lambda) if slot is None.
130
-
- slot: The method in the receiver if a receiver object is provided.
131
-
- connection_type: DIRECT_CONNECTION, QUEUED_CONNECTION, or AUTO_CONNECTION.
132
-
- AUTO_CONNECTION (default): Determines connection type automatically based on thread affinity and slot type.
129
+
-**receiver_or_slot:** Either the receiver object and slot method, or just a callable (function/lambda) if slot is None.
130
+
-**slot:** The method in the receiver if a receiver object is provided.
131
+
-**connection_type:** DIRECT_CONNECTION, QUEUED_CONNECTION, or AUTO_CONNECTION.
132
+
-**AUTO_CONNECTION (default):** Determines connection type automatically based on thread affinity and slot type.
133
+
-**weak:** If `True`, the receiver is kept via a weak reference so it can be garbage collected once there are no strong references. The signal automatically removes the connection if the receiver is collected.
134
+
-**one_shot:** If `True`, the connection is automatically disconnected after the first successful emit call. This is useful for events that should only notify a slot once.
133
135
134
136
**Examples:**
135
137
@@ -151,9 +153,29 @@ signal.connect(print)
151
153
152
154
Disconnects a previously connected slot. Returns the number of disconnected connections.
153
155
156
+
-**Parameters:**
157
+
- receiver: The object whose slot is connected. If receiver is None, all receivers are considered.
158
+
- slot: The specific slot to disconnect from the signal. If slot is None, all slots for the given receiver (or all connections if receiver is also None) are disconnected.
159
+
-**Returns:** The number of connections that were disconnected.-
160
+
161
+
**Examples:**
162
+
```python
163
+
# Disconnect all connections
164
+
signal.disconnect()
165
+
166
+
# Disconnect all slots from a specific receiver
167
+
signal.disconnect(receiver=my_receiver)
168
+
169
+
# Disconnect a specific slot from a specific receiver
Emits the signal, invoking all connected slots either directly or via the event loop of the slot’s associated thread.
178
+
Emits the signal, invoking all connected slots either directly or via the event loop of the slot’s associated thread, depending on the connection type. If a connection is marked one_shot, it is automatically removed right after invocation.
0 commit comments