Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/graphviz/saving.py: 80%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

45 statements  

1"""Save DOT source lines to a file.""" 

2 

3import logging 

4import os 

5import typing 

6 

7from . import _defaults 

8from . import _tools 

9from . import base 

10from . import encoding 

11 

12__all__ = ['Save'] 

13 

14log = logging.getLogger(__name__) 

15 

16 

17class Save(encoding.Encoding, base.Base): 

18 """Save DOT source lines to file.""" 

19 

20 directory: typing.Union[str, bytes] = '' 

21 

22 _default_extension = _defaults.DEFAULT_SOURCE_EXTENSION 

23 

24 _mkdirs = staticmethod(_tools.mkdirs) 

25 

26 def __init__(self, *, 

27 filename: typing.Union[os.PathLike, str], 

28 directory: typing.Union[os.PathLike, str, None] = None, 

29 **kwargs) -> None: 

30 super().__init__(**kwargs) 

31 

32 if filename is None: 

33 filename = f'{self.__class__.__name__}.{self._default_extension}' 

34 

35 self.filename = os.fspath(filename) 

36 """str: Target file name for saving the DOT source file.""" 

37 

38 if directory is not None: 

39 self.directory = os.fspath(directory) 

40 

41 def _copy_kwargs(self, **kwargs): 

42 """Return the kwargs to create a copy of the instance.""" 

43 assert 'directory' not in kwargs 

44 if 'directory' in self.__dict__: 

45 kwargs['directory'] = self.directory 

46 return super()._copy_kwargs(filename=self.filename, **kwargs) 

47 

48 @property 

49 def filepath(self) -> str: 

50 """The target path for saving the DOT source file.""" 

51 return os.path.join(self.directory, self.filename) 

52 

53 @_tools.deprecate_positional_args(supported_number=1, ignore_arg='self') 

54 def save(self, filename: typing.Union[os.PathLike, str, None] = None, 

55 directory: typing.Union[os.PathLike, str, None] = None, *, 

56 skip_existing: typing.Optional[bool] = False) -> str: 

57 """Save the DOT source to file. Ensure the file ends with a newline. 

58 

59 Args: 

60 filename: Filename for saving the source (defaults to ``name`` + ``'.gv'``) 

61 directory: (Sub)directory for source saving and rendering. 

62 skip_existing: Skip write if file exists (default: ``False``). 

63 

64 Returns: 

65 The (possibly relative) path of the saved source file. 

66 """ 

67 if filename is not None: 

68 self.filename = filename 

69 if directory is not None: 

70 self.directory = directory 

71 

72 filepath = self.filepath 

73 if skip_existing and os.path.exists(filepath): 

74 return filepath 

75 

76 self._mkdirs(filepath) 

77 

78 log.debug('write lines to %r', filepath) 

79 with open(filepath, 'w', encoding=self.encoding) as fd: 

80 for uline in self: 

81 fd.write(uline) 

82 

83 return filepath