Skip to content

Commit 150f0ea

Browse files
authored
Cleanup after drop of support for Python < 3.7 (#387)
* Remove unused config for Travis CI * Remove classifiers for unsupported Python versions * Add `python_requires` and remove unused dependencies * Use Python 3 style `super()` calls * Use “new style” classes Stop inheriting from object explicitly * Remove compatibility code for Python < 3.7 * Remove unnecessary future imports * Remove `string_types` from compat module
1 parent c57d293 commit 150f0ea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+123
-267
lines changed

.travis.yml

-26
This file was deleted.

aws_xray_sdk/core/__init__.py

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1+
from .async_recorder import AsyncAWSXRayRecorder
2+
from .patcher import patch, patch_all
13
from .recorder import AWSXRayRecorder
2-
from .patcher import patch_all, patch
3-
from .utils.compat import PY35
44

5-
6-
if not PY35:
7-
xray_recorder = AWSXRayRecorder()
8-
else:
9-
from .async_recorder import AsyncAWSXRayRecorder
10-
xray_recorder = AsyncAWSXRayRecorder()
5+
xray_recorder = AsyncAWSXRayRecorder()
116

127
__all__ = [
138
'patch',

aws_xray_sdk/core/async_context.py

+6-21
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import asyncio
2-
import sys
32
import copy
43

54
from .context import Context as _Context
65

7-
_GTE_PY37 = sys.version_info.major == 3 and sys.version_info.minor >= 7
8-
96

107
class AsyncContext(_Context):
118
"""
@@ -16,7 +13,7 @@ class AsyncContext(_Context):
1613
Also overrides clear_trace_entities
1714
"""
1815
def __init__(self, *args, loop=None, use_task_factory=True, **kwargs):
19-
super(AsyncContext, self).__init__(*args, **kwargs)
16+
super().__init__(*args, **kwargs)
2017

2118
self._loop = loop
2219
if loop is None:
@@ -35,7 +32,7 @@ def clear_trace_entities(self):
3532
self._local.clear()
3633

3734

38-
class TaskLocalStorage(object):
35+
class TaskLocalStorage:
3936
"""
4037
Simple task local storage
4138
"""
@@ -51,10 +48,7 @@ def __setattr__(self, name, value):
5148

5249
else:
5350
# Set task local attributes
54-
if _GTE_PY37:
55-
task = asyncio.current_task(loop=self._loop)
56-
else:
57-
task = asyncio.Task.current_task(loop=self._loop)
51+
task = asyncio.current_task(loop=self._loop)
5852
if task is None:
5953
return None
6054

@@ -68,10 +62,7 @@ def __getattribute__(self, item):
6862
# Return references to local objects
6963
return object.__getattribute__(self, item)
7064

71-
if _GTE_PY37:
72-
task = asyncio.current_task(loop=self._loop)
73-
else:
74-
task = asyncio.Task.current_task(loop=self._loop)
65+
task = asyncio.current_task(loop=self._loop)
7566
if task is None:
7667
return None
7768

@@ -82,10 +73,7 @@ def __getattribute__(self, item):
8273

8374
def clear(self):
8475
# If were in a task, clear the context dictionary
85-
if _GTE_PY37:
86-
task = asyncio.current_task(loop=self._loop)
87-
else:
88-
task = asyncio.Task.current_task(loop=self._loop)
76+
task = asyncio.current_task(loop=self._loop)
8977
if task is not None and hasattr(task, 'context'):
9078
task.context.clear()
9179

@@ -104,10 +92,7 @@ def task_factory(loop, coro):
10492
del task._source_traceback[-1] # flake8: noqa
10593

10694
# Share context with new task if possible
107-
if _GTE_PY37:
108-
current_task = asyncio.current_task(loop=loop)
109-
else:
110-
current_task = asyncio.Task.current_task(loop=loop)
95+
current_task = asyncio.current_task(loop=loop)
11196
if current_task is not None and hasattr(current_task, 'context'):
11297
if current_task.context.get('entities'):
11398
# NOTE: (enowell) Because the `AWSXRayRecorder`'s `Context` decides

aws_xray_sdk/core/context.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
CXT_MISSING_STRATEGY_KEY = 'AWS_XRAY_CONTEXT_MISSING'
1515

1616

17-
class Context(object):
17+
class Context:
1818
"""
1919
The context storage class to store trace entities(segments/subsegments).
2020
The default implementation uses threadlocal to store these entities.

aws_xray_sdk/core/daemon_config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
DEFAULT_ADDRESS = '127.0.0.1:2000'
77

88

9-
class DaemonConfig(object):
9+
class DaemonConfig:
1010
"""The class that stores X-Ray daemon configuration about
1111
the ip address and port for UDP and TCP port. It gets the address
1212
string from ``AWS_TRACING_DAEMON_ADDRESS`` and then from recorder's

aws_xray_sdk/core/emitters/udp_emitter.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
DEFAULT_DAEMON_ADDRESS = '127.0.0.1:2000'
1313

1414

15-
class UDPEmitter(object):
15+
class UDPEmitter:
1616
"""
1717
The default emitter the X-Ray recorder uses to send segments/subsegments
1818
to the X-Ray daemon over UDP using a non-blocking socket. If there is an

aws_xray_sdk/core/models/default_dynamic_naming.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from ..utils.search_pattern import wildcard_match
22

33

4-
class DefaultDynamicNaming(object):
4+
class DefaultDynamicNaming:
55
"""
66
Decides what name to use on a segment generated from an incoming request.
77
By default it takes the host name and compares it to a pre-defined pattern.

aws_xray_sdk/core/models/dummy_entities.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class DummySegment(Segment):
1818
def __init__(self, name='dummy'):
1919
no_op_id = os.getenv('AWS_XRAY_NOOP_ID')
2020
if no_op_id and no_op_id.lower() == 'false':
21-
super(DummySegment, self).__init__(name=name, traceid=TraceId().to_id())
21+
super().__init__(name=name, traceid=TraceId().to_id())
2222
else:
23-
super(DummySegment, self).__init__(name=name, traceid=NoOpTraceId().to_id(), entityid='0000000000000000')
23+
super().__init__(name=name, traceid=NoOpTraceId().to_id(), entityid='0000000000000000')
2424
self.sampled = False
2525

2626
def set_aws(self, aws_meta):
@@ -87,7 +87,7 @@ class DummySubsegment(Subsegment):
8787
"""
8888

8989
def __init__(self, segment, name='dummy'):
90-
super(DummySubsegment, self).__init__(name, 'dummy', segment)
90+
super().__init__(name, 'dummy', segment)
9191
no_op_id = os.getenv('AWS_XRAY_NOOP_ID')
9292
if no_op_id and no_op_id.lower() == 'false':
9393
super(Subsegment, self).__init__(name)

aws_xray_sdk/core/models/entity.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import json
88

9-
from ..utils.compat import annotation_value_types, string_types
9+
from ..utils.compat import annotation_value_types
1010
from ..utils.conversion import metadata_to_dict
1111
from .throwable import Throwable
1212
from . import http
@@ -21,7 +21,7 @@
2121
ORIGIN_TRACE_HEADER_ATTR_KEY = '_origin_trace_header'
2222

2323

24-
class Entity(object):
24+
class Entity:
2525
"""
2626
The parent class for segment/subsegment. It holds common properties
2727
and methods on segment and subsegment.
@@ -113,7 +113,7 @@ def put_http_meta(self, key, value):
113113
return
114114

115115
if key == http.STATUS:
116-
if isinstance(value, string_types):
116+
if isinstance(value, str):
117117
value = int(value)
118118
self.apply_status_code(value)
119119

@@ -139,7 +139,7 @@ def put_annotation(self, key, value):
139139
"""
140140
self._check_ended()
141141

142-
if not isinstance(key, string_types):
142+
if not isinstance(key, str):
143143
log.warning("ignoring non string type annotation key with type %s.", type(key))
144144
return
145145

@@ -165,7 +165,7 @@ def put_metadata(self, key, value, namespace='default'):
165165
"""
166166
self._check_ended()
167167

168-
if not isinstance(namespace, string_types):
168+
if not isinstance(namespace, str):
169169
log.warning("ignoring non string type metadata namespace")
170170
return
171171

@@ -271,7 +271,7 @@ def serialize(self):
271271
def to_dict(self):
272272
"""
273273
Convert Entity(Segment/Subsegment) object to dict
274-
with required properties that have non-empty values.
274+
with required properties that have non-empty values.
275275
"""
276276
entity_dict = {}
277277

aws_xray_sdk/core/models/facade_segment.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def __init__(self, name, entityid, traceid, sampled):
2222
sampled=sampled,
2323
)
2424

25-
super(FacadeSegment, self).__init__(
25+
super().__init__(
2626
name=name,
2727
entityid=entityid,
2828
traceid=traceid,

aws_xray_sdk/core/models/segment.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def __init__(self, name, entityid=None, traceid=None,
6363
if not name:
6464
raise SegmentNameMissingException("Segment name is required.")
6565

66-
super(Segment, self).__init__(name)
66+
super().__init__(name)
6767

6868
if not traceid:
6969
traceid = TraceId().to_id()
@@ -85,7 +85,7 @@ def add_subsegment(self, subsegment):
8585
Add input subsegment as a child subsegment and increment
8686
reference counter and total subsegments counter.
8787
"""
88-
super(Segment, self).add_subsegment(subsegment)
88+
super().add_subsegment(subsegment)
8989
self.increment()
9090

9191
def increment(self):
@@ -127,15 +127,15 @@ def remove_subsegment(self, subsegment):
127127
"""
128128
Remove the reference of input subsegment.
129129
"""
130-
super(Segment, self).remove_subsegment(subsegment)
130+
super().remove_subsegment(subsegment)
131131
self.decrement_subsegments_size()
132132

133133
def set_user(self, user):
134134
"""
135135
set user of a segment. One segment can only have one user.
136136
User is indexed and can be later queried.
137137
"""
138-
super(Segment, self)._check_ended()
138+
super()._check_ended()
139139
self.user = user
140140

141141
def set_service(self, service_info):
@@ -160,7 +160,7 @@ def to_dict(self):
160160
Convert Segment object to dict with required properties
161161
that have non-empty values.
162162
"""
163-
segment_dict = super(Segment, self).to_dict()
163+
segment_dict = super().to_dict()
164164

165165
del segment_dict['ref_counter']
166166
del segment_dict['_subsegments_counter']

aws_xray_sdk/core/models/subsegment.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def __init__(self, name, namespace, segment):
9595
support `aws`, `remote` and `local`.
9696
:param Segment segment: The parent segment
9797
"""
98-
super(Subsegment, self).__init__(name)
98+
super().__init__(name)
9999

100100
if not segment:
101101
raise SegmentNotFoundException("A parent segment is required for creating subsegments.")
@@ -114,7 +114,7 @@ def add_subsegment(self, subsegment):
114114
reference counter and total subsegments counter of the
115115
parent segment.
116116
"""
117-
super(Subsegment, self).add_subsegment(subsegment)
117+
super().add_subsegment(subsegment)
118118
self.parent_segment.increment()
119119

120120
def remove_subsegment(self, subsegment):
@@ -124,7 +124,7 @@ def remove_subsegment(self, subsegment):
124124
125125
:param Subsegment: subsegment to remove.
126126
"""
127-
super(Subsegment, self).remove_subsegment(subsegment)
127+
super().remove_subsegment(subsegment)
128128
self.parent_segment.decrement_subsegments_size()
129129

130130
def close(self, end_time=None):
@@ -136,7 +136,7 @@ def close(self, end_time=None):
136136
:param int end_time: Epoch in seconds. If not specified
137137
current time will be used.
138138
"""
139-
super(Subsegment, self).close(end_time)
139+
super().close(end_time)
140140
self.parent_segment.decrement_ref_counter()
141141

142142
def set_sql(self, sql):
@@ -154,7 +154,7 @@ def to_dict(self):
154154
Convert Subsegment object to dict with required properties
155155
that have non-empty values.
156156
"""
157-
subsegment_dict = super(Subsegment, self).to_dict()
157+
subsegment_dict = super().to_dict()
158158

159159
del subsegment_dict['parent_segment']
160160

aws_xray_sdk/core/models/throwable.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
import binascii
44
import logging
55

6-
from ..utils.compat import string_types
7-
86
log = logging.getLogger(__name__)
97

108

11-
class Throwable(object):
9+
class Throwable:
1210
"""
1311
An object recording exception infomation under trace entity
1412
`cause` section. The information includes the stack trace,
@@ -31,7 +29,7 @@ def __init__(self, exception, stack, remote=False):
3129
message = None
3230

3331
# do not record non-string exception message
34-
if isinstance(message, string_types):
32+
if isinstance(message, str):
3533
self.message = message
3634

3735
self.type = type(exception).__name__

aws_xray_sdk/core/models/trace_header.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
HEADER_DELIMITER = ";"
1111

1212

13-
class TraceHeader(object):
13+
class TraceHeader:
1414
"""
1515
The sampling decision and trace ID are added to HTTP requests in
1616
tracing headers named ``X-Amzn-Trace-Id``. The first X-Ray-integrated

aws_xray_sdk/core/patcher.py

+9-12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import wrapt
99

1010
from aws_xray_sdk import global_sdk_config
11-
from .utils.compat import PY2, is_classmethod, is_instance_method
11+
from .utils.compat import is_classmethod, is_instance_method
1212

1313
log = logging.getLogger(__name__)
1414

@@ -55,17 +55,14 @@ def patch_all(double_patch=False):
5555

5656
def _is_valid_import(module):
5757
module = module.replace('.', '/')
58-
if PY2:
59-
return bool(pkgutil.get_loader(module))
60-
else:
61-
realpath = os.path.realpath(module)
62-
is_module = os.path.isdir(realpath) and (
63-
os.path.isfile('{}/__init__.py'.format(module)) or os.path.isfile('{}/__init__.pyc'.format(module))
64-
)
65-
is_file = not is_module and (
66-
os.path.isfile('{}.py'.format(module)) or os.path.isfile('{}.pyc'.format(module))
67-
)
68-
return is_module or is_file
58+
realpath = os.path.realpath(module)
59+
is_module = os.path.isdir(realpath) and (
60+
os.path.isfile('{}/__init__.py'.format(module)) or os.path.isfile('{}/__init__.pyc'.format(module))
61+
)
62+
is_file = not is_module and (
63+
os.path.isfile('{}.py'.format(module)) or os.path.isfile('{}.pyc'.format(module))
64+
)
65+
return is_module or is_file
6966

7067

7168
def patch(modules_to_patch, raise_errors=True, ignore_module_patterns=None):

0 commit comments

Comments
 (0)