forked from irods/python-irodsclient
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path__init__.py
More file actions
162 lines (125 loc) · 5.23 KB
/
__init__.py
File metadata and controls
162 lines (125 loc) · 5.23 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import contextlib
import os
import sys
import irods.exception as ex
from irods import env_filename_from_keyword_args
from irods.message import _IRODS_VERSION, ET, XML_Parser_Type
from irods.path import iRODSPath
from irods.session import iRODSSession
__all__ = [
"make_session",
"home_collection",
"xml_mode",
"get_collection",
"get_data_object",
]
class StopTestsException(Exception):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if "unittest" in sys.modules.keys():
print("Aborting tests [ Got : %r ]" % self, file=sys.stderr)
os.abort()
class iRODS_Server_Too_Recent_For_Testing(StopTestsException):
pass
def _get_server_version_for_test(session, curtail_length):
return session._server_version(session.GET_SERVER_VERSION_WITHOUT_AUTH)[
:curtail_length
]
# Create a connection for test, based on ~/.irods environment by default.
def make_session(test_server_version=False, **kwargs):
"""Connect to an iRODS server as determined by any client environment
file present at a standard location, and by any keyword arguments given.
Arguments:
test_server_version: Of type bool; in the `irods.test.helpers` version of this
function, defaults to True. A True value causes
*iRODS_Server_Too_Recent* to be raised if the server
connected to is more recent than the current Python iRODS
client's advertised level of compatibility.
**kwargs: Keyword arguments. Fed directly to the iRODSSession
constructor."""
env_file = env_filename_from_keyword_args(kwargs)
session = iRODSSession(irods_env_file=env_file, **kwargs)
# irods.test.helpers version of this function sets test_server_version True by default, so
# that sessions generated for the test methods will abort on connecting with a server that
# is too recent. This is a way to ensure that tests don't fail due to a server mismatch.
if test_server_version:
connected_version = _get_server_version_for_test(session, curtail_length=3)
advertised_version = _IRODS_VERSION[:3]
if connected_version > advertised_version:
msg = (
"Connected server is {connected_version}, "
"but this python-irodsclient advertises compatibility up to {advertised_version}."
).format(**locals())
raise iRODS_Server_Too_Recent_For_Testing(msg)
return session
def home_collection(session):
"""Return a string value for the given session's home collection."""
return "/{0.zone}/home/{0.username}".format(session)
@contextlib.contextmanager
def xml_mode(s):
"""In a with-block, this context manager can temporarily change the client's choice of XML parser.
Example usages:
with("QUASI_XML"):
# ...
with(XML_Parser_Type.QUASI_XML):
# ..."""
try:
if isinstance(s, str):
ET(getattr(XML_Parser_Type, s)) # e.g. xml_mode("QUASI_XML")
elif isinstance(s, XML_Parser_Type):
ET(s) # e.g. xml_mode(XML_Parser_Type.QUASI_XML)
else:
msg = "xml_mode argument must be a string (e.g. 'QUASI_XML') or an XML_Parser_Type enum."
raise ValueError(msg)
yield
finally:
ET(None)
class _unlikely_value:
pass
@contextlib.contextmanager
def temporarily_assign_attribute(
target, attr, value, not_set_indicator=_unlikely_value()
):
save = not_set_indicator
try:
save = getattr(target, attr, not_set_indicator)
setattr(target, attr, value)
yield
finally:
if save != not_set_indicator:
setattr(target, attr, save)
else:
delattr(target, attr)
def get_data_object(sess, logical_path):
"""Get a reference to the data object (as an iRODSDataObject) at the given path, if one is found.
Else, return None.
Parameters:
sess: an authenticated session object.
logical_path: the full logical path where the data object is to be found. Can be in unnormalized form.
"""
try:
# Check for a data object at the normalized path.
return sess.data_objects.get(iRODSPath(logical_path))
except ex.DataObjectDoesNotExist:
return None
def get_collection(sess, logical_path):
"""Get a reference to the collection (as an iRODSCollection) at the given path, if one is found.
Else, return None.
Parameters:
sess: an authenticated session object.
logical_path: the full logical path where the collection is to be found. Can be in unnormalized form.
"""
try:
# Path normalization is internal to this call.
return sess.collections.get(logical_path)
except ex.CollectionDoesNotExist:
return None
# Utility class and factory function for storing the original value of variables within the given namespace.
def create_value_cache(namespace:dict):
class CachedValues:
__namespace = namespace
@classmethod
def make_entry(cls, name):
cached_value = cls.__namespace[name]
setattr(cls,name,property(lambda self: cached_value))
return CachedValues()