Skip to content

Commit

Permalink
Drop unsupported pythons
Browse files Browse the repository at this point in the history
Drop support for pythons <3.7 (including python 2).

Since this makes it part of the standard library, replace `mock` with
`unittest.mock` in tests.

This also required replacing `nose` with `pytest` in tests This is
because `nose` is not under active development[1], and the version
specified fails to run on python3 (and newer versions fail to run on
python3.10[2]):

    $ python -m nose
    Traceback (most recent call last):
      File "/usr/lib/python3.10/runpy.py", line 187, in _run_module_as_main
        mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
      File "/usr/lib/python3.10/runpy.py", line 146, in _get_module_details
        return _get_module_details(pkg_main_name, error)
      File "/usr/lib/python3.10/runpy.py", line 110, in _get_module_details
        __import__(pkg_name)
      File "/home/mjh/src/pystatsd/.venv/lib/python3.10/site-packages/nose/__init__.py", line 1, in <module>
        from nose.core import collector, main, run, run_exit, runmodule
      File "/home/mjh/src/pystatsd/.venv/lib/python3.10/site-packages/nose/core.py", line 143
        print "%s version %s" % (os.path.basename(sys.argv[0]), __version__)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?

`pytest` is pinned at the lowest version supporting python3.10[3],
similarly for coverage[4], `flake8` was also bump to a more recent
version.

[1] https://nose.readthedocs.io/en/latest/#note-to-users
[2] nose-devs/nose#1122
[3] https://docs.pytest.org/en/7.1.x/changelog.html#pytest-6-2-5-2021-08-29
[4] https://coverage.readthedocs.io/en/6.4.1/changes.html#version-6-0-2021-10-03
  • Loading branch information
matthewhughes934 committed Jul 8, 2022
1 parent f3f304b commit 91fe570
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 34 deletions.
4 changes: 2 additions & 2 deletions docs/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ You can also run the tests with tox::

$ tox

Tox will run the tests in Pythons 2.5, 2.6, 2.7, 3.2, 3.3, 3.4, and
PyPy, if they're available.
Tox will run the tests in Pythons 3.7, 3.8, 3.9, 3.10 and
PyPy3, if they're available.


Writing Tests
Expand Down
5 changes: 2 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
mock==1.0.1
nose==1.2.1
flake8==1.7.0
flake8>=4.0
pytest>=6.2.5
9 changes: 5 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,21 @@
include_package_data=True,
package_data={'': ['README.rst']},
test_suite='nose.collector',
python_requires='>=3.7',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries :: Python Modules',
],
)
37 changes: 16 additions & 21 deletions statsd/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import socket
from datetime import timedelta
from unittest import SkipTest

import mock
from nose.tools import eq_
from unittest import mock

from statsd import StatsClient
from statsd import TCPStatsClient
Expand Down Expand Up @@ -66,22 +64,19 @@ def _unix_socket_client(prefix=None, socket_path=None):

def _timer_check(sock, count, proto, start, end):
send = send_method[proto](sock)
eq_(send.call_count, count)
assert send.call_count == count
value = send.call_args[0][0].decode('ascii')
exp = re.compile(r'^%s:\d+|%s$' % (start, end))
assert exp.match(value)


def _sock_check(sock, count, proto, val=None, addr=None):
send = send_method[proto](sock)
eq_(send.call_count, count)
assert send.call_count == count
if not addr:
addr = ADDR
if val is not None:
eq_(
send.call_args,
make_val[proto](val, addr),
)
assert send.call_args == make_val[proto](val, addr)


class assert_raises(object):
Expand Down Expand Up @@ -443,7 +438,7 @@ def _test_prepare(cl, proto):

def _check(o, s, v, r):
with mock.patch.object(random, 'random', lambda: -1):
eq_(o, cl._prepare(s, v, r))
assert o == cl._prepare(s, v, r)

for o, (s, v, r) in tests:
_check(o, s, v, r)
Expand Down Expand Up @@ -519,13 +514,13 @@ def bar(a, b):

# make sure it works with more than one decorator, called multiple
# times, and that parameters are handled correctly
eq_([4, 2], foo(4, 2))
assert [4, 2] == foo(4, 2)
_timer_check(cl._sock, 1, proto, 'foo', 'ms')

eq_([2, 4], bar(4, 2))
assert [2, 4] == bar(4, 2)
_timer_check(cl._sock, 2, proto, 'bar', 'ms')

eq_([6, 5], bar(5, 6))
assert [6, 5] == bar(5, 6)
_timer_check(cl._sock, 3, proto, 'bar', 'ms')


Expand All @@ -543,7 +538,7 @@ def test_timer_decorator_tcp():

def _test_timer_capture(cl, proto):
with cl.timer('woo') as result:
eq_(result.ms, None)
assert result.ms is None
assert isinstance(result.ms, float)


Expand Down Expand Up @@ -587,7 +582,7 @@ def test_timer_decorator_partial_function():
foo = functools.partial(lambda x: x * x, 2)
func = cl.timer('foo')(foo)

eq_(4, func())
assert 4 == func()

_timer_check(cl._sock, 1, 'tcp', 'foo', 'ms|@0.1')

Expand All @@ -601,10 +596,10 @@ def foo(a, b):
def bar(a, b=2, c=3):
return [c, b, a]

eq_([2, 4], foo(4, 2))
assert [2, 4] == foo(4, 2)
_timer_check(cl._sock, 1, proto, 'foo', 'ms|@0.1')

eq_([3, 2, 5], bar(5))
assert [3, 2, 5] == bar(5)
_timer_check(cl._sock, 2, proto, 'bar', 'ms|@0.2')


Expand Down Expand Up @@ -906,8 +901,8 @@ def test_pipeline_timer_object_tcp():
def _test_pipeline_empty(cl):
with cl.pipeline() as pipe:
pipe.incr('foo')
eq_(1, len(pipe._stats))
eq_(0, len(pipe._stats))
assert 1 == len(pipe._stats)
assert 0 == len(pipe._stats)


def test_pipeline_empty_udp():
Expand Down Expand Up @@ -1006,7 +1001,7 @@ def test_pipeline_packet_size():
# 32 * 16 = 512, so this will need 2 packets.
pipe.incr('sixteen_char_str')
pipe.send()
eq_(2, sc._sock.sendto.call_count)
assert 2 == sc._sock.sendto.call_count
assert len(sc._sock.sendto.call_args_list[0][0][0]) <= 512
assert len(sc._sock.sendto.call_args_list[1][0][0]) <= 512

Expand All @@ -1017,7 +1012,7 @@ def test_tcp_raises_exception_to_user(mock_socket):
addr = ('127.0.0.1', 1234)
cl = _tcp_client(addr=addr[0], port=addr[1])
cl.incr('foo')
eq_(1, cl._sock.sendall.call_count)
assert 1 == cl._sock.sendall.call_count
cl._sock.sendall.side_effect = socket.error
with assert_raises(socket.error):
cl.incr('foo')
Expand Down
7 changes: 3 additions & 4 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ envlist = py27,pypy,py34,py35,py36,py37

[testenv]
deps=
mock==1.0.1
nose==1.2.1
coverage==3.5.2
coverage>=6.0
pytest>=6.2.5

commands=
nosetests statsd --with-coverage --cover-package=statsd []
pytest statsd/tests.py

0 comments on commit 91fe570

Please sign in to comment.