summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--python-asyncgui.spec480
-rw-r--r--sources1
3 files changed, 482 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..1e6710d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/asyncgui-0.5.5.tar.gz
diff --git a/python-asyncgui.spec b/python-asyncgui.spec
new file mode 100644
index 0000000..7a8f9f8
--- /dev/null
+++ b/python-asyncgui.spec
@@ -0,0 +1,480 @@
+%global _empty_manifest_terminate_build 0
+Name: python-asyncgui
+Version: 0.5.5
+Release: 1
+Summary: async/await without event-loop
+License: MIT
+URL: https://github.com/gottadiveintopython/asyncgui
+Source0: https://mirrors.aliyun.com/pypi/web/packages/e8/2a/2049a49aee3a1ef19385e5ca8da7420f07034014a1b1f9912a17ab41d6db/asyncgui-0.5.5.tar.gz
+BuildArch: noarch
+
+
+%description
+# AsyncGui
+
+A thin layer that helps to build an async/await-based api using a callback-based api.
+
+## How to use
+
+Despite its name, `asyncgui` has nothing to do with gui.
+You can wrap any kind of callback-based api in it.
+The simplest example of it would be [sched](https://docs.python.org/3/library/sched.html),
+whose the whole feature is a timer.
+All you need is just few lines of code:
+
+```python
+import types
+import sched
+import asyncgui
+
+s = sched.scheduler()
+
+# wrapping 'scheduler.enter()' takes only three lines
+@types.coroutine
+def sleep(duration):
+ yield lambda step_coro: s.enter(duration, 10, step_coro)
+
+
+async def main():
+ print('A')
+ await sleep(1) # Now you can sleep in an async-manner
+ print('B')
+ await sleep(1)
+ print('C')
+
+asyncgui.start(main())
+s.run()
+```
+
+And you already have structured concurrency apis as well:
+
+```python
+async def print_numbers():
+ for i in range(10):
+ await sleep(.1)
+ print(i)
+
+
+async def print_letters():
+ for c in "ABCDE":
+ await sleep(.1)
+ print(c)
+
+
+async def main():
+ from asyncgui.structured_concurrency import or_
+ # Let print_letters() and print_numbers() race.
+ # As soon as one of them finishes, the other one gets cancelled.
+ tasks = await or_(print_letters(), print_numbers())
+ if tasks[0].done:
+ print("print_letters() won")
+ else:
+ print("print_numbers() won")
+ print('main end')
+```
+
+```
+A
+0
+B
+1
+C
+2
+D
+3
+E
+print_letters() won
+main end
+```
+
+## Why not asyncio ?
+
+The above example may not attract you because you can just replace `sched` with [asyncio](https://docs.python.org/3/library/asyncio.html) or [Trio](https://trio.readthedocs.io/en/stable/),
+and can use thier sleep function (`asyncio.sleep` and `trio.sleep`).
+But in a read-world situation, that might not be an option:
+Kivy required [massive changes](https://github.com/kivy/kivy/pull/6368) in order to adapt to `asyncio` and `Trio`,
+[asyncio-tkinter](https://github.com/fluentpython/asyncio-tkinter)'s codebase is quite big as well.
+
+The reason they needed lots of work is that they had to merge two event-loops into one.
+One is from the gui libraries. The other one is from async libraries.
+You cannot just simply run multiple event-loops simultaneously in one thread.
+
+On the other hand, `asyncgui` doesn't require a lot of work as shown above **because it doesn't have an event-loop**.
+`asyncgui` and a library who has an event-loop can live in the same thread seemlessly because of it.
+
+## So, is asyncgui superior to asyncio ?
+
+No, it is not.
+For `asyncgui`, many features that exist in `asyncio` are either impossible or hard to implement because of the lack of event-loop.
+The implementation of those features needs to be specific to the event-loop you are using.
+You've already witnessed one, the `sleep`.
+
+## asyncgui is not usefull then.
+
+There is at least one situation that `asyncgui` shines.
+When you are creating a gui app, you probably want the app to quickly react to the gui events, like pressing a button.
+This is problematic for `asyncio` because it cannot immediately start/resume a task.
+It can schedule a task to *eventually* start/resume but not *immediate*,
+which causes to [spill gui events](https://github.com/gottadiveintopython/asynckivy/blob/main/examples/misc/why_asyncio_is_not_suitable_for_handling_touch_events.py).
+As a result, you need to use callback-based apis for that, and thus you cannot fully receive the benefits of async/await.
+
+If you use `asyncgui`, that never happens because:
+
+- `asyncgui.start()` immediately starts a task.
+- `asyncgui.Event.set()` immediately resumes the tasks waiting for it to happen.
+
+In summary, if your program needs to react to something immediately, `asyncgui` is for you.
+Otherwise, it's probably not worth it.
+
+## Installation
+
+It's recommended to pin the minor version, because if it changed, it means some *important* breaking changes occurred.
+
+```text
+poetry add asyncgui@~0.5
+pip install "asyncgui>=0.5,<0.6"
+```
+
+## Tested on
+
+- CPython 3.7
+- CPython 3.8
+- CPython 3.9
+- CPython 3.10
+
+## Async-libraries who relies on this
+
+- [asynckivy](https://github.com/gottadiveintopython/asynckivy)
+- [asynctkinter](https://github.com/gottadiveintopython/asynctkinter)
+
+
+%package -n python3-asyncgui
+Summary: async/await without event-loop
+Provides: python-asyncgui
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-asyncgui
+# AsyncGui
+
+A thin layer that helps to build an async/await-based api using a callback-based api.
+
+## How to use
+
+Despite its name, `asyncgui` has nothing to do with gui.
+You can wrap any kind of callback-based api in it.
+The simplest example of it would be [sched](https://docs.python.org/3/library/sched.html),
+whose the whole feature is a timer.
+All you need is just few lines of code:
+
+```python
+import types
+import sched
+import asyncgui
+
+s = sched.scheduler()
+
+# wrapping 'scheduler.enter()' takes only three lines
+@types.coroutine
+def sleep(duration):
+ yield lambda step_coro: s.enter(duration, 10, step_coro)
+
+
+async def main():
+ print('A')
+ await sleep(1) # Now you can sleep in an async-manner
+ print('B')
+ await sleep(1)
+ print('C')
+
+asyncgui.start(main())
+s.run()
+```
+
+And you already have structured concurrency apis as well:
+
+```python
+async def print_numbers():
+ for i in range(10):
+ await sleep(.1)
+ print(i)
+
+
+async def print_letters():
+ for c in "ABCDE":
+ await sleep(.1)
+ print(c)
+
+
+async def main():
+ from asyncgui.structured_concurrency import or_
+ # Let print_letters() and print_numbers() race.
+ # As soon as one of them finishes, the other one gets cancelled.
+ tasks = await or_(print_letters(), print_numbers())
+ if tasks[0].done:
+ print("print_letters() won")
+ else:
+ print("print_numbers() won")
+ print('main end')
+```
+
+```
+A
+0
+B
+1
+C
+2
+D
+3
+E
+print_letters() won
+main end
+```
+
+## Why not asyncio ?
+
+The above example may not attract you because you can just replace `sched` with [asyncio](https://docs.python.org/3/library/asyncio.html) or [Trio](https://trio.readthedocs.io/en/stable/),
+and can use thier sleep function (`asyncio.sleep` and `trio.sleep`).
+But in a read-world situation, that might not be an option:
+Kivy required [massive changes](https://github.com/kivy/kivy/pull/6368) in order to adapt to `asyncio` and `Trio`,
+[asyncio-tkinter](https://github.com/fluentpython/asyncio-tkinter)'s codebase is quite big as well.
+
+The reason they needed lots of work is that they had to merge two event-loops into one.
+One is from the gui libraries. The other one is from async libraries.
+You cannot just simply run multiple event-loops simultaneously in one thread.
+
+On the other hand, `asyncgui` doesn't require a lot of work as shown above **because it doesn't have an event-loop**.
+`asyncgui` and a library who has an event-loop can live in the same thread seemlessly because of it.
+
+## So, is asyncgui superior to asyncio ?
+
+No, it is not.
+For `asyncgui`, many features that exist in `asyncio` are either impossible or hard to implement because of the lack of event-loop.
+The implementation of those features needs to be specific to the event-loop you are using.
+You've already witnessed one, the `sleep`.
+
+## asyncgui is not usefull then.
+
+There is at least one situation that `asyncgui` shines.
+When you are creating a gui app, you probably want the app to quickly react to the gui events, like pressing a button.
+This is problematic for `asyncio` because it cannot immediately start/resume a task.
+It can schedule a task to *eventually* start/resume but not *immediate*,
+which causes to [spill gui events](https://github.com/gottadiveintopython/asynckivy/blob/main/examples/misc/why_asyncio_is_not_suitable_for_handling_touch_events.py).
+As a result, you need to use callback-based apis for that, and thus you cannot fully receive the benefits of async/await.
+
+If you use `asyncgui`, that never happens because:
+
+- `asyncgui.start()` immediately starts a task.
+- `asyncgui.Event.set()` immediately resumes the tasks waiting for it to happen.
+
+In summary, if your program needs to react to something immediately, `asyncgui` is for you.
+Otherwise, it's probably not worth it.
+
+## Installation
+
+It's recommended to pin the minor version, because if it changed, it means some *important* breaking changes occurred.
+
+```text
+poetry add asyncgui@~0.5
+pip install "asyncgui>=0.5,<0.6"
+```
+
+## Tested on
+
+- CPython 3.7
+- CPython 3.8
+- CPython 3.9
+- CPython 3.10
+
+## Async-libraries who relies on this
+
+- [asynckivy](https://github.com/gottadiveintopython/asynckivy)
+- [asynctkinter](https://github.com/gottadiveintopython/asynctkinter)
+
+
+%package help
+Summary: Development documents and examples for asyncgui
+Provides: python3-asyncgui-doc
+%description help
+# AsyncGui
+
+A thin layer that helps to build an async/await-based api using a callback-based api.
+
+## How to use
+
+Despite its name, `asyncgui` has nothing to do with gui.
+You can wrap any kind of callback-based api in it.
+The simplest example of it would be [sched](https://docs.python.org/3/library/sched.html),
+whose the whole feature is a timer.
+All you need is just few lines of code:
+
+```python
+import types
+import sched
+import asyncgui
+
+s = sched.scheduler()
+
+# wrapping 'scheduler.enter()' takes only three lines
+@types.coroutine
+def sleep(duration):
+ yield lambda step_coro: s.enter(duration, 10, step_coro)
+
+
+async def main():
+ print('A')
+ await sleep(1) # Now you can sleep in an async-manner
+ print('B')
+ await sleep(1)
+ print('C')
+
+asyncgui.start(main())
+s.run()
+```
+
+And you already have structured concurrency apis as well:
+
+```python
+async def print_numbers():
+ for i in range(10):
+ await sleep(.1)
+ print(i)
+
+
+async def print_letters():
+ for c in "ABCDE":
+ await sleep(.1)
+ print(c)
+
+
+async def main():
+ from asyncgui.structured_concurrency import or_
+ # Let print_letters() and print_numbers() race.
+ # As soon as one of them finishes, the other one gets cancelled.
+ tasks = await or_(print_letters(), print_numbers())
+ if tasks[0].done:
+ print("print_letters() won")
+ else:
+ print("print_numbers() won")
+ print('main end')
+```
+
+```
+A
+0
+B
+1
+C
+2
+D
+3
+E
+print_letters() won
+main end
+```
+
+## Why not asyncio ?
+
+The above example may not attract you because you can just replace `sched` with [asyncio](https://docs.python.org/3/library/asyncio.html) or [Trio](https://trio.readthedocs.io/en/stable/),
+and can use thier sleep function (`asyncio.sleep` and `trio.sleep`).
+But in a read-world situation, that might not be an option:
+Kivy required [massive changes](https://github.com/kivy/kivy/pull/6368) in order to adapt to `asyncio` and `Trio`,
+[asyncio-tkinter](https://github.com/fluentpython/asyncio-tkinter)'s codebase is quite big as well.
+
+The reason they needed lots of work is that they had to merge two event-loops into one.
+One is from the gui libraries. The other one is from async libraries.
+You cannot just simply run multiple event-loops simultaneously in one thread.
+
+On the other hand, `asyncgui` doesn't require a lot of work as shown above **because it doesn't have an event-loop**.
+`asyncgui` and a library who has an event-loop can live in the same thread seemlessly because of it.
+
+## So, is asyncgui superior to asyncio ?
+
+No, it is not.
+For `asyncgui`, many features that exist in `asyncio` are either impossible or hard to implement because of the lack of event-loop.
+The implementation of those features needs to be specific to the event-loop you are using.
+You've already witnessed one, the `sleep`.
+
+## asyncgui is not usefull then.
+
+There is at least one situation that `asyncgui` shines.
+When you are creating a gui app, you probably want the app to quickly react to the gui events, like pressing a button.
+This is problematic for `asyncio` because it cannot immediately start/resume a task.
+It can schedule a task to *eventually* start/resume but not *immediate*,
+which causes to [spill gui events](https://github.com/gottadiveintopython/asynckivy/blob/main/examples/misc/why_asyncio_is_not_suitable_for_handling_touch_events.py).
+As a result, you need to use callback-based apis for that, and thus you cannot fully receive the benefits of async/await.
+
+If you use `asyncgui`, that never happens because:
+
+- `asyncgui.start()` immediately starts a task.
+- `asyncgui.Event.set()` immediately resumes the tasks waiting for it to happen.
+
+In summary, if your program needs to react to something immediately, `asyncgui` is for you.
+Otherwise, it's probably not worth it.
+
+## Installation
+
+It's recommended to pin the minor version, because if it changed, it means some *important* breaking changes occurred.
+
+```text
+poetry add asyncgui@~0.5
+pip install "asyncgui>=0.5,<0.6"
+```
+
+## Tested on
+
+- CPython 3.7
+- CPython 3.8
+- CPython 3.9
+- CPython 3.10
+
+## Async-libraries who relies on this
+
+- [asynckivy](https://github.com/gottadiveintopython/asynckivy)
+- [asynctkinter](https://github.com/gottadiveintopython/asynctkinter)
+
+
+%prep
+%autosetup -n asyncgui-0.5.5
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "\"/%h/%f\"\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "\"/%h/%f\"\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "\"/%h/%f\"\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "\"/%h/%f\"\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "\"/%h/%f.gz\"\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-asyncgui -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Tue Jun 20 2023 Python_Bot <Python_Bot@openeuler.org> - 0.5.5-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..91538e5
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+106b3c5e12e8903a929a41f21c09a832 asyncgui-0.5.5.tar.gz