-
Notifications
You must be signed in to change notification settings - Fork 260
/
Copy pathfileholders.py
135 lines (111 loc) · 3.81 KB
/
fileholders.py
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
# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
#
# See COPYING file distributed along with the NiBabel package for the
# copyright and license terms.
#
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
''' Fileholder class '''
from copy import copy
from .volumeutils import allopen
class FileHolderError(Exception):
pass
class FileHolder(object):
''' class to contain filename, fileobj and file position
'''
def __init__(self,
filename=None,
fileobj=None,
pos=0):
''' Initialize FileHolder instance
Parameters
----------
filename : str, optional
filename. Default is None
fileobj : file-like object, optional
Should implement at least 'seek' (for the purposes for this
class). Default is None
pos : int, optional
position in filename or fileobject at which to start reading
or writing data; defaults to 0
'''
self.filename = filename
self.fileobj = fileobj
self.pos = pos
def get_prepare_fileobj(self, *args, **kwargs):
''' Return fileobj if present, or return fileobj from filename
Set position to that given in self.pos
Parameters
----------
*args : tuple
positional arguments to file open. Ignored if there is a
defined ``self.fileobj``. These might include the mode, such
as 'rb'
**kwargs : dict
named arguments to file open. Ignored if there is a
defined ``self.fileobj``
Returns
-------
fileobj : file-like object
object has position set (via ``fileobj.seek()``) to
``self.pos``
'''
if self.fileobj is not None:
obj = self.fileobj
obj.seek(self.pos)
elif self.filename is not None:
obj = allopen(self.filename, *args, **kwargs)
if self.pos != 0:
obj.seek(self.pos)
else:
raise FileHolderError('No filename or fileobj present')
return obj
def same_file_as(self, other):
""" Test if `self` refers to same files / fileobj as `other`
Parameters
----------
other : object
object with `filename` and `fileobj` attributes
Returns
-------
tf : bool
True if `other` has the same filename (or both have None) and the
same fileobj (or both have None
"""
return ((self.filename == other.filename) and
(self.fileobj == other.fileobj))
def state_stamper(self, caller):
""" Get record of state of fileholder
See: :mod:`stampers`
Parameters
----------
caller : object
Passed from stamper object, but not used by us
Returns
-------
stamp : tuple
state stamp
Notes
-----
We can get state stamp for these file objects assuming that the same
filename corresponds to the same file. We can let pass the position of
reading in the file because we are recording the position with
``self.pos``.
"""
return (self.filename, self.fileobj, self.pos)
def copy_file_map(file_map):
''' Copy mapping of fileholders given by `file_map`
Parameters
----------
file_map : mapping
mapping of ``FileHolder`` instances
Returns
-------
fm_copy : dict
Copy of `file_map`, using shallow copy of ``FileHolder``\s
'''
fm_copy = {}
for key, fh in file_map.items():
fm_copy[key] = copy(fh)
return fm_copy