Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

array module: deprecate '__int__' conversion support for array elements #57183

Closed
meadori opened this issue Sep 14, 2011 · 7 comments
Closed
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@meadori
Copy link
Member

meadori commented Sep 14, 2011

BPO 12974
Nosy @mdickinson, @meadori, @serhiy-storchaka, @orenmn
Superseder
  • bpo-36048: Deprecate implicit truncating when convert Python numbers to C integers: use index, not int
  • 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 = <Date 2019-03-14.14:54:58.648>
    created_at = <Date 2011-09-14.00:48:15.176>
    labels = ['type-bug', 'library']
    title = "array module: deprecate '__int__' conversion support for array elements"
    updated_at = <Date 2019-03-14.14:54:58.648>
    user = 'https://github.com/meadori'

    bugs.python.org fields:

    activity = <Date 2019-03-14.14:54:58.648>
    actor = 'serhiy.storchaka'
    assignee = 'none'
    closed = True
    closed_date = <Date 2019-03-14.14:54:58.648>
    closer = 'serhiy.storchaka'
    components = ['Library (Lib)']
    creation = <Date 2011-09-14.00:48:15.176>
    creator = 'meador.inge'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 12974
    keywords = []
    message_count = 7.0
    messages = ['144000', '144120', '144126', '144131', '144135', '144138', '336204']
    nosy_count = 4.0
    nosy_names = ['mark.dickinson', 'meador.inge', 'serhiy.storchaka', 'Oren Milman']
    pr_nums = []
    priority = 'normal'
    resolution = 'duplicate'
    stage = 'resolved'
    status = 'closed'
    superseder = '36048'
    type = 'behavior'
    url = 'https://bugs.python.org/issue12974'
    versions = ['Python 3.3']

    @meadori
    Copy link
    Member Author

    meadori commented Sep 14, 2011

    When reviewing the fix for bpo-1172711 it was discovered that the 'array' module allows for '__int__' conversions:

    >>> import array, struct
    >>> a = array.array('L', [1,2,3])
    >>> class T(object):
    ...     def __init__(self, value):
    ...         self.value = value
    ...     def __int__(self):
    ...          return self.value
    ...
    >>> a = array.array('L', [1,2,3])
    >>> struct.pack_into('L', a, 0, 9)
    >>> a
    array('L', [9, 2, 3])
    >>> a[0] = T(100)
    >>> a
    array('L', [100, 2, 3])

    As discussed in bpo-1172711, this behavior may not be desirable. We should look at deprecating '__int__' and adding '__index__' as was done for the struct module in bpo-1530559.

    @meadori meadori added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Sep 14, 2011
    @skrah
    Copy link
    Mannequin

    skrah mannequin commented Sep 16, 2011

    I just discovered that struct packs pointers from objects with an
    __index__() method. Is that intentional?

    >>> import struct
    >>> class IDX(object):
    ...     def __init__(self, value):
    ...         self.value = value
    ...     def __index__(self):
    ...          return self.value
    ... 
    >>> struct.pack('P', IDX(9))
    b'\t\x00\x00\x00\x00\x00\x00\x00'
    >>>

    @mdickinson
    Copy link
    Member

    mdickinson commented Sep 16, 2011

    Yes, that's intentional. When use of __int__ was deprecated, a bug report popped up from someone who wanted to be able to have their own objects treated as integers for the purposes of struct.pack. (I don't recall which issue; Meador, do you remember?) So we added use of __index__ at that point.

    I think __index__ is the right interface for something to expose if it wants to be usable as an integer, and this usage is consistent with the original __index__ PEP.

    @skrah
    Copy link
    Mannequin

    skrah mannequin commented Sep 16, 2011

    Mark Dickinson <report@bugs.python.org> wrote:

    Yes, that's intentional. When use of __int__ was deprecated, a bug
    report popped up from someone who wanted to be able to have their own
    objects treated as integers for the purposes of struct.pack.
    (I don't recall which issue; Meador, do you remember?)
    So we added use of __index__ at that point.

    Yes, I think that's bpo-1530559, and the bug report was about PyCUDA. I can
    see why 'bBhHiIlLqQ' allow __index__(), since they previously allowed
    __int__().

    I specifically meant the 'P' format. As far as I can see, PyLong_AsVoidPtr()
    never allowed __int__(), but now index objects can be packed as pointers.
    It isn't a big deal, I just have to know for features/pep-3118.

    To illustrate, this is python2.5.0; INT is an object with an __int__() method:

    '\x07\x00\x00\x00\x00\x00\x00\x00'
    >>> struct.pack('P', INT(7))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/stefan/hg/r25/Lib/struct.py", line 63, in pack
        return o.pack(*args)
    struct.error: cannot convert argument to long
    >>>

    @meadori
    Copy link
    Member Author

    meadori commented Sep 16, 2011

    > I specifically meant the 'P' format. As far as I can see, PyLong_AsVoidPtr()
    > never allowed __int__(), but now index objects can be packed as pointers.
    > It isn't a big deal, I just have to know for features/pep-3118.
    >
    > To illustrate, this is python2.5.0; INT is an object with an __int__() method:
    >
    > '\x07\x00\x00\x00\x00\x00\x00\x00'
    >>>> struct.pack('P', INT(7))
    > Traceback (most recent call last):
    >  File "<stdin>", line 1, in <module>
    >  File "/home/stefan/hg/r25/Lib/struct.py", line 63, in pack
    >    return o.pack(*args)
    > struct.error: cannot convert argument to long

    Huh, that's interesting. It doesn't allow 'unsigned long' packs either (2.6.7):

    Python 2.6.7+ (unknown, Sep 16 2011, 09:53:25)
    [GCC 4.6.0 20110603 (Red Hat 4.6.0-10)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import struct
    >>> class IDX(object):
    ...     def __init__(self, value):
    ...         self.value = value
    ...     def __int__(self):
    ...          return self.value
    ...
    >>> for code in ['l', 'L', 'P']:
    ...    try:
    ...       struct.pack(code, IDX(9))
    ...    except Exception as e:
    ...       print "pack('%s'): %s" % (code, e)
    ...
    '\t\x00\x00\x00'
    pack('L'): unsupported operand type(s) for &: 'IDX' and 'long'
    pack('P'): cannot convert argument to long

    The behavior around '__int__' in previous versions seems somewhat accidental.

    @skrah
    Copy link
    Mannequin

    skrah mannequin commented Sep 16, 2011

    Meador Inge <report@bugs.python.org> wrote:

    The behavior around '__int__' in previous versions seems somewhat accidental.

    I think struct followed the functions in longobject.c, which is not
    really consistent with respect to duck typing. See also bpo-12965 or
    http://bugs.python.org/issue1172711#msg48086.

    But I think that the decision to accept __index__() for both signed
    and unsigned integer formats is good for consistency.

    For 'P' I'm not sure, but course it might be used in the wild by now.

    @serhiy-storchaka
    Copy link
    Member

    serhiy-storchaka commented Feb 21, 2019

    See more general bpo-36048.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants