pyca / pynacl

Python binding to the Networking and Cryptography (NaCl) library
https://pynacl.readthedocs.io/
Apache License 2.0
1.06k stars 233 forks source link

Type annotations for `nacl.encoding` #695

Closed DMRobertson closed 2 years ago

DMRobertson commented 2 years ago

Pulled out from #692.

After we realised in #693 that we don't need typing_extensions to use SupportsBytes, I didn't want to pull in typing_extensions again for just one use of Protocol. (I have no other plans to use Protocol in other annotations.)

My understanding: doing so means that we can't run mypy under Python 3.6 or 3.7 to fully typecheck the package. Maybe that's fine? I guess the downside is that someone using nacl in a 3.6 or 3.7 project can't fully benefit from these annotations. What're your thoughts here?

(As a compromise, I could do a try-except dance to use from typing_extensions.Protocol, if it happens to be available.)

reaperhulk commented 2 years ago

I think doing a semi-gross abc workaround is probably the simplest answer here:

class Encoder(metaclass=abc.ABCMeta)
    @staticmethod
    @abstractmethod
    def encode(data: bytes) -> bytes:
        pass

    @staticmethod
    @abstractmethod
    def decode(data: bytes) -> bytes:
        pass

And then make all the encoders subclasses of that. Uses subclassing (boo), but we can make things nicer and move to protocols when we get to drop 3.6/3.7 support.

DMRobertson commented 2 years ago

@reaperhulk thanks for your input! I've done so in the latest commit (sorry for the force pushes there, I had some trouble with CI). I've prefixed the ABC's name with an underscore because I'm not sure if we want to expose it publicly. (Is the intention that users can define their own encoders?)

reaperhulk commented 2 years ago

Looks like you need to run black. I’m happy with it being private. I'd like to entirely remove encoders as I don’t think they bring any real value given how simple it is to compose your own arbitrary encoding without the library, but that’s a future PR for someone to tackle.