Skip to content

Commit 115c865

Browse files
committed
Updated and cleaned up documentation
1 parent 5c807ae commit 115c865

File tree

3 files changed

+175
-80
lines changed

3 files changed

+175
-80
lines changed

README.md

+39-9
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,16 @@ from aio_stdout import IOLock, ainput, aprint
8181

8282
async def countdown(n: int) -> None:
8383
"""Count down from `n`, taking `n` seconds to run."""
84-
async with IOLock(n=5) as io_lock:
84+
async with IOLock(n=5) as lock:
8585
for i in range(n, 0, -1):
86-
await io_lock.aprint(i)
86+
await lock.aprint(i)
8787
await asyncio.sleep(1)
8888

8989
async def get_name() -> str:
9090
"""Ask the user for their name."""
91-
async with IOLock() as io_lock:
92-
name = await io_lock.ainput("What is your name? ")
93-
await io_lock.aprint(f"Your name is {name}.")
91+
async with IOLock() as lock:
92+
name = await lock.ainput("What is your name? ")
93+
await lock.aprint(f"Your name is {name}.")
9494
return name
9595

9696
async def main() -> None:
@@ -122,7 +122,7 @@ Your name is Jane.
122122
1
123123
```
124124

125-
Notice that this time the `countdown` does not immediately yield to the `get_name`. Instead, it runs 5 messages before yielding control over to `get_name`. Now, after the `ainput` finishes, it does not yield to `countdown`. Instead, it runs its own `aprint` first. In the meantime, `countdown` continues to run in the background and flushes all of its buffered messages afterwards.
125+
Notice that this time the `countdown` does not immediately yield to the `get_name`. Instead, it runs 5 messages before yielding control over to `get_name`. Now, after the `lock.ainput` finishes, it does not yield to `countdown`. Instead, it runs its own `lock.aprint` first. In the meantime, `countdown` continues to run in the background and flushes all of its buffered messages afterwards.
126126

127127
Flushing
128128
---------
@@ -132,13 +132,43 @@ Since messages may be delayed, it is possible for your asynchronous code to fini
132132
```python
133133
from aio_stdout import flush
134134

135+
@flush
135136
async def main() -> None:
136-
async with flush:
137-
pass
137+
...
138+
```
139+
140+
Final Example
141+
-------------
142+
143+
Combining all best practices, the final example should look something like this:
144+
145+
```python
146+
import asyncio
147+
from aio_stdout import IOLock, ainput, aprint, flush
148+
149+
async def countdown(n: int) -> None:
150+
"""Count down from `n`, taking `n` seconds to run."""
151+
for i in range(n, 0, -1):
152+
await aprint(i)
153+
await asyncio.sleep(1)
154+
155+
async def get_name() -> str:
156+
"""Ask the user for their name."""
157+
async with IOLock() as lock:
158+
name = await lock.ainput("What is your name? ")
159+
await lock.aprint(f"Your name is {name}.")
160+
return name
161+
162+
@flush
163+
async def main() -> None:
164+
await asyncio.gather(countdown(15), get_name())
165+
166+
if __name__ == "__main__":
167+
asyncio.run(main())
138168
```
139169

140170
Common Gotchas
141171
---------------
142172

143173
- Using `input` or `print` instead of `ainput` and `aprint` will push a message immediately to the console, potentially conflicting with `ainput` or `aprint`.
144-
- Using `ainput` or `aprint` instead of `io_lock.ainput` and `io_lock.aprint` may produce **deadlock** due to having to wait for the lock to release. As such, the `io_lock` is equipped with a default `timeout` limit of 10 seconds to avoid deadlock and explain to users this potential problem.
174+
- Using `ainput` or `aprint` instead of `lock.ainput` and `lock.aprint` may produce **deadlock** due to having to wait for the lock to release. As such, the `lock` is equipped with a default `timeout` limit of 10 seconds to avoid deadlock and explain to users this potential problem.

aio_stdout/__init__.py

+46-40
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,16 @@ async def main() -> None:
8484
8585
async def countdown(n: int) -> None:
8686
"""Count down from `n`, taking `n` seconds to run."""
87-
async with IOLock(n=5) as io_lock:
87+
async with IOLock(n=5) as lock:
8888
for i in range(n, 0, -1):
89-
await io_lock.aprint(i)
89+
await lock.aprint(i)
9090
await asyncio.sleep(1)
9191
9292
async def get_name() -> str:
9393
"""Ask the user for their name."""
94-
async with IOLock() as io_lock:
95-
name = await io_lock.ainput("What is your name? ")
96-
await io_lock.aprint(f"Your name is {name}.")
94+
async with IOLock() as lock:
95+
name = await lock.ainput("What is your name? ")
96+
await lock.aprint(f"Your name is {name}.")
9797
return name
9898
9999
async def main() -> None:
@@ -127,9 +127,9 @@ async def main() -> None:
127127
128128
Notice that this time the `countdown` does not immediately yield to
129129
the `get_name`. Instead, it runs 5 messages before yielding control
130-
over to `get_name`. Now, after the `ainput` finishes, it does not
131-
yield to `countdown`. Instead, it runs its own `aprint` first. In the
132-
meantime, `countdown` continues to run in the background and flushes
130+
over to `get_name`. Now, after the `lock.ainput` finishes, it does not
131+
yield to `countdown`. Instead, it runs its own `lock.aprint` first. In
132+
the meantime, `countdown` continues to run in the background and flushes
133133
all of its buffered messages afterwards.
134134
135135
Flushing
@@ -143,9 +143,40 @@ async def main() -> None:
143143
```python
144144
from aio_stdout import flush
145145
146+
@flush
146147
async def main() -> None:
147-
async with flush:
148-
pass
148+
...
149+
```
150+
151+
Final Example
152+
-------------
153+
154+
Combining all best practices, the final example should look something
155+
like this:
156+
157+
```python
158+
import asyncio
159+
from aio_stdout import IOLock, ainput, aprint, flush
160+
161+
async def countdown(n: int) -> None:
162+
"""Count down from `n`, taking `n` seconds to run."""
163+
for i in range(n, 0, -1):
164+
await aprint(i)
165+
await asyncio.sleep(1)
166+
167+
async def get_name() -> str:
168+
"""Ask the user for their name."""
169+
async with IOLock() as lock:
170+
name = await lock.ainput("What is your name? ")
171+
await lock.aprint(f"Your name is {name}.")
172+
return name
173+
174+
@flush
175+
async def main() -> None:
176+
await asyncio.gather(countdown(15), get_name())
177+
178+
if __name__ == "__main__":
179+
asyncio.run(main())
149180
```
150181
151182
Common Gotchas
@@ -154,40 +185,15 @@ async def main() -> None:
154185
- Using `input` or `print` instead of `ainput` and `aprint` will push
155186
a message immediately to the console, potentially conflicting with
156187
`ainput` or `aprint`.
157-
- Using `ainput` or `aprint` instead of `io_lock.ainput` and
158-
`io_lock.aprint` may produce **deadlock** due to having to
159-
wait for the lock to release. As such, the `io_lock` is equipped
188+
- Using `ainput` or `aprint` instead of `lock.ainput` and
189+
`lock.aprint` may produce **deadlock** due to having to
190+
wait for the lock to release. As such, the `lock` is equipped
160191
with a default `timeout` limit of 10 seconds to avoid deadlock
161192
and explain to users this potential problem.
162193
'''
163-
from types import FunctionType
164-
from typing import get_type_hints
165-
from ._aio_stdout import *
194+
from ._aio_stdout import IOLock, ainput, aprint, flush
166195

167196
__all__ = ["IOLock", "ainput", "aprint", "flush"]
168197
__author__ = "Jack Nguyen"
169198
__email__ = "[email protected]"
170-
__version__ = "0.0.2"
171-
172-
obj = None
173-
name = None
174-
method = None
175-
176-
# Finalize type-hints.
177-
for obj in (IOLock, ainput, aprint, flush):
178-
if isinstance(obj, FunctionType):
179-
obj.__annotations__ = get_type_hints(obj)
180-
if not isinstance(obj, type):
181-
continue
182-
obj.__annotations__ = get_type_hints(obj)
183-
for name, method in vars(obj).items():
184-
if isinstance(method, classmethod):
185-
method.__func__.__annotations__ = get_type_hints(method.__func__)
186-
elif callable(method):
187-
method.__annotations__ = get_type_hints(method)
188-
189-
del name
190-
del method
191-
del obj
192-
del get_type_hints
193-
del FunctionType
199+
__version__ = "0.0.3"

0 commit comments

Comments
 (0)