Skip to content

Abstract async context manager in Python3.6 #29

@JoseKilo

Description

@JoseKilo

I have an abstract class that defines an abstract async context manager (Python 3.7 code):

import abc
import contextlib


class Foo(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    @contextlib.asynccontextmanager
    async def bar(self):
        pass

In order to make it compatible with Python 3.6, I would use async_generator.asynccontextmanager

import async_generator


class Foo(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    @async_generator.asynccontextmanager
    async def bar(self):
        pass

However, this raises an error:

TypeError: must be an async generator (native or from async_generator; if using @async_generator then @acontextmanager must be on top.

This can be fixed using async_generator.async_generator, but I think that was intended for Python3.5 (which lacked native async generators) and not for Python3.6.

class Foo(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    @async_generator.asynccontextmanager
    @async_generator.async_generator
    async def bar(self):
        pass

This seems to work on Python3.5 too.

I can extend the class and implement the method without using async_generator.async_generator in both, Python3.6 and Python3.7 (as expected):

class Bar(Foo):

    @async_generator.asynccontextmanager
    async def bar(self):
        print('Before')
        yield 42
        print('After')


bar = Bar()
async with bar.bar() as context:
    print('Context:', context)

Maybe the docs / readme could include an abstract method example.
Or maybe Python3.6 should work without adding @async_generator.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions