Skip to content

Commit f36378c

Browse files
committed
2024 Updates
- Drop Python 2.7 support and add word of caution about Pypy and setuptools - Update note about CI systems to include 4th gen systems (e.g GitHub Actions) - Convert from setup.py to setup.cfg using the newer methodology so no parameters are specified to `setup()` - Update the `version` test that ensures the code and installation version match to use `subprocess` to inspect the output of `pip show stackinabox` instead of importing `setup.py` as `setup.py` no longer contains the data it was searching for - Fix several tests where the query parameters were separated by both `;` and `&` and it should have only separated on `&` - Update the dependencies to latest stable versions
1 parent bf25972 commit f36378c

13 files changed

+107
-97
lines changed

README.rst

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ Installation is simple:
2828
2929
pip install stackinabox
3030
31+
.. note:: Python 2.7 is no longer supported. Pypy implements Python2.7 compatibility, however, the `setuptools` package
32+
may cause issues if you cannot install a version that supports Python2.7.
33+
3134
=====
3235
Goals
3336
=====
@@ -40,7 +43,7 @@ Goals
4043
- you should not necessarily need to know the ins and outs of each service
4144
- you should be able to register what you need (f.e authentication, storage) and have it just work
4245

43-
- should be useable on systems like Travis (https://travis-ci.org/)
46+
- should be useable on systems like Travis (https://travis-ci.org/), GitHub Actions, etc
4447
- should be light on requirements
4548

4649
- we do not want to bloat your testing to fit our needs

setup.cfg

+30
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,33 @@ cover-erase=1
77
cover-inclusive=true
88
cover-branches=true
99
cover-min-percentage=92
10+
11+
[metadata]
12+
name = stackinabox
13+
url = https://github.com/TestInABox/stackInABox
14+
version = attr: stackinabox.version
15+
author = Benjamen R. Meyer
16+
author_email = [email protected]
17+
description = RESTful API Testing Suite
18+
long_description = file: README.rst, LICENSE, CONTRIBUTING.rst
19+
license = Apache License 2.0
20+
classifiers =
21+
Intended Audience :: Developers
22+
License :: OSI Approved :: Apache Software License
23+
Topic :: Software Development :: Testing
24+
25+
[options]
26+
zip_safe = True
27+
packages = find:
28+
install_requires =
29+
six
30+
31+
[options.extras_require]
32+
httpretty = httpretty==1.1.4
33+
requests-mock = requests-mock
34+
responses = responses>=0.4.0
35+
36+
[options.packages.find]
37+
exclude =
38+
test*
39+
stackinabox/tests

setup.py

+2-26
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,3 @@
1-
import sys
2-
from setuptools import setup, find_packages
1+
from setuptools import setup
32

4-
REQUIRES = ['six']
5-
EXTRA_REQUIRES = {
6-
'httpretty': ['httpretty==0.8.6'],
7-
'requests-mock': ['requests-mock'],
8-
'responses': ['responses>=0.4.0']
9-
}
10-
11-
setup(
12-
name='stackinabox',
13-
version='0.13',
14-
description='RESTful API Testing Suite',
15-
license='Apache License 2.0',
16-
url='https://github.com/TestInABox/stackInABox',
17-
author='Benjamen R. Meyer',
18-
author_email='[email protected]',
19-
install_requires=REQUIRES,
20-
extras_require=EXTRA_REQUIRES,
21-
test_suite='stackinabox',
22-
packages=find_packages(exclude=['tests*', 'stackinabox/tests']),
23-
zip_safe=True,
24-
classifiers=["Intended Audience :: Developers",
25-
"License :: OSI Approved :: MIT License",
26-
"Topic :: Software Development :: Testing"],
27-
)
3+
setup()

tests/test_version.py

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import os.path
3+
import subprocess
34
import sys
45

56
import stackinabox
@@ -11,7 +12,6 @@ class TestVersionMatch(base.TestCase):
1112
def setUp(self):
1213
super(TestVersionMatch, self).setUp()
1314
self.local_directory = os.path.dirname(__file__)
14-
self.setup_py = '{0}/../setup.py'.format(self.local_directory)
1515
self.doc_conf = '{0}/../../docs/conf.py'.format(self.local_directory)
1616

1717
def tearDown(self):
@@ -27,14 +27,25 @@ def make_version_source():
2727
def test_version_match(self):
2828
version_source = self.make_version_source()
2929

30+
# read the data from `pip show <package>` to get the version
31+
# as seen by the installer
3032
version_setup = None
31-
with open(self.setup_py, 'rt') as input_data:
32-
for line in input_data:
33-
ln = line.strip()
34-
if ln.startswith('version='):
35-
ln_parts = ln.replace("'", '', 2).replace(',', '')
36-
version_setup = ln_parts.split('=')[1]
33+
cmd = ["pip", "show", "stackinabox"]
34+
pip_freeze = subprocess.Popen(cmd, stdout=subprocess.PIPE)
35+
output, error = pip_freeze.communicate()
36+
if error is None:
37+
output_lines = output.decode('utf-8').split("\n")
38+
print(f"Read pip freeze data:\n{output_lines}\n")
39+
for line in output_lines:
40+
line_data = line.split(':')
41+
key = line_data[0]
42+
value = ':'.join(line_data[1:]).strip()
43+
print(f"\tLine Key: {key} - Value: {value}")
44+
if key.lower() == "version":
45+
version_setup = value
3746
break
47+
else:
48+
self.fail(f"Unable to retrieve version data - error: {error}")
3849

3950
self.assertEqual(version_source, version_setup)
4051

tests/util/requests_mock/test_core.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,9 @@ def test_basic(self):
149149
'alice': 'alice: Good-Bye bob',
150150
'joe': 'joe: Good-Bye jane'
151151
}
152-
res = self.session.get('http://localhost/advanced/g?bob=alice;'
153-
'alice=bob&joe=jane')
152+
res = self.session.get(
153+
'http://localhost/advanced/g?bob=alice&alice=bob&joe=jane'
154+
)
154155
self.assertEqual(res.status_code, 200)
155156
self.assertEqual(res.json(), expected_result)
156157

@@ -185,8 +186,9 @@ def test_context_requests_mock(self):
185186
'alice': 'alice: Good-Bye bob',
186187
'joe': 'joe: Good-Bye jane'
187188
}
188-
res = requests.get('http://localhost/advanced/g?bob=alice;'
189-
'alice=bob&joe=jane')
189+
res = requests.get(
190+
'http://localhost/advanced/g?bob=alice&alice=bob&joe=jane'
191+
)
190192
self.assertEqual(res.status_code, 200)
191193
self.assertEqual(res.json(), expected_result)
192194

tests/util/requests_mock/test_decorator.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,9 @@ def test_basic(self, session):
9494
'alice': 'alice: Good-Bye bob',
9595
'joe': 'joe: Good-Bye jane'
9696
}
97-
res = session.get('http://localhost/advanced/g?bob=alice;'
98-
'alice=bob&joe=jane')
97+
res = session.get(
98+
'http://localhost/advanced/g?bob=alice&alice=bob&joe=jane'
99+
)
99100
self.assertEqual(res.status_code, 200)
100101
self.assertEqual(res.json(), expected_result)
101102

tests/util/response/test_core.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ def run(use_deprecated):
5656
'alice': 'alice: Good-Bye bob',
5757
'joe': 'joe: Good-Bye jane'
5858
}
59-
res = requests.get('http://localhost/advanced/g?bob=alice;'
60-
'alice=bob&joe=jane')
59+
res = requests.get(
60+
'http://localhost/advanced/g?bob=alice&alice=bob&joe=jane'
61+
)
6162
assert res.status_code == 200
6263
assert res.json() == expected_result
6364

tests/util/response/test_decorator.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,9 @@ def test_advanced_responses():
172172
'alice': 'alice: Good-Bye bob',
173173
'joe': 'joe: Good-Bye jane'
174174
}
175-
res = requests.get('http://localhost/advanced/g?bob=alice;'
176-
'alice=bob&joe=jane')
175+
res = requests.get(
176+
'http://localhost/advanced/g?bob=alice&alice=bob&joe=jane'
177+
)
177178
assert res.status_code == 200
178179
assert res.json() == expected_result
179180

tools/docs-requirements.txt

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
doc8==0.8.1
2-
httpretty==1.0.5
3-
requests==2.25.1
4-
requests-mock==1.8.0
1+
doc8==1.1.1
2+
httpretty==1.1.4
3+
requests==2.31.0
4+
requests-mock==1.11.0
55
responses>=0.12.1
6-
six==1.15.0
7-
sphinx==3.4.2
6+
six==1.16.0
7+
sphinx==7.2.6

tools/pep8-requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
setuptools>=1.1.6
2-
pycodestyle==2.6.0
2+
pycodestyle==2.11.1

tools/py2-test-requirements.txt

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
coverage==4.5.4
2-
ddt==1.2.1
3-
httpretty==0.8.6
4-
mock==3.0.5
5-
pytest==3.3.2
6-
pytest-cov==2.5.1
7-
requests==2.22.0
8-
requests-mock==1.7.0
9-
responses>=0.10.6
10-
six==1.12.0
11-
pycodestyle==2.5.0
12-
attrs==17.2.0
1+
coverage==7.4.1
2+
ddt==1.7.1
3+
httpretty==1.1.4
4+
mock==5.1.0
5+
pytest==8.0.0
6+
pytest-cov==4.1.0
7+
requests==2.31.0
8+
requests-mock==1.11.0
9+
responses>=0.12.1
10+
six==1.16.0
11+
pycodestyle==2.11.1
12+
attrs==23.2.0
13+
setuptools<=44.1.1

tools/test-requirements.txt

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
coverage==5.3.1
2-
ddt==1.4.1
3-
httpretty==1.0.5
4-
mock==4.0.3
5-
pytest==6.2.1
6-
pytest-cov==2.10.1
7-
requests==2.25.1
8-
requests-mock==1.8.0
1+
coverage==7.4.1
2+
ddt==1.7.1
3+
httpretty==1.1.4
4+
mock==5.1.0
5+
pytest==8.0.0
6+
pytest-cov==4.1.0
7+
requests==2.31.0
8+
requests-mock==1.11.0
99
responses>=0.12.1
10-
six==1.15.0
11-
pycodestyle==2.6.0
10+
six==1.16.0
11+
pycodestyle==2.11.1
1212
importlib-metadata==3.3.0 ;python_version<"3.8"

tox.ini

+8-24
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,48 @@
11
[tox]
22
minversion=1.8
3-
envlist = {py3.6,py3.7,py3.8,py3.9},py3-httpretty,py3-requests-mock,py3-responses,pep8,docs
3+
envlist = {py3.8,py3.9,py3.10,py3.11,py3.12},py3-httpretty,py3-requests-mock,py3-responses,pep8,docs
44
skip_missing_interpreters=True
55

66
[testenv]
77
basepython =
8-
py27: python2.7
98
pypy: pypy
109
pypy3: pypy3
11-
py35: python3.5
12-
py3.6: python3.6
13-
py3.7: python3.7
1410
py3.8: python3.8
1511
py3.9: python3.9
12+
py3.10: python3.10
13+
py3.11: python3.11
14+
py3.12: python3.12
1615
pep8: python3
1716
docs: python3
1817
deps =
19-
py27,pypy: -r{toxinidir}/tools/py2-test-requirements.txt
20-
pypy3,py35,py3.6,py3.7,py3.8,py3.9,docs: -r{toxinidir}/tools/test-requirements.txt
18+
pypy: -r{toxinidir}/tools/py2-test-requirements.txt
19+
pypy3,py3.8,py3.9,py3.10,py3.11,py3.12,docs: -r{toxinidir}/tools/test-requirements.txt
2120
pep8: -r{toxinidir}/tools/pep8-requirements.txt
2221
docs: -r{toxinidir}/tools/docs-requirements.txt
2322
commands =
24-
py27,pypy,pypy3,py35,py3.6,py3.7,py3.8,py3.9: pytest {toxinidir}/tests --cov-config=.coveragerc --cov=stackinabox {posargs}
23+
pypy,pypy3,py3.8,py3.9,py3.10,py3.11,py3.12: pytest {toxinidir}/tests --cov-config=.coveragerc --cov=stackinabox {posargs}
2524
pep8: pycodestyle --exclude=.tox,dist,doc,docs,*env*,.*env*,build --ignore=E128,W504
2625
docs: sphinx-build -b html -d {envtmpdir}/doctrees docs docs/_build/html
2726
docs: sphinx-build -b latex -d {envtmpdir}/doctrees docs docs/_build/latex
2827
docs: sphinx-build -b doctest -d {envtmpdir}/doctrees docs docs/_build/html
2928
docs: doc8 --allow-long-titles docs/
3029
setenv =
31-
pypy3,py35,py3.6,py3.7,py3.8,py3.9,py3-httpretty,py3-requests-mock,py3-responses: VIRTUAL_ENV={envdir} LC_ALL = en_US.utf-8
30+
pypy3,py3.8,py3.9,py3.10,py3.11,py3.12,py3-httpretty,py3-requests-mock,py3-responses: VIRTUAL_ENV={envdir} LC_ALL = en_US.utf-8
3231

3332
# Unfortunately the below doesn't seem to integrate well into the form above
3433
# but it's valuable for testing the setup with extra dependencies to make sure things install right
35-
[testenv:py27-httpretty]
36-
basepython = python2.7
37-
deps = .[httpretty]
38-
commands = python -c "import stackinabox.util.httpretty"
39-
4034
[testenv:py3-httpretty]
4135
basepython = python3
4236
deps = .[httpretty]
4337
commands = python -c "import stackinabox.util.httpretty"
4438
setenv ={envdir} LC_ALL = en_US.utf-8
4539

46-
[testenv:py27-requests-mock]
47-
basepython = python2.7
48-
deps = .[requests-mock]
49-
commands = python -c "import stackinabox.util.requests_mock"
50-
5140
[testenv:py3-requests-mock]
5241
basepython = python3
5342
deps = .[requests-mock]
5443
commands = python -c "import stackinabox.util.requests_mock"
5544
setenv ={envdir} LC_ALL = en_US.utf-8
5645

57-
[testenv:py27-responses]
58-
basepython = python2.7
59-
deps = .[responses]
60-
commands = python -c "import stackinabox.util.responses"
61-
6246
[testenv:py3-responses]
6347
basepython = python3
6448
deps = .[responses]

0 commit comments

Comments
 (0)