File size: 2,738 Bytes
d015b2a |
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 |
"""Save DOT source lines to a file."""
import logging
import os
import typing
from . import _defaults
from . import _tools
from . import base
from . import encoding
__all__ = ['Save']
log = logging.getLogger(__name__)
class Save(encoding.Encoding, base.Base):
"""Save DOT source lines to file."""
directory: typing.Union[str, bytes] = ''
_default_extension = _defaults.DEFAULT_SOURCE_EXTENSION
_mkdirs = staticmethod(_tools.mkdirs)
def __init__(self, *,
filename: typing.Union[os.PathLike, str],
directory: typing.Union[os.PathLike, str, None] = None,
**kwargs) -> None:
super().__init__(**kwargs)
if filename is None:
filename = f'{self.__class__.__name__}.{self._default_extension}'
self.filename = os.fspath(filename)
"""str: Target file name for saving the DOT source file."""
if directory is not None:
self.directory = os.fspath(directory)
def _copy_kwargs(self, **kwargs):
"""Return the kwargs to create a copy of the instance."""
assert 'directory' not in kwargs
if 'directory' in self.__dict__:
kwargs['directory'] = self.directory
return super()._copy_kwargs(filename=self.filename, **kwargs)
@property
def filepath(self) -> str:
"""The target path for saving the DOT source file."""
return os.path.join(self.directory, self.filename)
@_tools.deprecate_positional_args(supported_number=2)
def save(self, filename: typing.Union[os.PathLike, str, None] = None,
directory: typing.Union[os.PathLike, str, None] = None, *,
skip_existing: typing.Optional[bool] = False) -> str:
"""Save the DOT source to file. Ensure the file ends with a newline.
Args:
filename: Filename for saving the source (defaults to ``name`` + ``'.gv'``)
directory: (Sub)directory for source saving and rendering.
skip_existing: Skip write if file exists (default: ``False``).
Returns:
The (possibly relative) path of the saved source file.
"""
if filename is not None:
self.filename = filename
if directory is not None:
self.directory = directory
filepath = self.filepath
if skip_existing and os.path.exists(filepath):
return filepath
self._mkdirs(filepath)
log.debug('write lines to %r', filepath)
with open(filepath, 'w', encoding=self.encoding) as fd:
for uline in self:
fd.write(uline)
return filepath
|