"""Trio - A friendly Python library for async concurrency and I/O
"""

# General layout:
#
# trio/_core/... is the self-contained core library. It does various
# shenanigans to export a consistent "core API", but parts of the core API are
# too low-level to be recommended for regular use.
#
# trio/*.py define a set of more usable tools on top of this. They import from
# trio._core and from each other.
#
# This file pulls together the friendly public API, by re-exporting the more
# innocuous bits of the _core API + the higher-level tools from trio/*.py.

from ._version import __version__

from ._core import (
    TrioInternalError,
    RunFinishedError,
    WouldBlock,
    Cancelled,
    BusyResourceError,
    ClosedResourceError,
    MultiError,
    run,
    open_nursery,
    CancelScope,
    current_effective_deadline,
    TASK_STATUS_IGNORED,
    current_time,
    BrokenResourceError,
    EndOfChannel,
    Nursery,
)

from ._timeouts import (
    move_on_at,
    move_on_after,
    sleep_forever,
    sleep_until,
    sleep,
    fail_at,
    fail_after,
    TooSlowError,
)

from ._sync import (
    Event,
    CapacityLimiter,
    Semaphore,
    Lock,
    StrictFIFOLock,
    Condition,
)

from ._highlevel_generic import aclose_forcefully, StapledStream

from ._channel import (
    open_memory_channel,
    MemorySendChannel,
    MemoryReceiveChannel,
)

from ._signals import open_signal_receiver

from ._highlevel_socket import SocketStream, SocketListener

from ._file_io import open_file, wrap_file

from ._path import Path

from ._subprocess import Process, open_process, run_process

from ._ssl import SSLStream, SSLListener, NeedHandshakeError

from ._highlevel_serve_listeners import serve_listeners

from ._highlevel_open_tcp_stream import open_tcp_stream

from ._highlevel_open_tcp_listeners import open_tcp_listeners, serve_tcp

from ._highlevel_open_unix_stream import open_unix_socket

from ._highlevel_ssl_helpers import (
    open_ssl_over_tcp_stream,
    open_ssl_over_tcp_listeners,
    serve_ssl_over_tcp,
)

from ._deprecate import TrioDeprecationWarning

# Submodules imported by default
from . import lowlevel
from . import socket
from . import abc
from . import from_thread
from . import to_thread

# Not imported by default, but mentioned here so static analysis tools like
# pylint will know that it exists.
if False:
    from . import testing

_deprecate.enable_attribute_deprecations(__name__)
__deprecated_attributes__ = {
    "run_sync_in_worker_thread": _deprecate.DeprecatedAttribute(
        to_thread.run_sync, "0.12.0", issue=810,
    ),
    "current_default_worker_thread_limiter": _deprecate.DeprecatedAttribute(
        to_thread.current_default_thread_limiter, "0.12.0", issue=810,
    ),
    # NOTE: when you remove this, you should also remove the file
    # trio/hazmat.py. For details on why we have both, see:
    #
    #    https://github.com/python-trio/trio/pull/1484#issuecomment-622574499
    "hazmat": _deprecate.DeprecatedAttribute(
        lowlevel, "0.15.0", issue=476, instead="trio.lowlevel",
    ),
}

_deprecate.enable_attribute_deprecations(lowlevel.__name__)
lowlevel.__deprecated_attributes__ = {
    "wait_socket_readable": _deprecate.DeprecatedAttribute(
        lowlevel.wait_readable, "0.12.0", issue=878,
    ),
    "wait_socket_writable": _deprecate.DeprecatedAttribute(
        lowlevel.wait_writable, "0.12.0", issue=878,
    ),
    "notify_socket_close": _deprecate.DeprecatedAttribute(
        lowlevel.notify_closing, "0.12.0", issue=878,
    ),
    "notify_fd_close": _deprecate.DeprecatedAttribute(
        lowlevel.notify_closing, "0.12.0", issue=878,
    ),
}

# Having the public path in .__module__ attributes is important for:
# - exception names in printed tracebacks
# - sphinx :show-inheritance:
# - deprecation warnings
# - pickle
# - probably other stuff
from ._util import fixup_module_metadata

fixup_module_metadata(__name__, globals())
fixup_module_metadata(lowlevel.__name__, lowlevel.__dict__)
fixup_module_metadata(socket.__name__, socket.__dict__)
fixup_module_metadata(abc.__name__, abc.__dict__)
fixup_module_metadata(from_thread.__name__, from_thread.__dict__)
fixup_module_metadata(to_thread.__name__, to_thread.__dict__)
del fixup_module_metadata
