client_python icon indicating copy to clipboard operation
client_python copied to clipboard

Async context manager

Open denisSurkov opened this issue 4 years ago • 12 comments

Usecase:

c = Counter("errors_count")

@c.count_exceptions()
def foo():  # counter = 1
      raise Exception()

@c.count_exceptions()
async def foo_async(): # counter still 1
      await sleep(1)
      raise Exception()

Quick search in project did nothing to me.

It would be cool if counter (and other objects) would handle this right out of the box, especially if we're talking about metrics for web world.

denisSurkov avatar Apr 10 '20 15:04 denisSurkov

How would that work, keeping in mind that we support all the way back to 2.6?

brian-brazil avatar Apr 10 '20 15:04 brian-brazil

Well, I didn't think about it. Sorry.

denisSurkov avatar Apr 11 '20 09:04 denisSurkov

@brian-brazil, what do you think about Python version check inside decorator to exclude support for non-async syntax. Seems like it's not gonna affect backwards support. And will come really handy

LittleLampLight avatar Apr 21 '20 11:04 LittleLampLight

I'm not sure how that'd work given that it's a syntax thing, and thus 2.6 would choke on it.

brian-brazil avatar Apr 21 '20 12:04 brian-brazil

Yup, actually i was thinking about depending on version import of async compatible syntax. But it looks too complex and such case may be implemented easier with context manager as well.

c = Counter("errors_count")

async def foo_async():
    with c.count_exceptions():
        await sleep(1)
        raise Exception()

actually if someone really need the decorator then he can implement it by himself with a few lines of code

LittleLampLight avatar Apr 21 '20 18:04 LittleLampLight

The silent failure is surprising here.

How would that work, keeping in mind that we support all the way back to 2.6?

I believe it's possible to do version checks inside the __call__, then do a dynamic import for async to do the async check against the function passed in to avoid making code calls that aren't present in 2.6.

e.g. https://stackoverflow.com/questions/51344906/in-python-how-to-use-decorator-compatible-with-normal-function-and-coroutine-fun

actually if someone really need the decorator then he can implement it by himself with a few lines of code

Sure, but it's unexpected and causes metrics to be easily missed in a Python 3 world where 2.x is past EOL.

MSeal avatar Feb 10 '21 19:02 MSeal

Why don't just drop support for not-maintained-for-7-years Python 2.6? I vote for native asyncio support instead of ancient py2.x.

nikicat avatar Feb 23 '21 15:02 nikicat

I pulled some data for downloads over the last 6 months by python version:

Python Version Downloads Percent of Downloads
3.7 74,784,972 69.80%
3.6 15,260,503 14.24%
3.8 6,414,421 5.99%
2.7 5,773,263 5.39%
3.5 2,249,237 2.10%
Unknown 1,863,071 1.74%
3.9 750,521 0.70%
3.4 28,891 0.03%
2.6 9,442 0.01%
3.10 2,562 0.00%
3.3 241 0.00%
3.2 5 0.00%

I am hesitant to remove support for anything used by more than a couple percent of users, which means I think support for 2.6 could be removed but not yet 2.7.

csmarchbanks avatar Feb 23 '21 17:02 csmarchbanks

Also, note that 2.6 support has actually already been removed in master, but not yet in a release (https://github.com/prometheus/client_python/pull/592 for reference).

csmarchbanks avatar Feb 23 '21 18:02 csmarchbanks

Be aware a lot of download traffic is bot driven. So downloads may not be reflective of actual user percentages as there's a fair bit of old tooling churning away at 2.7 builds that aren't used anymore. There was a similar level of traffic for 2.7 on other projects I maintain but actual users keyed on library updates for that version ended up being much smaller than initially perceived by downloads, if that helps with decision making.

MSeal avatar Feb 23 '21 18:02 MSeal

Many other popular libraries have ended support for Python 2, regardless of how many 2.x downloads were reported. (gunicorn comes to mind.) We are a hard +1 for supporting Python 3 only, going forward.

RonRothman avatar Mar 04 '21 19:03 RonRothman

I opened https://github.com/prometheus/client_python/issues/717 for removing python 2 support, and enabling this feature.

csmarchbanks avatar Nov 01 '21 21:11 csmarchbanks