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

Backport to Python 2.7? #1

Closed
ahawker opened this issue Jun 16, 2017 · 6 comments
Closed

Backport to Python 2.7? #1

ahawker opened this issue Jun 16, 2017 · 6 comments

Comments

@ahawker
Copy link
Owner

ahawker commented Jun 16, 2017

Here are some initial thoughts but definitely incomplete list of changes necessary.

  • Switch hard coded bytes to be configurable to str.
  • Loss of int.to_bytes() and int.from_bytes().
  • Loss of datetime.timestamp()
  • Differences between memoryview and buffer?
@ahawker ahawker changed the title Consider a backport to Python 2.7? Backport to Python 2.7? Jun 16, 2017
@blakev
Copy link

blakev commented Jun 16, 2017

I'm almost done with this, ~20 more errors to squash in the test suite, mostly with handling bytes vs bytearray in python2

@nicktimko
Copy link

@blakev what are you using to strip out all the function annotations; something automated or just discarding them all?

@blakev
Copy link

blakev commented Jun 23, 2017

I did it by hand because there weren't too many.

This was the recommended way:

def decode(value):
    ...
    ...
decode.__annotations__ = {'value': str, 'return': bytes_}

There's also a ._compat.py file I'm working on to add missing functionality between the two versions:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# >>
#     ulid, 2017
# <<
from __future__ import division  # enable true division
import sys
import struct
import datetime
import binascii

PY2 = sys.version_info[0] == 2
MAX_INT = (256**8)-1  # unsigned long long
int_ = None           # deferred type

if PY2:
    bytes_ = bytearray
    string_types = (basestring,)

else:
    int_ = int
    bytes_ = bytes
    string_types = (str,)


class Int(object):
    def __init__(self, x='0', base=10):
        self.x = x
        self.base = base

    def __int__(self):
        return int(self.x)

    def to_bytes(self, length, byteorder='big'):
        try:
            ch = '>' if byteorder.startswith('b') else '<'
            hex_str = '%x' % int(self)
            n = len(hex_str)
            x = binascii.unhexlify(hex_str.zfill(n + (n & 1)))
            val = x[-1 * length:] if ch == '>' else x[:length]
        except OverflowError:
            raise ValueError(self)
        return val
    to_bytes.__annotations__ = {'length': int, 'byteorder': str, 'return': bytes_}

    @classmethod
    def from_bytes(cls, b, byteorder='big'):
        # type: (bytes, str) -> Int
        val = bytes_(memoryview(b).tobytes())
        byteorder = byteorder.lower()
        ch = '>' if byteorder.startswith('b') else '<'
        hi = struct.unpack(ch + 'B'*len(val), val)
        xo = 0 + sum(n**(i+1) for i, n in enumerate(hi))
        return xo

# 8670479856763644750035483567436052040L
# 300150790306154394174966339365723675170L

if PY2:
    int_ = Int


def to_timestamp(dt):
    if hasattr(dt, 'timestamp'):
        return dt.timestamp()
    utc_native = dt.replace(tzinfo=None) - dt.utcoffset()
    timestamp = (utc_native - datetime.datetime(1970, 1, 1)).total_seconds()
    return int_(timestamp)
to_timestamp.__annotations__ = {'dt': datetime.datetime, 'return': int_}

@ahawker
Copy link
Owner Author

ahawker commented Jun 23, 2017

Isn't there a backport of typing to 2.7? Or am I mis-remembering?

@blakev
Copy link

blakev commented Jun 23, 2017

It doesn't really work like you'd expect. The two recommended formats are the func.__annotations__ style or doing a single comment before the docstring:

    @classmethod
    def from_bytes(cls, b, byteorder='big'):
        # type: (bytes, str) -> Int
        """ My function method turns these bytes to a number! """

classmethod's didn't seem to work well with the __annotations__ style so I used # type: instead in those cases.

PyCharm and other tools will pick up on these.

@ahawker ahawker added the ready label Jun 25, 2017
@ahawker
Copy link
Owner Author

ahawker commented Oct 2, 2019

Closing as py27 is being EOL'd very soon.

@ahawker ahawker closed this as completed Oct 2, 2019
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants