free-threading 1.0.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 freethreading contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,151 @@
1
+ Metadata-Version: 2.4
2
+ Name: free-threading
3
+ Version: 1.0.0
4
+ Summary: Thread-first true parallelism
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Keywords: gil,nogil,thread,process,worker,threading,free-threading,multithreading,multiprocessing,concurrency,parallelism
8
+ Author: Iskander Gaba
9
+ Author-email: iskander@hey.com
10
+ Requires-Python: >=3.10
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Project-URL: Documentation, https://freethreading.readthedocs.io
18
+ Project-URL: Repository, https://github.com/iskandergaba/freethreading
19
+ Description-Content-Type: text/markdown
20
+
21
+ <div align="center">
22
+
23
+ # freethreading — Thread-first true parallelism
24
+
25
+ [![PyPI Version](https://img.shields.io/pypi/v/freethreading.svg?label=PyPI)](https://pypi.org/project/freethreading/)
26
+ ![Python Version](https://img.shields.io/pypi/pyversions/freethreading?label=Python)
27
+ ![License](https://img.shields.io/pypi/l/freethreading?label=License)
28
+ [![CI Build](https://github.com/iskandergaba/freethreading/actions/workflows/ci.yml/badge.svg)](https://github.com/iskandergaba/freethreading/actions/workflows/ci.yml)
29
+ [![Codecov](https://codecov.io/gh/iskandergaba/freethreading/graph/badge.svg?token=LWBRgtlX8j)](https://codecov.io/gh/iskandergaba/freethreading)
30
+ [![Docs](https://readthedocs.org/projects/freethreading/badge/?version=latest)](https://freethreading.readthedocs.io/en/latest)
31
+
32
+ `freethreading` is a lightweight wrapper that provides a unified API for true parallel execution in Python. It
33
+ automatically uses `threading` on free-threaded Python builds (where the
34
+ [Global Interpreter Lock (GIL)](https://docs.python.org/3/glossary.html#term-global-interpreter-lock) is disabled) and
35
+ falls back to `multiprocessing` on standard ones. This enables true parallelism across Python versions while preferring the efficiency of [threads](https://en.wikipedia.org/wiki/Thread_(computing)) over
36
+ [processes](https://en.wikipedia.org/wiki/Process_(computing)) whenever possible.
37
+
38
+ </div>
39
+
40
+ ## Installation
41
+
42
+ To install `freethreading`, simply run:
43
+
44
+ ```shell
45
+ pip install free-threading
46
+ ```
47
+
48
+ To install the latest development version, you can run:
49
+
50
+ ```shell
51
+ pip install git+https://github.com/iskandergaba/free-threading.git
52
+ ```
53
+
54
+ ## Quick Start
55
+
56
+ `freethreading` is a drop-in replacement for *most* pre-existing `threading` and `multiprocessing` code. To achieve
57
+ this, the module exposes only non-deprecated common functionality shared between both backends while discarding any
58
+ backend-specific APIs. The following examples show how to get started.
59
+
60
+ `freethreading` remains consistent with the standard library, so wrapper classes work as drop-in replacements for those
61
+ used by `threading` and `multiprocessing`. Here's how they work:
62
+
63
+ ```python
64
+ # threading
65
+ from queue import Queue
66
+ from threading import Event, Lock
67
+
68
+ # multiprocessing
69
+ from multiprocessing import Event, Lock, Queue
70
+
71
+ # freethreading (replaces both)
72
+ from freethreading import Event, Lock, Queue
73
+ event = Event()
74
+ lock = Lock()
75
+ queue = Queue()
76
+ lock.acquire()
77
+ # True
78
+ event.set()
79
+ queue.put("data")
80
+ event.is_set()
81
+ # True
82
+ queue.get()
83
+ # 'data'
84
+ lock.release()
85
+ ```
86
+
87
+ `freethreading` functions merge as much functionality from both backends as possible to ensure consistent behavior
88
+ across backends and simplify adoption. Here's what that looks like:
89
+
90
+ ```python
91
+ # threading
92
+ from threading import enumerate, get_ident
93
+
94
+ # multiprocessing
95
+ from multiprocessing import active_children
96
+ from os import getpid
97
+
98
+ # freethreading (replaces both)
99
+ from freethreading import active_children, enumerate, get_ident
100
+ len(active_children()) # excludes current thread or process
101
+ # 0
102
+ len(enumerate()) # includes current thread or process
103
+ # 1
104
+ get_ident() # current thread or process identifier
105
+ # 140247834...
106
+ ```
107
+
108
+ Only `Worker`, `WorkerPool`, `WorkerPoolExecutor`, and `current_worker` differ from the standard library naming, using
109
+ "worker" as a term for both threads and processes. Here is an example:
110
+
111
+ ```python
112
+ # threading
113
+ from concurrent.futures import ThreadPoolExecutor
114
+ from threading import Thread, current_thread
115
+
116
+ # multiprocessing
117
+ from concurrent.futures import ProcessPoolExecutor
118
+ from multiprocessing import Process, current_process
119
+
120
+ # freethreading (replaces both)
121
+ from freethreading import Worker, WorkerPool, WorkerPoolExecutor, current_worker
122
+ current_worker().name
123
+ # 'MainThread' or 'MainProcess'
124
+
125
+ def task():
126
+ print(f"Hello from {current_worker().name}!")
127
+
128
+ # Using Worker (Thread or Process) to run a task
129
+ w = Worker(target=task, name="MyWorker")
130
+ w.start()
131
+ w.join()
132
+ # Hello from MyWorker!
133
+
134
+ # Using WorkerPool (Pool or ThreadPool) to distribute work
135
+ def square(x):
136
+ return x * x
137
+
138
+ with WorkerPool(workers=2) as pool:
139
+ print(pool.map(square, range(5)))
140
+ # [0, 1, 4, 9, 16]
141
+
142
+ # Using WorkerPoolExecutor (ThreadPoolExecutor or ProcessPoolExecutor) to run a task
143
+ with WorkerPoolExecutor(max_workers=2) as executor:
144
+ future = executor.submit(task)
145
+ # 'Hello from ThreadPoolExecutor-0_0!' or 'Hello from ForkProcess-2!'
146
+ ```
147
+
148
+ ## Documentation
149
+
150
+ For more details, check out the full documentation at [freethreading.readthedocs.io](https://freethreading.readthedocs.io).
151
+
@@ -0,0 +1,130 @@
1
+ <div align="center">
2
+
3
+ # freethreading — Thread-first true parallelism
4
+
5
+ [![PyPI Version](https://img.shields.io/pypi/v/freethreading.svg?label=PyPI)](https://pypi.org/project/freethreading/)
6
+ ![Python Version](https://img.shields.io/pypi/pyversions/freethreading?label=Python)
7
+ ![License](https://img.shields.io/pypi/l/freethreading?label=License)
8
+ [![CI Build](https://github.com/iskandergaba/freethreading/actions/workflows/ci.yml/badge.svg)](https://github.com/iskandergaba/freethreading/actions/workflows/ci.yml)
9
+ [![Codecov](https://codecov.io/gh/iskandergaba/freethreading/graph/badge.svg?token=LWBRgtlX8j)](https://codecov.io/gh/iskandergaba/freethreading)
10
+ [![Docs](https://readthedocs.org/projects/freethreading/badge/?version=latest)](https://freethreading.readthedocs.io/en/latest)
11
+
12
+ `freethreading` is a lightweight wrapper that provides a unified API for true parallel execution in Python. It
13
+ automatically uses `threading` on free-threaded Python builds (where the
14
+ [Global Interpreter Lock (GIL)](https://docs.python.org/3/glossary.html#term-global-interpreter-lock) is disabled) and
15
+ falls back to `multiprocessing` on standard ones. This enables true parallelism across Python versions while preferring the efficiency of [threads](https://en.wikipedia.org/wiki/Thread_(computing)) over
16
+ [processes](https://en.wikipedia.org/wiki/Process_(computing)) whenever possible.
17
+
18
+ </div>
19
+
20
+ ## Installation
21
+
22
+ To install `freethreading`, simply run:
23
+
24
+ ```shell
25
+ pip install free-threading
26
+ ```
27
+
28
+ To install the latest development version, you can run:
29
+
30
+ ```shell
31
+ pip install git+https://github.com/iskandergaba/free-threading.git
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ `freethreading` is a drop-in replacement for *most* pre-existing `threading` and `multiprocessing` code. To achieve
37
+ this, the module exposes only non-deprecated common functionality shared between both backends while discarding any
38
+ backend-specific APIs. The following examples show how to get started.
39
+
40
+ `freethreading` remains consistent with the standard library, so wrapper classes work as drop-in replacements for those
41
+ used by `threading` and `multiprocessing`. Here's how they work:
42
+
43
+ ```python
44
+ # threading
45
+ from queue import Queue
46
+ from threading import Event, Lock
47
+
48
+ # multiprocessing
49
+ from multiprocessing import Event, Lock, Queue
50
+
51
+ # freethreading (replaces both)
52
+ from freethreading import Event, Lock, Queue
53
+ event = Event()
54
+ lock = Lock()
55
+ queue = Queue()
56
+ lock.acquire()
57
+ # True
58
+ event.set()
59
+ queue.put("data")
60
+ event.is_set()
61
+ # True
62
+ queue.get()
63
+ # 'data'
64
+ lock.release()
65
+ ```
66
+
67
+ `freethreading` functions merge as much functionality from both backends as possible to ensure consistent behavior
68
+ across backends and simplify adoption. Here's what that looks like:
69
+
70
+ ```python
71
+ # threading
72
+ from threading import enumerate, get_ident
73
+
74
+ # multiprocessing
75
+ from multiprocessing import active_children
76
+ from os import getpid
77
+
78
+ # freethreading (replaces both)
79
+ from freethreading import active_children, enumerate, get_ident
80
+ len(active_children()) # excludes current thread or process
81
+ # 0
82
+ len(enumerate()) # includes current thread or process
83
+ # 1
84
+ get_ident() # current thread or process identifier
85
+ # 140247834...
86
+ ```
87
+
88
+ Only `Worker`, `WorkerPool`, `WorkerPoolExecutor`, and `current_worker` differ from the standard library naming, using
89
+ "worker" as a term for both threads and processes. Here is an example:
90
+
91
+ ```python
92
+ # threading
93
+ from concurrent.futures import ThreadPoolExecutor
94
+ from threading import Thread, current_thread
95
+
96
+ # multiprocessing
97
+ from concurrent.futures import ProcessPoolExecutor
98
+ from multiprocessing import Process, current_process
99
+
100
+ # freethreading (replaces both)
101
+ from freethreading import Worker, WorkerPool, WorkerPoolExecutor, current_worker
102
+ current_worker().name
103
+ # 'MainThread' or 'MainProcess'
104
+
105
+ def task():
106
+ print(f"Hello from {current_worker().name}!")
107
+
108
+ # Using Worker (Thread or Process) to run a task
109
+ w = Worker(target=task, name="MyWorker")
110
+ w.start()
111
+ w.join()
112
+ # Hello from MyWorker!
113
+
114
+ # Using WorkerPool (Pool or ThreadPool) to distribute work
115
+ def square(x):
116
+ return x * x
117
+
118
+ with WorkerPool(workers=2) as pool:
119
+ print(pool.map(square, range(5)))
120
+ # [0, 1, 4, 9, 16]
121
+
122
+ # Using WorkerPoolExecutor (ThreadPoolExecutor or ProcessPoolExecutor) to run a task
123
+ with WorkerPoolExecutor(max_workers=2) as executor:
124
+ future = executor.submit(task)
125
+ # 'Hello from ThreadPoolExecutor-0_0!' or 'Hello from ForkProcess-2!'
126
+ ```
127
+
128
+ ## Documentation
129
+
130
+ For more details, check out the full documentation at [freethreading.readthedocs.io](https://freethreading.readthedocs.io).
@@ -0,0 +1,52 @@
1
+ [build-system]
2
+ requires = ["poetry-core"]
3
+ build-backend = "poetry.core.masonry.api"
4
+
5
+ [project]
6
+ name = "free-threading"
7
+ version = "1.0.0"
8
+ description = "Thread-first true parallelism"
9
+ license = "MIT"
10
+ readme = "README.md"
11
+ authors = [
12
+ { name = "Iskander Gaba", email = "iskander@hey.com" },
13
+ ]
14
+ keywords = [
15
+ "gil",
16
+ "nogil",
17
+ "thread",
18
+ "process",
19
+ "worker",
20
+ "threading",
21
+ "free-threading",
22
+ "multithreading",
23
+ "multiprocessing",
24
+ "concurrency",
25
+ "parallelism",
26
+ ]
27
+ requires-python = ">=3.10"
28
+
29
+ [project.urls]
30
+ repository = "https://github.com/iskandergaba/freethreading"
31
+ documentation = "https://freethreading.readthedocs.io"
32
+
33
+ [dependency-groups]
34
+ dev = [
35
+ "ruff~=0.14.0",
36
+ "pytest~=9.0.0",
37
+ "pytest-cov~=7.0.0",
38
+ "sphinx-autobuild~=2024.10.0",
39
+ ]
40
+ docs = [
41
+ "sphinx-autoapi~=3.6.0",
42
+ "python-docs-theme~=2025.10"
43
+ ]
44
+
45
+ [tool.poetry]
46
+ packages = [{ include = "freethreading", from = "src" }]
47
+
48
+ [tool.uv.dependency-groups]
49
+ docs = { requires-python = ">=3.12" }
50
+
51
+ [tool.ruff.lint]
52
+ extend-select = ["E501"]