<commit_before># files.py - save, render, view

"""Save DOT code objects, render with Graphviz dot, and open in viewer."""

import codecs
import locale
import logging
import os
import typing

from . import _compat
from . import backend
from . import tools

__all__ = ['File', 'Source']


log = logging.getLogger(__name__)


class Base:

    source: str

    def __iter__(self):
        raise NotImplementedError('must be implemented by subclasses')

    _engine = 'dot'

    _format = 'pdf'

    _encoding = backend.ENCODING

    @property
    def engine(self):
        """The layout engine used for rendering (``'dot'``, ``'neato'``, ...)."""
        return self._engine

    @engine.setter
    def engine(self, engine):
        engine = engine.lower()
        if engine not in backend.ENGINES:
            raise ValueError(f'unknown engine: {engine!r}')
        self._engine = engine

    @property
    def format(self):
        """The output format used for rendering (``'pdf'``, ``'png'``, ...)."""
        return self._format

    @format.setter
    def format(self, format):
        format = format.lower()
        if format not in backend.FORMATS:
            raise ValueError(f'unknown format: {format!r}')
        self._format = format

    @property
    def encoding(self):
        """The encoding for the saved source file."""
        return self._encoding

    @encoding.setter
    def encoding(self, encoding):
        if encoding is None:
            encoding = locale.getpreferredencoding()
        codecs.lookup(encoding)  # raise early
        self._encoding = encoding

    def copy(self):
        """Return a copied instance of the object.

        Returns:
            An independent copy of the current object.
        """
        kwargs = self._kwargs()
        return self.__class__(**kwargs)

    def _kwargs(self):
        ns = self.__dict__
        return {a[1:]: ns[a] for a in ('_format', '_engine', '_encoding')
                if a in ns}

    def __str__(self):
        """The DOT source code as string."""
        return self.source

    @property
    def source(self):
        """The generated DOT source code as string."""
        return ''.join(self)

    def ____iter__(self):
        r"""Yield the generated DOT source line by line.

        Yields: Line ending with a newline (``'\n'``).
        """
        raise NotImplementedError('to be implemented by concrete subclasses')


class File(Base):

    directory = ''

    _default_extension = 'gv'

    def __init__(self, filename=None, directory=None,
                 format=None, engine=None, encoding=backend.ENCODING):
        if filename is None:
            name = getattr(self, 'name', None) or self.__class__.__name__
            filename = f'{name}.{self._default_extension}'<commit_msg>fix duplication<commit_after># files.py - save, render, view

"""Save DOT code objects, render with Graphviz dot, and open in viewer."""

import codecs
import locale
import logging
import os
import typing

from . import _compat
from . import backend
from . import tools

__all__ = ['File', 'Source']


log = logging.getLogger(__name__)


class Base:

    _engine = 'dot'

    _format = 'pdf'

    _encoding = backend.ENCODING

    @property
    def engine(self):
        """The layout engine used for rendering (``'dot'``, ``'neato'``, ...)."""
        return self._engine

    @engine.setter
    def engine(self, engine):
        engine = engine.lower()
        if engine not in backend.ENGINES:
            raise ValueError(f'unknown engine: {engine!r}')
        self._engine = engine

    @property
    def format(self):
        """The output format used for rendering (``'pdf'``, ``'png'``, ...)."""
        return self._format

    @format.setter
    def format(self, format):
        format = format.lower()
        if format not in backend.FORMATS:
            raise ValueError(f'unknown format: {format!r}')
        self._format = format

    @property
    def encoding(self):
        """The encoding for the saved source file."""
        return self._encoding

    @encoding.setter
    def encoding(self, encoding):
        if encoding is None:
            encoding = locale.getpreferredencoding()
        codecs.lookup(encoding)  # raise early
        self._encoding = encoding

    def copy(self):
        """Return a copied instance of the object.

        Returns:
            An independent copy of the current object.
        """
        kwargs = self._kwargs()
        return self.__class__(**kwargs)

    def _kwargs(self):
        ns = self.__dict__
        return {a[1:]: ns[a] for a in ('_format', '_engine', '_encoding')
                if a in ns}

    def __str__(self):
        """The DOT source code as string."""
        return self.source

    @property
    def source(self) -> str:
        """The generated DOT source code as string."""
        return ''.join(self)

    def __iter__(self):
        r"""Yield the generated DOT source line by line.

        Yields: Line ending with a newline (``'\n'``).
        """
        raise NotImplementedError('to be implemented by concrete subclasses')


class File(Base):

    directory = ''

    _default_extension = 'gv'

    def __init__(self, filename=None, directory=None,
                 format=None, engine=None, encoding=backend.ENCODING):
        if filename is None:
            name = getattr(self, 'name', None) or self.__class__.__name__
            filename = f'{name}.{self._default_extension}'
{'fraction_non_alphanumeric': 0.11672155140870838, 'fraction_numerical': 0.00036589828027808267, 'mean_word_length': 2.356046654389196, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1952925', 'n_tokens_mistral': 1555, 'n_tokens_neox': 1491, 'n_words': 499}