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

[doc] Add examples to int.to_bytes and int.from_bytes #60784

Closed
paddy3118 mannequin opened this issue Nov 29, 2012 · 13 comments
Closed

[doc] Add examples to int.to_bytes and int.from_bytes #60784

paddy3118 mannequin opened this issue Nov 29, 2012 · 13 comments
Labels
3.9 only security fixes 3.10 only security fixes 3.11 only security fixes docs Documentation in the Doc dir easy type-feature A feature request or enhancement

Comments

@paddy3118
Copy link
Mannequin

paddy3118 mannequin commented Nov 29, 2012

BPO 16580
Nosy @mdickinson, @ezio-melotti, @asvetlov, @serhiy-storchaka, @quantumgc
PRs
  • bpo-16580: [doc] Add examples to int.to_bytes and int.from_bytes #27760
  • Files
  • issue16580.patch
  • issue16580.patch
  • 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 2021-08-15.11:30:16.312>
    created_at = <Date 2012-11-29.19:25:09.554>
    labels = ['easy', '3.9', '3.10', '3.11', 'type-feature', 'docs']
    title = '[doc] Add examples to int.to_bytes and int.from_bytes'
    updated_at = <Date 2021-08-15.11:30:16.311>
    user = 'https://bugs.python.org/paddy3118'

    bugs.python.org fields:

    activity = <Date 2021-08-15.11:30:16.311>
    actor = 'mark.dickinson'
    assignee = 'docs@python'
    closed = True
    closed_date = <Date 2021-08-15.11:30:16.312>
    closer = 'mark.dickinson'
    components = ['Documentation']
    creation = <Date 2012-11-29.19:25:09.554>
    creator = 'paddy3118'
    dependencies = []
    files = ['30372', '50210']
    hgrepos = []
    issue_num = 16580
    keywords = ['patch', 'easy']
    message_count = 13.0
    messages = ['176671', '177042', '177043', '177207', '177208', '177262', '190004', '190013', '190071', '399389', '399607', '399612', '399613']
    nosy_count = 8.0
    nosy_names = ['mark.dickinson', 'paddy3118', 'ezio.melotti', 'asvetlov', 'docs@python', 'serhiy.storchaka', 'woparry', 'quantum']
    pr_nums = ['27760']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue16580'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    @paddy3118
    Copy link
    Mannequin Author

    paddy3118 mannequin commented Nov 29, 2012

    http://docs.python.org/3.3/library/stdtypes.html?highlight=to_bytes#int.to_bytes and http://docs.python.org/3.3/library/stdtypes.html?highlight=to_bytes#int.to_bytes would benefit from an example showing what they do based on simpler coding.

    I have such an example that I wrote here: http://paddy3118.blogspot.co.uk/2012/11/some-identities-for-python-inttobytes.html that you can use.

    I.e.

    >> n = 2491969579123783355964723219455906992268673266682165637887
    >> length = 25
    >> n2bytesbig = n.to_bytes(length, 'big')
    >> n2byteslittle = n.to_bytes(length, 'little')
    >> assert n2bytesbig == bytes( (n >> i*8) & 0xff for i in reversed(range(length)))
    >> assert n2byteslittle == bytes( (n >> i*8) & 0xff for i in range(length))
    >> assert n == sum( n2bytesbig[::-1][i] << i*8 for i in range(length) )
    >> assert n == sum( n2byteslittle[i] << i*8 for i in range(length) )
    >> assert n == int.from_bytes(n2bytesbig, byteorder='big')
    >> assert n == int.from_bytes(n2byteslittle, byteorder='little')
    >>

    @paddy3118 paddy3118 mannequin assigned docspython Nov 29, 2012
    @paddy3118 paddy3118 mannequin added docs Documentation in the Doc dir type-feature A feature request or enhancement labels Nov 29, 2012
    @asvetlov
    Copy link
    Contributor

    asvetlov commented Dec 6, 2012

    Your example is comprehensive but not simple and obvious.
    I think better to keep it out of doc.

    @ezio-melotti
    Copy link
    Member

    I agree. The examples in the doc seem clear to me, whereas the ones you proposed are not as clear. Do you think there's something that they don't currently cover that should be added?

    @paddy3118
    Copy link
    Mannequin Author

    paddy3118 mannequin commented Dec 9, 2012

    On 06/12/2012 14:31, Ezio Melotti wrote:

    Ezio Melotti added the comment:

    I agree. The examples in the doc seem clear to me, whereas the ones you proposed are not as clear. Do you think there's something that they don't currently cover that should be added?

    ----------
    nosy: +ezio.melotti


    Python tracker <report@bugs.python.org>
    <http://bugs.python.org/issue16580\>


    First, Thanks Ezio and Andrew for your replies.

    My problem was that when working on bitcoin address validation I saw
    code that was shifting and &'ing with 0xFF to convert to multiple bytes
    and half remembered that there might be a Python function to do that. On
    finding the .to_bytes method and its parameter "big" or "little", the
    only way I had of working out which to use was to try each until I found
    out which worked.

    I therefore thought that what would have helped me was code that showed
    the equivalent "expanded Python" for the method in a similar way to what
    is done for some of the itertools functions etc.

    If we split my request into two:

    1. Is such extra explanation necessary.
    2. Is my specific code that extra explanation.

    I can work on the code a bit more.
    Have I persuaded you that an extra explanation is necessary?

    Thanks, Paddy.

    P.S. I guess what is currently present shows the result of the methods
    but nothing on how it could be generated. I am stating that the
    generation can aid comprehension.

    @ezio-melotti
    Copy link
    Member

    Usually we add plain Python equivalents when they are simple enough that the code equivalent is as understandable as the prose or more (see for example http://docs.python.org/3/library/functions.html#all, or the itertools functions you mentioned).
    For this case I think it would help if you presented an equivalent function, e.g.:

    def to_bytes(n, length, order):
        if order == 'little':
            return bytes((n >> i*8) & 0xff for i in range(length))
        elif order == 'big':
            return bytes((n >> i*8) & 0xff for i in reversed(range(length)))

    or even:

    def to_bytes(n, length, order):
        indexes = range(length) if order == 'little' else reversed(range(length))
        return bytes((n >> i*8) & 0xff for i in indexes)

    This is also done for http://docs.python.org/3.3/library/stdtypes.html#int.bit_length just above to/from_bytes, so it might be a good addition.
    If this is done, the equivalent function can also be added to the test suite, so we can verify that it's indeed equivalent.

    @paddy3118
    Copy link
    Mannequin Author

    paddy3118 mannequin commented Dec 10, 2012

    On 09/12/2012 10:55, Ezio Melotti wrote:

    Ezio Melotti added the comment:

    Usually we add plain Python equivalents when they are simple enough that the code equivalent is as understandable as the prose or more (see for example http://docs.python.org/3/library/functions.html#all, or the itertools functions you mentioned).
    For this case I think it would help if you presented an equivalent function, e.g.:

    def to_bytes(n, length, order):
    if order == 'little':
    return bytes((n >> i*8) & 0xff for i in range(length))
    elif order == 'big':
    return bytes((n >> i*8) & 0xff for i in reversed(range(length)))

    or even:

    def to_bytes(n, length, order):
    indexes = range(length) if order == 'little' else reversed(range(length))
    return bytes((n >> i*8) & 0xff for i in indexes)

    This is also done for http://docs.python.org/3.3/library/stdtypes.html#int.bit_length just above to/from_bytes, so it might be a good addition.
    If this is done, the equivalent function can also be added to the test suite, so we can verify that it's indeed equivalent.

    ----------
    keywords: +easy
    stage: -> needs patch
    versions: +Python 2.7, Python 3.2, Python 3.4


    Python tracker <report@bugs.python.org>
    <http://bugs.python.org/issue16580\>


    The second example looks great. I like the dual use for testing too and
    will try and remember both the next time I find I have ireas about the
    documentation.

    Thanks guys. It's appreciated!

    @RamchandraApte RamchandraApte mannequin changed the title Add examples to int.to_bytres and int.from_bytes Add examples to int.to_bytes and int.from_bytes Jan 13, 2013
    @woparry
    Copy link
    Mannequin

    woparry mannequin commented May 25, 2013

    Patch adding examples + tests for equivalence. Comments appreciated.

    In particular, I'm not sure that the from_bytes example is simple enough to be useful:

    def from_bytes(bytes, byteorder, signed=False):
        if byteorder == 'little':
            little_ordered = list(bytes)
        elif byteorder == 'big':
            little_ordered = list(reversed(bytes))
         n = sum(little_ordered[i] << i*8 for i in range(len(little_ordered)))
        if signed and little_ordered and (little_ordered[-1] & 0x80):
             n -= 1 << 8*len(little_ordered)
        return n

    @serhiy-storchaka
    Copy link
    Member

    I don't call it the examples. Here is the examples:

    >>> (1234).to_bytes(2, 'big')
    b'\x04\xd2'
    >>> (1234).to_bytes(2, 'little')
    b'\xd2\x04'
    >>> (-1234).to_bytes(2, 'big', signed=True)
    b'\xfb.'
    >>> int.from_bytes(b'\xde\xad\xbe\xef', 'big')
    3735928559
    >>> int.from_bytes(b'\xde\xad\xbe\xef', 'little')
    4022250974
    >>> int.from_bytes(b'\xde\xad\xbe\xef', 'big', signed=True)
    -559038737

    @mdickinson
    Copy link
    Member

    The from_bytes example code looks fine to me, except that I'd probably use enumerate in the iteration; i.e.,

        sum(b << 8*i for i, b in enumerate(little_ordered))

    instead of

        sum(little_ordered[i] << i*8 for i in range(len(little_ordered)))

    Also, in:

       if signed and little_ordered and (little_ordered[-1] & 0x80):

    I wondered why you needed the little_ordered check. But I see that int.from_bytes(b'', 'little', signed=True) produces 0, which is a little bit disappointing: I was expecting an exception. (A signed format should have a sign bit, which is impossible if the length of the byte string is 0.)

    The to_bytes example code is missing range checks for the input. It may be clearer to simply state that in the docs, instead of modifying the example code to add the range checks.

    @iritkatriel iritkatriel added 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes labels Aug 2, 2021
    @iritkatriel iritkatriel changed the title Add examples to int.to_bytes and int.from_bytes [doc] Add examples to int.to_bytes and int.from_bytes Aug 2, 2021
    @quantumgc
    Copy link
    Mannequin

    quantumgc mannequin commented Aug 11, 2021

    I've rewritten woparry's patch so that it targets the current codebase as well as fixing the issues that Mark mentioned. It appears that the range checks on to_bytes have already been added to the documentation so I haven't added those.

    Should a separate issue be raised for the behaviour of int.from_bytes(b'', <byteorder>, signed=True')? I think it's out of scope for this issue.

    @mdickinson
    Copy link
    Member

    @Gautam

    I think it's out of scope for this issue.

    Agreed. It was just a note in passing. I don't think it's worth opening a new issue, though, unless this is genuinely causing problems for someone. Just let it lie.

    @mdickinson
    Copy link
    Member

    New changeset ad0a8a9 by Gautam Chaudhuri in branch 'main':
    bpo-16580: [doc] Add examples to int.to_bytes and int.from_bytes (GH-27760)
    ad0a8a9

    @mdickinson
    Copy link
    Member

    Merged. Thank you for the contribution!

    @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
    3.9 only security fixes 3.10 only security fixes 3.11 only security fixes docs Documentation in the Doc dir easy type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    5 participants