"""
This type stub file was generated by pyright.
"""

import threading
from traitlets.config.configurable import LoggingConfigurable
from decorator import decorator
from IPython.utils.decorators import undoc
from traitlets import Integer

""" History related magics and functionality """
@undoc
class DummyDB:
    """Dummy DB that will act as a black hole for history.

    Only used in the absence of sqlite"""
    def execute(*args, **kwargs):
        ...
    
    def commit(self, *args, **kwargs): # -> None:
        ...
    
    def __enter__(self, *args, **kwargs): # -> None:
        ...
    
    def __exit__(self, *args, **kwargs): # -> None:
        ...
    


@decorator
def only_when_enabled(f, self, *a, **kw):
    """Decorator: return an empty list in the absence of sqlite."""
    ...

_SAVE_DB_SIZE = ...
@decorator
def catch_corrupt_db(f, self, *a, **kw):
    """A decorator which wraps HistoryAccessor method calls to catch errors from
    a corrupt SQLite database, move the old database out of the way, and create
    a new one.

    We avoid clobbering larger databases because this may be triggered due to filesystem issues,
    not just a corrupt file.
    """
    ...

class HistoryAccessorBase(LoggingConfigurable):
    """An abstract class for History Accessors """
    def get_tail(self, n=..., raw=..., output=..., include_latest=...):
        ...
    
    def search(self, pattern=..., raw=..., search_raw=..., output=..., n=..., unique=...):
        ...
    
    def get_range(self, session, start=..., stop=..., raw=..., output=...):
        ...
    
    def get_range_by_str(self, rangestr, raw=..., output=...):
        ...
    


class HistoryAccessor(HistoryAccessorBase):
    """Access the history database without adding to it.

    This is intended for use by standalone history tools. IPython shells use
    HistoryManager, below, which is a subclass of this."""
    _corrupt_db_counter = ...
    _corrupt_db_limit = ...
    hist_file = ...
    enabled = ...
    connection_options = ...
    db = ...
    def __init__(self, profile=..., hist_file=..., **traits) -> None:
        """Create a new history accessor.

        Parameters
        ----------
        profile : str
            The name of the profile from which to open history.
        hist_file : str
            Path to an SQLite history database stored by IPython. If specified,
            hist_file overrides profile.
        config : :class:`~traitlets.config.loader.Config`
            Config object. hist_file can also be set through this.
        """
        ...
    
    @catch_corrupt_db
    def init_db(self): # -> None:
        """Connect to the database, and create tables if necessary."""
        ...
    
    def writeout_cache(self): # -> None:
        """Overridden by HistoryManager to dump the cache before certain
        database lookups."""
        ...
    
    @only_when_enabled
    @catch_corrupt_db
    def get_session_info(self, session):
        """Get info about a session.

        Parameters
        ----------
        session : int
            Session number to retrieve.

        Returns
        -------
        session_id : int
            Session ID number
        start : datetime
            Timestamp for the start of the session.
        end : datetime
            Timestamp for the end of the session, or None if IPython crashed.
        num_cmds : int
            Number of commands run, or None if IPython crashed.
        remark : unicode
            A manually set description.
        """
        ...
    
    @catch_corrupt_db
    def get_last_session_id(self): # -> None:
        """Get the last session ID currently in the database.

        Within IPython, this should be the same as the value stored in
        :attr:`HistoryManager.session_number`.
        """
        ...
    
    @catch_corrupt_db
    def get_tail(self, n=..., raw=..., output=..., include_latest=...):
        """Get the last n lines from the history database.

        Parameters
        ----------
        n : int
            The number of lines to get
        raw, output : bool
            See :meth:`get_range`
        include_latest : bool
            If False (default), n+1 lines are fetched, and the latest one
            is discarded. This is intended to be used where the function
            is called by a user command, which it should not return.

        Returns
        -------
        Tuples as :meth:`get_range`
        """
        ...
    
    @catch_corrupt_db
    def search(self, pattern=..., raw=..., search_raw=..., output=..., n=..., unique=...):
        """Search the database using unix glob-style matching (wildcards
        * and ?).

        Parameters
        ----------
        pattern : str
            The wildcarded pattern to match when searching
        search_raw : bool
            If True, search the raw input, otherwise, the parsed input
        raw, output : bool
            See :meth:`get_range`
        n : None or int
            If an integer is given, it defines the limit of
            returned entries.
        unique : bool
            When it is true, return only unique entries.

        Returns
        -------
        Tuples as :meth:`get_range`
        """
        ...
    
    @catch_corrupt_db
    def get_range(self, session, start=..., stop=..., raw=..., output=...):
        """Retrieve input by session.

        Parameters
        ----------
        session : int
            Session number to retrieve.
        start : int
            First line to retrieve.
        stop : int
            End of line range (excluded from output itself). If None, retrieve
            to the end of the session.
        raw : bool
            If True, return untranslated input
        output : bool
            If True, attempt to include output. This will be 'real' Python
            objects for the current session, or text reprs from previous
            sessions if db_log_output was enabled at the time. Where no output
            is found, None is used.

        Returns
        -------
        entries
            An iterator over the desired lines. Each line is a 3-tuple, either
            (session, line, input) if output is False, or
            (session, line, (input, output)) if output is True.
        """
        ...
    
    def get_range_by_str(self, rangestr, raw=..., output=...):
        """Get lines of history from a string of ranges, as used by magic
        commands %hist, %save, %macro, etc.

        Parameters
        ----------
        rangestr : str
            A string specifying ranges, e.g. "5 ~2/1-4". If empty string is used,
            this will return everything from current session's history.

            See the documentation of :func:`%history` for the full details.

        raw, output : bool
            As :meth:`get_range`

        Returns
        -------
        Tuples as :meth:`get_range`
        """
        ...
    


class HistoryManager(HistoryAccessor):
    """A class to organize all history-related functionality in one place.
    """
    shell = ...
    input_hist_parsed = ...
    input_hist_raw = ...
    dir_hist = ...
    output_hist = ...
    output_hist_reprs = ...
    session_number = Integer()
    db_log_output = ...
    db_cache_size = Integer(0, help="Write to database every x commands (higher values save disk access & power).\n" "Values of 1 or less effectively disable caching.").tag(config=True)
    db_input_cache = ...
    db_output_cache = ...
    save_thread = ...
    save_flag = ...
    _i00 = ...
    _i = ...
    _ii = ...
    _iii = ...
    _exit_re = ...
    def __init__(self, shell=..., config=..., **traits) -> None:
        """Create a new history manager associated with a shell instance.
        """
        ...
    
    @only_when_enabled
    def new_session(self, conn=...): # -> None:
        """Get a new session number."""
        ...
    
    def end_session(self): # -> None:
        """Close the database session, filling in the end time and line count."""
        ...
    
    def name_session(self, name): # -> None:
        """Give the current session a name in the history database."""
        ...
    
    def reset(self, new_session=...): # -> None:
        """Clear the session history, releasing all object references, and
        optionally open a new session."""
        ...
    
    def get_session_info(self, session=...):
        """Get info about a session.

        Parameters
        ----------
        session : int
            Session number to retrieve. The current session is 0, and negative
            numbers count back from current session, so -1 is the previous session.

        Returns
        -------
        session_id : int
            Session ID number
        start : datetime
            Timestamp for the start of the session.
        end : datetime
            Timestamp for the end of the session, or None if IPython crashed.
        num_cmds : int
            Number of commands run, or None if IPython crashed.
        remark : unicode
            A manually set description.
        """
        ...
    
    @catch_corrupt_db
    def get_tail(self, n=..., raw=..., output=..., include_latest=...):
        """Get the last n lines from the history database.

        Most recent entry last.

        Completion will be reordered so that that the last ones are when
        possible from current session.

        Parameters
        ----------
        n : int
            The number of lines to get
        raw, output : bool
            See :meth:`get_range`
        include_latest : bool
            If False (default), n+1 lines are fetched, and the latest one
            is discarded. This is intended to be used where the function
            is called by a user command, which it should not return.

        Returns
        -------
        Tuples as :meth:`get_range`
        """
        ...
    
    def get_range(self, session=..., start=..., stop=..., raw=..., output=...):
        """Retrieve input by session.

        Parameters
        ----------
        session : int
            Session number to retrieve. The current session is 0, and negative
            numbers count back from current session, so -1 is previous session.
        start : int
            First line to retrieve.
        stop : int
            End of line range (excluded from output itself). If None, retrieve
            to the end of the session.
        raw : bool
            If True, return untranslated input
        output : bool
            If True, attempt to include output. This will be 'real' Python
            objects for the current session, or text reprs from previous
            sessions if db_log_output was enabled at the time. Where no output
            is found, None is used.

        Returns
        -------
        entries
            An iterator over the desired lines. Each line is a 3-tuple, either
            (session, line, input) if output is False, or
            (session, line, (input, output)) if output is True.
        """
        ...
    
    def store_inputs(self, line_num, source, source_raw=...): # -> None:
        """Store source and raw input in history and create input cache
        variables ``_i*``.

        Parameters
        ----------
        line_num : int
            The prompt number of this input.
        source : str
            Python input.
        source_raw : str, optional
            If given, this is the raw input without any IPython transformations
            applied to it.  If not given, ``source`` is used.
        """
        ...
    
    def store_output(self, line_num): # -> None:
        """If database output logging is enabled, this saves all the
        outputs from the indicated prompt number to the database. It's
        called by run_cell after code has been executed.

        Parameters
        ----------
        line_num : int
            The line number from which to save outputs
        """
        ...
    
    @only_when_enabled
    def writeout_cache(self, conn=...): # -> None:
        """Write any entries in the cache to the database."""
        ...
    


class HistorySavingThread(threading.Thread):
    """This thread takes care of writing history to the database, so that
    the UI isn't held up while that happens.

    It waits for the HistoryManager's save_flag to be set, then writes out
    the history cache. The main thread is responsible for setting the flag when
    the cache size reaches a defined threshold."""
    daemon = ...
    stop_now = ...
    enabled = ...
    def __init__(self, history_manager) -> None:
        ...
    
    @only_when_enabled
    def run(self): # -> None:
        ...
    
    def stop(self): # -> None:
        """This can be called from the main thread to safely stop this thread.

        Note that it does not attempt to write out remaining history before
        exiting. That should be done by calling the HistoryManager's
        end_session method."""
        ...
    


range_re = ...
def extract_hist_ranges(ranges_str):
    """Turn a string of history ranges into 3-tuples of (session, start, stop).

    Empty string results in a `[(0, 1, None)]`, i.e. "everything from current
    session".

    Examples
    --------
    >>> list(extract_hist_ranges("~8/5-~7/4 2"))
    [(-8, 5, None), (-7, 1, 5), (0, 2, 3)]
    """
    ...

