Skip to content

Commit c8d0751

Browse files
Drop Python 3.6 support (#543)
The following steps have been taken: 1. Black was updated to latest version. The code has been formatted with the new version. 2. The pyupgrade utility is installed. This helped to remove all the code that was needed to support Python < 3.7. Fix #541. Co-authored-by: Inada Naoki <songofacandy@gmail.com>
1 parent feec062 commit c8d0751

23 files changed

+60
-119
lines changed

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
PYTHON_SOURCES = msgpack test setup.py
2+
13
.PHONY: all
24
all: cython
35
python setup.py build_ext -i -f
46

57
.PHONY: black
68
black:
7-
black -S msgpack/ test/ setup.py
9+
black $(PYTHON_SOURCES)
10+
11+
.PHONY: pyupgrade
12+
pyupgrade:
13+
@find $(PYTHON_SOURCES) -name '*.py' -type f -exec pyupgrade --py37-plus '{}' \;
814

915
.PHONY: cython
1016
cython:

msgpack/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# coding: utf-8
21
from .exceptions import *
32
from .ext import ExtType, Timestamp
43

msgpack/ext.py

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# coding: utf-8
21
from collections import namedtuple
32
import datetime
43
import sys
@@ -15,10 +14,10 @@ def __new__(cls, code, data):
1514
raise TypeError("data must be bytes")
1615
if not 0 <= code <= 127:
1716
raise ValueError("code must be 0~127")
18-
return super(ExtType, cls).__new__(cls, code, data)
17+
return super().__new__(cls, code, data)
1918

2019

21-
class Timestamp(object):
20+
class Timestamp:
2221
"""Timestamp represents the Timestamp extension type in msgpack.
2322
2423
When built with Cython, msgpack uses C methods to pack and unpack `Timestamp`. When using pure-Python
@@ -47,24 +46,18 @@ def __init__(self, seconds, nanoseconds=0):
4746
if not isinstance(nanoseconds, int):
4847
raise TypeError("nanoseconds must be an integer")
4948
if not (0 <= nanoseconds < 10**9):
50-
raise ValueError(
51-
"nanoseconds must be a non-negative integer less than 999999999."
52-
)
49+
raise ValueError("nanoseconds must be a non-negative integer less than 999999999.")
5350
self.seconds = seconds
5451
self.nanoseconds = nanoseconds
5552

5653
def __repr__(self):
5754
"""String representation of Timestamp."""
58-
return "Timestamp(seconds={0}, nanoseconds={1})".format(
59-
self.seconds, self.nanoseconds
60-
)
55+
return f"Timestamp(seconds={self.seconds}, nanoseconds={self.nanoseconds})"
6156

6257
def __eq__(self, other):
6358
"""Check for equality with another Timestamp object"""
6459
if type(other) is self.__class__:
65-
return (
66-
self.seconds == other.seconds and self.nanoseconds == other.nanoseconds
67-
)
60+
return self.seconds == other.seconds and self.nanoseconds == other.nanoseconds
6861
return False
6962

7063
def __ne__(self, other):
@@ -164,9 +157,7 @@ def to_datetime(self):
164157
:rtype: datetime.
165158
"""
166159
utc = datetime.timezone.utc
167-
return datetime.datetime.fromtimestamp(0, utc) + datetime.timedelta(
168-
seconds=self.to_unix()
169-
)
160+
return datetime.datetime.fromtimestamp(0, utc) + datetime.timedelta(seconds=self.to_unix())
170161

171162
@staticmethod
172163
def from_datetime(dt):

msgpack/fallback.py

Lines changed: 20 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,6 @@
44
import struct
55

66

7-
if sys.version_info < (3, 5):
8-
# Ugly hack...
9-
RecursionError = RuntimeError
10-
11-
def _is_recursionerror(e):
12-
return (
13-
len(e.args) == 1
14-
and isinstance(e.args[0], str)
15-
and e.args[0].startswith("maximum recursion depth exceeded")
16-
)
17-
18-
else:
19-
20-
def _is_recursionerror(e):
21-
return True
22-
23-
247
if hasattr(sys, "pypy_version_info"):
258
# StringIO is slow on PyPy, StringIO is faster. However: PyPy's own
269
# StringBuilder is fastest.
@@ -32,7 +15,7 @@ def _is_recursionerror(e):
3215
from __pypy__.builders import StringBuilder
3316
USING_STRINGBUILDER = True
3417

35-
class StringIO(object):
18+
class StringIO:
3619
def __init__(self, s=b""):
3720
if s:
3821
self.builder = StringBuilder(len(s))
@@ -109,10 +92,8 @@ def unpackb(packed, **kwargs):
10992
ret = unpacker._unpack()
11093
except OutOfData:
11194
raise ValueError("Unpack failed: incomplete input")
112-
except RecursionError as e:
113-
if _is_recursionerror(e):
114-
raise StackError
115-
raise
95+
except RecursionError:
96+
raise StackError
11697
if unpacker._got_extradata():
11798
raise ExtraData(ret, unpacker._get_extradata())
11899
return ret
@@ -151,7 +132,7 @@ def unpackb(packed, **kwargs):
151132
}
152133

153134

154-
class Unpacker(object):
135+
class Unpacker:
155136
"""Streaming unpacker.
156137
157138
Arguments:
@@ -334,9 +315,7 @@ def __init__(
334315
if object_pairs_hook is not None and not callable(object_pairs_hook):
335316
raise TypeError("`object_pairs_hook` is not callable")
336317
if object_hook is not None and object_pairs_hook is not None:
337-
raise TypeError(
338-
"object_pairs_hook and object_hook are mutually " "exclusive"
339-
)
318+
raise TypeError("object_pairs_hook and object_hook are mutually exclusive")
340319
if not callable(ext_hook):
341320
raise TypeError("`ext_hook` is not callable")
342321

@@ -428,20 +407,18 @@ def _read_header(self):
428407
n = b & 0b00011111
429408
typ = TYPE_RAW
430409
if n > self._max_str_len:
431-
raise ValueError("%s exceeds max_str_len(%s)" % (n, self._max_str_len))
410+
raise ValueError(f"{n} exceeds max_str_len({self._max_str_len})")
432411
obj = self._read(n)
433412
elif b & 0b11110000 == 0b10010000:
434413
n = b & 0b00001111
435414
typ = TYPE_ARRAY
436415
if n > self._max_array_len:
437-
raise ValueError(
438-
"%s exceeds max_array_len(%s)" % (n, self._max_array_len)
439-
)
416+
raise ValueError(f"{n} exceeds max_array_len({self._max_array_len})")
440417
elif b & 0b11110000 == 0b10000000:
441418
n = b & 0b00001111
442419
typ = TYPE_MAP
443420
if n > self._max_map_len:
444-
raise ValueError("%s exceeds max_map_len(%s)" % (n, self._max_map_len))
421+
raise ValueError(f"{n} exceeds max_map_len({self._max_map_len})")
445422
elif b == 0xC0:
446423
obj = None
447424
elif b == 0xC2:
@@ -457,15 +434,15 @@ def _read_header(self):
457434
n = self._buffer[self._buff_i]
458435
self._buff_i += size
459436
if n > self._max_bin_len:
460-
raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
437+
raise ValueError(f"{n} exceeds max_bin_len({self._max_bin_len})")
461438
obj = self._read(n)
462439
elif 0xC7 <= b <= 0xC9:
463440
size, fmt, typ = _MSGPACK_HEADERS[b]
464441
self._reserve(size)
465442
L, n = struct.unpack_from(fmt, self._buffer, self._buff_i)
466443
self._buff_i += size
467444
if L > self._max_ext_len:
468-
raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
445+
raise ValueError(f"{L} exceeds max_ext_len({self._max_ext_len})")
469446
obj = self._read(L)
470447
elif 0xCA <= b <= 0xD3:
471448
size, fmt = _MSGPACK_HEADERS[b]
@@ -478,9 +455,7 @@ def _read_header(self):
478455
elif 0xD4 <= b <= 0xD8:
479456
size, fmt, typ = _MSGPACK_HEADERS[b]
480457
if self._max_ext_len < size:
481-
raise ValueError(
482-
"%s exceeds max_ext_len(%s)" % (size, self._max_ext_len)
483-
)
458+
raise ValueError(f"{size} exceeds max_ext_len({self._max_ext_len})")
484459
self._reserve(size + 1)
485460
n, obj = struct.unpack_from(fmt, self._buffer, self._buff_i)
486461
self._buff_i += size + 1
@@ -493,24 +468,22 @@ def _read_header(self):
493468
n = self._buffer[self._buff_i]
494469
self._buff_i += size
495470
if n > self._max_str_len:
496-
raise ValueError("%s exceeds max_str_len(%s)" % (n, self._max_str_len))
471+
raise ValueError(f"{n} exceeds max_str_len({self._max_str_len})")
497472
obj = self._read(n)
498473
elif 0xDC <= b <= 0xDD:
499474
size, fmt, typ = _MSGPACK_HEADERS[b]
500475
self._reserve(size)
501476
(n,) = struct.unpack_from(fmt, self._buffer, self._buff_i)
502477
self._buff_i += size
503478
if n > self._max_array_len:
504-
raise ValueError(
505-
"%s exceeds max_array_len(%s)" % (n, self._max_array_len)
506-
)
479+
raise ValueError(f"{n} exceeds max_array_len({self._max_array_len})")
507480
elif 0xDE <= b <= 0xDF:
508481
size, fmt, typ = _MSGPACK_HEADERS[b]
509482
self._reserve(size)
510483
(n,) = struct.unpack_from(fmt, self._buffer, self._buff_i)
511484
self._buff_i += size
512485
if n > self._max_map_len:
513-
raise ValueError("%s exceeds max_map_len(%s)" % (n, self._max_map_len))
486+
raise ValueError(f"{n} exceeds max_map_len({self._max_map_len})")
514487
else:
515488
raise FormatError("Unknown header: 0x%x" % b)
516489
return typ, n, obj
@@ -549,17 +522,14 @@ def _unpack(self, execute=EX_CONSTRUCT):
549522
return
550523
if self._object_pairs_hook is not None:
551524
ret = self._object_pairs_hook(
552-
(self._unpack(EX_CONSTRUCT), self._unpack(EX_CONSTRUCT))
553-
for _ in range(n)
525+
(self._unpack(EX_CONSTRUCT), self._unpack(EX_CONSTRUCT)) for _ in range(n)
554526
)
555527
else:
556528
ret = {}
557529
for _ in range(n):
558530
key = self._unpack(EX_CONSTRUCT)
559531
if self._strict_map_key and type(key) not in (str, bytes):
560-
raise ValueError(
561-
"%s is not allowed for map key" % str(type(key))
562-
)
532+
raise ValueError("%s is not allowed for map key" % str(type(key)))
563533
if type(key) is str:
564534
key = sys.intern(key)
565535
ret[key] = self._unpack(EX_CONSTRUCT)
@@ -634,7 +604,7 @@ def tell(self):
634604
return self._stream_offset
635605

636606

637-
class Packer(object):
607+
class Packer:
638608
"""
639609
MessagePack Packer
640610
@@ -844,9 +814,9 @@ def _pack(
844814
continue
845815

846816
if self._datetime and check(obj, _DateTime):
847-
raise ValueError("Cannot serialize %r where tzinfo=None" % (obj,))
817+
raise ValueError(f"Cannot serialize {obj!r} where tzinfo=None")
848818

849-
raise TypeError("Cannot serialize %r" % (obj,))
819+
raise TypeError(f"Cannot serialize {obj!r}")
850820

851821
def pack(self, obj):
852822
try:
@@ -933,7 +903,7 @@ def _pack_map_header(self, n):
933903

934904
def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT):
935905
self._pack_map_header(n)
936-
for (k, v) in pairs:
906+
for k, v in pairs:
937907
self._pack(k, nest_limit - 1)
938908
self._pack(v, nest_limit - 1)
939909

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ requires = [
66
"setuptools >= 35.0.2",
77
]
88
build-backend = "setuptools.build_meta"
9+
10+
[tool.black]
11+
line-length = 100
12+
target-version = ["py37"]
13+
skip_string_normalization = true

requirements.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
# Also declared in pyproject.toml, if updating here please also update there
1+
# Also declared in pyproject.toml, if updating here please also update there.
22
Cython~=0.29.30
33

4-
# dev only tools. no need to add pyproject
5-
black==22.3.0
4+
# Tools required only for development. No need to add it to pyproject.toml file.
5+
black==23.3.0
6+
pytest==7.3.1
7+
pyupgrade==3.3.2

setup.cfg

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ project_urls =
1717

1818
classifiers =
1919
Programming Language :: Python :: 3
20-
Programming Language :: Python :: 3.6
2120
Programming Language :: Python :: 3.7
2221
Programming Language :: Python :: 3.8
2322
Programming Language :: Python :: 3.9

setup.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/usr/bin/env python
2-
# coding: utf-8
32
import io
43
import os
54
import sys
@@ -25,7 +24,7 @@ class NoCython(Exception):
2524

2625

2726
def cythonize(src):
28-
sys.stderr.write("cythonize: %r\n" % (src,))
27+
sys.stderr.write(f"cythonize: {src!r}\n")
2928
cython_compiler.compile([src], cplus=True)
3029

3130

@@ -36,11 +35,7 @@ def ensure_source(src):
3635
if not have_cython:
3736
raise NoCython
3837
cythonize(pyx)
39-
elif (
40-
os.path.exists(pyx)
41-
and os.stat(src).st_mtime < os.stat(pyx).st_mtime
42-
and have_cython
43-
):
38+
elif os.path.exists(pyx) and os.stat(src).st_mtime < os.stat(pyx).st_mtime and have_cython:
4439
cythonize(pyx)
4540
return src
4641

test/test_buffer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/usr/bin/env python
2-
# coding: utf-8
32

43
import sys
54
import pytest

test/test_case.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
#!/usr/bin/env python
2-
# coding: utf-8
32
from msgpack import packb, unpackb
43

54

65
def check(length, obj, use_bin_type=True):
76
v = packb(obj, use_bin_type=use_bin_type)
8-
assert len(v) == length, "%r length should be %r but get %r" % (obj, length, len(v))
7+
assert len(v) == length, f"{obj!r} length should be {length!r} but get {len(v)!r}"
98
assert unpackb(v, use_list=0, raw=not use_bin_type) == obj
109

1110

@@ -120,11 +119,11 @@ def test_match():
120119
),
121120
({}, b"\x80"),
122121
(
123-
dict([(x, x) for x in range(15)]),
122+
{x: x for x in range(15)},
124123
b"\x8f\x00\x00\x01\x01\x02\x02\x03\x03\x04\x04\x05\x05\x06\x06\x07\x07\x08\x08\t\t\n\n\x0b\x0b\x0c\x0c\r\r\x0e\x0e",
125124
),
126125
(
127-
dict([(x, x) for x in range(16)]),
126+
{x: x for x in range(16)},
128127
b"\xde\x00\x10\x00\x00\x01\x01\x02\x02\x03\x03\x04\x04\x05\x05\x06\x06\x07\x07\x08\x08\t\t\n\n\x0b\x0b\x0c\x0c\r\r\x0e\x0e\x0f\x0f",
129128
),
130129
]

test/test_except.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/usr/bin/env python
2-
# coding: utf-8
32

43
from pytest import raises
54
from msgpack import packb, unpackb, Unpacker, FormatError, StackError, OutOfData

test/test_extension.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from __future__ import print_function
21
import array
32
import msgpack
43
from msgpack import ExtType
@@ -17,9 +16,7 @@ def p(s):
1716
assert p(b"A" * 16) == b"\xd8\x42" + b"A" * 16 # fixext 16
1817
assert p(b"ABC") == b"\xc7\x03\x42ABC" # ext 8
1918
assert p(b"A" * 0x0123) == b"\xc8\x01\x23\x42" + b"A" * 0x0123 # ext 16
20-
assert (
21-
p(b"A" * 0x00012345) == b"\xc9\x00\x01\x23\x45\x42" + b"A" * 0x00012345
22-
) # ext 32
19+
assert p(b"A" * 0x00012345) == b"\xc9\x00\x01\x23\x45\x42" + b"A" * 0x00012345 # ext 32
2320

2421

2522
def test_unpack_ext_type():
@@ -49,7 +46,7 @@ def default(obj):
4946
except AttributeError:
5047
data = obj.tostring()
5148
return ExtType(typecode, data)
52-
raise TypeError("Unknown type object %r" % (obj,))
49+
raise TypeError(f"Unknown type object {obj!r}")
5350

5451
def ext_hook(code, data):
5552
print("ext_hook called", code, data)

0 commit comments

Comments
 (0)