From njs at pobox.com Thu Aug 16 03:01:52 2018 From: njs at pobox.com (Nathaniel Smith) Date: Thu, 16 Aug 2018 00:01:52 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= Message-ID: Hi all, A number of people are working on packages that support multiple async backends (e.g., asyncio + trio, or trio + curio, or trio + twisted, ...). So then the question arises... how can I figure out which async library my user is actually using? Answer: install sniffio, and then call sniffio.current_async_library(), and it tells you. Well, right now it only works for trio and asyncio, but if you maintain an async library and you want to make it easier for packages to detect you, then it's easy to add support ? see the manual. We considered various clever things, but ultimately decided that the best approach was to use a ContextVar and make it the coroutine runner's responsibility to advertise which async flavor it uses. In particular, this approach works even for hybrid programs that are using multiple coroutine runners in the same loop, like a Twisted program with asyncio-flavored and twisted-flavored coroutines in the same thread, or a Trio program using trio-asyncio to run both asyncio-flavored and trio-flavored coroutines in the same thread. Github: https://github.com/python-trio/sniffio Manual: https://sniffio.readthedocs.io/ PyPI: https://pypi.org/p/sniffio -n -- Nathaniel J. Smith -- https://vorpus.org From guido at python.org Thu Aug 16 03:31:38 2018 From: guido at python.org (Guido van Rossum) Date: Thu, 16 Aug 2018 09:31:38 +0200 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: Neat! On Thu, Aug 16, 2018 at 9:02 AM Nathaniel Smith wrote: > Hi all, > > A number of people are working on packages that support multiple async > backends (e.g., asyncio + trio, or trio + curio, or trio + twisted, > ...). So then the question arises... how can I figure out which async > library my user is actually using? > > Answer: install sniffio, and then call > sniffio.current_async_library(), and it tells you. > > Well, right now it only works for trio and asyncio, but if you > maintain an async library and you want to make it easier for packages > to detect you, then it's easy to add support ? see the manual. We > considered various clever things, but ultimately decided that the best > approach was to use a ContextVar and make it the coroutine runner's > responsibility to advertise which async flavor it uses. In particular, > this approach works even for hybrid programs that are using multiple > coroutine runners in the same loop, like a Twisted program with > asyncio-flavored and twisted-flavored coroutines in the same thread, > or a Trio program using trio-asyncio to run both asyncio-flavored and > trio-flavored coroutines in the same thread. > > Github: https://github.com/python-trio/sniffio > Manual: https://sniffio.readthedocs.io/ > PyPI: https://pypi.org/p/sniffio > > -n > > -- > Nathaniel J. Smith -- https://vorpus.org > _______________________________________________ > Async-sig mailing list > Async-sig at python.org > https://mail.python.org/mailman/listinfo/async-sig > Code of Conduct: https://www.python.org/psf/codeofconduct/ > -- --Guido (mobile) -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.gronholm at nextday.fi Fri Aug 17 12:09:10 2018 From: alex.gronholm at nextday.fi (Alex =?ISO-8859-1?Q?Gr=F6nholm?=) Date: Fri, 17 Aug 2018 19:09:10 +0300 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: This was my approach: def _detect_running_asynclib() -> str: if 'trio' in sys.modules: from trio.hazmat import current_trio_token try: current_trio_token() except RuntimeError: pass else: return 'trio' if 'curio' in sys.modules: from curio.meta import curio_running if curio_running(): return 'curio' if 'asyncio' in sys.modules: from .backends.asyncio import get_running_loop if get_running_loop() is not None: return 'asyncio' raise LookupError('Cannot find any running async event loop') Is there something wrong with this? to, 2018-08-16 kello 00:01 -0700, Nathaniel Smith kirjoitti: > Hi all, > A number of people are working on packages that support multiple > asyncbackends (e.g., asyncio + trio, or trio + curio, or trio + > twisted,...). So then the question arises... how can I figure out > which asynclibrary my user is actually using? > Answer: install sniffio, and then > callsniffio.current_async_library(), and it tells you. > Well, right now it only works for trio and asyncio, but if > youmaintain an async library and you want to make it easier for > packagesto detect you, then it's easy to add support ? see the > manual. Weconsidered various clever things, but ultimately decided > that the bestapproach was to use a ContextVar and make it the > coroutine runner'sresponsibility to advertise which async flavor it > uses. In particular,this approach works even for hybrid programs that > are using multiplecoroutine runners in the same loop, like a Twisted > program withasyncio-flavored and twisted-flavored coroutines in the > same thread,or a Trio program using trio-asyncio to run both asyncio- > flavored andtrio-flavored coroutines in the same thread. > Github: https://github.com/python-trio/sniffioManual: > https://sniffio.readthedocs.io/PyPI: https://pypi.org/p/sniffio > -n > -------------- next part -------------- An HTML attachment was scrubbed... URL: From brett at python.org Fri Aug 17 12:26:24 2018 From: brett at python.org (Brett Cannon) Date: Fri, 17 Aug 2018 09:26:24 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: Importation does not equate to execution. I.e. since I could have multiple event loops running at once that means what's in sys.modules can't tell me what event loop I'm currently interacting with. On Fri, 17 Aug 2018 at 09:09 Alex Gr?nholm wrote: > This was my approach: > > def _detect_running_asynclib() -> str: > if 'trio' in sys.modules: > from trio.hazmat import current_trio_token > try: > current_trio_token() > except RuntimeError: > pass > else: > return 'trio' > > if 'curio' in sys.modules: > from curio.meta import curio_running > if curio_running(): > return 'curio' > > if 'asyncio' in sys.modules: > from .backends.asyncio import get_running_loop > if get_running_loop() is not None: > return 'asyncio' > > raise LookupError('Cannot find any running async event loop') > > > Is there something wrong with this? > > to, 2018-08-16 kello 00:01 -0700, Nathaniel Smith kirjoitti: > > Hi all, > > > A number of people are working on packages that support multiple async > > backends (e.g., asyncio + trio, or trio + curio, or trio + twisted, > > ...). So then the question arises... how can I figure out which async > > library my user is actually using? > > > Answer: install sniffio, and then call > > sniffio.current_async_library(), and it tells you. > > > Well, right now it only works for trio and asyncio, but if you > > maintain an async library and you want to make it easier for packages > > to detect you, then it's easy to add support ? see the manual. We > > considered various clever things, but ultimately decided that the best > > approach was to use a ContextVar and make it the coroutine runner's > > responsibility to advertise which async flavor it uses. In particular, > > this approach works even for hybrid programs that are using multiple > > coroutine runners in the same loop, like a Twisted program with > > asyncio-flavored and twisted-flavored coroutines in the same thread, > > or a Trio program using trio-asyncio to run both asyncio-flavored and > > trio-flavored coroutines in the same thread. > > > Github: https://github.com/python-trio/sniffio > > Manual: https://sniffio.readthedocs.io/ > > PyPI: https://pypi.org/p/sniffio > > > -n > > > > _______________________________________________ > Async-sig mailing list > Async-sig at python.org > https://mail.python.org/mailman/listinfo/async-sig > Code of Conduct: https://www.python.org/psf/codeofconduct/ > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.gronholm at nextday.fi Fri Aug 17 14:54:58 2018 From: alex.gronholm at nextday.fi (Alex =?ISO-8859-1?Q?Gr=F6nholm?=) Date: Fri, 17 Aug 2018 21:54:58 +0300 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: <55e28c5d0c45e3f67f29b97f8e97229aada65364.camel@nextday.fi> If you look at the code more carefully, you'll see that I'm not merely checking what's been imported. In each case I'm asking the relevant framework if they're running an event loop *in the current thread*. pe, 2018-08-17 kello 09:26 -0700, Brett Cannon kirjoitti: > Importation does not equate to execution. I.e. since I could have > multiple event loops running at once that means what's in sys.modules > can't tell me what event loop I'm currently interacting with. > > On Fri, 17 Aug 2018 at 09:09 Alex Gr?nholm > wrote: > > This was my approach: > > > > def _detect_running_asynclib() -> str: > > if 'trio' in sys.modules: > > from trio.hazmat import current_trio_token > > try: > > current_trio_token() > > except RuntimeError: > > pass > > else: > > return 'trio' > > > > if 'curio' in sys.modules: > > from curio.meta import curio_running > > if curio_running(): > > return 'curio' > > > > if 'asyncio' in sys.modules: > > from .backends.asyncio import get_running_loop > > if get_running_loop() is not None: > > return 'asyncio' > > > > raise LookupError('Cannot find any running async event loop') > > > > Is there something wrong with this? > > to, 2018-08-16 kello 00:01 -0700, Nathaniel Smith kirjoitti: > > > Hi all, > > > A number of people are working on packages that support multiple > > > asyncbackends (e.g., asyncio + trio, or trio + curio, or trio + > > > twisted,...). So then the question arises... how can I figure out > > > which asynclibrary my user is actually using? > > > Answer: install sniffio, and then > > > callsniffio.current_async_library(), and it tells you. > > > Well, right now it only works for trio and asyncio, but if > > > youmaintain an async library and you want to make it easier for > > > packagesto detect you, then it's easy to add support ? see the > > > manual. Weconsidered various clever things, but ultimately > > > decided that the bestapproach was to use a ContextVar and make it > > > the coroutine runner'sresponsibility to advertise which async > > > flavor it uses. In particular,this approach works even for hybrid > > > programs that are using multiplecoroutine runners in the same > > > loop, like a Twisted program withasyncio-flavored and twisted- > > > flavored coroutines in the same thread,or a Trio program using > > > trio-asyncio to run both asyncio-flavored andtrio-flavored > > > coroutines in the same thread. > > > Github: https://github.com/python-trio/sniffioManual: > > > https://sniffio.readthedocs.io/PyPI: https://pypi.org/p/sniffio > > > -n > > > > > > > _______________________________________________ > > > > Async-sig mailing list > > > > Async-sig at python.org > > > > https://mail.python.org/mailman/listinfo/async-sig > > > > Code of Conduct: https://www.python.org/psf/codeofconduct/ > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From chris.jerdonek at gmail.com Fri Aug 17 15:12:07 2018 From: chris.jerdonek at gmail.com (Chris Jerdonek) Date: Fri, 17 Aug 2018 12:12:07 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: If I'm reading the docs correctly, it looks like an async library has to depend on sniffio in order to be detected by sniffio: https://sniffio.readthedocs.io/en/latest/#adding-support-to-a-new-async-library Did you also think about whether it would be possible for a library to advertise itself without having to depend on a third-party library (e.g. using some sort of convention)? That would permit a less "centralized" approach. --Chris On Thu, Aug 16, 2018 at 12:01 AM, Nathaniel Smith wrote: > Hi all, > > A number of people are working on packages that support multiple async > backends (e.g., asyncio + trio, or trio + curio, or trio + twisted, > ...). So then the question arises... how can I figure out which async > library my user is actually using? > > Answer: install sniffio, and then call > sniffio.current_async_library(), and it tells you. > > Well, right now it only works for trio and asyncio, but if you > maintain an async library and you want to make it easier for packages > to detect you, then it's easy to add support ? see the manual. We > considered various clever things, but ultimately decided that the best > approach was to use a ContextVar and make it the coroutine runner's > responsibility to advertise which async flavor it uses. In particular, > this approach works even for hybrid programs that are using multiple > coroutine runners in the same loop, like a Twisted program with > asyncio-flavored and twisted-flavored coroutines in the same thread, > or a Trio program using trio-asyncio to run both asyncio-flavored and > trio-flavored coroutines in the same thread. > > Github: https://github.com/python-trio/sniffio > Manual: https://sniffio.readthedocs.io/ > PyPI: https://pypi.org/p/sniffio > > -n > > -- > Nathaniel J. Smith -- https://vorpus.org > _______________________________________________ > Async-sig mailing list > Async-sig at python.org > https://mail.python.org/mailman/listinfo/async-sig > Code of Conduct: https://www.python.org/psf/codeofconduct/ From njs at pobox.com Fri Aug 17 15:38:52 2018 From: njs at pobox.com (Nathaniel Smith) Date: Fri, 17 Aug 2018 12:38:52 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: On Fri, Aug 17, 2018, 09:09 Alex Gr?nholm wrote: > This was my approach: > > def _detect_running_asynclib() -> str: > if 'trio' in sys.modules: > from trio.hazmat import current_trio_token > try: > current_trio_token() > except RuntimeError: > pass > else: > return 'trio' > > if 'curio' in sys.modules: > from curio.meta import curio_running > if curio_running(): > return 'curio' > > if 'asyncio' in sys.modules: > from .backends.asyncio import get_running_loop > if get_running_loop() is not None: > return 'asyncio' > > raise LookupError('Cannot find any running async event loop') > > > Is there something wrong with this? > If you're using trio-asyncio, then you can have both trio-flavored coroutines and asyncio-flavored coroutines running in the same thread. And in particular, the trio and asyncio tests you do above will both return true at the same time, even though at any given moment only you can only 'await' one kind of async function or the other. Twisted running on the asyncio reactor has a similar situation. -n -------------- next part -------------- An HTML attachment was scrubbed... URL: From njs at pobox.com Fri Aug 17 15:50:17 2018 From: njs at pobox.com (Nathaniel Smith) Date: Fri, 17 Aug 2018 12:50:17 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: On Fri, Aug 17, 2018, 12:12 Chris Jerdonek wrote: > If I'm reading the docs correctly, it looks like an async library has > to depend on sniffio in order to be detected by sniffio: > > https://sniffio.readthedocs.io/en/latest/#adding-support-to-a-new-async-library If you don't want to depend then you can do the traditional try: import sniffio except ImportError: have_sniffio = False else: have_sniffio = True dance. For trio I was lazy and just made it a dependency because the sniffio wheel is a whopping 4 kilobytes. But there's no problem with doing that if you want. > Did you also think about whether it would be possible for a library to > advertise itself without having to depend on a third-party library > (e.g. using some sort of convention)? That would permit a less > "centralized" approach. > What kind of convention do you have in mind? The problem with a convention AFAICT is that you need some shared agreement about where to rendezvous. That's basically all the sniffio library is: a shared, neutral place for libraries to advertise themselves. (Plus a fallback for detecting asyncio, because stdlib libraries have special constraints.) -n -------------- next part -------------- An HTML attachment was scrubbed... URL: From chris.jerdonek at gmail.com Sat Aug 18 02:44:06 2018 From: chris.jerdonek at gmail.com (Chris Jerdonek) Date: Fri, 17 Aug 2018 23:44:06 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: On Fri, Aug 17, 2018 at 12:50 PM, Nathaniel Smith wrote: > On Fri, Aug 17, 2018, 12:12 Chris Jerdonek wrote: >> >> Did you also think about whether it would be possible for a library to >> advertise itself without having to depend on a third-party library >> (e.g. using some sort of convention)? That would permit a less >> "centralized" approach. > > > What kind of convention do you have in mind? Good question. I don't claim to know the answer which is why I asked if you had thought about it. The *kind* of thing I had in mind was to set a variable with an agreed-upon name and value on an agreed-upon module in the standard library -- though I agree that seems hacky as stated. It does seem to me like something that should (already?) have a general solution. What other ways does Python let things register or "announce" themselves? --Chris > > The problem with a convention AFAICT is that you need some shared agreement > about where to rendezvous. That's basically all the sniffio library is: a > shared, neutral place for libraries to advertise themselves. (Plus a > fallback for detecting asyncio, because stdlib libraries have special > constraints.) > > -n From njs at pobox.com Sat Aug 18 03:20:31 2018 From: njs at pobox.com (Nathaniel Smith) Date: Sat, 18 Aug 2018 00:20:31 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: On Fri, Aug 17, 2018 at 11:44 PM, Chris Jerdonek wrote: > On Fri, Aug 17, 2018 at 12:50 PM, Nathaniel Smith wrote: >> On Fri, Aug 17, 2018, 12:12 Chris Jerdonek wrote: >>> >>> Did you also think about whether it would be possible for a library to >>> advertise itself without having to depend on a third-party library >>> (e.g. using some sort of convention)? That would permit a less >>> "centralized" approach. >> >> >> What kind of convention do you have in mind? > > Good question. I don't claim to know the answer which is why I asked > if you had thought about it. The *kind* of thing I had in mind was to > set a variable with an agreed-upon name and value on an agreed-upon > module in the standard library -- though I agree that seems hacky as > stated. > > It does seem to me like something that should (already?) have a > general solution. What other ways does Python let things register or > "announce" themselves? Well, you could register an entry in an some global dict under an agreed-on key, like, say, sys.modules["sniffio"]. Of course, whenever you're mutating a global object like this you should worry about name collisions, but fortunately that particular dict has a good convention for reserving names. In fact there's a whole web service called "PyPI" devoted to managing those registrations! And then you might as well upload the code for accessing that variable to the web service, so everyone doesn't have to copy/paste it into their programs... ;-) Now that packaging works reliably, it's a pretty good solution for this kind of thing IMHO. -n -- Nathaniel J. Smith -- https://vorpus.org From chris.jerdonek at gmail.com Sat Aug 18 03:50:20 2018 From: chris.jerdonek at gmail.com (Chris Jerdonek) Date: Sat, 18 Aug 2018 00:50:20 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: On Sat, Aug 18, 2018 at 12:20 AM, Nathaniel Smith wrote: > On Fri, Aug 17, 2018 at 11:44 PM, Chris Jerdonek > wrote: >> On Fri, Aug 17, 2018 at 12:50 PM, Nathaniel Smith wrote: >>> On Fri, Aug 17, 2018, 12:12 Chris Jerdonek wrote: >>>> >>>> Did you also think about whether it would be possible for a library to >>>> advertise itself without having to depend on a third-party library >>>> (e.g. using some sort of convention)? That would permit a less >>>> "centralized" approach. >>> >>> >>> What kind of convention do you have in mind? >> >> Good question. I don't claim to know the answer which is why I asked >> if you had thought about it. The *kind* of thing I had in mind was to >> set a variable with an agreed-upon name and value on an agreed-upon >> module in the standard library -- though I agree that seems hacky as >> stated. >> >> It does seem to me like something that should (already?) have a >> general solution. What other ways does Python let things register or >> "announce" themselves? > > Well, you could register an entry in an some global dict under an > agreed-on key, like, say, sys.modules["sniffio"]. Of course, whenever > you're mutating a global object like this you should worry about name > collisions, but fortunately that particular dict has a good convention > for reserving names. In fact there's a whole web service called "PyPI" > devoted to managing those registrations! And then you might as well > upload the code for accessing that variable to the web service, so > everyone doesn't have to copy/paste it into their programs... ;-) Yes, I know. My original question was whether it would be possible _without_ a third-party library. It just feels to me as overly heavy-weight to rely on all of that infrastructure just to pick a key name. You have to rely on convention for the "identifier string" anyways to prevent name collisions. (It can still be misused.) And the sniffio docs already have code you have to copy-and-paste anyways (not including the "have_sniffio = False" code above). --Chris > > Now that packaging works reliably, it's a pretty good solution for > this kind of thing IMHO. > > -n > > -- > Nathaniel J. Smith -- https://vorpus.org From chris.jerdonek at gmail.com Sat Aug 18 04:22:21 2018 From: chris.jerdonek at gmail.com (Chris Jerdonek) Date: Sat, 18 Aug 2018 01:22:21 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: Also, just to be clear, I think the idea of a library to sniff this information is great. It's just the location of where this information is being stored that I'm focusing in on and asking about. It seems like it should be in a "neutral" location, and in particular different from / decoupled from the library above. One advantage of decoupling the sniffing library from the registry location is that it would allow for someone to write an improved library in the future (say "detectio") without forever locking in / requiring the old library to be installed. --Chris On Sat, Aug 18, 2018 at 12:50 AM, Chris Jerdonek wrote: > On Sat, Aug 18, 2018 at 12:20 AM, Nathaniel Smith wrote: >> On Fri, Aug 17, 2018 at 11:44 PM, Chris Jerdonek >> wrote: >>> On Fri, Aug 17, 2018 at 12:50 PM, Nathaniel Smith wrote: >>>> On Fri, Aug 17, 2018, 12:12 Chris Jerdonek wrote: >>>>> >>>>> Did you also think about whether it would be possible for a library to >>>>> advertise itself without having to depend on a third-party library >>>>> (e.g. using some sort of convention)? That would permit a less >>>>> "centralized" approach. >>>> >>>> >>>> What kind of convention do you have in mind? >>> >>> Good question. I don't claim to know the answer which is why I asked >>> if you had thought about it. The *kind* of thing I had in mind was to >>> set a variable with an agreed-upon name and value on an agreed-upon >>> module in the standard library -- though I agree that seems hacky as >>> stated. >>> >>> It does seem to me like something that should (already?) have a >>> general solution. What other ways does Python let things register or >>> "announce" themselves? >> >> Well, you could register an entry in an some global dict under an >> agreed-on key, like, say, sys.modules["sniffio"]. Of course, whenever >> you're mutating a global object like this you should worry about name >> collisions, but fortunately that particular dict has a good convention >> for reserving names. In fact there's a whole web service called "PyPI" >> devoted to managing those registrations! And then you might as well >> upload the code for accessing that variable to the web service, so >> everyone doesn't have to copy/paste it into their programs... ;-) > > Yes, I know. My original question was whether it would be possible > _without_ a third-party library. > > It just feels to me as overly heavy-weight to rely on all of that > infrastructure just to pick a key name. You have to rely on convention > for the "identifier string" anyways to prevent name collisions. (It > can still be misused.) And the sniffio docs already have code you have > to copy-and-paste anyways (not including the "have_sniffio = False" > code above). > > --Chris > > >> >> Now that packaging works reliably, it's a pretty good solution for >> this kind of thing IMHO. >> >> -n >> >> -- >> Nathaniel J. Smith -- https://vorpus.org From njs at pobox.com Sat Aug 18 17:13:18 2018 From: njs at pobox.com (Nathaniel Smith) Date: Sat, 18 Aug 2018 14:13:18 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: On Sat, Aug 18, 2018, 01:22 Chris Jerdonek wrote: > Also, just to be clear, I think the idea of a library to sniff this > information is great. > > It's just the location of where this information is being stored that > I'm focusing in on and asking about. It seems like it should be in a > "neutral" location, and in particular different from / decoupled from > the library above. > > One advantage of decoupling the sniffing library from the registry > location is that it would allow for someone to write an improved > library in the future (say "detectio") without forever locking in / > requiring the old library to be installed. Yeah, we discussed this some when initially designing it, because we were worried about the lock in issue too. Obviously if you want to do anything you need to make some decisions, but to reduce the risk here we intentionally kept sniffio as minimal and unopinionated as possible: https://github.com/python-trio/sniffio/issues/1#issuecomment-408812146 Have you seen the code? It's not *entirely* trivial ? certainly big enough to contain a bug or two ? but it's tiny and only contains what it absolutely needs to work: a contextvar (native on 3.7, or via Yury's backport library on earlier pythons), and a fallback for detecting asyncio (since as a stdlib module it can't really work any other way). https://github.com/python-trio/sniffio/blob/master/sniffio/_impl.py -n -------------- next part -------------- An HTML attachment was scrubbed... URL: From chris.jerdonek at gmail.com Sat Aug 18 17:44:52 2018 From: chris.jerdonek at gmail.com (Chris Jerdonek) Date: Sat, 18 Aug 2018 14:44:52 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: On Sat, Aug 18, 2018 at 2:13 PM, Nathaniel Smith wrote: > On Sat, Aug 18, 2018, 01:22 Chris Jerdonek wrote: >> >> Also, just to be clear, I think the idea of a library to sniff this >> information is great. >> >> It's just the location of where this information is being stored that >> I'm focusing in on and asking about. It seems like it should be in a >> "neutral" location, and in particular different from / decoupled from >> the library above. >> >> One advantage of decoupling the sniffing library from the registry >> location is that it would allow for someone to write an improved >> library in the future (say "detectio") without forever locking in / >> requiring the old library to be installed. > > > Yeah, we discussed this some when initially designing it, because we were > worried about the lock in issue too. Obviously if you want to do anything > you need to make some decisions, but to reduce the risk here we > intentionally kept sniffio as minimal and unopinionated as possible: > https://github.com/python-trio/sniffio/issues/1#issuecomment-408812146 > > Have you seen the code? It's not *entirely* trivial ? certainly big enough > to contain a bug or two ? but it's tiny and only contains what it absolutely > needs to work: a contextvar (native on 3.7, or via Yury's backport library > on earlier pythons), and a fallback for detecting asyncio (since as a stdlib > module it can't really work any other way). > > https://github.com/python-trio/sniffio/blob/master/sniffio/_impl.py Yes, I had looked at the code a few times and agree it's simple and useful. (But it could always grow.) I looked in the linked issue and didn't see any discussion of the registry location though, which is the part I was interested in. The kind of alternative I had in mind for a neutral location is setting an attribute with an agreed upon name on a module in the standard lib, perhaps something like `contextvars.current_async_library_cvar` to use your naming. This is analogous to agreeing on a file name to store information of a certain kind in a repository root, like .travis.yml, package.json, or pyproject.toml. It's light-weight and doesn't require any infrastructure or tying to a particular package on PyPI. --Chris From njs at pobox.com Tue Aug 21 03:24:39 2018 From: njs at pobox.com (Nathaniel Smith) Date: Tue, 21 Aug 2018 00:24:39 -0700 Subject: [Async-sig] =?utf-8?q?new_library=3A_sniffio_=E2=80=93_Sniff_out?= =?utf-8?q?_which_async_library_your_code_is_running_under?= In-Reply-To: References: Message-ID: On Sat, Aug 18, 2018 at 2:44 PM, Chris Jerdonek wrote: > The kind of alternative I had in mind for a neutral location is > setting an attribute with an agreed upon name on a module in the > standard lib, perhaps something like > `contextvars.current_async_library_cvar` to use your naming. This is > analogous to agreeing on a file name to store information of a certain > kind in a repository root, like .travis.yml, package.json, or > pyproject.toml. It's light-weight and doesn't require any > infrastructure or tying to a particular package on PyPI. Yeah, it'd be possible. I guess it just didn't seem worth the extra complication. -n -- Nathaniel J. Smith -- https://vorpus.org From saurabh3460 at gmail.com Mon Aug 27 05:46:40 2018 From: saurabh3460 at gmail.com (saurabh singh) Date: Mon, 27 Aug 2018 15:16:40 +0530 Subject: [Async-sig] concurrency mistake Message-ID: my question is 1st one is concurrent but 2nd one is not, how and please correct me, what i miss and what should i know more thank you import asyncio # 1st code async def say(what, when): await asyncio.sleep(when) print(what) loop = asyncio.get_event_loop() loop.create_task(say('first hello', 2)) loop.create_task(say('second hello', 1)) loop.run_forever() loop.close() ''' result >>> second hello >>> first hello ''' # 2nd code async def say(what, when): await asyncio.sleep(when) print(what) async def main(loop): yield from loop.create_task(say('first hello', 2)) yield from loop.create_task(say('second hello', 1)) print('close') loop = asyncio.get_event_loop() loop.run_until_complete(main(loop)) loop.close() ''' result >>> first hello >>> second hello ''' -------------- next part -------------- An HTML attachment was scrubbed... URL: From brett at python.org Mon Aug 27 12:14:54 2018 From: brett at python.org (Brett Cannon) Date: Mon, 27 Aug 2018 09:14:54 -0700 Subject: [Async-sig] concurrency mistake In-Reply-To: References: Message-ID: It's because you're awaiting on your tasks in your 2nd example, causing you to make your main() call wait until each task is complete before moving on (notice how you don't await in your calls to loop.create_task() in your 1st example). I think you want is something like: import asyncio async def say(what, when): await asyncio.sleep(when) print(what) async def main(loop): task1 = loop.create_task(say('first hello (sleep 2 seconds)', 2)) task2 = loop.create_task(say('second hello (sleep one second)', 1)) await asyncio.gather(task1, task2, loop=loop) print('close') loop = asyncio.get_event_loop() loop.run_until_complete(main(loop)) loop.close() On Mon, 27 Aug 2018 at 02:47 saurabh singh wrote: > my question is 1st one is concurrent but 2nd one is not, how and please > correct me, what i miss and what should i know more > thank you > > import asyncio > > # 1st code > async def say(what, when): > await asyncio.sleep(when) > print(what) > > loop = asyncio.get_event_loop() > > loop.create_task(say('first hello', 2)) > loop.create_task(say('second hello', 1)) > > loop.run_forever() > loop.close() > > ''' > result > >>> second hello > >>> first hello > ''' > > # 2nd code > async def say(what, when): > await asyncio.sleep(when) > print(what) > > async def main(loop): > yield from loop.create_task(say('first hello', 2)) > yield from loop.create_task(say('second hello', 1)) > print('close') > > loop = asyncio.get_event_loop() > loop.run_until_complete(main(loop)) > loop.close() > > ''' > result > >>> first hello > >>> second hello > ''' > > _______________________________________________ > Async-sig mailing list > Async-sig at python.org > https://mail.python.org/mailman/listinfo/async-sig > Code of Conduct: https://www.python.org/psf/codeofconduct/ > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dimaqq at gmail.com Tue Aug 28 07:30:48 2018 From: dimaqq at gmail.com (Dima Tisnek) Date: Tue, 28 Aug 2018 19:30:48 +0800 Subject: [Async-sig] concurrency mistake In-Reply-To: References: Message-ID: What Bret said, here (perhaps) more concise: async def main(): f1 = ensure_future(say("two", 2)) f2 = ensure_future(say("one", 1)) # at this point both are running await f1 await f2 Note that current event loop is automatic since Python 3.6; Futures are higher level abstraction, but I think it's better to start with futures :) On Mon, 27 Aug 2018 at 5:47 PM, saurabh singh wrote: > my question is 1st one is concurrent but 2nd one is not, how and please > correct me, what i miss and what should i know more > thank you > > import asyncio > > # 1st code > async def say(what, when): > await asyncio.sleep(when) > print(what) > > loop = asyncio.get_event_loop() > > loop.create_task(say('first hello', 2)) > loop.create_task(say('second hello', 1)) > > loop.run_forever() > loop.close() > > ''' > result > >>> second hello > >>> first hello > ''' > > # 2nd code > async def say(what, when): > await asyncio.sleep(when) > print(what) > > async def main(loop): > yield from loop.create_task(say('first hello', 2)) > yield from loop.create_task(say('second hello', 1)) > print('close') > > loop = asyncio.get_event_loop() > loop.run_until_complete(main(loop)) > loop.close() > > ''' > result > >>> first hello > >>> second hello > ''' > > _______________________________________________ > Async-sig mailing list > Async-sig at python.org > https://mail.python.org/mailman/listinfo/async-sig > Code of Conduct: https://www.python.org/psf/codeofconduct/ > -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew.svetlov at gmail.com Tue Aug 28 09:23:40 2018 From: andrew.svetlov at gmail.com (Andrew Svetlov) Date: Tue, 28 Aug 2018 16:23:40 +0300 Subject: [Async-sig] concurrency mistake In-Reply-To: References: Message-ID: Actually future is low level abstraction :) On Tue, Aug 28, 2018 at 2:31 PM Dima Tisnek wrote: > What Bret said, here (perhaps) more concise: > > async def main(): > f1 = ensure_future(say("two", 2)) > f2 = ensure_future(say("one", 1)) > # at this point both are running > await f1 > await f2 > > Note that current event loop is automatic since Python 3.6; Futures are > higher level abstraction, but I think it's better to start with futures :) > > On Mon, 27 Aug 2018 at 5:47 PM, saurabh singh > wrote: > >> my question is 1st one is concurrent but 2nd one is not, how and please >> correct me, what i miss and what should i know more >> thank you >> >> import asyncio >> >> # 1st code >> async def say(what, when): >> await asyncio.sleep(when) >> print(what) >> >> loop = asyncio.get_event_loop() >> >> loop.create_task(say('first hello', 2)) >> loop.create_task(say('second hello', 1)) >> >> loop.run_forever() >> loop.close() >> >> ''' >> result >> >>> second hello >> >>> first hello >> ''' >> >> # 2nd code >> async def say(what, when): >> await asyncio.sleep(when) >> print(what) >> >> async def main(loop): >> yield from loop.create_task(say('first hello', 2)) >> yield from loop.create_task(say('second hello', 1)) >> print('close') >> >> loop = asyncio.get_event_loop() >> loop.run_until_complete(main(loop)) >> loop.close() >> >> ''' >> result >> >>> first hello >> >>> second hello >> ''' >> >> _______________________________________________ >> Async-sig mailing list >> Async-sig at python.org >> https://mail.python.org/mailman/listinfo/async-sig >> Code of Conduct: https://www.python.org/psf/codeofconduct/ >> > _______________________________________________ > Async-sig mailing list > Async-sig at python.org > https://mail.python.org/mailman/listinfo/async-sig > Code of Conduct: https://www.python.org/psf/codeofconduct/ > -- Thanks, Andrew Svetlov -------------- next part -------------- An HTML attachment was scrubbed... URL: