Metadata-Version: 2.1
Name: plain-abc
Version: 0.0.3
Summary: An ABC implementation without metaclass
Project-URL: Homepage, https://github.com/ChieloNewctle/plain-abc
Project-URL: Bug Tracker, https://github.com/ChieloNewctle/plain-abc/issues
Author-email: Chielo Newctle <ChieloNewctle@Yandex.com>
License-File: LICENSE
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.7
Requires-Dist: importlib-metadata>=1.0; python_version < '3.8'
Provides-Extra: tests
Requires-Dist: pytest; extra == 'tests'
Description-Content-Type: text/markdown

# plain-abc

An ABC implementation without metaclass.

It is a little bit annoying to have metaclass conflict,
especially when trying to use ABC along with other libraries.

`plain-abc` provides a simple ABC implementation without metaclass.

## Solving metaclass conflict without `plain-abc`

Here is an example of metaclass conflict
and a solution to mix ABCMeta and other metaclasses.

```python
from abc import ABC, ABCMeta, abstractmethod


class _SomeHiddenMetaclass(type):
    pass


class Base(metaclass=_SomeHiddenMetaclass):
    pass


class IFoo(ABC):
    @abstractmethod
    def foo(self): ...


# oh no, metaclass conflict!
# class Foo(Base, IFoo):
#     def foo(self): ...


# create a new metaclass for either IFoo or Foo
class NewMetaclass(_SomeHiddenMetaclass, ABCMeta):
    ...


class Foo(Base, IFoo, metaclass=NewMetaclass):
    def foo(self): ...
```

## Usage

But you can also use `plain-abc` to solve the problem:

```python
from abc import abstractmethod
from plain_abc import PlainABC


class _SomeHiddenMetaclass(type):
    pass


class Base(metaclass=_SomeHiddenMetaclass):
    pass


class IFoo(PlainABC):
    @abstractmethod
    def foo(self): ...


class Foo(Base, IFoo):
    def foo(self): ...
```

To skip signature checking,
you can add the member names in `__abc_concrete_members__` of a subclass:

```python
class IEnum(PlainABC):
    @property
    @abstractmethod
    def foo(self) -> str:
        ...

class Foo(IEnum, Enum):
    # for python 3.10 or lower
    __abc_concrete_members__ = ('foo',)
    foo = 'foo'

assert Foo.foo.value == 'foo'
```
