11from contextlib import contextmanager
22from ctypes import c_char_p , create_string_buffer
3+ import math
34
45from . import ffi
56
@@ -38,6 +39,10 @@ def __str__(self):
3839 def filetype (self ):
3940 return ffi .entry_filetype (self ._entry_p )
4041
42+ @filetype .setter
43+ def filetype (self , value ):
44+ ffi .entry_set_filetype (self ._entry_p , value )
45+
4146 @property
4247 def uid (self ):
4348 return ffi .entry_uid (self ._entry_p )
@@ -89,16 +94,6 @@ def islnk(self):
8994 def issym (self ):
9095 return self .filetype & 0o170000 == 0o120000
9196
92- def _linkpath (self ):
93- return (ffi .entry_symlink_w (self ._entry_p ) or
94- ffi .entry_hardlink_w (self ._entry_p ) or
95- ffi .entry_symlink (self ._entry_p ) or
96- ffi .entry_hardlink (self ._entry_p ))
97-
98- # aliases to get the same api as tarfile
99- linkpath = property (_linkpath )
100- linkname = property (_linkpath )
101-
10297 @property
10398 def isreg (self ):
10499 return self .filetype & 0o170000 == 0o100000
@@ -121,6 +116,16 @@ def atime(self):
121116 nsec_val = ffi .entry_atime_nsec (self ._entry_p )
122117 return format_time (sec_val , nsec_val )
123118
119+ @atime .setter
120+ def atime (self , value ):
121+ if isinstance (value , int ):
122+ self .set_atime (value )
123+ elif isinstance (value , tuple ):
124+ self .set_atime (* value )
125+ else :
126+ seconds , fraction = math .modf (value )
127+ self .set_atime (int (seconds ), int (fraction * 1_000_000_000 ))
128+
124129 def set_atime (self , timestamp_sec , timestamp_nsec ):
125130 return ffi .entry_set_atime (self ._entry_p ,
126131 timestamp_sec , timestamp_nsec )
@@ -131,6 +136,16 @@ def mtime(self):
131136 nsec_val = ffi .entry_mtime_nsec (self ._entry_p )
132137 return format_time (sec_val , nsec_val )
133138
139+ @mtime .setter
140+ def mtime (self , value ):
141+ if isinstance (value , int ):
142+ self .set_mtime (value )
143+ elif isinstance (value , tuple ):
144+ self .set_mtime (* value )
145+ else :
146+ seconds , fraction = math .modf (value )
147+ self .set_mtime (int (seconds ), int (fraction * 1_000_000_000 ))
148+
134149 def set_mtime (self , timestamp_sec , timestamp_nsec ):
135150 return ffi .entry_set_mtime (self ._entry_p ,
136151 timestamp_sec , timestamp_nsec )
@@ -141,6 +156,16 @@ def ctime(self):
141156 nsec_val = ffi .entry_ctime_nsec (self ._entry_p )
142157 return format_time (sec_val , nsec_val )
143158
159+ @ctime .setter
160+ def ctime (self , value ):
161+ if isinstance (value , int ):
162+ self .set_ctime (value )
163+ elif isinstance (value , tuple ):
164+ self .set_ctime (* value )
165+ else :
166+ seconds , fraction = math .modf (value )
167+ self .set_ctime (int (seconds ), int (fraction * 1_000_000_000 ))
168+
144169 def set_ctime (self , timestamp_sec , timestamp_nsec ):
145170 return ffi .entry_set_ctime (self ._entry_p ,
146171 timestamp_sec , timestamp_nsec )
@@ -151,43 +176,91 @@ def birthtime(self):
151176 nsec_val = ffi .entry_birthtime_nsec (self ._entry_p )
152177 return format_time (sec_val , nsec_val )
153178
154- def set_birthtime (self , timestamp_sec , timestamp_nsec ):
155- return ffi .entry_set_birthtime (self ._entry_p ,
156- timestamp_sec , timestamp_nsec )
179+ @birthtime .setter
180+ def birthtime (self , value ):
181+ if isinstance (value , int ):
182+ self .set_birthtime (value )
183+ elif isinstance (value , tuple ):
184+ self .set_birthtime (* value )
185+ else :
186+ seconds , fraction = math .modf (value )
187+ self .set_birthtime (int (seconds ), int (fraction * 1_000_000_000 ))
188+
189+ def set_birthtime (self , timestamp_sec , timestamp_nsec = 0 ):
190+ return ffi .entry_set_birthtime (
191+ self ._entry_p , timestamp_sec , timestamp_nsec
192+ )
157193
158- def _getpathname (self ):
194+ @property
195+ def pathname (self ):
159196 return (ffi .entry_pathname_w (self ._entry_p ) or
160197 ffi .entry_pathname (self ._entry_p ))
161198
162- def _setpathname (self , value ):
199+ @pathname .setter
200+ def pathname (self , value ):
163201 if not isinstance (value , bytes ):
164202 value = value .encode ('utf8' )
165203 ffi .entry_update_pathname_utf8 (self ._entry_p , c_char_p (value ))
166204
167- pathname = property (_getpathname , _setpathname )
168- # aliases to get the same api as tarfile
169- path = property (_getpathname , _setpathname )
170- name = property (_getpathname , _setpathname )
205+ @property
206+ def linkpath (self ):
207+ return (ffi .entry_symlink_w (self ._entry_p ) or
208+ ffi .entry_hardlink_w (self ._entry_p ) or
209+ ffi .entry_symlink (self ._entry_p ) or
210+ ffi .entry_hardlink (self ._entry_p ))
211+
212+ @linkpath .setter
213+ def linkpath (self , value ):
214+ ffi .entry_update_link_utf8 (self ._entry_p , value )
215+
216+ # aliases for compatibility with the standard `tarfile` module
217+ path = property (pathname .fget , pathname .fset , doc = "alias of pathname" )
218+ name = path
219+ linkname = property (linkpath .fget , linkpath .fset , doc = "alias of linkpath" )
171220
172221 @property
173222 def size (self ):
174223 if ffi .entry_size_is_set (self ._entry_p ):
175224 return ffi .entry_size (self ._entry_p )
176225
226+ @size .setter
227+ def size (self , value ):
228+ ffi .entry_set_size (self ._entry_p , value )
229+
177230 @property
178231 def mode (self ):
179232 return ffi .entry_mode (self ._entry_p )
180233
234+ @mode .setter
235+ def mode (self , value ):
236+ ffi .entry_set_mode (self ._entry_p , value )
237+
181238 @property
182239 def strmode (self ):
183240 # note we strip the mode because archive_entry_strmode
184241 # returns a trailing space: strcpy(bp, "?rwxrwxrwx ");
185242 return ffi .entry_strmode (self ._entry_p ).strip ()
186243
244+ @property
245+ def perm (self ):
246+ return ffi .entry_perm (self ._entry_p )
247+
248+ @perm .setter
249+ def perm (self , value ):
250+ ffi .entry_set_perm (self ._entry_p , value )
251+
187252 @property
188253 def rdevmajor (self ):
189254 return ffi .entry_rdevmajor (self ._entry_p )
190255
256+ @rdevmajor .setter
257+ def rdevmajor (self , value ):
258+ ffi .entry_set_rdevmajor (self ._entry_p , value )
259+
191260 @property
192261 def rdevminor (self ):
193262 return ffi .entry_rdevminor (self ._entry_p )
263+
264+ @rdevminor .setter
265+ def rdevminor (self , value ):
266+ ffi .entry_set_rdevminor (self ._entry_p , value )
0 commit comments