Skip to content
Open
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
14 changes: 0 additions & 14 deletions .arcconfig

This file was deleted.

29 changes: 0 additions & 29 deletions .arclint

This file was deleted.

1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ services:
- redis-server

python:
- "3.8"
- "2.7"

script: python setup.py test
8 changes: 0 additions & 8 deletions Gemfile

This file was deleted.

21 changes: 0 additions & 21 deletions Gemfile.lock

This file was deleted.

5 changes: 0 additions & 5 deletions Guardfile

This file was deleted.

5 changes: 1 addition & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,4 @@ release:
git push origin master
python setup.py sdist upload

watch:
bundle exec guard

.PHONY: test test-xunit lint release watch
.PHONY: test test-xunit lint release
28 changes: 28 additions & 0 deletions docker-compose.test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: '3'

services:

python3:
image: python:3.8
command: sleep infinity
working_dir: /src
volumes:
- .:/src
links:
- redis-server
environment:
- REDIS_HOST=redis-server

python2:
image: python:2.7
command: sleep infinity
working_dir: /src
volumes:
- .:/src
links:
- redis-server
environment:
- REDIS_HOST=redis-server

redis-server:
image: redis
7 changes: 5 additions & 2 deletions gutter/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

try:
VERSION = __import__('pkg_resources').get_distribution('gutter').version
except Exception, e:
except Exception as e:
VERSION = 'unknown'

CLIENT_CACHE = {}


def get_gutter_client(
alias='default',
cache=CLIENT_CACHE,
cache=None,
**kwargs
):
"""
Expand All @@ -34,6 +34,9 @@ def get_gutter_client(
"""
from gutter.client.models import Manager

if cache is None:
cache = CLIENT_CACHE

if not alias:
return Manager(**kwargs)
elif alias not in cache:
Expand Down
4 changes: 2 additions & 2 deletions gutter/client/arguments/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from functools import partial

from base import Container, argument # noqa
import variables
from . import variables
from .base import Container, argument # noqa

Value = partial(argument, variables.Value)
Boolean = partial(argument, variables.Boolean)
Expand Down
6 changes: 4 additions & 2 deletions gutter/client/arguments/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from types import NoneType
import six

from gutter.client.compat import NoneType


class classproperty(object):
Expand All @@ -13,7 +15,7 @@ def __get__(self, instance, owner):
class argument(object):

def __init__(self, variable, getter):
if issubclass(type(getter), basestring):
if issubclass(type(getter), six.string_types):
self.getter = lambda self: getattr(self.input, getter)
else:
self.getter = getter
Expand Down
23 changes: 23 additions & 0 deletions gutter/client/arguments/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ def func(self, *args, **kwargs):
__hash__ = __proxy_to_value_method('__hash__')
__nonzero__ = __proxy_to_value_method('__nonzero__')

# PY3
__lt__ = __proxy_to_value_method('__lt__')
__le__ = __proxy_to_value_method('__le__')
__gt__ = __proxy_to_value_method('__gt__')
__ge__ = __proxy_to_value_method('__ge__')
__eq__ = __proxy_to_value_method('__eq__')
__ne__ = __proxy_to_value_method('__ne__')
__bool__ = __proxy_to_value_method('__bool__')

@staticmethod
def to_python(value):
return value
Expand Down Expand Up @@ -62,9 +71,23 @@ class String(Base):
def __cmp__(self, other):
return cmp(self.value, other)

def __lt__(self, other):
return self.value < other

def __gt__(self, other):
return self.value > other

def __eq__(self, other):
return self.value == other

def __hash__(self):
return hash(self.value)

def __nonzero__(self, *args, **kwargs):
return bool(self.value)

__bool__ = __nonzero__

@staticmethod
def to_python(value):
return str(value)
22 changes: 22 additions & 0 deletions gutter/client/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""
Python 3 compatibility.
"""

import six


if six.PY3:
import unittest
ifilter = filter
else:
import unittest2 as unittest
from itertools import ifilter


NoneType = type(None)


class TestCaseMixin(object):
if six.PY3:
def assertItemsEqual(self, actual, expected, msg=None):
self.assertCountEqual(actual, expected, msg=None)
50 changes: 48 additions & 2 deletions gutter/client/encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,59 @@


class JsonPickleEncoding(PickleEncoding):

ENCODING = 'utf-8'

@staticmethod
def encode(data):
return pickle.dumps(data)
json_string = pickle.dumps(data)
return json_string.encode(JsonPickleEncoding.ENCODING)

@staticmethod
def decode(data):
try:
return pickle.loads(data)
json_string = data.decode(JsonPickleEncoding.ENCODING)
return pickle.loads(json_string)
except Exception:
return PickleEncoding.decode(data)


class KeyEncoderProxy:
"""
Helps to ensure that keys are encoded and decoded.

This is mainly useful on Python3 where we use text values as the key but on
some storages like redis we can only store byte values. Without a
consistent encoding switches cannot be found again, because the returned
keys are `bytes` objects instead of `str` objects.
"""

def __init__(self, storage, encoding='utf-8'):
self._encoding = encoding
self._storage = storage

def __setitem__(self, key, val):
key = key.encode(self._encoding)
self._storage[key] = val

def __delitem__(self, key):
key = key.encode(self._encoding)
del self._storage[key]

def __getitem__(self, key):
key = key.encode(self._encoding)
return self._storage[key]

def __contains__(self, key):
key = key.encode(self._encoding)
return key in self._storage

def items(self):
return (
(key.decode(self._encoding), val)
for key, val in self._storage.items())

def keys(self):
return (
key.decode(self._encoding)
for key in self._storage.keys())
13 changes: 9 additions & 4 deletions gutter/client/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
import threading
from collections import defaultdict
from functools import partial
from itertools import ifilter

# External Libraries
import six
from gutter.client import signals
from gutter.client.compat import ifilter

DEFAULT_SEPARATOR = ':'

Expand Down Expand Up @@ -330,6 +331,9 @@ def __eq__(self, other):
self.negative is other.negative
)

# TODO: not sure if that's ok
__hash__ = object.__hash__

def call(self, inpt):
"""
Returns if the condition applies to the ``inpt``.
Expand Down Expand Up @@ -410,7 +414,7 @@ def __init__(

if namespace is None:
namespace = self.default_namespace
elif isinstance(namespace, basestring):
elif isinstance(namespace, six.string_types):
namespace = [namespace]

self.storage = storage
Expand Down Expand Up @@ -440,7 +444,7 @@ def switches(self):
List of all switches currently registered.
"""
results = [
switch for name, switch in self.storage.iteritems()
switch for name, switch in six.iteritems(self.storage)
if name.startswith(self.__joined_namespace)
]

Expand Down Expand Up @@ -491,7 +495,8 @@ def register(self, switch, signal=signals.switch_registered):
def unregister(self, switch_or_name):
switch = getattr(switch_or_name, 'name', switch_or_name)

map(self.unregister, self.get_children(switch))
for child in self.get_children(switch):
self.unregister(child)

if switch in self:
signals.switch_unregistered.call(self.switch(switch))
Expand Down
3 changes: 2 additions & 1 deletion gutter/client/testutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
:copyright: (c) 2010-2012 DISQUS.
:license: Apache License 2.0, see LICENSE for more details.
"""
import six

from functools import wraps
from gutter.client import get_gutter_client
Expand Down Expand Up @@ -39,7 +40,7 @@ def __init__(self, gutter=None, **keys):
def gutter(self):
if self._gutter is None:
self._gutter = get_gutter_client()
elif isinstance(self._gutter, basestring):
elif isinstance(self._gutter, six.string_types):
self._gutter = get_gutter_client(alias=self._gutter)
return self._gutter

Expand Down
Loading