Comments (16)
FYI, since the only piece I was missing from async_generator was an AsyncExitStack
and since I only need Python 3.6, I packaged a "backport" for 3.5+ (more or less a verbatim copy from 3.7) here https://github.com/sorcio/async_exit_stack
I'd be happy to help with a proper backport.
from contextlib2.
With @jayvdb submitting the synchronous enhancements as a separate PR (which I'm about to release as 0.6.0) that opens up a new alternative: what if contextlib2 0.7.0 were to just drop support for all versions prior to 3.6, leaving users of old Python versions on 0.6.0 indefinitely?
from contextlib2.
@graingert It makes me even happier with the idea of 0.7.0 being 3.6+ only, which means it should be possible to just sync the latest version over from CPython 3.10 (modulo keeping the contextlib2 APIs that never graduated to the stdlib version)
from contextlib2.
Can't imagine how you can manage this to work on 3.5 without yield support inside coroutines. I'll subscribe to this thread to see any useful ideas for that.
from contextlib2.
But supporting at least 3.6 would be great. I am already using personal package for this, and could provide a PR for asynccontextmanager
from contextlib2.
Like Nick, I'd prefer keeping a single package. Having fewer packages with similar purposes makes it easier for people to decide what package to install.
The implementation would probably involve making contextlib2 into a package, organized something like this:
- _contextlib.py has all the current code
- _contextlib_async.py has @asynccontextmanager
__init__.py
doesfrom _contextlib import *
andif sys.version >= (3, 6): from _contextlib_async import asynccontextmanager
. Thus, _contextlib_async would only be imported on Python versions where it's syntactically valid.
Yes, this probably can't be backported to 3.5 (maybe using https://github.com/njsmith/async_generator would work?). However, other future async enhancements to contextmanager, like AsyncExitStack, could be backported to 3.5 (and even earlier if you want to use yield from).
from contextlib2.
Using another libraries with their own logic ( yield_
) will make it a pain in python 3.7 to migrate from this package to a standart one. Also, it won't be a clear solution for end-users
from contextlib2.
For now, I've reworded the issue to just target 3.6+. However, we can keep the possibility of supporting earlier versions in mind as we consider possible solutions.
-
the first option would be something like @JelleZijlstra suggested, only with the "minimum compatible version" files named after the earliest version that can import them (
_contextlib_needs35.py
,_contextlib_needs36.py
, etc). I think this is the cleanest approach from an install time and runtime perspective, but the trickiest from the point of view of actually merging changes from the stdlib into the backport (but, as noted, we don't need to do that very often) -
the second option that comes to mind would be to include full copies of the versions of interest (so
contextlib2._contextlib_37.py
would be an actual pre-release copy of the 3.7 version of the module). Aside from the inevitable code duplication, the main argument against this is that it wouldn't help with cases likeAsyncExitStack
, where that's likely to be compatible with 3.5, even thoughasynccontextmanager
will need 3.6. That's enough of a downside that I don't think any simplification of future maintenance could make it worthwhile to accept as a limitation
from contextlib2.
FWIW, I use a home grown version of this all the time on 3.5, via https://github.com/njsmith/async_generator. For example, trio.open_nursery
is implemented this way. The asynccontextmanager
code itself doesn't need to define async generators, so there's no trouble importing it on 3.5; it just depends on the user to provide something that quacks like an async generator function, and it's up to them to decide if they want to use async_generator
or whatever to make that function. (Why do I care about 3.5 support? PyPy.)
This code is sometimes a bit annoying to maintain, so I'd be happy to delegate to contextlib2 :-).
OTOH there might be a few challenges. The homegrown changes in my version are:
-
Nice error message if someone accidentally uses
with
when they meantasync with
: python-trio/trio#212 -
Adding some metadata so that functions returning async generators are recognizable: https://github.com/python-trio/trio/blob/e4c8ce7b81669f3e886c2ee434c7249aba7f55ed/trio/_util.py#L147-L148 (see bpo-30359, though here there's the additional wrinkle that AFAIK we don't yet have a way to express "async context manager" in
__annotations__
) -
(Not yet but someday) Right now, there's a race condition in signal handling when exiting from an async context manager: if control-C arrives just as we're entering the
__aexit__
method, it causes it not to be run. In general trio protects from this using some complicated annotations, but I haven't bothered trying to solve this race condition yet, because even if I fixed it here then essentially the same race condition exists in the interpreter itself, so what's the point really. But if bpo-29988 got fixed then I would be motivated to figure out how to fix the part in the context manager as well, and it might be trickier if it lives in another library. Of course,contextmanager
has the same problem, and I can probably solve it using some disgusting hack like noticing that all(async)contextmanager
objects use the samecode
objects for their__(a)exit__
methods.
I don't think these are showstoppers, just figured put them on the radar.
from contextlib2.
I think between @sorcio's async_exit_stack
module and the simple passage of time, the idea of copying in the Python 3.7 version of the modules as contextlib2._contextlib_36_compat.py
, moving the current code that implements stdlib APIs to contextlib2._contextlib_26_compat.py
, and then populating contextlib2.__init__.py
with code to choose the newest importable option and then add the extra contextlib2
specific backwards compatibility code is a lot more viable now than it was when I first opened this issue.
While there a few APIs it would be nice to extract and make universally available, that could be considered as a separate issue after the initial 3.6+ option was implemented.
from contextlib2.
@ncoghlan does the Python 3.5 EOL change anything?
from contextlib2.
I've merged the changes from #29 (switch to CalVer, set the minimum version to 3.6), clearing the way for the Python 3.10 version to be sync'ed over. With the 2.x compatibility code gone, I'm hoping that will now be a lot simpler than it used to be.
from contextlib2.
PR is up #32
CI mostly looks good, just need to check what's up with PyPy3
from contextlib2.
As far as I can tell, the PyPy3 issue was a bug in the stdlib test suite (assuming the use of a refcounted GC): https://bugs.python.org/issue44515
CPython PR submitted at python/cpython#26910
from contextlib2.
Bah, forgot to include the docs updates for the new APIs
from contextlib2.
OK, docs are also updated now.
from contextlib2.
Related Issues (20)
- setup.py does not fallback to using distutils.core import setup HOT 2
- Rebase API for Python 3.7
- Initial Update HOT 1
- asynccontextmanager as decorator HOT 5
- Not up-to-date changelog HOT 3
- Documentation is not rebuilding HOT 3
- add py3.10 contextlib.aclosing HOT 2
- 0.6.0.post1: pytest is failing HOT 9
- Switch to CalVer and update supported versions
- Remove deprecated APIs that never graduated to stdlib module HOT 1
- backport the typeshed contextlib.pyi file and add a py.typed HOT 4
- Use mypy.stubtest in CI HOT 3
- widen _SupportsAclose
- add py3.10 async contextlib.nullcontext type annotation
- Release 24.6.0 HOT 2
- backport contextlib from python 3.12 HOT 11
- pyi resync
- python3.11 support? HOT 2
- 21.6.0: sdist is missing dev/mypy.allowlist
- 21.6.0: mypy errors HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from contextlib2.