Skip to content

Commit 9764d80

Browse files
authored
Remove python 2 support (#78)
* Remove python 2 support * Lint * Simplify pyproject and remove requires_py3 refs * Properly fix compat * flynt/pyupgrade changes
1 parent e190ad6 commit 9764d80

10 files changed

+30
-88
lines changed

.ci/Jenkinsfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pipeline {
5555
axes {
5656
axis {
5757
name 'VERSION'
58-
values '2.7', '3.6', '3.7', '3.8'
58+
values '3.6', '3.7', '3.8', '3.9', '3.10'
5959
}
6060
}
6161
stages {
@@ -88,7 +88,7 @@ pipeline {
8888
}
8989

9090
def python(Map v = [:], body) {
91-
def dockerImage = v.version.equals('2.7') ? 'python:3.7' : "python:${v.version}"
91+
def dockerImage = "python:${v.version}"
9292
// If dockerhub got issues then let's retry twice
9393
retry(2) {
9494
sleep 5

ecs_logging/_stdlib.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,9 @@ def __init__(
111111
if validate is not None:
112112
# validate was introduced in py3.8 so we need to only provide it if the user provided it
113113
_kwargs["validate"] = validate
114-
if sys.version_info < (3, 0): # Different args in py2.7
115-
super(StdlibFormatter, self).__init__( # type: ignore[call-arg]
116-
fmt=fmt, datefmt=datefmt
117-
)
118-
else:
119-
super(StdlibFormatter, self).__init__( # type: ignore[call-arg]
120-
fmt=fmt, datefmt=datefmt, style=style, **_kwargs
121-
)
114+
super().__init__( # type: ignore[call-arg]
115+
fmt=fmt, datefmt=datefmt, style=style, **_kwargs
116+
)
122117

123118
if stack_trace_limit is not None:
124119
if not isinstance(stack_trace_limit, int):

ecs_logging/_utils.py

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,15 @@ def flatten_dict(value):
6262
for key, val in value.items():
6363
if not isinstance(val, collections_abc.Mapping):
6464
if key in top_level:
65-
raise ValueError(
66-
"Duplicate entry for '%s' with different nesting" % key
67-
)
65+
raise ValueError(f"Duplicate entry for '{key}' with different nesting")
6866
top_level[key] = val
6967
else:
7068
val = flatten_dict(val)
7169
for vkey, vval in val.items():
72-
vkey = "%s.%s" % (key, vkey)
70+
vkey = f"{key}.{vkey}"
7371
if vkey in top_level:
7472
raise ValueError(
75-
"Duplicate entry for '%s' with different nesting" % vkey
73+
f"Duplicate entry for '{vkey}' with different nesting"
7674
)
7775
top_level[vkey] = vval
7876

@@ -163,16 +161,9 @@ def json_dumps(value):
163161
# Need to call json.dumps() on values just in
164162
# case the given values aren't strings (even though
165163
# they should be according to the spec)
166-
ordered_json = ",".join(
167-
'"%s":%s'
168-
% (
169-
k,
170-
json_dumps(v),
171-
)
172-
for k, v in ordered_fields
173-
)
164+
ordered_json = ",".join(f'"{k}":{json_dumps(v)}' for k, v in ordered_fields)
174165
if value:
175-
return "{%s,%s" % (
166+
return "{{{},{}".format(
176167
ordered_json,
177168
json_dumps(value)[1:],
178169
)

noxfile.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,27 @@ def tests_impl(session):
3232
"--junitxml=junit-test.xml",
3333
"--cov=ecs_logging",
3434
*(session.posargs or ("tests/",)),
35-
env={"PYTHONWARNINGS": "always::DeprecationWarning"}
35+
env={"PYTHONWARNINGS": "always::DeprecationWarning"},
3636
)
3737

3838

39-
@nox.session(python=["2.7", "3.6", "3.7", "3.8"])
39+
@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10"])
4040
def test(session):
4141
tests_impl(session)
4242

4343

4444
@nox.session()
4545
def blacken(session):
4646
session.install("black")
47-
session.run("black", "--target-version=py27", *SOURCE_FILES)
47+
session.run("black", "--target-version=py36", *SOURCE_FILES)
4848

4949
lint(session)
5050

5151

5252
@nox.session
5353
def lint(session):
5454
session.install("flake8", "black", "mypy")
55-
session.run("black", "--check", "--target-version=py27", *SOURCE_FILES)
55+
session.run("black", "--check", "--target-version=py36", *SOURCE_FILES)
5656
session.run("flake8", "--ignore=E501,W503", *SOURCE_FILES)
5757
session.run(
5858
"mypy",

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ classifiers = [
1313
"Development Status :: 5 - Production/Stable",
1414
"Intended Audience :: Developers",
1515
"Programming Language :: Python :: 2",
16-
"Programming Language :: Python :: 2.7",
1716
"Programming Language :: Python :: 3",
1817
"Programming Language :: Python :: 3.6",
1918
"Programming Language :: Python :: 3.7",
@@ -26,7 +25,7 @@ classifiers = [
2625
requires = [
2726
"backports.functools-lru-cache; python_version < '3.3'"
2827
]
29-
requires-python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
28+
requires-python = ">=3.6"
3029

3130
[tool.flit.metadata.requires-extra]
3231
develop = [

tests/compat.py

Lines changed: 0 additions & 25 deletions
This file was deleted.

tests/conftest.py

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,9 @@ class ValidationError(Exception):
3030
pass
3131

3232

33-
if sys.version_info[0] >= 3:
34-
basestring = str
35-
36-
3733
@pytest.fixture
3834
def spec_validator():
39-
with open(
40-
os.path.join(os.path.dirname(__file__), "resources", "spec.json"), "r"
41-
) as fh:
35+
with open(os.path.join(os.path.dirname(__file__), "resources", "spec.json")) as fh:
4236
spec = json.load(fh)
4337

4438
def validator(data_json):
@@ -63,13 +57,11 @@ def validator(data_json):
6357
if subval:
6458
found = True
6559
if not found:
66-
raise ValidationError("Missing required key {}".format(k))
60+
raise ValidationError(f"Missing required key {k}")
6761
if k in data:
68-
if v["type"] == "string" and not (
69-
isinstance(data[k], str) or isinstance(data[k], basestring)
70-
):
62+
if v["type"] == "string" and not isinstance(data[k], str):
7163
raise ValidationError(
72-
"Value {0} for key {1} should be string, is {2}".format(
64+
"Value {} for key {} should be string, is {}".format(
7365
data[k], k, type(data[k])
7466
)
7567
)
@@ -78,12 +70,12 @@ def validator(data_json):
7870
datetime.datetime.strptime(data[k], "%Y-%m-%dT%H:%M:%S.%fZ")
7971
except ValueError:
8072
raise ValidationError(
81-
"Value {0} for key {1} doesn't parse as an ISO datetime".format(
73+
"Value {} for key {} doesn't parse as an ISO datetime".format(
8274
data[k], k
8375
)
8476
)
8577
if v.get("index") and list(data.keys())[v.get("index")] != k:
86-
raise ValidationError("Key {0} is not at index {1}".format(k, index))
78+
raise ValidationError(f"Key {k} is not at index {index}")
8779

8880
return data_json
8981

@@ -92,12 +84,8 @@ def validator(data_json):
9284

9385
@pytest.fixture
9486
def apm():
95-
if sys.version_info < (3, 6):
96-
pytest.skip("elasticapm only supports python 3.6+")
97-
if sys.version_info[0] >= 3:
98-
record_factory = logging.getLogRecordFactory()
87+
record_factory = logging.getLogRecordFactory()
9988
apm = elasticapm.Client({"SERVICE_NAME": "apm-service", "DISABLE_SEND": True})
10089
yield apm
10190
apm.close()
102-
if sys.version_info[0] >= 3:
103-
logging.setLogRecordFactory(record_factory)
91+
logging.setLogRecordFactory(record_factory)

tests/test_apm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import logging
2525
import structlog
2626
import pytest
27-
from .compat import StringIO
27+
from io import StringIO
2828

2929

3030
def test_elasticapm_structlog_log_correlation_ecs_fields(spec_validator, apm):

tests/test_stdlib_formatter.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,19 @@
1717

1818
import logging
1919
import logging.config
20-
import mock
20+
from unittest import mock
2121
import pytest
2222
import json
2323
import time
2424
import random
2525
import sys
2626
import ecs_logging
27-
from .compat import StringIO
28-
29-
requires_py3 = pytest.mark.skipif(
30-
sys.version_info[0] < 3, reason="Test requires Python 3.x+"
31-
)
27+
from io import StringIO
3228

3329

3430
@pytest.fixture(scope="function")
3531
def logger():
36-
return logging.getLogger("test-logger-%f-%f" % (time.time(), random.random()))
32+
return logging.getLogger(f"test-logger-{time.time():f}-{random.random():f}")
3733

3834

3935
def make_record():
@@ -78,7 +74,7 @@ def test_extra_global_is_merged(spec_validator):
7874
def test_can_be_overridden(spec_validator):
7975
class CustomFormatter(ecs_logging.StdlibFormatter):
8076
def format_to_ecs(self, record):
81-
ecs_dict = super(CustomFormatter, self).format_to_ecs(record)
77+
ecs_dict = super().format_to_ecs(record)
8278
ecs_dict["custom"] = "field"
8379
return ecs_dict
8480

@@ -311,7 +307,6 @@ def test_exclude_fields_type_and_values():
311307
assert str(e.value) == "'exclude_fields' must be a sequence of strings"
312308

313309

314-
@requires_py3
315310
def test_stack_info(logger):
316311
stream = StringIO()
317312
handler = logging.StreamHandler(stream)
@@ -327,7 +322,6 @@ def test_stack_info(logger):
327322
assert "test_stack_info" in error_stack_trace and __file__ in error_stack_trace
328323

329324

330-
@requires_py3
331325
@pytest.mark.parametrize("exclude_fields", [["error"], ["error.stack_trace"]])
332326
def test_stack_info_excluded(logger, exclude_fields):
333327
stream = StringIO()

tests/test_structlog_formatter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
import ecs_logging
1919
import structlog
20-
import mock
21-
from .compat import StringIO
20+
from unittest import mock
21+
from io import StringIO
2222

2323
import pytest
2424

0 commit comments

Comments
 (0)