Skip to content

Commit dcd59ee

Browse files
committed
sync to Atlas repo
1 parent b38e6fc commit dcd59ee

File tree

12 files changed

+490
-0
lines changed

12 files changed

+490
-0
lines changed

concurrency/flags/graphs.ods

81.2 KB
Binary file not shown.

dicts/strkeydict0_userdictsub.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""StrKeyDict0 converts non-string keys to `str` on lookup
2+
3+
# BEGIN STRKEYDICT0_TESTS
4+
5+
Tests for item retrieval using `d[key]` notation::
6+
7+
>>> d = StrKeyDict0([('2', 'two'), ('4', 'four')])
8+
>>> d['2']
9+
'two'
10+
>>> d[4]
11+
'four'
12+
>>> d[1]
13+
Traceback (most recent call last):
14+
...
15+
KeyError: '1'
16+
17+
18+
Tests for item retrieval using `d.get(key)` notation::
19+
20+
>>> d.get('2')
21+
'two'
22+
>>> d.get(4)
23+
'four'
24+
>>> d.get(1, 'N/A')
25+
'N/A'
26+
27+
28+
Tests for the `in` operator::
29+
30+
>>> 2 in d
31+
True
32+
>>> 1 in d
33+
False
34+
35+
# END STRKEYDICT0_TESTS
36+
"""
37+
38+
# BEGIN STRKEYDICT0
39+
40+
import collections
41+
42+
43+
class StrKeyDict0(collections.UserDict): # <1>
44+
45+
def __missing__(self, key):
46+
if isinstance(key, str): # <2>
47+
raise KeyError(key)
48+
return self[str(key)] # <3>
49+
50+
def __contains__(self, key):
51+
return str(key) in self.data # <3>
52+
53+
# END STRKEYDICT0

dicts/strkeydict_dictsub.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
"""StrKeyDict always converts non-string keys to `str`
2+
3+
This is a variation of `strkeydict.StrKeyDict` implemented
4+
as a `dict` built-in subclass (instead of a `UserDict` subclass)
5+
6+
Test for initializer: keys are converted to `str`.
7+
8+
>>> d = StrKeyDict([(2, 'two'), ('4', 'four')])
9+
>>> sorted(d.keys())
10+
['2', '4']
11+
12+
Tests for item retrieval using `d[key]` notation::
13+
14+
>>> d['2']
15+
'two'
16+
>>> d[4]
17+
'four'
18+
>>> d[1]
19+
Traceback (most recent call last):
20+
...
21+
KeyError: '1'
22+
23+
Tests for item retrieval using `d.get(key)` notation::
24+
25+
>>> d.get('2')
26+
'two'
27+
>>> d.get(4)
28+
'four'
29+
>>> d.get(1, 'N/A')
30+
'N/A'
31+
32+
Tests for the `in` operator::
33+
34+
>>> 2 in d
35+
True
36+
>>> 1 in d
37+
False
38+
39+
Test for item assignment using non-string key::
40+
41+
>>> d[0] = 'zero'
42+
>>> d['0']
43+
'zero'
44+
45+
Tests for update using a `dict` or a sequence of pairs::
46+
47+
>>> d.update({6:'six', '8':'eight'})
48+
>>> sorted(d.keys())
49+
['0', '2', '4', '6', '8']
50+
>>> d.update([(10, 'ten'), ('12', 'twelve')])
51+
>>> sorted(d.keys())
52+
['0', '10', '12', '2', '4', '6', '8']
53+
>>> d.update([1, 3, 5])
54+
Traceback (most recent call last):
55+
...
56+
TypeError: 'int' object is not iterable
57+
58+
"""
59+
60+
import collections.abc
61+
62+
63+
class StrKeyDict(dict):
64+
65+
def __init__(self, iterable=None, **kwds):
66+
super().__init__()
67+
self.update(iterable, **kwds)
68+
69+
def __missing__(self, key):
70+
if isinstance(key, str):
71+
raise KeyError(key)
72+
return self[str(key)]
73+
74+
def __contains__(self, key):
75+
return key in self.keys() or str(key) in self.keys()
76+
77+
def __setitem__(self, key, item):
78+
super().__setitem__(str(key), item)
79+
80+
def get(self, key, default=None):
81+
try:
82+
return self[key]
83+
except KeyError:
84+
return default
85+
86+
def update(self, iterable=None, **kwds):
87+
if iterable is not None:
88+
if isinstance(iterable, collections.abc.Mapping):
89+
pairs = iterable.items()
90+
else:
91+
pairs = ((k, v) for k, v in iterable)
92+
for key, value in pairs:
93+
self[key] = value
94+
if kwds:
95+
self.update(kwds)

functions/accgen.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""
2+
Accumulator generator examples
3+
4+
http://www.paulgraham.com/accgen.html
5+
6+
>>> f3 = foo(3)
7+
>>> f3(2)
8+
5
9+
>>> f3(2)
10+
7
11+
>>> f3(2)
12+
9
13+
14+
15+
"""
16+
17+
class foo0:
18+
def __init__(self, n):
19+
self.n = n
20+
def __call__(self, i):
21+
self.n += i
22+
return self.n
23+
24+
def foo0(n):
25+
def bar(i):
26+
bar.s += i
27+
return bar.s
28+
bar.s = n
29+
return bar
30+
31+
def foo(n):
32+
def bar(i):
33+
nonlocal n
34+
n += i
35+
return n
36+
return bar

interfaces/dict_subclass.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Code and text by BitBucket user "enigmacurry" posted to
2+
# https://bitbucket.org/pypy/pypy/issue/708/discrepancy-in-dict-subclass-__getitem__
3+
# Adapted by Luciano Ramalho:
4+
# - changed comments to docstring to run with doctest;
5+
# - added test for Test class raising exception
6+
# - and added () to print.
7+
8+
"""
9+
This is a test case to describe a bug I'm seeing in PyPy 1.5. I have
10+
a Cache object that is a dictionary that supports lookup via regular
11+
attribute access. For instance:
12+
13+
>>> c = Cache()
14+
>>> c["asdf"] = "asdf"
15+
>>> c.asdf == c["asdf"]
16+
True
17+
>>> t = Test()
18+
>>> t["asdf"] = "asdf"
19+
>>> t.asdf == t["asdf"]
20+
Traceback (most recent call last):
21+
...
22+
Exception: Trying to getitem: asdf
23+
24+
When looking up keys via attribute, PyPy 1.5 calls __getitem__
25+
whereas CPython 2.7.1 does not.
26+
"""
27+
28+
class Cache(dict):
29+
"A dictionary that supports attribute style key lookup"
30+
def __init__(self, **kw):
31+
dict.__init__(self, kw)
32+
self.__dict__ = self
33+
34+
class Test(Cache):
35+
def __getitem__(self, item):
36+
# I want to process items differently than attributes:
37+
raise Exception("Trying to getitem: %s" % item)
38+
39+
if __name__ == "__main__":
40+
t = Test()
41+
t["asdf"] = "asdf"
42+
#CPython does not call __getitem__ .. PyPy does:
43+
print(t.asdf)
44+
#Doesn't matter if it's a member of __dict__ or not:
45+
print(t.__getattribute__)

interfaces/tombola_subhook.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
Variation of ``tombola.Tombola`` implementing ``__subclasshook__``.
3+
4+
Tests with simple classes::
5+
6+
>>> Tombola.__subclasshook__(object)
7+
NotImplemented
8+
>>> class Complete:
9+
... def __init__(): pass
10+
... def load(): pass
11+
... def pick(): pass
12+
... def loaded(): pass
13+
...
14+
>>> Tombola.__subclasshook__(Complete)
15+
True
16+
>>> issubclass(Complete, Tombola)
17+
18+
"""
19+
20+
21+
from abc import ABC, abstractmethod
22+
from inspect import getmembers, isfunction
23+
24+
25+
class Tombola(ABC): # <1>
26+
27+
@abstractmethod
28+
def __init__(self, iterable): # <2>
29+
"""New instance is loaded from an iterable."""
30+
31+
@abstractmethod
32+
def load(self, iterable):
33+
"""Add items from an iterable."""
34+
35+
@abstractmethod
36+
def pick(self): # <3>
37+
"""Remove item at random, returning it.
38+
39+
This method should raise `LookupError` when the instance is empty.
40+
"""
41+
42+
def loaded(self): # <4>
43+
try:
44+
item = self.pick()
45+
except LookupError:
46+
return False
47+
else:
48+
self.load([item]) # put it back
49+
return True
50+
51+
@classmethod
52+
def __subclasshook__(cls, other_cls):
53+
if cls is Tombola:
54+
interface_names = function_names(cls)
55+
found_names = set()
56+
for a_cls in other_cls.__mro__:
57+
found_names |= function_names(a_cls)
58+
if found_names >= interface_names:
59+
return True
60+
return NotImplemented
61+
62+
63+
def function_names(obj):
64+
return {name for name, _ in getmembers(obj, isfunction)}

iterables/aritprog_v1.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""
2+
Arithmetic progression class
3+
4+
>>> ap = ArithmeticProgression(1, .5, 3)
5+
>>> list(ap)
6+
[1.0, 1.5, 2.0, 2.5]
7+
8+
9+
"""
10+
11+
import array
12+
from collections import abc
13+
14+
class ArithmeticProgression:
15+
16+
def __init__(self, begin, step, end):
17+
self.begin = begin
18+
self.step = step
19+
self.end = end
20+
self._build()
21+
22+
def _build(self):
23+
self._numbers = array.array('d')
24+
n = self.begin
25+
while n < self.end:
26+
self._numbers.append(n)
27+
n += self.step
28+
29+
def __iter__(self):
30+
return ArithmeticProgressionIterator(self._numbers)
31+
32+
33+
class ArithmeticProgressionIterator(abc.Iterator):
34+
35+
def __init__(self, series):
36+
self._series = series
37+
self._index = 0
38+
39+
def __next__(self):
40+
if self._index < len(self._series):
41+
item = self._series[self._index]
42+
self._index += 1
43+
return item
44+
else:
45+
raise StopIteration
46+
47+
48+

iterables/aritprog_v1b.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
Arithmetic progression class
3+
4+
>>> ap = ArithmeticProgression(1, .5, 3)
5+
>>> list(ap)
6+
[1.0, 1.5, 2.0, 2.5]
7+
8+
9+
"""
10+
11+
import array
12+
from collections import abc
13+
14+
class ArithmeticProgression:
15+
16+
def __init__(self, begin, step, end):
17+
self.begin = begin
18+
self.step = step
19+
self.end = end
20+
21+
def __iter__(self):
22+
return ArithmeticProgressionIterator(self)
23+
24+
25+
class ArithmeticProgressionIterator(abc.Iterator):
26+
27+
def __init__(self, arithmetic_progression):
28+
self._ap = arithmetic_progression
29+
self._index = 0
30+
31+
def __next__(self):
32+
result = self._ap.begin + self._ap.step * self._index
33+
if result < self._ap.end:
34+
self._index += 1
35+
return result
36+
else:
37+
raise StopIteration

0 commit comments

Comments
 (0)