GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Buffer protocol types · Issue #593 · python/typing

Buffer protocol types #593

New issue
Copy link
New issue
Copy link
Closed
Closed
Buffer protocol types#593
Copy link
Labels
topic: featureDiscussions about new features for Python's type annotationsDiscussions about new features for Python's type annotations

Description

@srittau
srittau
opened on Nov 20, 2018
Issue body actions

We had several typeshed issues and pull requests lately that try to work around the fact that there is no way to express that a method receives any object following the buffer protocol. The typing documentation mentions BytesType ByteString, which is an alias for Union[bytes, memoryview, bytearray] (and that bytes can be used as an alias in argument types), but this is missing other types such as array.array or user-defined objects. As this is a C API protocol, just defining such a protocol in typeshed in not possible.

Reacted by dgelessus, Stephan Hoyer, Titusz, Patrick Reader, Sergei Izmailov, David Lechner, Nathaniel Manista, Marco, GalaxySnail and Bar Harel

Activity

  1. JelleZijlstra commented on Nov 20, 2018

    @JelleZijlstra
    JelleZijlstra
    on Nov 20, 2018
    Member
    More actions

    Since the buffer protocol is a standard Python feature and we need to be able to use it in type annotations, it makes sense to me to add typing.Buffer or similar. Perhaps we can make concrete buffer classes inherit from Buffer, so we'd do something like

    # typing.pyi
    class Buffer: ...  # empty at the Python level
    
    # builtins.pyi
    class bytes(Buffer, Sequence[int]): ...

    We'd have to add Buffer also to typing_extensions.

    (Side note: I think you mean ByteString (https://docs.python.org/3/library/typing.html#typing.ByteString), not BytesType.)

  2. ilevkivskyi commented on Nov 20, 2018

    @ilevkivskyi
    ilevkivskyi
    on Nov 20, 2018
    Member
    More actions

    I like what @JelleZijlstra proposes (obviously the type should be abstract).

  3. JelleZijlstra commented on Nov 20, 2018

    @JelleZijlstra
    JelleZijlstra
    on Nov 20, 2018
    Member
    More actions

    Actually, it's a bit more complicated, since some buffers are writable and others aren't (see the types in python/typeshed#2610). This is controlled by whether the type responds to requests with PyBuf_WRITABLE (https://docs.python.org/3/c-api/buffer.html#c.PyBUF_WRITABLE) set. So here's a revised proposal:

    # typing.pyi
    class ReadableBuffer: ...  # abstract, no Python attributes; corresponds to C types that expose buffers without PyBUF_WRITABLE set
    class WriteableBuffer(ReadableBuffer): ...  # same; corresponds to C types that expose buffers with PyBUF_WRITABLE set
    
    # builtins.pyi
    class bytes(ReadableBuffer, Sequence[int]): ...
    class bytearray(WritableBuffer, Sequence[int]): ...

    There are a number of other flags controlling format, dimensions, etc., but I'm not sure those could be easily expressed in the type system. Perhaps we could implement format flag by making Buffer generic over a typevar that is restricted to certain types, but Python types don't map cleanly to C types, so that doesn't seem like it would work well.

    Reacted by Sebastian Rittau, Ivan Levkivskyi, Emma Smith, Spencer Brown, dgelessus, Jakub Stasiak and Aaron Denney
  4. srittau commented on Mar 30, 2019

    @srittau
    srittau
    on Mar 30, 2019
    CollaboratorAuthor
    More actions

    python/typeshed#2895 is one example where this could be useful.

  5. ilevkivskyi commented on Apr 2, 2019

    @ilevkivskyi
    ilevkivskyi
    on Apr 2, 2019
    Member
    More actions

    python/typeshed#2895 is one example where this could be useful.

    It is fine to experiment with such things defined locally (with an underscore, like _Reader), we can put something in typing later, when we will have more experience.

  6. ilevkivskyi commented on Apr 2, 2019

    @ilevkivskyi
    ilevkivskyi
    on Apr 2, 2019
    Member
    More actions

    Oh sorry, this is a wrong issue, disregard my last comment.

  7. srittau commented on Aug 7, 2019

    @srittau
    srittau
    on Aug 7, 2019
    CollaboratorAuthor
    More actions

    Is this something that could be considered? What steps are necessary to continue?

  8. ilevkivskyi commented on Aug 7, 2019

    @ilevkivskyi
    ilevkivskyi
    on Aug 7, 2019
    Member
    More actions

    @srittau If it is not too hard maybe you can directly make a PoC PR to typeshed, so that we can discuss the details (IIUC you want this to be a stub-only feature).

    cc @gvanrossum

  9. christopher-hesse commented on Nov 26, 2019

    @christopher-hesse
    christopher-hesse
    on Nov 26, 2019
    More actions

    I believe there is an open python issue about this: https://bugs.python.org/issue27501

  10. rwarren commented on Mar 28, 2020

    @rwarren
    rwarren
    on Mar 28, 2020
    More actions

    Until a proper type for the buffer protocol is available, would it make sense to at least partially fix this (in places like zlib) with "better-than-just-bytes" coverage workarounds? For example:

    Union[bytes, bytearray, memoryview]
    

    It seems like that would cover the vast majority of use cases.

    An example of something missing from that type definition that works, at least, for zlib.compress is an array.array of bytes. I can't seem to figure out how to force to be an array of bytes from a typing perspective, though.

    Also - typing.Bytestring (mentioned in the original post) doesn't seem appropriate in all cases since it looks like it is Sequence[int] in there. A sequence of ints is not accepted by zlib.decompress, for example, although my dusty memory uncertainly thinks that a sequence of ints was supposed to be legit for a true buffer protocol (I'm really not sure, though).

  11. bmerry
    added a commit that references this issue on Jun 15, 2020

    Introduce ReadableBuffer and WriteableBuffer Union aliases

    0c0bcf4
  12. srittau
    added a commit that references this issue on Jun 19, 2020

    Introduce ReadableBuffer and WriteableBuffer Union aliases (#4232)

    e05fbab
  13. vishalkuo
    added a commit that references this issue on Jun 26, 2020

    Introduce ReadableBuffer and WriteableBuffer Union aliases (python#4232)

    c686923
  14. srittau
    added
    topic: featureDiscussions about new features for Python's type annotationsDiscussions about new features for Python's type annotations
    on Nov 4, 2021
  15. covert-encryption commented on Jan 2, 2022

    @covert-encryption
    covert-encryption
    on Jan 2, 2022
    More actions

    As mentioned in #997 it would also be useful to be able to specify length for any buffer types, in particular where a fixed length string is expected.

  16. itaisteinherz commented on Feb 7, 2022

    @itaisteinherz
    itaisteinherz
    on Feb 7, 2022
    More actions

    Bump :)

    @ilevkivskyi @srittau What's the process to getting this accepted? Does this require a new PEP? I'd be open to working on this, but I'm not sure where to start.

  17. jakirkham commented on Feb 7, 2022

    @jakirkham
    jakirkham
    on Feb 7, 2022
    More actions

    A related question is how this would be handled in Python given the move to builtins for type hints (like with PEP 585)

  18. itaisteinherz commented on Feb 7, 2022

    @itaisteinherz
    itaisteinherz
    on Feb 7, 2022
    More actions

    By the way, I just noticed that @JelleZijlstra's suggestion has been implemented:

    https://github.com/python/typeshed/blob/494481a0aed2ef0e00bbe190476ace0b8261bce6/stdlib/_typeshed/__init__.pyi#L185-L191

    I suppose that means those should be moved here in order to consider this issue resolved?

  19. JelleZijlstra commented on Feb 7, 2022

    @JelleZijlstra
    JelleZijlstra
    on Feb 7, 2022
    Member
    More actions

    I think it doesn't necessarily require a PEP: we could just add the types to typing.pyi and typing_extensions.pyi (as I suggested in #593 (comment) a long time ago). The process could be similar to what we just did with reveal_type(): a typing-sig discussion, followed by direct implementation in CPython.

    Reacted by Sebastian Rittau
  20. jakirkham commented on Feb 23, 2022

    @jakirkham
    jakirkham
    on Feb 23, 2022
    More actions

    By the way, I just noticed that @JelleZijlstra's suggestion has been implemented:

    https://github.com/python/typeshed/blob/494481a0aed2ef0e00bbe190476ace0b8261bce6/stdlib/_typeshed/__init__.pyi#L185-L191

    I suppose that means those should be moved here in order to consider this issue resolved?

    This doesn't seem quite right either as memoryview and mmap are being treated as writeable. However they may or may not be. For example a memoryview of a bytes object or an mmap of a read-only file are not writeable

  21. JelleZijlstra commented on Apr 22, 2022

    @JelleZijlstra
    JelleZijlstra
    on Apr 22, 2022
    Member
    More actions

    I am preparing a PEP to support checking the buffer protocol not only in the type system, but also at runtime. A first draft is at https://github.com/JelleZijlstra/peps/blob/bufferpep/pep-9999.rst. Any early feedback is welcome.

    Reacted by GalaxySnail and Ralf Gommers
  22. srittau commented on Apr 22, 2022

    @srittau
    srittau
    on Apr 22, 2022
    CollaboratorAuthor
    More actions

    @JelleZijlstra LGTM so far, although it's unfortunate that it's difficult to distinguish between readable and read/writable buffers, but it makes sense.

  23. rgommers commented on Apr 25, 2022

    @rgommers
    rgommers
    on Apr 25, 2022
    More actions

    although it's unfortunate that it's difficult to distinguish between readable and read/writable buffers, but it makes sense.

    Readonly is only one of a number of attributes that are important for determining whether a buffer can be used. Some libraries can only deal with contiguous buffers, or native endianness, or aligned data. It looks to me like the PEP does the right thing here - best to support either all attributes or none, but not make readonly more important than other attributes.

    Reacted by Leo Fang
  24. JelleZijlstra commented on Apr 25, 2022

    @JelleZijlstra
    JelleZijlstra
    on Apr 25, 2022
    Member
    More actions

    This is now PEP 688: https://peps.python.org/pep-0688/.

    Reacted by GalaxySnail, Leo Fang, Shantanu and Bas van Beek
    Reacted by Alex Waygood, dgelessus, Shantanu and ZhengYu, Xu
  25. JelleZijlstra commented on May 22, 2023

    @JelleZijlstra
    JelleZijlstra
    on May 22, 2023
    Member
    More actions

    Fixed by PEP-688.

    Reacted by jakirkham
    Reacted by jakirkham and Zac Hatfield-Dodds
    Reacted by jakirkham and Zac Hatfield-Dodds
  26. JelleZijlstra
    closed this as completedon May 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: featureDiscussions about new features for Python's type annotationsDiscussions about new features for Python's type annotations

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.