Skip to content

Commit fa1281a

Browse files
committed
fixes #811
1 parent 6ba21e6 commit fa1281a

5 files changed

Lines changed: 102 additions & 41 deletions

File tree

fastcore/parallel.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222
except: pass
2323

2424
# %% ../nbs/03a_parallel.ipynb #21e71104
25-
def threaded(process=False):
25+
def threaded(
26+
process=False, # Create a Process instead of a Thread?
27+
daemon=False # Use daemon mode?
28+
): # The Process or Thread created, which will have `result` attr injected in once complete
2629
"Run `f` in a `Thread` (or `Process` if `process=True`), and returns it"
2730
def _r(f):
2831
def g(_obj_td, *args, **kwargs):
@@ -33,6 +36,7 @@ def _f(*args, **kwargs):
3336
Proc = get_context('fork').Process if sys.platform == 'darwin' else Process
3437
res = (Thread,Proc)[process](target=g, args=args, kwargs=kwargs)
3538
res._args = (res,)+res._args
39+
if daemon: res.daemon = True
3640
res.start()
3741
return res
3842
return _f

nbs/03_xtras.ipynb

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,7 +1049,7 @@
10491049
{
10501050
"data": {
10511051
"text/plain": [
1052-
"'pip 26.0.1 from /Users/jhoward/aai-ws/.venv/lib/python3.12/site-packages/pip (python 3.12)'"
1052+
"'pip 26.1 from /Users/jhoward/aai-ws/.venv/lib/python3.12/site-packages/pip (python 3.12)'"
10531053
]
10541054
},
10551055
"execution_count": null,
@@ -1336,13 +1336,10 @@
13361336
{
13371337
"cell_type": "code",
13381338
"execution_count": null,
1339-
"id": "5c6c3416",
1339+
"id": "cc850566",
13401340
"metadata": {},
13411341
"outputs": [],
13421342
"source": [
1343-
"import tempfile\n",
1344-
"from fastcore.test import test_fail\n",
1345-
"\n",
13461343
"with tempfile.TemporaryDirectory() as tmpdir:\n",
13471344
" base = Path(tmpdir)\n",
13481345
" p1 = base/'test1'\n",
@@ -4926,7 +4923,16 @@
49264923
]
49274924
}
49284925
],
4929-
"metadata": {},
4926+
"metadata": {
4927+
"solveit": {
4928+
"default_code": false,
4929+
"mode": "learning",
4930+
"use_fence": false,
4931+
"use_thinking": true,
4932+
"use_tools": true,
4933+
"ver": 2
4934+
}
4935+
},
49304936
"nbformat": 4,
49314937
"nbformat_minor": 5
49324938
}

nbs/03a_parallel.ipynb

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@
6363
"outputs": [],
6464
"source": [
6565
"#| export\n",
66-
"def threaded(process=False):\n",
66+
"def threaded(\n",
67+
" process=False, # Create a Process instead of a Thread?\n",
68+
" daemon=False # Use daemon mode?\n",
69+
"): # The Process or Thread created, which will have `result` attr injected in once complete\n",
6770
" \"Run `f` in a `Thread` (or `Process` if `process=True`), and returns it\"\n",
6871
" def _r(f):\n",
6972
" def g(_obj_td, *args, **kwargs):\n",
@@ -74,6 +77,7 @@
7477
" Proc = get_context('fork').Process if sys.platform == 'darwin' else Process\n",
7578
" res = (Thread,Proc)[process](target=g, args=args, kwargs=kwargs)\n",
7679
" res._args = (res,)+res._args\n",
80+
" if daemon: res.daemon = True\n",
7781
" res.start()\n",
7882
" return res\n",
7983
" return _f\n",
@@ -146,6 +150,27 @@
146150
"a.result"
147151
]
148152
},
153+
{
154+
"cell_type": "markdown",
155+
"id": "fcd33a0d",
156+
"metadata": {},
157+
"source": [
158+
"Pass `daemon=True` to make the thread (or process) a daemon, so it won't prevent the parent from exiting. Useful for background services like webservers, where you don't want a still-running thread to block process shutdown."
159+
]
160+
},
161+
{
162+
"cell_type": "code",
163+
"execution_count": null,
164+
"id": "87ba1a19",
165+
"metadata": {},
166+
"outputs": [],
167+
"source": [
168+
"@threaded(daemon=True)\n",
169+
"def f(): time.sleep(0.01)\n",
170+
"\n",
171+
"assert f().daemon"
172+
]
173+
},
149174
{
150175
"cell_type": "code",
151176
"execution_count": null,
@@ -169,7 +194,13 @@
169194
"name": "stdout",
170195
"output_type": "stream",
171196
"text": [
172-
"first\n",
197+
"first\n"
198+
]
199+
},
200+
{
201+
"name": "stdout",
202+
"output_type": "stream",
203+
"text": [
173204
"second\n"
174205
]
175206
}
@@ -342,9 +373,7 @@
342373
"def ThreadPoolExecutor(\n",
343374
" max_workers:int=16, on_exc:builtin_function_or_method=print, pause:int=0, kwargs:VAR_KEYWORD\n",
344375
"):\n",
345-
"\"\"\"\n",
346-
"Same as Python's ThreadPoolExecutor, except can pass `max_workers==0` for serial execution\n",
347-
"\"\"\""
376+
"\"\"\"Same as Python's ThreadPoolExecutor, except can pass `max_workers==0` for serial execution\"\"\""
348377
]
349378
},
350379
"execution_count": null,
@@ -419,9 +448,7 @@
419448
" max_workers:int=16, on_exc:builtin_function_or_method=print, pause:int=0, mp_context:NoneType=None,\n",
420449
" initializer:NoneType=None, initargs:tuple=(), max_tasks_per_child:NoneType=None\n",
421450
"):\n",
422-
"\"\"\"\n",
423-
"Same as Python's ProcessPoolExecutor, except can pass `max_workers==0` for serial execution\n",
424-
"\"\"\""
451+
"\"\"\"Same as Python's ProcessPoolExecutor, except can pass `max_workers==0` for serial execution\"\"\""
425452
]
426453
},
427454
"execution_count": null,
@@ -543,7 +570,7 @@
543570
"name": "stdout",
544571
"output_type": "stream",
545572
"text": [
546-
"2026-03-09 17:02:02.475188"
573+
"2026-05-02 06:18:54.278913"
547574
]
548575
},
549576
{
@@ -571,7 +598,7 @@
571598
"name": "stdout",
572599
"output_type": "stream",
573600
"text": [
574-
"2026-03-09 17:02:02.575907"
601+
"2026-05-02 06:18:54.380686"
575602
]
576603
},
577604
{
@@ -599,7 +626,7 @@
599626
"name": "stdout",
600627
"output_type": "stream",
601628
"text": [
602-
"2026-03-09 17:02:02.677131"
629+
"2026-05-02 06:18:54.481676"
603630
]
604631
},
605632
{
@@ -627,7 +654,7 @@
627654
"name": "stdout",
628655
"output_type": "stream",
629656
"text": [
630-
"2026-03-09 17:02:02.778713"
657+
"2026-05-02 06:18:54.584016"
631658
]
632659
},
633660
{
@@ -655,7 +682,7 @@
655682
"name": "stdout",
656683
"output_type": "stream",
657684
"text": [
658-
"2026-03-09 17:02:02.880124"
685+
"2026-05-02 06:18:54.684495"
659686
]
660687
},
661688
{
@@ -733,12 +760,12 @@
733760
"name": "stdout",
734761
"output_type": "stream",
735762
"text": [
736-
"1 2026-03-09 17:04:29.973713 2026-03-09 17:04:29.980911 0.006317305978820205\n",
737-
"2 2026-03-09 17:04:29.973734 2026-03-09 17:04:29.985213 0.010986495373929654\n",
738-
"0 2026-03-09 17:04:29.973659 2026-03-09 17:04:30.001349 0.02660853512134027\n",
739-
"5 2026-03-09 17:04:30.001397 2026-03-09 17:04:30.009049 0.006747053859902045\n",
740-
"3 2026-03-09 17:04:29.981235 2026-03-09 17:04:30.009845 0.028491947602613043\n",
741-
"4 2026-03-09 17:04:29.985275 2026-03-09 17:04:30.012762 0.027138033640580195\n"
763+
"0 2026-05-02 06:18:54.863372 2026-05-02 06:18:54.879976 0.015635678708191197\n",
764+
"1 2026-05-02 06:18:54.863397 2026-05-02 06:18:54.882997 0.019249022668796727\n",
765+
"2 2026-05-02 06:18:54.863403 2026-05-02 06:18:54.887730 0.023758669309642773\n",
766+
"3 2026-05-02 06:18:54.880132 2026-05-02 06:18:54.900268 0.01907637860895647\n",
767+
"4 2026-05-02 06:18:54.883061 2026-05-02 06:18:54.900419 0.01732184794923949\n",
768+
"5 2026-05-02 06:18:54.887778 2026-05-02 06:18:54.903026 0.014917916227832732\n"
742769
]
743770
}
744771
],
@@ -770,24 +797,31 @@
770797
"name": "stdout",
771798
"output_type": "stream",
772799
"text": [
773-
"0 2026-03-09 17:04:31.418755 2026-03-09 17:04:31.432981 0.013117748051221312\n",
774-
"1 2026-03-09 17:04:31.519680 2026-03-09 17:04:31.536720 0.016248614341927096\n"
800+
"0 2026-05-02 06:18:54.926304 2026-05-02 06:18:54.943307 0.015931215772872948\n",
801+
"1 2026-05-02 06:18:55.027303 2026-05-02 06:18:55.033705 0.005639884521666661\n"
775802
]
776803
},
777804
{
778805
"name": "stdout",
779806
"output_type": "stream",
780807
"text": [
781-
"2 2026-03-09 17:04:31.619834 2026-03-09 17:04:31.637578 0.01662938067120506\n",
782-
"3 2026-03-09 17:04:31.719084 2026-03-09 17:04:31.747357 0.02714251612256462\n"
808+
"2"
783809
]
784810
},
785811
{
786812
"name": "stdout",
787813
"output_type": "stream",
788814
"text": [
789-
"4 2026-03-09 17:04:31.819673 2026-03-09 17:04:31.838811 0.017785103040610917\n",
790-
"5 2026-03-09 17:04:31.919186 2026-03-09 17:04:31.940911 0.020535072775403555\n"
815+
" 2026-05-02 06:18:55.127385 2026-05-02 06:18:55.144286 0.01569178427437135\n",
816+
"3 2026-05-02 06:18:55.227448 2026-05-02 06:18:55.257822 0.02922957194858668\n",
817+
"4 2026-05-02 06:18:55.327466 2026-05-02 06:18:55.337080 0.008768163173784578\n"
818+
]
819+
},
820+
{
821+
"name": "stdout",
822+
"output_type": "stream",
823+
"text": [
824+
"5 2026-05-02 06:18:55.427390 2026-05-02 06:18:55.456955 0.028371390226150824\n"
791825
]
792826
}
793827
],
@@ -1050,7 +1084,16 @@
10501084
]
10511085
}
10521086
],
1053-
"metadata": {},
1087+
"metadata": {
1088+
"solveit": {
1089+
"default_code": false,
1090+
"mode": "concise",
1091+
"use_fence": false,
1092+
"use_thinking": true,
1093+
"use_tools": true,
1094+
"ver": 2
1095+
}
1096+
},
10541097
"nbformat": 4,
10551098
"nbformat_minor": 5
10561099
}

nbs/04_docments.ipynb

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@
5252
"source": [
5353
"#| hide\n",
5454
"from nbdev.showdoc import *\n",
55-
"from fastcore.test import *"
55+
"from fastcore.test import *\n",
56+
"from functools import wraps"
5657
]
5758
},
5859
{
@@ -2725,9 +2726,7 @@
27252726
"outputs": [],
27262727
"source": [
27272728
"#| hide\n",
2728-
"# Test: plain @wraps (no __signature__) — should unwrap to get original's docments\n",
2729-
"from functools import wraps\n",
2730-
"\n",
2729+
"# Plain @wraps (no __signature__) — should unwrap to get original's docments\n",
27312730
"def _orig_fn(\n",
27322731
" x:int, # The x value\n",
27332732
" y:str='hi', # The y value\n",
@@ -2753,7 +2752,7 @@
27532752
"outputs": [],
27542753
"source": [
27552754
"#| hide\n",
2756-
"# Test: async wrapper with __signature__ — should show async def, not unwrap\n",
2755+
"# Async wrapper with __signature__ — should show async def, not unwrap\n",
27572756
"def _async_wrapper(f):\n",
27582757
" @wraps(f)\n",
27592758
" async def wrapper(*args, **kwargs): return f(*args, **kwargs)\n",
@@ -2773,7 +2772,7 @@
27732772
"outputs": [],
27742773
"source": [
27752774
"#| hide\n",
2776-
"# Test: wrapper with custom __signature__ — should respect it\n",
2775+
"# Wrapper with custom __signature__ — should respect it\n",
27772776
"def _custom_wrapper(f):\n",
27782777
" @wraps(f)\n",
27792778
" def wrapper(*args, **kwargs): return f(*args, **kwargs)\n",
@@ -2850,7 +2849,16 @@
28502849
]
28512850
}
28522851
],
2853-
"metadata": {},
2852+
"metadata": {
2853+
"solveit": {
2854+
"default_code": false,
2855+
"mode": "learning",
2856+
"use_fence": false,
2857+
"use_thinking": true,
2858+
"use_tools": true,
2859+
"ver": 2
2860+
}
2861+
},
28542862
"nbformat": 4,
28552863
"nbformat_minor": 5
28562864
}

nbs/nbdev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ website:
66
site-url: "https://fastcore.fast.ai/"
77
description: "Python supercharged for fastai development"
88
repo-branch: main
9-
repo-url: "https://github.com/AnswerDotAI/fastcore/"
9+
repo-url: "https://github.com/AnswerDotAI/fastcore"

0 commit comments

Comments
 (0)