Skip to content

Commit 8640a69

Browse files
committed
self review
1 parent 54526b9 commit 8640a69

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

src/reactpy/core/hooks.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,11 @@ def use_async_effect(
215215
shield:
216216
If ``True``, the effect will not be cancelled when the hook is running clean-up.
217217
This can be useful if you want to ensure that the effect runs to completion even if the
218-
component is unmounted while the effect is still running (e.g. a database query).
219-
However, use this option with caution as it can lead to memory leaks.
218+
component is unmounted while the effect is still running (e.g. a multi-step database query).
219+
220+
Use this option with caution as it can lead to memory leaks if a faulty effect
221+
stays alive indefinitely. If using this option, it is highly suggested to implement
222+
your own timeout within the effect to mitigate this risk.
220223
221224
Returns:
222225
If not function is provided, a decorator. Otherwise ``None``.

tests/test_core/test_events.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@ async def test_controlled_input_default_debounce_prefers_latest_client_value(
714714
display: DisplayFixture,
715715
):
716716
"""Prefer the latest client value for a controlled input when using debounce, even if the server is still processing an older event."""
717+
717718
@reactpy.component
718719
def ControlledInput():
719720
value, set_value = use_state("")

tests/test_reactjs/test_utils.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,38 @@ def test_copy_file_fallback(tmp_path):
190190
mock_rename.assert_called_once()
191191

192192

193+
def test_copy_file_symlink_falls_back_to_hard_link(tmp_path):
194+
source = tmp_path / "source.txt"
195+
source.write_text("content")
196+
target = tmp_path / "target.txt"
197+
198+
path_cls = type(target)
199+
200+
with patch.object(path_cls, "symlink_to", side_effect=OSError):
201+
with patch("os.link") as mock_link:
202+
copy_file(target, source, symlink=True)
203+
204+
mock_link.assert_called_once_with(source, target)
205+
206+
207+
def test_copy_file_symlink_fallback_reraises_original_error(tmp_path):
208+
source = tmp_path / "source.txt"
209+
source.write_text("content")
210+
target = tmp_path / "target.txt"
211+
212+
path_cls = type(target)
213+
symlink_error = OSError("symlink failed")
214+
hard_link_error = OSError("hard link failed")
215+
216+
with patch.object(path_cls, "symlink_to", side_effect=symlink_error):
217+
with patch("os.link", side_effect=hard_link_error):
218+
with pytest.raises(OSError) as exc_info:
219+
copy_file(target, source, symlink=True)
220+
221+
assert exc_info.value is symlink_error
222+
assert exc_info.value.__cause__ is hard_link_error
223+
224+
193225
def test_simple_file_lock_timeout(tmp_path):
194226
lock_file = tmp_path / "lock"
195227

0 commit comments

Comments
 (0)