Skip to content

Commit 89e6059

Browse files
authored
Merge pull request #224 from splitio/task/removingp2
Task/removingp2
2 parents 3052e6a + 8947da4 commit 89e6059

File tree

9 files changed

+19
-68
lines changed

9 files changed

+19
-68
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This SDK is designed to work with Split, the platform for controlled rollouts, w
77
[![Twitter Follow](https://img.shields.io/twitter/follow/splitsoftware.svg?style=social&label=Follow&maxAge=1529000)](https://twitter.com/intent/follow?screen_name=splitsoftware)
88

99
## Compatibility
10-
This SDK is compatible with **Python 2.7 and higher**.
10+
This SDK is compatible with **Python 3 and higher**.
1111

1212
## Getting started
1313
Below is a simple example that describes the instantiation and most basic usage of our SDK:

doc/source/introduction.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This project provides Python programs access to the `Split.io <http://split.io/>
66
Installation and Requirements
77
-----------------------------
88

9-
``splitio_client`` supports both Python 2 (2.7 or later) and Python 3 (3.3 or later). Stable versions can be installed from `PyPI <https://pypi.python.org>`_ using pip: ::
9+
``splitio_client`` supports Python 3 (3.3 or later). Stable versions can be installed from `PyPI <https://pypi.python.org>`_ using pip: ::
1010

1111
pip install splitio_client
1212

setup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66

77
TESTS_REQUIRES = [
88
'flake8',
9-
'pytest<=4.6', # for deprecated python versions: https://docs.pytest.org/en/latest/py27-py34-deprecation.html
10-
'pytest-mock==2.0.0',
9+
'pytest>=6.2.3',
10+
'pytest-mock>=3.5.1',
1111
'coverage',
1212
'pytest-cov',
13-
'mock;python_version<"3"'
1413
]
1514

1615
INSTALL_REQUIRES = [

splitio/push/sse.py

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
"""Low-level SSE Client."""
22
import logging
33
import socket
4-
import sys
54
from collections import namedtuple
6-
7-
try: # try to import python3 names. fallback to python2
8-
from http.client import HTTPConnection, HTTPSConnection
9-
from urllib.parse import urlparse
10-
except ImportError:
11-
from urlparse import urlparse
12-
from httplib import HTTPConnection, HTTPSConnection
5+
from http.client import HTTPConnection, HTTPSConnection
6+
from urllib.parse import urlparse
137

148

159
_LOGGER = logging.getLogger(__name__)
@@ -23,30 +17,6 @@
2317

2418

2519
__ENDING_CHARS = set(['\n', ''])
26-
def __httpresponse_readline_py2(response):
27-
"""
28-
Hacky `readline` implementation to be used with chunked transfers in python2.
29-
30-
This makes syscalls in a loop, so not particularly efficient. Migrate to py3 now!
31-
32-
:param response: HTTPConnection's response after a .request() call
33-
:type response: httplib.HTTPResponse
34-
35-
:returns: a string with the read line
36-
:rtype: str
37-
"""
38-
buf = []
39-
while True:
40-
read = response.read(1)
41-
buf.append(read)
42-
if read in __ENDING_CHARS:
43-
break
44-
45-
return ''.join(buf)
46-
47-
48-
_http_response_readline = (__httpresponse_readline_py2 if sys.version_info.major <= 2 #pylint:disable=invalid-name
49-
else lambda response: response.readline())
5020

5121

5222
class EventBuilder(object):
@@ -105,7 +75,7 @@ def _read_events(self):
10575
response = self._conn.getresponse()
10676
event_builder = EventBuilder()
10777
while True:
108-
line = _http_response_readline(response)
78+
line = response.readline()
10979
if line is None or len(line) <= 0: # connection ended
11080
break
11181
elif line.startswith(b':'): # comment. Skip
@@ -118,7 +88,7 @@ def _read_events(self):
11888
event_builder = EventBuilder()
11989
else:
12090
event_builder.process_line(line)
121-
except Exception: #pylint:disable=broad-except
91+
except Exception: # pylint:disable=broad-except
12292
_LOGGER.debug('sse connection ended.')
12393
_LOGGER.debug('stack trace: ', exc_info=True)
12494
finally:
@@ -127,7 +97,7 @@ def _read_events(self):
12797

12898
return self._shutdown_requested
12999

130-
def start(self, url, extra_headers=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): #pylint:disable=protected-access
100+
def start(self, url, extra_headers=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): # pylint:disable=protected-access
131101
"""
132102
Connect and start listening for events.
133103

splitio/storage/adapters/redis.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,7 @@ def add_prefix(self, k):
6363
"""
6464
Add a prefix to the contents of k.
6565
66-
'k' may be:
67-
- a single key (of type string or unicode in python2, or type string
68-
in python 3. In which case we simple add a prefix with a dot.
69-
- a list, in which the prefix is applied to element.
70-
If no user prefix is stored, the key/list of keys will be returned as is
71-
72-
:param k: single (string) or list of (list) keys.
66+
:param k: single (string).
7367
:returns: Key(s) with prefix if applicable
7468
"""
7569
if self._prefix:

splitio/util/decorators.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
"""Misc decorators."""
2-
import sys
2+
from abc import abstractmethod
33

4-
from abc import abstractmethod, abstractproperty
54

65
def abstract_property(func):
76
"""
8-
Python2/3 compatible abstract property decorator.
7+
Abstract property decorator.
98
109
:param func: method to decorate
1110
:type func: callable
1211
1312
:returns: decorated function
1413
:rtype: callable
1514
"""
16-
return (property(abstractmethod(func)) if sys.version_info > (3, 3)
17-
else abstractproperty(func))
15+
return property(abstractmethod(func))

splitio/util/threadutil.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
"""Threading utilities."""
2-
from inspect import isclass
3-
import threading
4-
5-
6-
# python2 workaround
7-
_EventClass = threading.Event if isclass(threading.Event) else threading._Event #pylint:disable=protected-access,invalid-name
2+
from threading import Event, Condition
83

94

105
class EventGroup(object):
116
"""EventGroup that can be waited with an OR condition."""
127

13-
class Event(_EventClass): #pylint:disable=too-few-public-methods
8+
class Event(Event): # pylint:disable=too-few-public-methods
149
"""Threading event meant to be used in an group."""
1510

1611
def __init__(self, shared_condition):
@@ -20,18 +15,18 @@ def __init__(self, shared_condition):
2015
:param shared_condition: shared condition varaible.
2116
:type shared_condition: threading.Condition
2217
"""
23-
_EventClass.__init__(self)
18+
Event.__init__(self)
2419
self._shared_cond = shared_condition
2520

2621
def set(self):
2722
"""Set the event."""
28-
_EventClass.set(self)
23+
Event.set(self)
2924
with self._shared_cond:
3025
self._shared_cond.notify()
3126

3227
def __init__(self):
3328
"""Construct an event group."""
34-
self._cond = threading.Condition()
29+
self._cond = Condition()
3530

3631
def make_event(self):
3732
"""

tests/integration/test_streaming_e2e.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@
77
from queue import Queue
88
from splitio.client.factory import get_factory
99
from tests.helpers.mockserver import SSEMockServer, SplitMockServer
10-
11-
try: # try to import python3 names. fallback to python2
12-
from urllib.parse import parse_qs
13-
except ImportError:
14-
from urlparse import parse_qs
10+
from urllib.parse import parse_qs
1511

1612

1713
class StreamingIntegrationTests(object):

tests/storage/test_redis.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,6 @@ def test_add_events(self, mocker):
366366
}
367367
}) for e in events]
368368

369-
# To deal with python2 & 3 differences in hashing/order when dumping json.
370369
list_of_raw_json_strings_called = adapter.rpush.mock_calls[0][1][1:]
371370
list_of_events_called = [json.loads(event) for event in list_of_raw_json_strings_called]
372371
list_of_events_sent = [json.loads(event) for event in list_of_raw_events]

0 commit comments

Comments
 (0)