Skip to content

drop support for python < 3.6 #105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
language: python
python:
- 2.7
- 3.5
- 3.6
- 3.7
install:
- pip install -U pip setuptools
- pip install -e .[testing]
Expand Down
8 changes: 4 additions & 4 deletions backslash/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@
_MAX_PARAMS_UNCOMPRESSED_SIZE = 10 * 1024 * 1024 # 10Mb


class API(object):
class API():

def __init__(self, client, url, runtoken, timeout_seconds=60, headers=None):
super(API, self).__init__()
super().__init__()
self.client = client
self.url = URL(url)
self.runtoken = runtoken
Expand Down Expand Up @@ -177,10 +177,10 @@ def _compress(self, data):
return s.getvalue()


class CallProxy(object):
class CallProxy():

def __init__(self, api):
super(CallProxy, self).__init__()
super().__init__()
self._api = api

def __getattr__(self, attr):
Expand Down
6 changes: 3 additions & 3 deletions backslash/api_object.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

class APIObject(object):
class APIObject():

def __init__(self, client, json_data):
super(APIObject, self).__init__()
super().__init__()
self.client = client
self._data = json_data

Expand Down Expand Up @@ -38,7 +38,7 @@ def _fetch(self):
return self.client.api.get(self.api_path, raw=True)[self._data['type']]

def __repr__(self):
return '<API:{data[type]}:{data[id]}>'.format(data=self._data)
return f'<API:{self._data[type]}:{self._data[id]}>'

def without_fields(self, field_names):
new_data = dict((field_name, field_value)
Expand Down
2 changes: 1 addition & 1 deletion backslash/archiveable.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class Archiveable(object):
class Archiveable():

def toggle_archived(self):
self.client.api.call_function('toggle_archived', {self._get_id_key(): self.id})
8 changes: 4 additions & 4 deletions backslash/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
_logger = logbook.Logger(__name__)


class Backslash(object):
class Backslash():

def __init__(self, url, runtoken, headers=None):
super(Backslash, self).__init__()
super().__init__()
if not url.startswith('http'):
url = 'http://{0}'.format(url)
url = f'http://{url}'
self._url = URL(url)
self.api = API(self, url, runtoken, headers=headers)

Expand All @@ -33,7 +33,7 @@ def get_ui_url(self, fragment=None):
fragment = '/'
elif not fragment.startswith('/'):
fragment = '/' + fragment
returned += '#{}'.format(fragment)
returned += f'#{fragment}'
return returned


Expand Down
6 changes: 3 additions & 3 deletions backslash/commentable.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from .lazy_query import LazyQuery


class Commentable(object):
class Commentable():

def post_comment(self, comment):
return self.client.api.call_function('post_comment', {
'comment': comment,
'{}_id'.format(self.type): self.id
f'{self.type}_id': self.id
})

def get_comments(self):
return LazyQuery(self.client, '/rest/comments', query_params={'{}_id'.format(self.type): self.id})
return LazyQuery(self.client, '/rest/comments', query_params={f'{self.type}_id': self.id})
4 changes: 2 additions & 2 deletions backslash/compatibility.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Compatibility(object):
class Compatibility():

def __init__(self, client):
super(Compatibility, self).__init__()
super().__init__()
self.client = client
2 changes: 1 addition & 1 deletion backslash/contrib/keepalive_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class KeepaliveThread(threading.Thread):

def __init__(self, client, session, interval, error_callback=None):
super(KeepaliveThread, self).__init__()
super().__init__()
self._client = client
self._session = session
self._interval = interval / 2.0
Expand Down
16 changes: 8 additions & 8 deletions backslash/contrib/slash_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class BackslashPlugin(PluginInterface):

def __init__(self, url=None, keepalive_interval=None, runtoken=None,
propagate_exceptions=False, config_filename=_DEFAULT_CONFIG_FILENAME):
super(BackslashPlugin, self).__init__()
super().__init__()
self._url = url
self._repo_cache = {}
self._config_filename = config_filename
Expand Down Expand Up @@ -98,7 +98,7 @@ def session_webapp_url(self):
session = slash.context.session
if session is None or self.client is None:
return None
return self.client.get_ui_url('sessions/{}'.format(session.id))
return self.client.get_ui_url(f'sessions/{session.id}')

def _handle_exception(self, exc_info):
pass
Expand Down Expand Up @@ -144,7 +144,7 @@ def _get_default_headers(self):
def deactivate(self):
if self._keepalive_thread is not None:
self._keepalive_thread.stop()
super(BackslashPlugin, self).deactivate()
super().deactivate()

def _notify_session_start(self):
metadata = self._get_initial_session_metadata()
Expand Down Expand Up @@ -298,7 +298,7 @@ def test_skip(self, reason=None):
@slash.plugins.registers_on(None)
def is_session_exist(self, session_id):
try:
self.client.api.get('/rest/sessions/{0}'.format(session_id))
self.client.api.get(f'/rest/sessions/{session_id}')
return True
except HTTPError as e:
if e.response.status_code == 404:
Expand Down Expand Up @@ -392,10 +392,10 @@ def _calculate_file_hash(self, filename):
data = f.read()
h = hashlib.sha1()
h.update('blob '.encode('utf-8'))
h.update('{0}\0'.format(len(data)).encode('utf-8'))
h.update(f'{len(data)}\0'.encode('utf-8'))
h.update(data)
except IOError as e:
_logger.debug('Ignoring IOError {0!r} when calculating file hash for {1}', e, filename)
_logger.debug(f'Ignoring IOError {e!r} when calculating file hash for {filename}')
returned = None
else:
returned = h.hexdigest()
Expand Down Expand Up @@ -452,7 +452,7 @@ def _session_report_end(self, hook_name):
self.session.report_end(**kwargs)
self._started = False
except Exception: # pylint: disable=broad-except
_logger.error('Exception ignored in {}'.format(hook_name), exc_info=True)
_logger.error(f'Exception ignored in {hook_name}', exc_info=True)

@handle_exceptions
def error_added(self, result, error):
Expand Down Expand Up @@ -588,7 +588,7 @@ def fetch_token(self, username, password):
headers={'Content-type': 'application/json'})\
.raise_for_status()

s.post(URL(self._get_backslash_url()).add_path('/runtoken/request/{}/complete'.format(request_id)))\
s.post(URL(self._get_backslash_url()).add_path(f'/runtoken/request/{request_id}/complete'))\
.raise_for_status()

resp = s.get(response_url)
Expand Down
6 changes: 3 additions & 3 deletions backslash/contrib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def _unwrap_object_variable(var_name, var_value):
return

for attr, value in _iter_distilled_object_attributes(var_value):
yield 'self.{}'.format(attr), value
yield f'self.{attr}', value

def _iter_distilled_object_attributes(obj):
try:
Expand Down Expand Up @@ -162,12 +162,12 @@ def _nested_assign(dictionary, key, value):

def _safe_repr(value, repr_blacklisted_types, truncate=True):
if isinstance(value, repr_blacklisted_types):
returned = "<{!r} object {:x}>".format(type(value).__name__, id(value))
returned = f"<{type(value).__name__!r} object {id(value):x}>"

try:
returned = repr(value)
except Exception: # pylint: disable=broad-except
return "[Unprintable {0!r} object]".format(type(value).__name__)
return f"[Unprintable {type(value).__name__!r} object]"

if truncate and len(returned) > _MAX_VARIABLE_VALUE_LENGTH:
returned = returned[:_MAX_VARIABLE_VALUE_LENGTH - 3] + '...'
Expand Down
2 changes: 1 addition & 1 deletion backslash/error_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
_logger = logbook.Logger(__name__)


class ErrorContainer(object):
class ErrorContainer():

def add_error(self, message, exception_type=NOTHING, traceback=NOTHING,
timestamp=NOTHING, is_failure=NOTHING, exception_attrs=NOTHING, is_interruption=NOTHING, is_fatal=NOTHING):
Expand Down
10 changes: 5 additions & 5 deletions backslash/field_filters.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
class FieldFilter(object):
class FieldFilter():

def __init__(self, field_name):
super(FieldFilter, self).__init__()
super().__init__()
self.field_name = field_name
self._filters = []

def add_to_url(self, url):
for operator_name, value in self._filters:
url = url.add_query_param(self.field_name, '{0}:{1}'.format(operator_name, value))
url = url.add_query_param(self.field_name, f'{operator_name}:{value}')
return url

def _add_field_proxy_operator_method(operator_name):

def method(self, other):
self._filters.append((operator_name, other)) # pylint: disable=protected-access
return self
method_name = method.__name__ = '__{0}__'.format(operator_name)
method_name = method.__name__ = f'__{operator_name}__'
setattr(FieldFilter, method_name, method)

for _operator_name in ['eq', 'ne', 'lt', 'le', 'gt', 'ge']:
_add_field_proxy_operator_method(_operator_name)


class _Fields(object):
class _Fields():

def __getattr__(self, name):
return FieldFilter(name)
Expand Down
8 changes: 4 additions & 4 deletions backslash/lazy_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
from .utils import raise_for_status


class LazyQuery(object):
class LazyQuery():

def __init__(self, client, path=None, url=None, query_params=None, page_size=100):
super(LazyQuery, self).__init__()
super().__init__()
self._client = client
if url is None:
url = client.api.url
Expand All @@ -37,7 +37,7 @@ def filter(self, *filter_objects, **fields):
return LazyQuery(self._client, url=returned_url, page_size=self._page_size)

def __repr__(self):
return '<Query {0!r}>'.format(str(self._url))
return f'<Query {str(self._url)!r}>'

def __iter__(self):
for i in itertools.count():
Expand Down Expand Up @@ -77,7 +77,7 @@ def _fetch_page(self, page_index):
raise RuntimeError('Multiple keys returned')
[obj_typename] = keys
if self._typename is not None and obj_typename != self._typename:
raise RuntimeError('Got different typename in query: {!r} != {!r}'.format(obj_typename, self._typename))
raise RuntimeError(f'Got different typename in query: {obj_typename!r} != {self._typename!r}')
self._typename = obj_typename

for index, json_obj in enumerate(response_data[self._typename]):
Expand Down
2 changes: 1 addition & 1 deletion backslash/metadata_holder.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class MetadataHolder(object):
class MetadataHolder():

def set_metadata(self, key, value):
self.client.api.call_function('set_metadata', {
Expand Down
2 changes: 1 addition & 1 deletion backslash/related_entity_container.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class RelatedEntityContainer(object):
class RelatedEntityContainer():

def add_related_entity(self, entity_type, entity_name):
# pylint: disable=no-member
Expand Down
4 changes: 2 additions & 2 deletions backslash/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Session(APIObject, MetadataHolder, ErrorContainer, WarningContainer, Archi

@property
def ui_url(self):
return self.client.get_ui_url('/sessions/{}'.format(self.logical_id or self.id))
return self.client.get_ui_url(f'/sessions/{self.logical_id or self.id}')

def report_end(self, duration=NOTHING, has_fatal_errors=NOTHING):

Expand Down Expand Up @@ -100,7 +100,7 @@ def query_tests(self, include_planned=False):
params = None
if include_planned:
params = {'show_planned':'true'}
return LazyQuery(self.client, '/rest/sessions/{0}/tests'.format(self.id), query_params=params)
return LazyQuery(self.client, f'/rest/sessions/{self.id}/tests', query_params=params)

def query_errors(self):
"""Queries tests of the current session
Expand Down
4 changes: 2 additions & 2 deletions backslash/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Test(APIObject, MetadataHolder, ErrorContainer, WarningContainer, Commenta

@property
def ui_url(self):
return self.client.get_ui_url('sessions/{}/tests/{}'.format(self.session_display_id, self.logical_id or self.id))
return self.client.get_ui_url(f'sessions/{self.session_display_id}/tests/{self.logical_id or self.id}')

def report_end(self, duration=NOTHING):
self.client.api.call_function('report_test_end', {'id': self.id, 'duration': duration})
Expand All @@ -33,7 +33,7 @@ def query_errors(self):
return LazyQuery(self.client, '/rest/errors', query_params={'test_id': self.id})

def get_session(self):
return self.client.api.get('/rest/sessions/{0}'.format(self.session_id))
return self.client.api.get(f'/rest/sessions/{self.session_id}')

def get_parent(self):
return self.get_session()
Expand Down
4 changes: 2 additions & 2 deletions backslash/timing_container.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class TimingContainer(object):
class TimingContainer():

def report_timing_start(self, name):
self._report('start', name)
Expand All @@ -9,7 +9,7 @@ def report_timing_end(self, name):
def _report(self, start_stop, name):
kwargs = {'name': name}
kwargs.update(self._get_identity_kwargs())
self.client.api.call_function('report_timing_{}'.format(start_stop), kwargs) # pylint: disable=no-member
self.client.api.call_function(f'report_timing_{start_stop}', kwargs) # pylint: disable=no-member

def _get_identity_kwargs(self):
if self.type.lower() == 'session': # pylint: disable=no-member
Expand Down
2 changes: 1 addition & 1 deletion backslash/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ def raise_for_status(resp):
resp.raise_for_status()
except HTTPError as e:
raise HTTPError(
'{0.request.method} {0.request.url}: {0.status_code}\n\n{0.content}'.format(e.response),
f'{e.response.request.method} {e.response.request.url}: {e.response.status_code}\n\n{e.response.content}',
response=resp, request=resp.request)
2 changes: 1 addition & 1 deletion backslash/warning_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .lazy_query import LazyQuery


class WarningContainer(object):
class WarningContainer():

def add_warning(self, message, filename=NOTHING, lineno=NOTHING, timestamp=NOTHING):
return self.client.api.call_function('add_warning', {self._get_id_key(): self.id,
Expand Down
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Changelog
=========

* :feature:`104` Drop support for python version < 3.6
* :release:`2.39.0 <03-07-2019>`
* :feature:`101` Report if error is fatal
* :feature:`91` Allow passing custom default headers to server
Expand Down
12 changes: 4 additions & 8 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
[metadata]
name = backslash
classifiers =
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
description = Client library for the Backslash test reporting service
license = BSD
author = Rotem Yaari
Expand All @@ -16,12 +15,9 @@ testing =
slash>=1.5.0
Flask
Flask-Loopback
pylint~=1.9.0; python_version<'3.0'
pylint~=2.2.0; python_version>='3.0'
pytest; python_version < '3.0'
pytest>4.0; python_version >= '3.0'
pytest-cov<2.6; python_version < '3.0'
pytest-cov>=2.6; python_version >= '3.0'
pylint~=2.2.0
pytest>4.0
pytest-cov>=2.6
URLObject
weber-utils

Expand Down
Loading