77 from python_toolbox .third_party import pathlib
88
99import os
10- import functools
1110import re
12- import operator
1311
1412from python_toolbox import cute_iter_tools
1513from python_toolbox import context_management
@@ -186,94 +184,3 @@ def atomic_create(path, binary=False):
186184 actual_temp_file_path .unlink ()
187185
188186
189- class Chmod :
190- # blocktodo test and doc, include testing __repr__. methods for setting on
191- # file. Say in docs it's static and modification returns a new object.
192- # explode fiel_tools to package and chmod-stuff to module.
193-
194- @staticmethod
195- def _get_permissions_from_single_digit (digit ):
196- assert 0 <= digit <= 7
197- permissions = set ()
198- if digit & 4 : permissions .add ('r' )
199- if digit & 1 : permissions .add ('w' )
200- if digit & 2 : permissions .add ('x' )
201- return frozenset (permissions )
202-
203- @staticmethod
204- def _get_nice_string_from_single_digit (digit ):
205- permissions = Chmod ._get_permissions_from_single_digit (digit )
206- return '%s%s%s' % (
207- 'r' if 'r' in permissions else '-' ,
208- 'w' if 'w' in permissions else '-' ,
209- 'x' if 'x' in permissions else '-' ,
210- )
211-
212- def __init__ (self , path_or_number ):
213- if isinstance (path_or_number , int ):
214- self ._number = path_or_number
215- else :
216- self ._number = pathlib .Path (path ).stat () & 0o777
217- self ._dict = {
218- 'u' : Chmod ._get_permissions_from_single_digit (self & 0o700 ),
219- 'g' : Chmod ._get_permissions_from_single_digit (self & 0o070 ),
220- 'o' : Chmod ._get_permissions_from_single_digit (self & 0o007 ),
221- }
222- self ._dict ['a' ] = functools .reduce (operator .and_ , self ._dict .values ())
223-
224- self .nice_string = '' .join (map (
225- Chmod ._get_nice_string_from_single_digit ,
226- (self & 0o700 , self & 0o070 , self & 0o007 )
227- ))
228-
229- __getitem__ = lambda self , key : self ._dict [key ]
230-
231- def __repr__ (self ):
232- return '<Chmod %s: %s>' % (oct (self ), self .nice_string )
233-
234- def set_to_file (self , path ):
235- pathlib .Path (path ).chmod (self ._number )
236-
237- _pattern = re .compile ('^(?P<who>[ugoa]{0,4})(?P<operator>[-+=])(?P<what>['
238- 'rwx]{1,3)$' )
239-
240- def change (self , s ):
241- from python_toolbox import sequence_tools
242- parts = ',' .split (s )
243- matches = tuple (map (Chmod ._pattern .match , parts ))
244- if None in matches :
245- raise Exception ('%s not valid.' % repr (s ))
246- for match in matches :
247- who , operator , what = match .groups ()
248- if sequence_tools .get_recurrences (who ):
249- raise Exception ('Can\' t repeat here: %s' % match .group (0 ))
250- if sequence_tools .get_recurrences (what ):
251- raise Exception ('Can\' t repeat here: %s' % match .group (0 ))
252- number = self ._number
253- for match in matches :
254- who , operator , what = match .groups ()
255- who_mask = 0o777 if 'a' in who else (
256- (0o700 * ('u' in who )) + (0o070 * ('g' in who )) +
257- (0o007 * ('o' in who ))
258- )
259- what_mask = (0o444 * ('r' in what )) + (0o222 * ('w' in what )) + \
260- (0o111 * ('x' in what ))
261- t = who_mask & what_mask
262-
263- if operator == '+' :
264- number |= t
265- elif operator == '-' :
266- number &= ~ t
267- else :
268- assert operator == '='
269- number = (number & (0o777 - who_mask )) | t
270-
271- return Chmod (number )
272-
273- __int__ = lambda self : self ._number
274- __and__ = lambda self : self ._number & other
275- __or__ = lambda self : self ._number | other
276-
277-
278-
279-
0 commit comments