Sitelet https://github.com/python/cpython/issues/76963
Skip to content

memoryview & ctypes: incorrect itemsize for empty array #76963

Description

@eric-wieser
BPO 32782
Nosy @terryjreedy, @amauryfa, @abalkin, @skrah, @meadori, @eric-wieser
PRs
  • bpo-32782: PEP3118 itemsize of an empty ctypes array should not be 0 #5576
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2018-02-06.18:53:21.025>
    labels = ['interpreter-core', 'type-bug', '3.8', '3.9', '3.10', 'ctypes']
    title = 'memoryview & ctypes: incorrect itemsize for empty array'
    updated_at = <Date 2020-05-23.15:47:49.464>
    user = 'https://github.com/eric-wieser'

    bugs.python.org fields:

    activity = <Date 2020-05-23.15:47:49.464>
    actor = 'cheryl.sabella'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Interpreter Core', 'ctypes']
    creation = <Date 2018-02-06.18:53:21.025>
    creator = 'Eric.Wieser'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 32782
    keywords = ['patch']
    message_count = 9.0
    messages = ['311740', '321290', '324705', '340230', '340231', '340232', '340235', '340236', '348004']
    nosy_count = 8.0
    nosy_names = ['terry.reedy', 'teoliphant', 'amaury.forgeotdarc', 'belopolsky', 'skrah', 'meador.inge', 'Eric.Wieser', 'Eric Wieser']
    pr_nums = ['5576']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue32782'
    versions = ['Python 3.8', 'Python 3.9', 'Python 3.10']

    Linked PRs

    Activity

    1. eric-wieser commented on Feb 6, 2018

      eric-wiesermannequin
      MannequinAuthor

      Take the following simple structure:

          class Foo(ctypes.Structure):
              _fields_ = [('f', ctypes.uint32_t)]

      And construct some arrays with it:

          def get_array_view(N):
              return memoryview((Foo * N)())

      In most cases, this works as expected, returning the size of one item:

          >>> get_array_view(10).itemsize
          4
          >>> get_array_view(1).itemsize
          4

      But when N=0, it returns the wrong result

          >>> get_array_view(0).itemsize
          0

      Which contradicts its .format, which still describes a 4-byte struct

          >>> get_array_view(0).format
          'T{>I:one:}'

      This causes a downstream problem in numpy:

          >>> np.array(get_array_view(0))
          RuntimeWarning: Item size computed from the PEP 3118 buffer format string does not match the actual item size.
    2. eric-wieser commented on Jul 8, 2018

      eric-wiesermannequin
      MannequinAuthor

      Pinging, as recommended by https://devguide.python.org/pullrequest/#reviewing. Ideally this and https://bugs.python.org/issue32780 would make the same patch release.

    3. eric-wieser commented on Sep 6, 2018

      eric-wiesermannequin
      MannequinAuthor

      Pinging again, for lack of a clearer path forward

    4. terryjreedy commented on Apr 14, 2019

      @terryjreedy
      Member

      This issue is about the itemsize attribute of instances of the built-in memoryview class. Ctypes in only involved in providing format information. Hence the nosy additions.

      On Win10 with 3.8, ctypes has no uint attributes. Using 'c_int32' instead, I see the same behavior (itemsize 0 for empty structure).

      About itemsize, https://www.python.org/dev/peps/pep-3118/ says

      "This is a storage for the itemsize (in bytes) of each element of the shared memory. It is technically un-necessary as it can be obtained using PyBuffer_SizeFromFormat, however an exporter may know this information without parsing the format string and it is necessary to know the itemsize for proper interpretation of striding. Therefore, storing it is more convenient and faster."

      The first line could be seen as implying that itemsize is undefined if there are no items (and as justifying numbytes/numitems otherwise). The 0 return could be seen as equivalent to a None return from a python-coded function. If so, it is not a bug, and there might be code that would break if it is changed.

      On the other hand, the next lines imply that itemsize is *usually*, though not necessarily, a cache for PyBuffer_SizeFromFormat. This could be seen as implying that in the absence of other information, the itemsize should be calculated from the format, making 0 a bug.

    5. changed the title [-]ctypes: memoryview gives incorrect PEP3118 itemsize for array of length zero[/-] [+]memoryview gives incorrect PEP3118 itemsize for empty array[/+] on Apr 14, 2019
    6. terryjreedy commented on Apr 14, 2019

      @terryjreedy
      Member

      This is actually about memoryview.itemsize within ctypes.

    7. changed the title [-]memoryview gives incorrect PEP3118 itemsize for empty array[/-] [+]memoryview & ctypes: incorrect PEP3118 itemsize for empty array[/+] on Apr 14, 2019
    8. terryjreedy commented on Apr 14, 2019

      @terryjreedy
      Member
      https://docs.python.org/3/library/stdtypes.html#typememoryview
      says "itemsize The size in bytes of each element of the memoryview"
      Revising the code example to use an empty array:
      >>> import array, struct
      >>> m = memoryview(array.array('H', [0])
      >>> m.itemsize
      2
      I agree that itemsize should also be non-zero for ctype formats.
    9. changed the title [-]memoryview & ctypes: incorrect PEP3118 itemsize for empty array[/-] [+]memoryview & ctypes: incorrect itemsize for empty array[/+] on Apr 14, 2019
    10. 4 remaining items

    11. transferred this issue fromon Apr 10, 2022
    12. added a commit that references this issue on Dec 23, 2022
    13. added 2 commits that reference this issue on Dec 23, 2022
    14. added 2 commits that reference this issue on Dec 23, 2022
    15. mattip commented on Dec 23, 2022

      @mattip
      Contributor

      Thanks for the fix that closed this. @eric-wieser do you remember where this impacted NumPy? I don't see the relevant issue or PR.

    16. eric-wieser commented on Dec 23, 2022

      @eric-wieser
      ContributorAuthor

      I think the workaround in numpy needs to stay till after #5561

    17. eric-wieser commented on Dec 23, 2022

      @eric-wieser
      ContributorAuthor
    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

      Projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions