Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
D
Django-Redis-Cache
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Shared
Django-Redis-Cache
Commits
90ad4e7f
Commit
90ad4e7f
authored
Jul 16, 2015
by
Sean Bleier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add 2.6 compat.
parent
97d27b77
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
194 additions
and
2 deletions
+194
-2
compat.py
redis_cache/compat.py
+185
-0
multi_server_tests.py
tests/testapp/tests/multi_server_tests.py
+5
-1
socket_tests.py
tests/testapp/tests/socket_tests.py
+4
-1
No files found.
redis_cache/compat.py
View file @
90ad4e7f
import
sys
import
django
from
operator
import
itemgetter
from
heapq
import
nlargest
from
itertools
import
repeat
,
ifilter
PY3
=
(
sys
.
version_info
>=
(
3
,))
...
...
@@ -42,3 +45,185 @@ def python_2_unicode_compatible(klass):
klass
.
__unicode__
=
klass
.
__str__
klass
.
__str__
=
lambda
self
:
self
.
__unicode__
()
.
encode
(
'utf-8'
)
return
klass
class
Counter
(
dict
):
'''Dict subclass for counting hashable objects. Sometimes called a bag
or multiset. Elements are stored as dictionary keys and their counts
are stored as dictionary values.
>>> Counter('zyzygy')
Counter({'y': 3, 'z': 2, 'g': 1})
'''
def
__init__
(
self
,
iterable
=
None
,
**
kwds
):
'''Create a new, empty Counter object. And if given, count elements
from an input iterable. Or, initialize the count from another mapping
of elements to their counts.
>>> c = Counter() # a new, empty counter
>>> c = Counter('gallahad') # a new counter from an iterable
>>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping
>>> c = Counter(a=4, b=2) # a new counter from keyword args
'''
self
.
update
(
iterable
,
**
kwds
)
def
__missing__
(
self
,
key
):
return
0
def
most_common
(
self
,
n
=
None
):
'''List the n most common elements and their counts from the most
common to the least. If n is None, then list all element counts.
>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]
'''
if
n
is
None
:
return
sorted
(
self
.
iteritems
(),
key
=
itemgetter
(
1
),
reverse
=
True
)
return
nlargest
(
n
,
self
.
iteritems
(),
key
=
itemgetter
(
1
))
def
elements
(
self
):
'''Iterator over elements repeating each as many times as its count.
>>> c = Counter('ABCABC')
>>> sorted(c.elements())
['A', 'A', 'B', 'B', 'C', 'C']
If an element's count has been set to zero or is a negative number,
elements() will ignore it.
'''
for
elem
,
count
in
self
.
iteritems
():
for
_
in
repeat
(
None
,
count
):
yield
elem
# Override dict methods where the meaning changes for Counter objects.
@
classmethod
def
fromkeys
(
cls
,
iterable
,
v
=
None
):
raise
NotImplementedError
(
'Counter.fromkeys() is undefined. Use Counter(iterable) instead.'
)
def
update
(
self
,
iterable
=
None
,
**
kwds
):
'''Like dict.update() but add counts instead of replacing them.
Source can be an iterable, a dictionary, or another Counter instance.
>>> c = Counter('which')
>>> c.update('witch') # add elements from another iterable
>>> d = Counter('watch')
>>> c.update(d) # add elements from another counter
>>> c['h'] # four 'h' in which, witch, and watch
4
'''
if
iterable
is
not
None
:
if
hasattr
(
iterable
,
'iteritems'
):
if
self
:
self_get
=
self
.
get
for
elem
,
count
in
iterable
.
iteritems
():
self
[
elem
]
=
self_get
(
elem
,
0
)
+
count
else
:
dict
.
update
(
self
,
iterable
)
# fast path when counter is empty
else
:
self_get
=
self
.
get
for
elem
in
iterable
:
self
[
elem
]
=
self_get
(
elem
,
0
)
+
1
if
kwds
:
self
.
update
(
kwds
)
def
copy
(
self
):
'Like dict.copy() but returns a Counter instance instead of a dict.'
return
Counter
(
self
)
def
__delitem__
(
self
,
elem
):
'Like dict.__delitem__() but does not raise KeyError for missing values.'
if
elem
in
self
:
dict
.
__delitem__
(
self
,
elem
)
def
__repr__
(
self
):
if
not
self
:
return
'
%
s()'
%
self
.
__class__
.
__name__
items
=
', '
.
join
(
map
(
'
%
r:
%
r'
.
__mod__
,
self
.
most_common
()))
return
'
%
s({
%
s})'
%
(
self
.
__class__
.
__name__
,
items
)
# Multiset-style mathematical operations discussed in:
# Knuth TAOCP Volume II section 4.6.3 exercise 19
# and at http://en.wikipedia.org/wiki/Multiset
#
# Outputs guaranteed to only include positive counts.
#
# To strip negative and zero counts, add-in an empty counter:
# c += Counter()
def
__add__
(
self
,
other
):
'''Add counts from two counters.
>>> Counter('abbb') + Counter('bcc')
Counter({'b': 4, 'c': 2, 'a': 1})
'''
if
not
isinstance
(
other
,
Counter
):
return
NotImplemented
result
=
Counter
()
for
elem
in
set
(
self
)
|
set
(
other
):
newcount
=
self
[
elem
]
+
other
[
elem
]
if
newcount
>
0
:
result
[
elem
]
=
newcount
return
result
def
__sub__
(
self
,
other
):
''' Subtract count, but keep only results with positive counts.
>>> Counter('abbbc') - Counter('bccd')
Counter({'b': 2, 'a': 1})
'''
if
not
isinstance
(
other
,
Counter
):
return
NotImplemented
result
=
Counter
()
for
elem
in
set
(
self
)
|
set
(
other
):
newcount
=
self
[
elem
]
-
other
[
elem
]
if
newcount
>
0
:
result
[
elem
]
=
newcount
return
result
def
__or__
(
self
,
other
):
'''Union is the maximum of value in either of the input counters.
>>> Counter('abbb') | Counter('bcc')
Counter({'b': 3, 'c': 2, 'a': 1})
'''
if
not
isinstance
(
other
,
Counter
):
return
NotImplemented
_max
=
max
result
=
Counter
()
for
elem
in
set
(
self
)
|
set
(
other
):
newcount
=
_max
(
self
[
elem
],
other
[
elem
])
if
newcount
>
0
:
result
[
elem
]
=
newcount
return
result
def
__and__
(
self
,
other
):
''' Intersection is the minimum of corresponding counts.
>>> Counter('abbb') & Counter('bcc')
Counter({'b': 1})
'''
if
not
isinstance
(
other
,
Counter
):
return
NotImplemented
_min
=
min
result
=
Counter
()
if
len
(
self
)
<
len
(
other
):
self
,
other
=
other
,
self
for
elem
in
ifilter
(
self
.
__contains__
,
other
):
newcount
=
_min
(
self
[
elem
],
other
[
elem
])
if
newcount
>
0
:
result
[
elem
]
=
newcount
return
result
tests/testapp/tests/multi_server_tests.py
View file @
90ad4e7f
from
collections
import
Counter
try
:
from
collections
import
Counter
except
ImportError
:
from
redis_cache.compat
import
Counter
from
math
import
sqrt
from
redis_cache.sharder
import
HashRing
...
...
tests/testapp/tests/socket_tests.py
View file @
90ad4e7f
# # -*- coding: utf-8 -*-
from
collections
import
Counter
try
:
from
collections
import
Counter
except
ImportError
:
from
redis_cache.compat
import
Counter
from
tests.testapp.tests.base_tests
import
BaseRedisTestCase
from
tests.testapp.tests.multi_server_tests
import
MultiServerTests
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment