Skip to content

Commit 64bdfcc

Browse files
committed
-
1 parent 089d45c commit 64bdfcc

File tree

9 files changed

+1380
-260
lines changed

9 files changed

+1380
-260
lines changed

source_py2/python_toolbox/misc_tools/misc_tools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ def limit_positional_arguments(n_positional_arguments=0):
389389
useful when you don't want to let people use some arguments without
390390
specifying them as keyword arguments, because if they access them as
391391
positional arguments, you can't ever change their order or insert more
392-
arguments there because of backward compatibility.
392+
arguments there because of backward compatibility.
393393
'''
394394
def decorator(function):
395395
@functools.wraps(function)

source_py2/python_toolbox/misc_tools/proxy_property.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
See its documentation for more information.
88
'''
99

10+
import re
1011

1112
class ProxyProperty(object):
1213
'''
@@ -56,32 +57,31 @@ def __init__(self, attribute_name, doc=None):
5657
raise Exception("The `attribute_name` must start with a dot to "
5758
"make it clear it's an attribute. %s does not "
5859
"start with a dot." % repr(attribute_name))
60+
self.getter = self.setter = None
61+
exec('def getter(thing): return thing%s' % attribute_name)
62+
exec('def setter(thing, value): thing%s = value' % attribute_name)
63+
exec('self.getter, self.setter = getter, setter')
5964
self.attribute_name = attribute_name[1:]
6065
self.__doc__ = doc
6166

6267

63-
def __get__(self, obj, our_type=None):
64-
if obj is None:
68+
def __get__(self, thing, our_type=None):
69+
if thing is None:
6570
# We're being accessed from the class itself, not from an object
6671
return self
6772
else:
68-
if '.' in self.attribute_name:
69-
from python_toolbox import address_tools
70-
return address_tools.resolve('obj.%s' % self.attribute_name,
71-
namespace={'obj': obj})
72-
else:
73-
return getattr(obj, self.attribute_name)
73+
return self.getter(thing)
7474

75-
def __set__(self, obj, value):
76-
77-
# todo: should I check if `obj` is `None` and set on class? Same for
75+
def __set__(self, thing, value):
76+
# todo: should I check if `thing` is `None` and set on class? Same for
7877
# `__delete__`?
7978

80-
if '.' in self.attribute_name:
81-
from python_toolbox import address_tools
82-
left_segment, right_segment = self.attribute_name.rsplit('.', 1)
83-
deepest_object = address_tools.resolve('obj.%s' % left_segment,
84-
namespace={'obj': obj})
85-
setattr(deepest_object, right_segment, value)
86-
else:
87-
setattr(obj, self.attribute_name, value)
79+
return self.setter(thing, value)
80+
81+
def __repr__(self):
82+
return '<%s: %s%s>' % (
83+
type(self).__name__,
84+
repr('.%s' % self.attribute_name),
85+
', doc=%s' % repr(self.__doc__) if self.__doc__ else ''
86+
)
87+
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright 2009-2015 Ram Rachum.
2+
# This program is distributed under the MIT license.
3+
4+
import abc
5+
import collections
6+
import queue
7+
import multiprocessing.queues
8+
9+
10+
###############################################################################
11+
12+
class Ordered():
13+
'''
14+
A data structure that has a defined order.
15+
16+
This is an abstract type. You can use `isinstance(whatever, Ordered)` to
17+
check whether a data structure is ordered. (Note that there will be false
18+
negatives.)
19+
'''
20+
__metaclass__ = abc.ABCMeta
21+
__slots__ = ()
22+
23+
24+
Ordered.register(collections.Sequence)
25+
Ordered.register(collections.OrderedDict)
26+
Ordered.register(collections.deque)
27+
Ordered.register(queue.Queue)
28+
Ordered.register(multiprocessing.queues.Queue)
29+
30+
###############################################################################
31+
32+
class DefinitelyUnordered():
33+
'''
34+
A data structure that does not have a defined order.
35+
36+
This is an abstract type. You can use `isinstance(whatever,
37+
DefinitelyUnordered)` to check whether a data structure is unordered. (Note
38+
that there will be false negatives.)
39+
'''
40+
__metaclass__ = abc.ABCMeta
41+
__slots__ = ()
42+
43+
@classmethod
44+
def __subclasshook__(cls, type_):
45+
if cls is DefinitelyUnordered and \
46+
issubclass(type_, collections.OrderedDict):
47+
return False
48+
else:
49+
return NotImplemented
50+
51+
52+
DefinitelyUnordered.register(set)
53+
DefinitelyUnordered.register(frozenset)
54+
DefinitelyUnordered.register(dict)
55+
DefinitelyUnordered.register(collections.defaultdict)
56+
DefinitelyUnordered.register(collections.Counter)

0 commit comments

Comments
 (0)