Coverage for sources/mimeogram/fsprotect/core.py: 96%

22 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-05 19:46 +0000

1# vim: set filetype=python fileencoding=utf-8: 

2# -*- coding: utf-8 -*- 

3 

4#============================================================================# 

5# # 

6# Licensed under the Apache License, Version 2.0 (the "License"); # 

7# you may not use this file except in compliance with the License. # 

8# You may obtain a copy of the License at # 

9# # 

10# http://www.apache.org/licenses/LICENSE-2.0 # 

11# # 

12# Unless required by applicable law or agreed to in writing, software # 

13# distributed under the License is distributed on an "AS IS" BASIS, # 

14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

15# See the License for the specific language governing permissions and # 

16# limitations under the License. # 

17# # 

18#============================================================================# 

19 

20 

21''' Core entities for filesystem protection. ''' 

22 

23 

24from .. import __ 

25 

26 

27class Reasons( __.enum.Enum ): 

28 ''' Reasons why location may be protected. ''' 

29 

30 Concealment = 'Hidden file or directory' 

31 Credentials = 'Credentials or secrets location' 

32 CustomAddition = 'User-specified custom location' 

33 OsDirectory = 'Operating system directory' 

34 PlatformSensitive = 'Platform-sensitive location' 

35 UserConfiguration = 'User configuration directory' 

36 VersionControl = 'Version control internals' 

37 

38 

39class Status( __.immut.DataclassObject ): 

40 ''' Protection status for location. ''' 

41 

42 path: __.Path 

43 reason: __.typx.Optional[ Reasons ] = None 

44 active: bool = False 

45 

46 def __bool__( self ): return self.active 

47 

48 @property 

49 def description( self ) -> str: 

50 ''' Human-readable description of protection. ''' 

51 if not self.active: return 'Not protected' 

52 return ( 

53 f"Protected: {self.reason.value}" 

54 if self.reason else 'Protected' ) 

55 

56 

57class Protector( 

58 __.immut.DataclassProtocol, __.typx.Protocol, 

59 decorators = ( __.typx.runtime_checkable, ), 

60): 

61 ''' Filesystem protection checker. ''' 

62 

63 @__.abc.abstractmethod 

64 def verify( self, path: __.Path ) -> Status: 

65 ''' Verifies if a path should be protected. ''' 

66 raise NotImplementedError