8000 Drop support for EOL Python 2.7 and 3.4-3.5 (#718) · Cameron-Calpin/client_python@038b5bd · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit 038b5bd

Browse files
authored
Drop support for EOL Python 2.7 and 3.4-3.5 (prometheus#718)
* Drop support for EOL Python 2.7 and 3.4-3.5 Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com> * Upgrade Python syntax with pyupgrade --py36-plus Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com> * Universal wheels only for Python 2 and 3 Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com> * Simplify text Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
1 parent a2042ab commit 038b5bd

36 files changed

+130
-266
lines changed

.circleci/config.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ workflows:
6868
matrix:
6969
parameters:
7070
python:
71-
- "2.7"
72-
- "3.4"
73-
- "3.5"
7471
- "3.6"
7572
- "3.7"
7673
- "3.8"
@@ -80,11 +77,9 @@ workflows:
8077
matrix:
8178
parameters:
8279
python:
83-
- "2.7"
8480
- "3.9"
8581
- test_pypy:
8682
matrix:
8783
parameters:
8884
python:
89-
- "2.7"
9085
- "3.7"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Prometheus Python Client
22

3-
The official Python 2 and 3 client for [Prometheus](http://prometheus.io).
3+
The official Python client for [Prometheus](https://prometheus.io).
44

55
## Three Step Demo
66

prometheus_client/__init__.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,7 @@
2121
generate_latest = exposition.generate_latest
2222
MetricsHandler = exposition.MetricsHandler
2323
make_wsgi_app = exposition.make_wsgi_app
24-
try:
25-
# Python >3.5 only
26-
make_asgi_app = exposition.make_asgi_app
27-
except:
28-
pass
24+
make_asgi_app = exposition.make_asgi_app
2925
start_http_server = exposition.start_http_server
3026
start_wsgi_server = exposition.start_wsgi_server
3127
write_to_textfile = exposition.write_to_textfile

prometheus_client/bridge/graphite.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/usr/bin/python
2-
from __future__ import unicode_literals
32

43
import logging
54
import re
@@ -22,7 +21,7 @@ def _sanitize(s):
2221

2322
class _RegularPush(threading.Thread):
2423
def __init__(self, pusher, interval, prefix):
25-
super(_RegularPush, self).__init__()
24+
super().__init__()
2625
self._pusher = pusher
2726
self._interval = interval
2827
self._prefix = prefix
@@ -41,11 +40,11 @@ def run(self):
4140
time.sleep(wait_until - now)
4241
try:
4342
self._pusher.push(prefix=self._prefix)
44-
except IOError:
43+
except OSError:
4544
logging.exception("Push failed")
4645

4746

48-
class GraphiteBridge(object):
47+
class GraphiteBridge:
4948
def __init__(self, address, registry=REGISTRY, timeout_seconds=30, _timer=time.time, tags=False):
5049
self._address = address
5150
self._registry = registry
@@ -76,8 +75,7 @@ def push(self, prefix=''):
7675
for k, v in sorted(s.labels.items())])
7776
else:
7877
labelstr = ''
79-
output.append('{0}{1}{2} {3} {4}\n'.format(
80-
prefixstr, _sanitize(s.name), labelstr, float(s.value), now))
78+
output.append(f'{prefixstr}{_sanitize(s.name)}{labelstr} {float(s.value)} {now}\n')
8179

8280
conn = socket.create_connection(self._address, self._timeout)
8381
conn.sendall(''.join(output).encode('ascii'))

prometheus_client/context_managers.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
from __future__ import unicode_literals
2-
31
from timeit import default_timer
42

53
from .decorator import decorate
64

75

8-
class ExceptionCounter(object):
6+
class ExceptionCounter:
97
def __init__(self, counter, exception):
108
self._counter = counter
119
self._exception = exception
@@ -25,7 +23,7 @@ def wrapped(func, *args, **kwargs):
2523
return decorate(f, wrapped)
2624

2725

28-
class InprogressTracker(object):
26+
class InprogressTracker:
2927
def __init__(self, gauge):
3028
self._gauge = gauge
3129

@@ -43,7 +41,7 @@ def wrapped(func, *args, **kwargs):
4341
return decorate(f, wrapped)
4442

4543

46-
class Timer(object):
44+
class Timer:
4745
def __init__(self, callback):
4846
self._callback = callback
4947

prometheus_client/core.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from __future__ import unicode_literals
2-
31
from .metrics import Counter, Enum, Gauge, Histogram, Info, Summary
42
from .metrics_core import (
53
CounterMetricFamily, GaugeHistogramMetricFamily, GaugeMetricFamily,

prometheus_client/exposition.py

Lines changed: 28 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,24 @@
1-
from __future__ import unicode_literals
2-
31
import base64
42
from contextlib import closing
3+
from http.server import BaseHTTPRequestHandler
54
import os
65
import socket
6+
from socketserver import ThreadingMixIn
77
import sys
88
import threading
9+
from urllib.error import HTTPError
10+
from urllib.parse import parse_qs, quote_plus, urlparse
11+
from urllib.request import (
12+
build_opener, HTTPHandler, HTTPRedirectHandler, Request,
13+
)
914
from wsgiref.simple_server import make_server, WSGIRequestHandler, WSGIServer
1015

1116
from .openmetrics import exposition as openmetrics
1217
from .registry import REGISTRY
1318
from .utils import floatToGoString
1419

15-
try:
16-
from urllib import quote_plus
17-
18-
from BaseHTTPServer import BaseHTTPRequestHandler
19-
from SocketServer import ThreadingMixIn
20-
from urllib2 import (
21-
build_opener, HTTPError, HTTPHandler, HTTPRedirectHandler, Request,
22-
)
23-
from urlparse import parse_qs, urlparse
24-
except ImportError:
25-
# Python 3
26-
from http.server import BaseHTTPRequestHandler
27-
from socketserver import ThreadingMixIn
28-
from urllib.error import HTTPError
29-
from urllib.parse import parse_qs, quote_plus, urlparse
30-
from urllib.request import (
31-
build_opener, HTTPHandler, HTTPRedirectHandler, Request,
32-
)
33-
34-
CONTENT_TYPE_LATEST = str('text/plain; version=0.0.4; charset=utf-8')
20+
CONTENT_TYPE_LATEST = 'text/plain; version=0.0.4; charset=utf-8'
3521
"""Content type of the latest text format"""
36-
PYTHON27_OR_OLDER = sys.version_info < (3, )
3722
PYTHON376_OR_NEWER = sys.version_info > (3, 7, 5)
3823

3924

@@ -88,11 +73,7 @@ def redirect_request(self, req, fp, code, msg, headers, newurl):
8873
unverifiable=True,
8974
data=req.data,
9075
)
91-
if PYTHON27_OR_OLDER:
92-
# the `method` attribute did not exist for Request in Python 2.7.
93-
new_request.get_method = lambda: m
94-
else:
95-
new_request.method = m
76+
new_request.method = m
9677
return new_request
9778

9879

@@ -102,7 +83,7 @@ def _bake_output(registry, accept_header, params):
10283
if 'name[]' in params:
10384
registry = registry.restricted_registry(params['name[]'])
10485
output = encoder(registry)
105-
return str('200 OK'), (str('Content-Type'), content_type), output
86+
return '200 OK', ('Content-Type', content_type), output
10687

10788

10889
def make_wsgi_app(registry=REGISTRY):
@@ -114,8 +95,8 @@ def prometheus_app(environ, start_response):
11495
params = parse_qs(environ.get('QUERY_STRING', ''))
11596
if environ['PATH_INFO'] == '/favicon.ico':
11697
# Serve empty response for browsers
117-
status = str('200 OK')
118-
header = (str(''), str(''))
98+
status = '200 OK'
99+
header = ('', '')
119100
output = b''
120101
else:
121102
# Bake output
@@ -160,17 +141,16 @@ def generate_latest(registry=REGISTRY):
160141
def sample_line(line):
161142
if line.labels:
162143
labelstr = '{{{0}}}'.format(','.join(
163-
['{0}="{1}"'.format(
144+
['{}="{}"'.format(
164145
k, v.replace('\\', r'\\').replace('\n', r'\n').replace('"', r'\"'))
165146
for k, v in sorted(line.labels.items())]))
166147
else:
167148
labelstr = ''
168149
timestamp = ''
169150
if line.timestamp is not None:
170151
# Convert to milliseconds.
171-
timestamp = ' {0:d}'.format(int(float(line.timestamp) * 1000))
172-
return '{0}{1} {2}{3}\n'.format(
173-
line.name, labelstr, floatToGoString(line.value), timestamp)
152+
timestamp = f' {int(float(line.timestamp) * 1000):d}'
153+
return f'{line.name}{labelstr} {floatToGoString(line.value)}{timestamp}\n'
174154

175155
output = []
176156
for metric in registry.collect():
@@ -192,9 +172,9 @@ def sample_line(line):
192172
elif mtype == 'unknown':
193173
mtype = 'untyped'
194174

195-
output.append('# HELP {0} {1}\n'.format(
175+
output.append('# HELP {} {}\n'.format(
196176
mname, metric.documentation.replace('\\', r'\\').replace('\n', r'\n')))
197-
output.append('# TYPE {0} {1}\n'.format(mname, mtype))
177+
output.append(f'# TYPE {mname} {mtype}\n')
198178

199179
om_samples = {}
200180
for s in metric.samples:
@@ -210,9 +190,9 @@ def sample_line(line):
210190
raise
211191

212192
for suffix, lines in sorted(om_samples.items()):
213-
output.append('# HELP {0}{1} {2}\n'.format(metric.name, suffix,
214-
metric.documentation.replace('\\', r'\\').replace('\n', r'\n')))
215-
output.append('# TYPE {0}{1} gauge\n'.format(metric.name, suffix))
193+
output.append('# HELP {}{} {}\n'.format(metric.name, suffix,
194+
metric.documentation.replace('\\', r'\\').replace('\n', r'\n')))
195+
output.append(f'# TYPE {metric.name}{suffix} gauge\n')
216196
output.extend(lines)
217197
return ''.join(output).encode('utf-8')
218198

@@ -267,25 +247,13 @@ def write_to_textfile(path, registry):
267247
268248
This is intended for use with the Node exporter textfile collector.
269249
The path must end in .prom for the textfile collector to process it."""
270-
tmppath = '%s.%s.%s' % (path, os.getpid(), threading.current_thread().ident)
250+
tmppath = f'{path}.{os.getpid()}.{threading.current_thread().ident}'
271251
with open(tmppath, 'wb') as f:
272252
f.write(generate_latest(registry))
273253

274254
# rename(2) is atomic but fails on Windows if the destination file exists
275255
if os.name == 'nt':
276-
if sys.version_info <= (3, 3):
277-
# Unable to guarantee atomic rename on Windows and Python<3.3
278-
# Remove and rename instead (risks losing the file)
279-
try:
280-
os.remove(path)
281-
except FileNotFoundError:
282-
pass
283-
284-
os.rename(tmppath, path)
285-
else:
286-
# os.replace is introduced in Python 3.3 but there is some dispute whether
287-
# it is a truly atomic file operation: https://bugs.python.org/issue8828
288-
os.replace(tmppath, path)
256+
os.replace(tmppath, path)
289257
else:
290258
os.rename(tmppath, path)
291259

@@ -299,8 +267,7 @@ def handle():
299267
request.add_header(k, v)
300268
resp = build_opener(base_handler).open(request, timeout=timeout)
301269
if resp.code >= 400:
302-
raise IOError("error talking to pushgateway: {0} {1}".format(
303-
resp.code, resp.msg))
270+
raise OSError(f"error talking to pushgateway: {resp.code} {resp.msg}")
304271

305272
return handle
306273

@@ -337,7 +304,7 @@ def handle():
337304
"""Handler that implements HTTP Basic Auth.
338305
"""
339306
if username is not None and password is not None:
340-
auth_value = '{0}:{1}'.format(username, password).encode('utf-8')
307+
auth_value = f'{username}:{password}'.encode()
341308
auth_token = base64.b64encode(auth_value)
342309
auth_header = b'Basic ' + auth_token
343310
headers.append(['Authorization', auth_header])
@@ -447,10 +414,10 @@ def _use_gateway(method, gateway, job, registry, grouping_key, timeout, handler)
447414
PYTHON376_OR_NEWER
448415
and gateway_url.scheme not in ['http', 'https']
449416
):
450-
gateway = 'http://{0}'.format(gateway)
417+
gateway = f'http://{gateway}'
451418

452419
gateway = gateway.rstrip('/')
453-
url = '{0}/metrics/{1}/{2}'.format(gateway, *_escape_grouping_key("job", job))
420+
url = '{}/metrics/{}/{}'.format(gateway, *_escape_grouping_key("job", job))
454421

455422
data = b''
456423
if method != 'DELETE':
@@ -459,7 +426,7 @@ def _use_gateway(method, gateway, job, registry, grouping_key, timeout, handler)
459426
if grouping_key is None:
460427
grouping_key = {}
461428
url += ''.join(
462-
'/{0}/{1}'.format(*_escape_grouping_key(str(k), str(v)))
429+
'/{}/{}'.format(*_escape_grouping_key(str(k), str(v)))
463430
for k, v in sorted(grouping_key.items()))
464431

465432
handler(
@@ -495,8 +462,4 @@ def instance_ip_grouping_key():
495462
return {'instance': s.getsockname()[0]}
496463

497464

498-
try:
499-
# Python >3.5 only
500-
from .asgi import make_asgi_app # noqa
501-
except:
502-
pass
465+
from .asgi import make_asgi_app # noqa

prometheus_client/gc_collector.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
from __future__ import unicode_literals
2-
31
import gc
42
import platform
53

64
from .metrics_core import CounterMetricFamily
75
from .registry import REGISTRY
86

97

10-
class GCCollector(object):
8+
class GCCollector:
119
"""Collector for Garbage collection statistics."""
1210

1311
def __init__(self, registry=REGISTRY):

0 commit comments

Comments
 (0)
0