Skip to content

Commit

Permalink
Drop python2 support (#519)
Browse files Browse the repository at this point in the history
The PR removes python2 references and cases.

Close #518

Co-authored-by: Inada Naoki <[email protected]>
  • Loading branch information
sblondon and methane authored May 21, 2023
1 parent 45f8486 commit feec062
Show file tree
Hide file tree
Showing 17 changed files with 58 additions and 143 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,9 @@ and `raw=True` options.

```pycon
>>> import msgpack
>>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs'], use_bin_type=False), raw=True)
>>> msgpack.unpackb(msgpack.packb([b'spam', 'eggs'], use_bin_type=False), raw=True)
[b'spam', b'eggs']
>>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs'], use_bin_type=True), raw=False)
>>> msgpack.unpackb(msgpack.packb([b'spam', 'eggs'], use_bin_type=True), raw=False)
[b'spam', 'eggs']
```

Expand Down
20 changes: 10 additions & 10 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
master_doc = "index"

# General information about the project.
project = u"msgpack"
copyright = u"Inada Naoki"
project = "msgpack"
copyright = "Inada Naoki"

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -181,7 +181,7 @@
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
("index", "msgpack.tex", u"msgpack Documentation", u"Author", "manual"),
("index", "msgpack.tex", "msgpack Documentation", "Author", "manual"),
]

# The name of an image file (relative to this directory) to place at the top of
Expand Down Expand Up @@ -209,7 +209,7 @@

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [("index", "msgpack", u"msgpack Documentation", [u"Author"], 1)]
man_pages = [("index", "msgpack", "msgpack Documentation", ["Author"], 1)]

# If true, show URL addresses after external links.
# man_show_urls = False
Expand All @@ -224,8 +224,8 @@
(
"index",
"msgpack",
u"msgpack Documentation",
u"Author",
"msgpack Documentation",
"Author",
"msgpack",
"One line description of project.",
"Miscellaneous",
Expand All @@ -245,10 +245,10 @@
# -- Options for Epub output ---------------------------------------------------

# Bibliographic Dublin Core info.
epub_title = u"msgpack"
epub_author = u"Author"
epub_publisher = u"Author"
epub_copyright = u"2013, Author"
epub_title = "msgpack"
epub_author = "Author"
epub_publisher = "Author"
epub_copyright = "2013, Author"

# The language of the text. It defaults to the language option
# or en if the language is not set.
Expand Down
2 changes: 1 addition & 1 deletion msgpack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
__version__ = "1.0.5"


if os.environ.get("MSGPACK_PUREPYTHON") or sys.version_info[0] == 2:
if os.environ.get("MSGPACK_PUREPYTHON"):
from .fallback import Packer, unpackb, Unpacker
else:
try:
Expand Down
1 change: 0 additions & 1 deletion msgpack/_packer.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ cdef class Packer(object):
If set to true, datetime with tzinfo is packed into Timestamp type.
Note that the tzinfo is stripped in the timestamp.
You can get UTC datetime with `timestamp=3` option of the Unpacker.
(Python 2 is not supported).
:param str unicode_errors:
The error handler for encoding unicode. (default: 'strict')
Expand Down
2 changes: 1 addition & 1 deletion msgpack/_unpacker.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ cdef class Unpacker(object):
0 - Timestamp
1 - float (Seconds from the EPOCH)
2 - int (Nanoseconds from the EPOCH)
3 - datetime.datetime (UTC). Python 2 is not supported.
3 - datetime.datetime (UTC).
:param bool strict_map_key:
If true (default), only str or bytes are accepted for map (dict) keys.
Expand Down
24 changes: 4 additions & 20 deletions msgpack/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,6 @@
import struct


PY2 = sys.version_info[0] == 2

if PY2:
int_types = (int, long)
_utc = None
else:
int_types = int
try:
_utc = datetime.timezone.utc
except AttributeError:
_utc = datetime.timezone(datetime.timedelta(0))


class ExtType(namedtuple("ExtType", "code data")):
"""ExtType represents ext type in msgpack."""

Expand Down Expand Up @@ -55,9 +42,9 @@ def __init__(self, seconds, nanoseconds=0):
Note: Negative times (before the UNIX epoch) are represented as negative seconds + positive ns.
"""
if not isinstance(seconds, int_types):
if not isinstance(seconds, int):
raise TypeError("seconds must be an integer")
if not isinstance(nanoseconds, int_types):
if not isinstance(nanoseconds, int):
raise TypeError("nanoseconds must be an integer")
if not (0 <= nanoseconds < 10**9):
raise ValueError(
Expand Down Expand Up @@ -174,20 +161,17 @@ def to_unix_nano(self):
def to_datetime(self):
"""Get the timestamp as a UTC datetime.
Python 2 is not supported.
:rtype: datetime.
"""
return datetime.datetime.fromtimestamp(0, _utc) + datetime.timedelta(
utc = datetime.timezone.utc
return datetime.datetime.fromtimestamp(0, utc) + datetime.timedelta(
seconds=self.to_unix()
)

@staticmethod
def from_datetime(dt):
"""Create a Timestamp from datetime with tzinfo.
Python 2 is not supported.
:rtype: Timestamp
"""
return Timestamp.from_unix(dt.timestamp())
70 changes: 20 additions & 50 deletions msgpack/fallback.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,6 @@
import struct


PY2 = sys.version_info[0] == 2
if PY2:
int_types = (int, long)

def dict_iteritems(d):
return d.iteritems()

else:
int_types = int
unicode = str
xrange = range

def dict_iteritems(d):
return d.items()


if sys.version_info < (3, 5):
# Ugly hack...
RecursionError = RuntimeError
Expand Down Expand Up @@ -134,15 +118,6 @@ def unpackb(packed, **kwargs):
return ret


if sys.version_info < (2, 7, 6):

def _unpack_from(f, b, o=0):
"""Explicit type cast for legacy struct.unpack_from"""
return struct.unpack_from(f, bytes(b), o)

else:
_unpack_from = struct.unpack_from

_NO_FORMAT_USED = ""
_MSGPACK_HEADERS = {
0xC4: (1, _NO_FORMAT_USED, TYPE_BIN),
Expand Down Expand Up @@ -202,7 +177,7 @@ class Unpacker(object):
0 - Timestamp
1 - float (Seconds from the EPOCH)
2 - int (Nanoseconds from the EPOCH)
3 - datetime.datetime (UTC). Python 2 is not supported.
3 - datetime.datetime (UTC).
:param bool strict_map_key:
If true (default), only str or bytes are accepted for map (dict) keys.
Expand Down Expand Up @@ -477,7 +452,7 @@ def _read_header(self):
size, fmt, typ = _MSGPACK_HEADERS[b]
self._reserve(size)
if len(fmt) > 0:
n = _unpack_from(fmt, self._buffer, self._buff_i)[0]
n = struct.unpack_from(fmt, self._buffer, self._buff_i)[0]
else:
n = self._buffer[self._buff_i]
self._buff_i += size
Expand All @@ -487,7 +462,7 @@ def _read_header(self):
elif 0xC7 <= b <= 0xC9:
size, fmt, typ = _MSGPACK_HEADERS[b]
self._reserve(size)
L, n = _unpack_from(fmt, self._buffer, self._buff_i)
L, n = struct.unpack_from(fmt, self._buffer, self._buff_i)
self._buff_i += size
if L > self._max_ext_len:
raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
Expand All @@ -496,7 +471,7 @@ def _read_header(self):
size, fmt = _MSGPACK_HEADERS[b]
self._reserve(size)
if len(fmt) > 0:
obj = _unpack_from(fmt, self._buffer, self._buff_i)[0]
obj = struct.unpack_from(fmt, self._buffer, self._buff_i)[0]
else:
obj = self._buffer[self._buff_i]
self._buff_i += size
Expand All @@ -507,13 +482,13 @@ def _read_header(self):
"%s exceeds max_ext_len(%s)" % (size, self._max_ext_len)
)
self._reserve(size + 1)
n, obj = _unpack_from(fmt, self._buffer, self._buff_i)
n, obj = struct.unpack_from(fmt, self._buffer, self._buff_i)
self._buff_i += size + 1
elif 0xD9 <= b <= 0xDB:
size, fmt, typ = _MSGPACK_HEADERS[b]
self._reserve(size)
if len(fmt) > 0:
(n,) = _unpack_from(fmt, self._buffer, self._buff_i)
(n,) = struct.unpack_from(fmt, self._buffer, self._buff_i)
else:
n = self._buffer[self._buff_i]
self._buff_i += size
Expand All @@ -523,7 +498,7 @@ def _read_header(self):
elif 0xDC <= b <= 0xDD:
size, fmt, typ = _MSGPACK_HEADERS[b]
self._reserve(size)
(n,) = _unpack_from(fmt, self._buffer, self._buff_i)
(n,) = struct.unpack_from(fmt, self._buffer, self._buff_i)
self._buff_i += size
if n > self._max_array_len:
raise ValueError(
Expand All @@ -532,7 +507,7 @@ def _read_header(self):
elif 0xDE <= b <= 0xDF:
size, fmt, typ = _MSGPACK_HEADERS[b]
self._reserve(size)
(n,) = _unpack_from(fmt, self._buffer, self._buff_i)
(n,) = struct.unpack_from(fmt, self._buffer, self._buff_i)
self._buff_i += size
if n > self._max_map_len:
raise ValueError("%s exceeds max_map_len(%s)" % (n, self._max_map_len))
Expand All @@ -554,38 +529,38 @@ def _unpack(self, execute=EX_CONSTRUCT):
# TODO should we eliminate the recursion?
if typ == TYPE_ARRAY:
if execute == EX_SKIP:
for i in xrange(n):
for i in range(n):
# TODO check whether we need to call `list_hook`
self._unpack(EX_SKIP)
return
ret = newlist_hint(n)
for i in xrange(n):
for i in range(n):
ret.append(self._unpack(EX_CONSTRUCT))
if self._list_hook is not None:
ret = self._list_hook(ret)
# TODO is the interaction between `list_hook` and `use_list` ok?
return ret if self._use_list else tuple(ret)
if typ == TYPE_MAP:
if execute == EX_SKIP:
for i in xrange(n):
for i in range(n):
# TODO check whether we need to call hooks
self._unpack(EX_SKIP)
self._unpack(EX_SKIP)
return
if self._object_pairs_hook is not None:
ret = self._object_pairs_hook(
(self._unpack(EX_CONSTRUCT), self._unpack(EX_CONSTRUCT))
for _ in xrange(n)
for _ in range(n)
)
else:
ret = {}
for _ in xrange(n):
for _ in range(n):
key = self._unpack(EX_CONSTRUCT)
if self._strict_map_key and type(key) not in (unicode, bytes):
if self._strict_map_key and type(key) not in (str, bytes):
raise ValueError(
"%s is not allowed for map key" % str(type(key))
)
if not PY2 and type(key) is str:
if type(key) is str:
key = sys.intern(key)
ret[key] = self._unpack(EX_CONSTRUCT)
if self._object_hook is not None:
Expand Down Expand Up @@ -698,7 +673,6 @@ class Packer(object):
If set to true, datetime with tzinfo is packed into Timestamp type.
Note that the tzinfo is stripped in the timestamp.
You can get UTC datetime with `timestamp=3` option of the Unpacker.
(Python 2 is not supported).
:param str unicode_errors:
The error handler for encoding unicode. (default: 'strict')
Expand Down Expand Up @@ -743,8 +717,6 @@ def __init__(
self._autoreset = autoreset
self._use_bin_type = use_bin_type
self._buffer = StringIO()
if PY2 and datetime:
raise ValueError("datetime is not supported in Python 2")
self._datetime = bool(datetime)
self._unicode_errors = unicode_errors or "strict"
if default is not None:
Expand Down Expand Up @@ -774,7 +746,7 @@ def _pack(
if obj:
return self._buffer.write(b"\xc3")
return self._buffer.write(b"\xc2")
if check(obj, int_types):
if check(obj, int):
if 0 <= obj < 0x80:
return self._buffer.write(struct.pack("B", obj))
if -0x20 <= obj < 0:
Expand Down Expand Up @@ -806,7 +778,7 @@ def _pack(
raise ValueError("%s is too large" % type(obj).__name__)
self._pack_bin_header(n)
return self._buffer.write(obj)
if check(obj, unicode):
if check(obj, str):
obj = obj.encode("utf-8", self._unicode_errors)
n = len(obj)
if n >= 2**32:
Expand Down Expand Up @@ -855,13 +827,11 @@ def _pack(
if check(obj, list_types):
n = len(obj)
self._pack_array_header(n)
for i in xrange(n):
for i in range(n):
self._pack(obj[i], nest_limit - 1)
return
if check(obj, dict):
return self._pack_map_pairs(
len(obj), dict_iteritems(obj), nest_limit - 1
)
return self._pack_map_pairs(len(obj), obj.items(), nest_limit - 1)

if self._datetime and check(obj, _DateTime) and obj.tzinfo is not None:
obj = Timestamp.from_datetime(obj)
Expand Down Expand Up @@ -1004,7 +974,7 @@ def reset(self):

def getbuffer(self):
"""Return view of internal buffer."""
if USING_STRINGBUILDER or PY2:
if USING_STRINGBUILDER:
return memoryview(self.bytes())
else:
return self._buffer.getbuffer()
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@


PYPY = hasattr(sys, "pypy_version_info")
PY2 = sys.version_info[0] == 2


class NoCython(Exception):
Expand Down Expand Up @@ -79,7 +78,7 @@ def __init__(self, *args, **kwargs):
macros = [("__LITTLE_ENDIAN__", "1")]

ext_modules = []
if not PYPY and not PY2 and not os.environ.get("MSGPACK_PUREPYTHON"):
if not PYPY and not os.environ.get("MSGPACK_PUREPYTHON"):
ext_modules.append(
Extension(
"msgpack._cmsgpack",
Expand Down
1 change: 0 additions & 1 deletion test/test_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from msgpack import packb, unpackb


@pytest.mark.skipif(sys.version_info[0] == 2, reason="Python 2 is not supported")
def test_unpack_buffer():
from array import array

Expand Down
2 changes: 1 addition & 1 deletion test/test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,4 @@ def test_match():


def test_unicode():
assert unpackb(packb(u"foobar"), use_list=1) == u"foobar"
assert unpackb(packb("foobar"), use_list=1) == "foobar"
Loading

0 comments on commit feec062

Please sign in to comment.