Skip to content

Commit ea3ba0d

Browse files
authored
Merge pull request #458 from groutr/python3
Remove Python 2 support
2 parents afef2c1 + 918918a commit ea3ba0d

22 files changed

+265
-486
lines changed

.coveragerc

-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@ omit =
77
[report]
88
exclude_lines =
99
pragma: no cover
10-
pragma: py$MAJOR_PYTHON_VERSION no cover

.travis.yml

+5-11
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
sudo: false
22
language: python
33
python:
4-
- "2.7"
5-
- "3.4"
64
- "3.5"
75
- "3.6"
8-
- "3.7-dev"
9-
- "pypy"
10-
11-
# Enable 3.7 without globally enabling sudo and dist: xenial for other build jobs
12-
matrix:
13-
include:
14-
- python: 3.7
15-
dist: xenial
16-
sudo: true
6+
- "3.7"
7+
- "3.8"
8+
- "3.9-dev"
9+
- "pypy3.5-7.0"
10+
- "pypy3.6-7.1.1"
1711

1812
env:
1913
- PEP8_IGNORE="E731,W503,E402"

README.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ This builds a standard wordcount function from pieces within ``toolz``:
7373
Dependencies
7474
------------
7575

76-
``toolz`` supports Python 2.7 and Python 3.4+ with a common codebase.
76+
``toolz`` supports Python 3.5+ with a common codebase.
7777
It is pure Python and requires no dependencies beyond the standard
7878
library.
7979

doc/source/install.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ three ways:
1111

1212
1. Toolz is pure Python
1313
2. Toolz relies only on the standard library
14-
3. Toolz simultaneously supports Python versions 2.7, 3.4+, PyPy
14+
3. Toolz simultaneously supports Python versions 3.4+ and PyPy

doc/source/references.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ References
77
similar library for Ruby
88
- `Clojure <http://clojure.org>`__: A functional language whose
99
standard library has several counterparts in ``toolz``
10-
- `itertools <http://docs.python.org/2/library/itertools.html>`__: The
10+
- `itertools <http://docs.python.org/3/library/itertools.html>`__: The
1111
Python standard library for iterator tools
12-
- `functools <http://docs.python.org/2/library/functools.html>`__: The
12+
- `functools <http://docs.python.org/3/library/functools.html>`__: The
1313
Python standard library for function tools
1414
- `Functional Programming HOWTO <http://docs.python.org/dev/howto/functional.html>`__:
1515
The description of functional programming features from the official

setup.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,15 @@
2121
long_description=(open('README.rst').read() if exists('README.rst')
2222
else ''),
2323
zip_safe=False,
24-
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
24+
python_requires=">=3.5",
2525
classifiers=[
2626
"Development Status :: 5 - Production/Stable",
2727
"License :: OSI Approved :: BSD License",
2828
"Programming Language :: Python",
29-
"Programming Language :: Python :: 2",
30-
"Programming Language :: Python :: 2.7",
3129
"Programming Language :: Python :: 3",
32-
"Programming Language :: Python :: 3.4",
3330
"Programming Language :: Python :: 3.5",
3431
"Programming Language :: Python :: 3.6",
3532
"Programming Language :: Python :: 3.7",
33+
"Programming Language :: Python :: 3.8",
3634
"Programming Language :: Python :: Implementation :: CPython",
3735
"Programming Language :: Python :: Implementation :: PyPy"])

toolz/__init__.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66

77
from .recipes import *
88

9-
from .compatibility import map, filter
10-
119
from functools import partial, reduce
1210

1311
sorted = sorted
1412

13+
map = map
14+
15+
filter = filter
16+
1517
# Aliases
1618
comp = compose
1719

toolz/_signatures.py

+59-109
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,10 @@
1818
import operator
1919
from importlib import import_module
2020

21-
from .compatibility import PY3
2221
from .functoolz import (is_partial_args, is_arity, has_varargs,
2322
has_keywords, num_required_args)
2423

25-
if PY3: # pragma: py2 no cover
26-
import builtins
27-
else: # pragma: py3 no cover
28-
import __builtin__ as builtins
24+
import builtins
2925

3026
# We mock builtin callables using lists of tuples with lambda functions.
3127
#
@@ -235,54 +231,33 @@
235231
lambda source, globals: None,
236232
lambda source, globals, locals: None]
237233

238-
if PY3: # pragma: py2 no cover
239-
module_info[builtins].update(
240-
breakpoint=[
241-
lambda *args, **kws: None],
242-
bytes=[
243-
lambda: None,
244-
lambda int: None,
245-
lambda string, encoding='utf8', errors='strict': None],
246-
compile=[
247-
(0, lambda source, filename, mode, flags=0,
248-
dont_inherit=False, optimize=-1: None)],
249-
max=[
250-
(1, lambda iterable: None, ('default', 'key',)),
251-
(1, lambda arg1, arg2, *args: None, ('key',))],
252-
min=[
253-
(1, lambda iterable: None, ('default', 'key',)),
254-
(1, lambda arg1, arg2, *args: None, ('key',))],
255-
open=[
256-
(0, lambda file, mode='r', buffering=-1, encoding=None,
257-
errors=None, newline=None, closefd=True, opener=None: None)],
258-
sorted=[
259-
(1, lambda iterable: None, ('key', 'reverse'))],
260-
str=[
261-
lambda object='', encoding='utf', errors='strict': None],
262-
)
263-
module_info[builtins]['print'] = [
264-
(0, lambda *args: None, ('sep', 'end', 'file', 'flush',))]
265-
266-
else: # pragma: py3 no cover
267-
module_info[builtins].update(
268-
bytes=[
269-
lambda object='': None],
270-
compile=[
271-
(0, lambda source, filename, mode, flags=0,
272-
dont_inherit=False: None)],
273-
max=[
274-
(1, lambda iterable, *args: None, ('key',))],
275-
min=[
276-
(1, lambda iterable, *args: None, ('key',))],
277-
open=[
278-
(0, lambda file, mode='r', buffering=-1: None)],
279-
sorted=[
280-
lambda iterable, cmp=None, key=None, reverse=False: None],
281-
str=[
282-
lambda object='': None],
283-
)
284-
module_info[builtins]['print'] = [
285-
(0, lambda *args: None, ('sep', 'end', 'file',))]
234+
module_info[builtins].update(
235+
breakpoint=[
236+
lambda *args, **kws: None],
237+
bytes=[
238+
lambda: None,
239+
lambda int: None,
240+
lambda string, encoding='utf8', errors='strict': None],
241+
compile=[
242+
(0, lambda source, filename, mode, flags=0,
243+
dont_inherit=False, optimize=-1: None)],
244+
max=[
245+
(1, lambda iterable: None, ('default', 'key',)),
246+
(1, lambda arg1, arg2, *args: None, ('key',))],
247+
min=[
248+
(1, lambda iterable: None, ('default', 'key',)),
249+
(1, lambda arg1, arg2, *args: None, ('key',))],
250+
open=[
251+
(0, lambda file, mode='r', buffering=-1, encoding=None,
252+
errors=None, newline=None, closefd=True, opener=None: None)],
253+
sorted=[
254+
(1, lambda iterable: None, ('key', 'reverse'))],
255+
str=[
256+
lambda object='', encoding='utf', errors='strict': None],
257+
)
258+
module_info[builtins]['print'] = [
259+
(0, lambda *args: None, ('sep', 'end', 'file', 'flush',))]
260+
286261

287262
module_info[functools] = dict(
288263
cmp_to_key=[
@@ -346,16 +321,11 @@
346321
(0, lambda *iterables: None, ('fillvalue',))],
347322
)
348323

349-
if PY3: # pragma: py2 no cover
350-
module_info[itertools].update(
351-
product=[
352-
(0, lambda *iterables: None, ('repeat',))],
353-
)
354-
else: # pragma: py3 no cover
355-
module_info[itertools].update(
356-
product=[
357-
lambda *iterables: None],
358-
)
324+
module_info[itertools].update(
325+
product=[
326+
(0, lambda *iterables: None, ('repeat',))],
327+
)
328+
359329

360330
module_info[operator] = dict(
361331
__abs__=[
@@ -622,51 +592,31 @@
622592
classval=None: None)],
623593
)
624594

625-
if PY3: # pragma: py2 no cover
626-
def num_pos_args(sigspec):
627-
""" Return the number of positional arguments. ``f(x, y=1)`` has 1"""
628-
return sum(1 for x in sigspec.parameters.values()
629-
if x.kind == x.POSITIONAL_OR_KEYWORD
630-
and x.default is x.empty)
631-
632-
def get_exclude_keywords(num_pos_only, sigspec):
633-
""" Return the names of position-only arguments if func has **kwargs"""
634-
if num_pos_only == 0:
635-
return ()
636-
has_kwargs = any(x.kind == x.VAR_KEYWORD
637-
for x in sigspec.parameters.values())
638-
if not has_kwargs:
639-
return ()
640-
pos_args = list(sigspec.parameters.values())[:num_pos_only]
641-
return tuple(x.name for x in pos_args)
642-
643-
def signature_or_spec(func):
644-
try:
645-
return inspect.signature(func)
646-
except (ValueError, TypeError):
647-
return None
648-
649-
else: # pragma: py3 no cover
650-
def num_pos_args(sigspec):
651-
""" Return the number of positional arguments. ``f(x, y=1)`` has 1"""
652-
if sigspec.defaults:
653-
return len(sigspec.args) - len(sigspec.defaults)
654-
return len(sigspec.args)
655-
656-
def get_exclude_keywords(num_pos_only, sigspec):
657-
""" Return the names of position-only arguments if func has **kwargs"""
658-
if num_pos_only == 0:
659-
return ()
660-
has_kwargs = sigspec.keywords is not None
661-
if not has_kwargs:
662-
return ()
663-
return tuple(sigspec.args[:num_pos_only])
664-
665-
def signature_or_spec(func):
666-
try:
667-
return inspect.getargspec(func)
668-
except TypeError:
669-
return None
595+
596+
def num_pos_args(sigspec):
597+
""" Return the number of positional arguments. ``f(x, y=1)`` has 1"""
598+
return sum(1 for x in sigspec.parameters.values()
599+
if x.kind == x.POSITIONAL_OR_KEYWORD
600+
and x.default is x.empty)
601+
602+
603+
def get_exclude_keywords(num_pos_only, sigspec):
604+
""" Return the names of position-only arguments if func has **kwargs"""
605+
if num_pos_only == 0:
606+
return ()
607+
has_kwargs = any(x.kind == x.VAR_KEYWORD
608+
for x in sigspec.parameters.values())
609+
if not has_kwargs:
610+
return ()
611+
pos_args = list(sigspec.parameters.values())[:num_pos_only]
612+
return tuple(x.name for x in pos_args)
613+
614+
615+
def signature_or_spec(func):
616+
try:
617+
return inspect.signature(func)
618+
except (ValueError, TypeError):
619+
return None
670620

671621

672622
def expand_sig(sig):
@@ -792,7 +742,7 @@ def _has_varargs(func):
792742
checks = [check_varargs(sig) for sig in sigs]
793743
if all(checks):
794744
return True
795-
elif any(checks): # pragma: py2 no cover
745+
elif any(checks):
796746
return None
797747
return False
798748

toolz/compatibility.py

+21-25
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,30 @@
1+
import warnings
2+
warnings.warn("The toolz.compatibility module is no longer "
3+
"needed in Python 3 and has been deprecated. Please "
4+
"import these utilities directly from the standard library. "
5+
"This module will be removed in a future release.",
6+
category=DeprecationWarning)
7+
18
import operator
29
import sys
10+
311
PY3 = sys.version_info[0] > 2
412
PY34 = sys.version_info[0] == 3 and sys.version_info[1] == 4
5-
PYPY = hasattr(sys, 'pypy_version_info')
13+
PYPY = hasattr(sys, 'pypy_version_info') and PY3
614

715
__all__ = ('map', 'filter', 'range', 'zip', 'reduce', 'zip_longest',
816
'iteritems', 'iterkeys', 'itervalues', 'filterfalse',
917
'PY3', 'PY34', 'PYPY')
1018

11-
if PY3:
12-
map = map
13-
filter = filter
14-
range = range
15-
zip = zip
16-
from functools import reduce
17-
from itertools import zip_longest
18-
from itertools import filterfalse
19-
iteritems = operator.methodcaller('items')
20-
iterkeys = operator.methodcaller('keys')
21-
itervalues = operator.methodcaller('values')
22-
from collections.abc import Sequence, Mapping
23-
else:
24-
range = xrange
25-
reduce = reduce
26-
from itertools import imap as map
27-
from itertools import ifilter as filter
28-
from itertools import ifilterfalse as filterfalse
29-
from itertools import izip as zip
30-
from itertools import izip_longest as zip_longest
31-
iteritems = operator.methodcaller('iteritems')
32-
iterkeys = operator.methodcaller('iterkeys')
33-
itervalues = operator.methodcaller('itervalues')
34-
from collections import Sequence, Mapping
19+
20+
map = map
21+
filter = filter
22+
range = range
23+
zip = zip
24+
from functools import reduce
25+
from itertools import zip_longest
26+
from itertools import filterfalse
27+
iteritems = operator.methodcaller('items')
28+
iterkeys = operator.methodcaller('keys')
29+
itervalues = operator.methodcaller('values')
30+
from collections.abc import Sequence

0 commit comments

Comments
 (0)