forked from ivankorobkov/python-inject
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathutils.py
More file actions
55 lines (42 loc) · 1.64 KB
/
Copy pathutils.py
File metadata and controls
55 lines (42 loc) · 1.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
'''Utility functions.'''
import inspect
from inject.exc import MultipleAttrsFound, NoAttrFound
def get_attrname_by_value(obj, attrvalue):
'''Return a name for object's attribute by its value.
It first iterates over instance's C{__dict__}, then fallbacks to
C{inspect.getmembers}. It is used by L{inject.injections.AttributeInjection}.
Example:
>>> class A(object):
>>> a = 'myvalue'
>>> get_attrname_by_value('myvalue')
'a'
>>>
@raise MultipleAttrsFound: If multiple attributes are found for a given value.
@raise NoAttrFound: If no attribute is found for a given value.
'''
def _get(items):
attrname = None
multiple = False
for name, value in items:
if value is not attrvalue:
continue
if attrname is not None:
if not isinstance(attrname, list):
attrname = [attrname]
multiple = True
attrname.append(name)
else:
attrname = name
if multiple:
raise MultipleAttrsFound('Multiple attributes %r found for '
'attrvalue %r in %r.' % (attrname, attrvalue, obj))
return attrname
attrname = _get(iter(obj.__dict__.items()))
if attrname is not None:
return attrname
# Fallback to a slow way.
attrname = _get(inspect.getmembers(obj))
if attrname is not None:
return attrname
raise NoAttrFound('Can\'t find an attribute in %r with the value %r.'
% (obj, attrvalue))