Загрузить файлы в «venv/Lib/site-packages/sqlalchemy/util»

This commit is contained in:
2026-07-02 20:40:37 +00:00
parent 023f5e5e82
commit b233a68801
5 changed files with 1584 additions and 150 deletions

View File

@@ -1,162 +1,283 @@
# util/__init__.py # __init__.py
# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors # Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
# <see AUTHORS file> # <see AUTHORS file>
# #
# This module is part of SQLAlchemy and is released under # This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php # the MIT License: https://www.opensource.org/licenses/mit-license.php
from __future__ import annotations
from collections import defaultdict as defaultdict from typing import Any
from functools import partial as partial
from functools import update_wrapper as update_wrapper
from . import preloaded as preloaded from . import util as _util
from ._collections import coerce_generator_arg as coerce_generator_arg from .engine import AdaptedConnection as AdaptedConnection
from ._collections import coerce_to_immutabledict as coerce_to_immutabledict from .engine import BaseRow as BaseRow
from ._collections import column_dict as column_dict from .engine import BindTyping as BindTyping
from ._collections import column_set as column_set from .engine import ChunkedIteratorResult as ChunkedIteratorResult
from ._collections import EMPTY_DICT as EMPTY_DICT from .engine import Compiled as Compiled
from ._collections import EMPTY_SET as EMPTY_SET from .engine import Connection as Connection
from ._collections import FacadeDict as FacadeDict from .engine import create_engine as create_engine
from ._collections import flatten_iterator as flatten_iterator from .engine import create_mock_engine as create_mock_engine
from ._collections import has_dupes as has_dupes from .engine import create_pool_from_url as create_pool_from_url
from ._collections import has_intersection as has_intersection from .engine import CreateEnginePlugin as CreateEnginePlugin
from ._collections import IdentitySet as IdentitySet from .engine import CursorResult as CursorResult
from ._collections import immutabledict as immutabledict from .engine import Dialect as Dialect
from ._collections import LRUCache as LRUCache from .engine import Engine as Engine
from ._collections import merge_lists_w_ordering as merge_lists_w_ordering from .engine import engine_from_config as engine_from_config
from ._collections import NONE_SET as NONE_SET from .engine import ExceptionContext as ExceptionContext
from ._collections import ordered_column_set as ordered_column_set from .engine import ExecutionContext as ExecutionContext
from ._collections import OrderedDict as OrderedDict from .engine import FrozenResult as FrozenResult
from ._collections import OrderedIdentitySet as OrderedIdentitySet from .engine import Inspector as Inspector
from ._collections import OrderedProperties as OrderedProperties from .engine import IteratorResult as IteratorResult
from ._collections import OrderedSet as OrderedSet from .engine import make_url as make_url
from ._collections import PopulateDict as PopulateDict from .engine import MappingResult as MappingResult
from ._collections import Properties as Properties from .engine import MergedResult as MergedResult
from ._collections import ReadOnlyContainer as ReadOnlyContainer from .engine import NestedTransaction as NestedTransaction
from ._collections import ReadOnlyProperties as ReadOnlyProperties from .engine import Result as Result
from ._collections import ScopedRegistry as ScopedRegistry from .engine import result_tuple as result_tuple
from ._collections import sort_dictionary as sort_dictionary from .engine import ResultProxy as ResultProxy
from ._collections import ThreadLocalRegistry as ThreadLocalRegistry from .engine import RootTransaction as RootTransaction
from ._collections import to_column_set as to_column_set from .engine import Row as Row
from ._collections import to_list as to_list from .engine import RowMapping as RowMapping
from ._collections import to_set as to_set from .engine import ScalarResult as ScalarResult
from ._collections import unique_list as unique_list from .engine import Transaction as Transaction
from ._collections import UniqueAppender as UniqueAppender from .engine import TwoPhaseTransaction as TwoPhaseTransaction
from ._collections import update_copy as update_copy from .engine import TypeCompiler as TypeCompiler
from ._collections import WeakPopulateDict as WeakPopulateDict from .engine import URL as URL
from ._collections import WeakSequence as WeakSequence from .inspection import inspect as inspect
from .compat import anext_ as anext_ from .pool import AssertionPool as AssertionPool
from .compat import arm as arm from .pool import AsyncAdaptedQueuePool as AsyncAdaptedQueuePool
from .compat import b as b from .pool import (
from .compat import b64decode as b64decode FallbackAsyncAdaptedQueuePool as FallbackAsyncAdaptedQueuePool,
from .compat import b64encode as b64encode
from .compat import cmp as cmp
from .compat import cpython as cpython
from .compat import dataclass_fields as dataclass_fields
from .compat import decode_backslashreplace as decode_backslashreplace
from .compat import dottedgetter as dottedgetter
from .compat import freethreading as freethreading
from .compat import get_annotations as get_annotations
from .compat import has_refcount_gc as has_refcount_gc
from .compat import inspect_getfullargspec as inspect_getfullargspec
from .compat import is64bit as is64bit
from .compat import local_dataclass_fields as local_dataclass_fields
from .compat import mini_gil as mini_gil
from .compat import osx as osx
from .compat import py310 as py310
from .compat import py311 as py311
from .compat import py312 as py312
from .compat import py313 as py313
from .compat import py314 as py314
from .compat import py38 as py38
from .compat import py39 as py39
from .compat import pypy as pypy
from .compat import win32 as win32
from .concurrency import await_fallback as await_fallback
from .concurrency import await_only as await_only
from .concurrency import greenlet_spawn as greenlet_spawn
from .concurrency import is_exit_exception as is_exit_exception
from .deprecations import became_legacy_20 as became_legacy_20
from .deprecations import deprecated as deprecated
from .deprecations import deprecated_cls as deprecated_cls
from .deprecations import deprecated_params as deprecated_params
from .deprecations import moved_20 as moved_20
from .deprecations import warn_deprecated as warn_deprecated
from .langhelpers import add_parameter_text as add_parameter_text
from .langhelpers import as_interface as as_interface
from .langhelpers import asbool as asbool
from .langhelpers import asint as asint
from .langhelpers import assert_arg_type as assert_arg_type
from .langhelpers import attrsetter as attrsetter
from .langhelpers import bool_or_str as bool_or_str
from .langhelpers import chop_traceback as chop_traceback
from .langhelpers import class_hierarchy as class_hierarchy
from .langhelpers import classproperty as classproperty
from .langhelpers import clsname_as_plain_name as clsname_as_plain_name
from .langhelpers import coerce_kw_type as coerce_kw_type
from .langhelpers import constructor_copy as constructor_copy
from .langhelpers import constructor_key as constructor_key
from .langhelpers import counter as counter
from .langhelpers import create_proxy_methods as create_proxy_methods
from .langhelpers import decode_slice as decode_slice
from .langhelpers import decorator as decorator
from .langhelpers import dictlike_iteritems as dictlike_iteritems
from .langhelpers import duck_type_collection as duck_type_collection
from .langhelpers import ellipses_string as ellipses_string
from .langhelpers import EnsureKWArg as EnsureKWArg
from .langhelpers import FastIntFlag as FastIntFlag
from .langhelpers import format_argspec_init as format_argspec_init
from .langhelpers import format_argspec_plus as format_argspec_plus
from .langhelpers import generic_fn_descriptor as generic_fn_descriptor
from .langhelpers import generic_repr as generic_repr
from .langhelpers import get_callable_argspec as get_callable_argspec
from .langhelpers import get_cls_kwargs as get_cls_kwargs
from .langhelpers import get_func_kwargs as get_func_kwargs
from .langhelpers import getargspec_init as getargspec_init
from .langhelpers import has_compiled_ext as has_compiled_ext
from .langhelpers import HasMemoized as HasMemoized
from .langhelpers import (
HasMemoized_ro_memoized_attribute as HasMemoized_ro_memoized_attribute,
) )
from .langhelpers import hybridmethod as hybridmethod from .pool import NullPool as NullPool
from .langhelpers import hybridproperty as hybridproperty from .pool import Pool as Pool
from .langhelpers import inject_docstring_text as inject_docstring_text from .pool import PoolProxiedConnection as PoolProxiedConnection
from .langhelpers import iterate_attributes as iterate_attributes from .pool import PoolResetState as PoolResetState
from .langhelpers import map_bits as map_bits from .pool import QueuePool as QueuePool
from .langhelpers import md5_hex as md5_hex from .pool import SingletonThreadPool as SingletonThreadPool
from .langhelpers import memoized_instancemethod as memoized_instancemethod from .pool import StaticPool as StaticPool
from .langhelpers import memoized_property as memoized_property from .schema import BaseDDLElement as BaseDDLElement
from .langhelpers import MemoizedSlots as MemoizedSlots from .schema import BLANK_SCHEMA as BLANK_SCHEMA
from .langhelpers import method_is_overridden as method_is_overridden from .schema import CheckConstraint as CheckConstraint
from .langhelpers import methods_equivalent as methods_equivalent from .schema import Column as Column
from .langhelpers import ( from .schema import ColumnDefault as ColumnDefault
monkeypatch_proxied_specials as monkeypatch_proxied_specials, from .schema import Computed as Computed
from .schema import Constraint as Constraint
from .schema import DDL as DDL
from .schema import DDLElement as DDLElement
from .schema import DefaultClause as DefaultClause
from .schema import ExecutableDDLElement as ExecutableDDLElement
from .schema import FetchedValue as FetchedValue
from .schema import ForeignKey as ForeignKey
from .schema import ForeignKeyConstraint as ForeignKeyConstraint
from .schema import Identity as Identity
from .schema import Index as Index
from .schema import insert_sentinel as insert_sentinel
from .schema import MetaData as MetaData
from .schema import PrimaryKeyConstraint as PrimaryKeyConstraint
from .schema import Sequence as Sequence
from .schema import Table as Table
from .schema import UniqueConstraint as UniqueConstraint
from .sql import ColumnExpressionArgument as ColumnExpressionArgument
from .sql import NotNullable as NotNullable
from .sql import Nullable as Nullable
from .sql import SelectLabelStyle as SelectLabelStyle
from .sql.expression import Alias as Alias
from .sql.expression import alias as alias
from .sql.expression import AliasedReturnsRows as AliasedReturnsRows
from .sql.expression import all_ as all_
from .sql.expression import and_ as and_
from .sql.expression import any_ as any_
from .sql.expression import asc as asc
from .sql.expression import between as between
from .sql.expression import BinaryExpression as BinaryExpression
from .sql.expression import bindparam as bindparam
from .sql.expression import BindParameter as BindParameter
from .sql.expression import bitwise_not as bitwise_not
from .sql.expression import BooleanClauseList as BooleanClauseList
from .sql.expression import CacheKey as CacheKey
from .sql.expression import Case as Case
from .sql.expression import case as case
from .sql.expression import Cast as Cast
from .sql.expression import cast as cast
from .sql.expression import ClauseElement as ClauseElement
from .sql.expression import ClauseList as ClauseList
from .sql.expression import collate as collate
from .sql.expression import CollectionAggregate as CollectionAggregate
from .sql.expression import column as column
from .sql.expression import ColumnClause as ColumnClause
from .sql.expression import ColumnCollection as ColumnCollection
from .sql.expression import ColumnElement as ColumnElement
from .sql.expression import ColumnOperators as ColumnOperators
from .sql.expression import CompoundSelect as CompoundSelect
from .sql.expression import CTE as CTE
from .sql.expression import cte as cte
from .sql.expression import custom_op as custom_op
from .sql.expression import Delete as Delete
from .sql.expression import delete as delete
from .sql.expression import desc as desc
from .sql.expression import distinct as distinct
from .sql.expression import except_ as except_
from .sql.expression import except_all as except_all
from .sql.expression import Executable as Executable
from .sql.expression import Exists as Exists
from .sql.expression import exists as exists
from .sql.expression import Extract as Extract
from .sql.expression import extract as extract
from .sql.expression import false as false
from .sql.expression import False_ as False_
from .sql.expression import FromClause as FromClause
from .sql.expression import FromGrouping as FromGrouping
from .sql.expression import func as func
from .sql.expression import funcfilter as funcfilter
from .sql.expression import Function as Function
from .sql.expression import FunctionElement as FunctionElement
from .sql.expression import FunctionFilter as FunctionFilter
from .sql.expression import GenerativeSelect as GenerativeSelect
from .sql.expression import Grouping as Grouping
from .sql.expression import HasCTE as HasCTE
from .sql.expression import HasPrefixes as HasPrefixes
from .sql.expression import HasSuffixes as HasSuffixes
from .sql.expression import Insert as Insert
from .sql.expression import insert as insert
from .sql.expression import intersect as intersect
from .sql.expression import intersect_all as intersect_all
from .sql.expression import Join as Join
from .sql.expression import join as join
from .sql.expression import Label as Label
from .sql.expression import label as label
from .sql.expression import LABEL_STYLE_DEFAULT as LABEL_STYLE_DEFAULT
from .sql.expression import (
LABEL_STYLE_DISAMBIGUATE_ONLY as LABEL_STYLE_DISAMBIGUATE_ONLY,
) )
from .langhelpers import non_memoized_property as non_memoized_property from .sql.expression import LABEL_STYLE_NONE as LABEL_STYLE_NONE
from .langhelpers import NoneType as NoneType from .sql.expression import (
from .langhelpers import only_once as only_once LABEL_STYLE_TABLENAME_PLUS_COL as LABEL_STYLE_TABLENAME_PLUS_COL,
from .langhelpers import (
parse_user_argument_for_enum as parse_user_argument_for_enum,
) )
from .langhelpers import PluginLoader as PluginLoader from .sql.expression import lambda_stmt as lambda_stmt
from .langhelpers import portable_instancemethod as portable_instancemethod from .sql.expression import LambdaElement as LambdaElement
from .langhelpers import quoted_token_parser as quoted_token_parser from .sql.expression import Lateral as Lateral
from .langhelpers import ro_memoized_property as ro_memoized_property from .sql.expression import lateral as lateral
from .langhelpers import ro_non_memoized_property as ro_non_memoized_property from .sql.expression import literal as literal
from .langhelpers import rw_hybridproperty as rw_hybridproperty from .sql.expression import literal_column as literal_column
from .langhelpers import safe_reraise as safe_reraise from .sql.expression import modifier as modifier
from .langhelpers import set_creation_order as set_creation_order from .sql.expression import not_ as not_
from .langhelpers import string_or_unprintable as string_or_unprintable from .sql.expression import Null as Null
from .langhelpers import symbol as symbol from .sql.expression import null as null
from .langhelpers import TypingOnly as TypingOnly from .sql.expression import nulls_first as nulls_first
from .langhelpers import ( from .sql.expression import nulls_last as nulls_last
unbound_method_to_callable as unbound_method_to_callable, from .sql.expression import nullsfirst as nullsfirst
from .sql.expression import nullslast as nullslast
from .sql.expression import Operators as Operators
from .sql.expression import or_ as or_
from .sql.expression import outerjoin as outerjoin
from .sql.expression import outparam as outparam
from .sql.expression import Over as Over
from .sql.expression import over as over
from .sql.expression import quoted_name as quoted_name
from .sql.expression import ReleaseSavepointClause as ReleaseSavepointClause
from .sql.expression import ReturnsRows as ReturnsRows
from .sql.expression import (
RollbackToSavepointClause as RollbackToSavepointClause,
) )
from .langhelpers import walk_subclasses as walk_subclasses from .sql.expression import SavepointClause as SavepointClause
from .langhelpers import warn as warn from .sql.expression import ScalarSelect as ScalarSelect
from .langhelpers import warn_exception as warn_exception from .sql.expression import Select as Select
from .langhelpers import warn_limited as warn_limited from .sql.expression import select as select
from .langhelpers import wrap_callable as wrap_callable from .sql.expression import Selectable as Selectable
from .preloaded import preload_module as preload_module from .sql.expression import SelectBase as SelectBase
from .typing import is_non_string_iterable as is_non_string_iterable from .sql.expression import SQLColumnExpression as SQLColumnExpression
from .sql.expression import StatementLambdaElement as StatementLambdaElement
from .sql.expression import Subquery as Subquery
from .sql.expression import table as table
from .sql.expression import TableClause as TableClause
from .sql.expression import TableSample as TableSample
from .sql.expression import tablesample as tablesample
from .sql.expression import TableValuedAlias as TableValuedAlias
from .sql.expression import text as text
from .sql.expression import TextAsFrom as TextAsFrom
from .sql.expression import TextClause as TextClause
from .sql.expression import TextualSelect as TextualSelect
from .sql.expression import true as true
from .sql.expression import True_ as True_
from .sql.expression import try_cast as try_cast
from .sql.expression import TryCast as TryCast
from .sql.expression import Tuple as Tuple
from .sql.expression import tuple_ as tuple_
from .sql.expression import type_coerce as type_coerce
from .sql.expression import TypeClause as TypeClause
from .sql.expression import TypeCoerce as TypeCoerce
from .sql.expression import UnaryExpression as UnaryExpression
from .sql.expression import union as union
from .sql.expression import union_all as union_all
from .sql.expression import Update as Update
from .sql.expression import update as update
from .sql.expression import UpdateBase as UpdateBase
from .sql.expression import Values as Values
from .sql.expression import values as values
from .sql.expression import ValuesBase as ValuesBase
from .sql.expression import Visitable as Visitable
from .sql.expression import within_group as within_group
from .sql.expression import WithinGroup as WithinGroup
from .types import ARRAY as ARRAY
from .types import BIGINT as BIGINT
from .types import BigInteger as BigInteger
from .types import BINARY as BINARY
from .types import BLOB as BLOB
from .types import BOOLEAN as BOOLEAN
from .types import Boolean as Boolean
from .types import CHAR as CHAR
from .types import CLOB as CLOB
from .types import DATE as DATE
from .types import Date as Date
from .types import DATETIME as DATETIME
from .types import DateTime as DateTime
from .types import DECIMAL as DECIMAL
from .types import DOUBLE as DOUBLE
from .types import Double as Double
from .types import DOUBLE_PRECISION as DOUBLE_PRECISION
from .types import Enum as Enum
from .types import FLOAT as FLOAT
from .types import Float as Float
from .types import INT as INT
from .types import INTEGER as INTEGER
from .types import Integer as Integer
from .types import Interval as Interval
from .types import JSON as JSON
from .types import LargeBinary as LargeBinary
from .types import NCHAR as NCHAR
from .types import NUMERIC as NUMERIC
from .types import Numeric as Numeric
from .types import NVARCHAR as NVARCHAR
from .types import PickleType as PickleType
from .types import REAL as REAL
from .types import SMALLINT as SMALLINT
from .types import SmallInteger as SmallInteger
from .types import String as String
from .types import TEXT as TEXT
from .types import Text as Text
from .types import TIME as TIME
from .types import Time as Time
from .types import TIMESTAMP as TIMESTAMP
from .types import TupleType as TupleType
from .types import TypeDecorator as TypeDecorator
from .types import Unicode as Unicode
from .types import UnicodeText as UnicodeText
from .types import UUID as UUID
from .types import Uuid as Uuid
from .types import VARBINARY as VARBINARY
from .types import VARCHAR as VARCHAR
__version__ = "2.0.51"
def __go(lcls: Any) -> None:
_util.preloaded.import_prefix("sqlalchemy")
from . import exc
exc._version_token = "".join(__version__.split(".")[0:2])
__go(locals())

View File

@@ -0,0 +1,17 @@
# events.py
# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php
"""Core event interfaces."""
from __future__ import annotations
from .engine.events import ConnectionEvents
from .engine.events import DialectEvents
from .pool import PoolResetState
from .pool.events import PoolEvents
from .sql.base import SchemaEventTarget
from .sql.events import DDLEvents

View File

@@ -0,0 +1,833 @@
# exc.py
# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php
"""Exceptions used with SQLAlchemy.
The base exception class is :exc:`.SQLAlchemyError`. Exceptions which are
raised as a result of DBAPI exceptions are all subclasses of
:exc:`.DBAPIError`.
"""
from __future__ import annotations
import typing
from typing import Any
from typing import List
from typing import Optional
from typing import overload
from typing import Tuple
from typing import Type
from typing import Union
from .util import compat
from .util import preloaded as _preloaded
if typing.TYPE_CHECKING:
from .engine.interfaces import _AnyExecuteParams
from .engine.interfaces import Dialect
from .sql.compiler import Compiled
from .sql.compiler import TypeCompiler
from .sql.elements import ClauseElement
if typing.TYPE_CHECKING:
_version_token: str
else:
# set by __init__.py
_version_token = None
class HasDescriptionCode:
"""helper which adds 'code' as an attribute and '_code_str' as a method"""
code: Optional[str] = None
def __init__(self, *arg: Any, **kw: Any):
code = kw.pop("code", None)
if code is not None:
self.code = code
super().__init__(*arg, **kw)
_what_are_we = "error"
def _code_str(self) -> str:
if not self.code:
return ""
else:
return (
f"(Background on this {self._what_are_we} at: "
f"https://sqlalche.me/e/{_version_token}/{self.code})"
)
def __str__(self) -> str:
message = super().__str__()
if self.code:
message = "%s %s" % (message, self._code_str())
return message
class SQLAlchemyError(HasDescriptionCode, Exception):
"""Generic error class."""
def _message(self) -> str:
# rules:
#
# 1. single arg string will usually be a unicode
# object, but since __str__() must return unicode, check for
# bytestring just in case
#
# 2. for multiple self.args, this is not a case in current
# SQLAlchemy though this is happening in at least one known external
# library, call str() which does a repr().
#
text: str
if len(self.args) == 1:
arg_text = self.args[0]
if isinstance(arg_text, bytes):
text = compat.decode_backslashreplace(arg_text, "utf-8")
# This is for when the argument is not a string of any sort.
# Otherwise, converting this exception to string would fail for
# non-string arguments.
else:
text = str(arg_text)
return text
else:
# this is not a normal case within SQLAlchemy but is here for
# compatibility with Exception.args - the str() comes out as
# a repr() of the tuple
return str(self.args)
def _sql_message(self) -> str:
message = self._message()
if self.code:
message = "%s %s" % (message, self._code_str())
return message
def __str__(self) -> str:
return self._sql_message()
class ArgumentError(SQLAlchemyError):
"""Raised when an invalid or conflicting function argument is supplied.
This error generally corresponds to construction time state errors.
"""
class DuplicateColumnError(ArgumentError):
"""a Column is being added to a Table that would replace another
Column, without appropriate parameters to allow this in place.
.. versionadded:: 2.0.0b4
"""
class ObjectNotExecutableError(ArgumentError):
"""Raised when an object is passed to .execute() that can't be
executed as SQL.
"""
def __init__(self, target: Any):
super().__init__("Not an executable object: %r" % target)
self.target = target
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
return self.__class__, (self.target,)
class NoSuchModuleError(ArgumentError):
"""Raised when a dynamically-loaded module (usually a database dialect)
of a particular name cannot be located."""
class NoForeignKeysError(ArgumentError):
"""Raised when no foreign keys can be located between two selectables
during a join."""
class AmbiguousForeignKeysError(ArgumentError):
"""Raised when more than one foreign key matching can be located
between two selectables during a join."""
class ConstraintColumnNotFoundError(ArgumentError):
"""raised when a constraint refers to a string column name that
is not present in the table being constrained.
.. versionadded:: 2.0
"""
class CircularDependencyError(SQLAlchemyError):
"""Raised by topological sorts when a circular dependency is detected.
There are two scenarios where this error occurs:
* In a Session flush operation, if two objects are mutually dependent
on each other, they can not be inserted or deleted via INSERT or
DELETE statements alone; an UPDATE will be needed to post-associate
or pre-deassociate one of the foreign key constrained values.
The ``post_update`` flag described at :ref:`post_update` can resolve
this cycle.
* In a :attr:`_schema.MetaData.sorted_tables` operation, two
:class:`_schema.ForeignKey`
or :class:`_schema.ForeignKeyConstraint` objects mutually refer to each
other. Apply the ``use_alter=True`` flag to one or both,
see :ref:`use_alter`.
"""
def __init__(
self,
message: str,
cycles: Any,
edges: Any,
msg: Optional[str] = None,
code: Optional[str] = None,
):
if msg is None:
message += " (%s)" % ", ".join(repr(s) for s in cycles)
else:
message = msg
SQLAlchemyError.__init__(self, message, code=code)
self.cycles = cycles
self.edges = edges
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
return (
self.__class__,
(None, self.cycles, self.edges, self.args[0]),
{"code": self.code} if self.code is not None else {},
)
class CompileError(SQLAlchemyError):
"""Raised when an error occurs during SQL compilation"""
class UnsupportedCompilationError(CompileError):
"""Raised when an operation is not supported by the given compiler.
.. seealso::
:ref:`faq_sql_expression_string`
:ref:`error_l7de`
"""
code = "l7de"
def __init__(
self,
compiler: Union[Compiled, TypeCompiler],
element_type: Type[ClauseElement],
message: Optional[str] = None,
):
super().__init__(
"Compiler %r can't render element of type %s%s"
% (compiler, element_type, ": %s" % message if message else "")
)
self.compiler = compiler
self.element_type = element_type
self.message = message
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
return self.__class__, (self.compiler, self.element_type, self.message)
class IdentifierError(SQLAlchemyError):
"""Raised when a schema name is beyond the max character limit"""
class DisconnectionError(SQLAlchemyError):
"""A disconnect is detected on a raw DB-API connection.
This error is raised and consumed internally by a connection pool. It can
be raised by the :meth:`_events.PoolEvents.checkout`
event so that the host pool
forces a retry; the exception will be caught three times in a row before
the pool gives up and raises :class:`~sqlalchemy.exc.InvalidRequestError`
regarding the connection attempt.
"""
invalidate_pool: bool = False
class InvalidatePoolError(DisconnectionError):
"""Raised when the connection pool should invalidate all stale connections.
A subclass of :class:`_exc.DisconnectionError` that indicates that the
disconnect situation encountered on the connection probably means the
entire pool should be invalidated, as the database has been restarted.
This exception will be handled otherwise the same way as
:class:`_exc.DisconnectionError`, allowing three attempts to reconnect
before giving up.
.. versionadded:: 1.2
"""
invalidate_pool: bool = True
class TimeoutError(SQLAlchemyError): # noqa
"""Raised when a connection pool times out on getting a connection."""
class InvalidRequestError(SQLAlchemyError):
"""SQLAlchemy was asked to do something it can't do.
This error generally corresponds to runtime state errors.
"""
class IllegalStateChangeError(InvalidRequestError):
"""An object that tracks state encountered an illegal state change
of some kind.
.. versionadded:: 2.0
"""
class NoInspectionAvailable(InvalidRequestError):
"""A subject passed to :func:`sqlalchemy.inspection.inspect` produced
no context for inspection."""
class PendingRollbackError(InvalidRequestError):
"""A transaction has failed and needs to be rolled back before
continuing.
.. versionadded:: 1.4
"""
class ResourceClosedError(InvalidRequestError):
"""An operation was requested from a connection, cursor, or other
object that's in a closed state."""
class NoSuchColumnError(InvalidRequestError, KeyError):
"""A nonexistent column is requested from a ``Row``."""
class NoResultFound(InvalidRequestError):
"""A database result was required but none was found.
.. versionchanged:: 1.4 This exception is now part of the
``sqlalchemy.exc`` module in Core, moved from the ORM. The symbol
remains importable from ``sqlalchemy.orm.exc``.
"""
class MultipleResultsFound(InvalidRequestError):
"""A single database result was required but more than one were found.
.. versionchanged:: 1.4 This exception is now part of the
``sqlalchemy.exc`` module in Core, moved from the ORM. The symbol
remains importable from ``sqlalchemy.orm.exc``.
"""
class NoReferenceError(InvalidRequestError):
"""Raised by ``ForeignKey`` to indicate a reference cannot be resolved."""
table_name: str
class AwaitRequired(InvalidRequestError):
"""Error raised by the async greenlet spawn if no async operation
was awaited when it required one.
"""
code = "xd1r"
class MissingGreenlet(InvalidRequestError):
r"""Error raised by the async greenlet await\_ if called while not inside
the greenlet spawn context.
"""
code = "xd2s"
class NoReferencedTableError(NoReferenceError):
"""Raised by ``ForeignKey`` when the referred ``Table`` cannot be
located.
"""
def __init__(self, message: str, tname: str):
NoReferenceError.__init__(self, message)
self.table_name = tname
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
return self.__class__, (self.args[0], self.table_name)
class NoReferencedColumnError(NoReferenceError):
"""Raised by ``ForeignKey`` when the referred ``Column`` cannot be
located.
"""
def __init__(self, message: str, tname: str, cname: str):
NoReferenceError.__init__(self, message)
self.table_name = tname
self.column_name = cname
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
return (
self.__class__,
(self.args[0], self.table_name, self.column_name),
)
class NoSuchTableError(InvalidRequestError):
"""Table does not exist or is not visible to a connection."""
class UnreflectableTableError(InvalidRequestError):
"""Table exists but can't be reflected for some reason.
.. versionadded:: 1.2
"""
class UnboundExecutionError(InvalidRequestError):
"""SQL was attempted without a database connection to execute it on."""
class DontWrapMixin:
"""A mixin class which, when applied to a user-defined Exception class,
will not be wrapped inside of :exc:`.StatementError` if the error is
emitted within the process of executing a statement.
E.g.::
from sqlalchemy.exc import DontWrapMixin
class MyCustomException(Exception, DontWrapMixin):
pass
class MySpecialType(TypeDecorator):
impl = String
def process_bind_param(self, value, dialect):
if value == "invalid":
raise MyCustomException("invalid!")
"""
class StatementError(SQLAlchemyError):
"""An error occurred during execution of a SQL statement.
:class:`StatementError` wraps the exception raised
during execution, and features :attr:`.statement`
and :attr:`.params` attributes which supply context regarding
the specifics of the statement which had an issue.
The wrapped exception object is available in
the :attr:`.orig` attribute.
"""
statement: Optional[str] = None
"""The string SQL statement being invoked when this exception occurred."""
params: Optional[_AnyExecuteParams] = None
"""The parameter list being used when this exception occurred."""
orig: Optional[BaseException] = None
"""The original exception that was thrown.
"""
ismulti: Optional[bool] = None
"""multi parameter passed to repr_params(). None is meaningful."""
connection_invalidated: bool = False
def __init__(
self,
message: str,
statement: Optional[str],
params: Optional[_AnyExecuteParams],
orig: Optional[BaseException],
hide_parameters: bool = False,
code: Optional[str] = None,
ismulti: Optional[bool] = None,
):
SQLAlchemyError.__init__(self, message, code=code)
self.statement = statement
self.params = params
self.orig = orig
self.ismulti = ismulti
self.hide_parameters = hide_parameters
self.detail: List[str] = []
def add_detail(self, msg: str) -> None:
self.detail.append(msg)
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
return (
self.__class__,
(
self.args[0],
self.statement,
self.params,
self.orig,
self.hide_parameters,
self.__dict__.get("code"),
self.ismulti,
),
{"detail": self.detail},
)
@_preloaded.preload_module("sqlalchemy.sql.util")
def _sql_message(self) -> str:
util = _preloaded.sql_util
details = [self._message()]
if self.statement:
stmt_detail = "[SQL: %s]" % self.statement
details.append(stmt_detail)
if self.params:
if self.hide_parameters:
details.append(
"[SQL parameters hidden due to hide_parameters=True]"
)
else:
params_repr = util._repr_params(
self.params, 10, ismulti=self.ismulti
)
details.append("[parameters: %r]" % params_repr)
code_str = self._code_str()
if code_str:
details.append(code_str)
return "\n".join(["(%s)" % det for det in self.detail] + details)
class DBAPIError(StatementError):
"""Raised when the execution of a database operation fails.
Wraps exceptions raised by the DB-API underlying the
database operation. Driver-specific implementations of the standard
DB-API exception types are wrapped by matching sub-types of SQLAlchemy's
:class:`DBAPIError` when possible. DB-API's ``Error`` type maps to
:class:`DBAPIError` in SQLAlchemy, otherwise the names are identical. Note
that there is no guarantee that different DB-API implementations will
raise the same exception type for any given error condition.
:class:`DBAPIError` features :attr:`~.StatementError.statement`
and :attr:`~.StatementError.params` attributes which supply context
regarding the specifics of the statement which had an issue, for the
typical case when the error was raised within the context of
emitting a SQL statement.
The wrapped exception object is available in the
:attr:`~.StatementError.orig` attribute. Its type and properties are
DB-API implementation specific.
"""
code = "dbapi"
@overload
@classmethod
def instance(
cls,
statement: Optional[str],
params: Optional[_AnyExecuteParams],
orig: Exception,
dbapi_base_err: Type[Exception],
hide_parameters: bool = False,
connection_invalidated: bool = False,
dialect: Optional[Dialect] = None,
ismulti: Optional[bool] = None,
) -> StatementError: ...
@overload
@classmethod
def instance(
cls,
statement: Optional[str],
params: Optional[_AnyExecuteParams],
orig: DontWrapMixin,
dbapi_base_err: Type[Exception],
hide_parameters: bool = False,
connection_invalidated: bool = False,
dialect: Optional[Dialect] = None,
ismulti: Optional[bool] = None,
) -> DontWrapMixin: ...
@overload
@classmethod
def instance(
cls,
statement: Optional[str],
params: Optional[_AnyExecuteParams],
orig: BaseException,
dbapi_base_err: Type[Exception],
hide_parameters: bool = False,
connection_invalidated: bool = False,
dialect: Optional[Dialect] = None,
ismulti: Optional[bool] = None,
) -> BaseException: ...
@classmethod
def instance(
cls,
statement: Optional[str],
params: Optional[_AnyExecuteParams],
orig: Union[BaseException, DontWrapMixin],
dbapi_base_err: Type[Exception],
hide_parameters: bool = False,
connection_invalidated: bool = False,
dialect: Optional[Dialect] = None,
ismulti: Optional[bool] = None,
) -> Union[BaseException, DontWrapMixin]:
# Don't ever wrap these, just return them directly as if
# DBAPIError didn't exist.
if (
isinstance(orig, BaseException) and not isinstance(orig, Exception)
) or isinstance(orig, DontWrapMixin):
return orig
if orig is not None:
# not a DBAPI error, statement is present.
# raise a StatementError
if isinstance(orig, SQLAlchemyError) and statement:
return StatementError(
"(%s.%s) %s"
% (
orig.__class__.__module__,
orig.__class__.__name__,
orig.args[0],
),
statement,
params,
orig,
hide_parameters=hide_parameters,
code=orig.code,
ismulti=ismulti,
)
elif not isinstance(orig, dbapi_base_err) and statement:
return StatementError(
"(%s.%s) %s"
% (
orig.__class__.__module__,
orig.__class__.__name__,
orig,
),
statement,
params,
orig,
hide_parameters=hide_parameters,
ismulti=ismulti,
)
glob = globals()
for super_ in orig.__class__.__mro__:
name = super_.__name__
if dialect:
name = dialect.dbapi_exception_translation_map.get(
name, name
)
if name in glob and issubclass(glob[name], DBAPIError):
cls = glob[name]
break
return cls(
statement,
params,
orig,
connection_invalidated=connection_invalidated,
hide_parameters=hide_parameters,
code=cls.code,
ismulti=ismulti,
)
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
return (
self.__class__,
(
self.statement,
self.params,
self.orig,
self.hide_parameters,
self.connection_invalidated,
self.__dict__.get("code"),
self.ismulti,
),
{"detail": self.detail},
)
def __init__(
self,
statement: Optional[str],
params: Optional[_AnyExecuteParams],
orig: BaseException,
hide_parameters: bool = False,
connection_invalidated: bool = False,
code: Optional[str] = None,
ismulti: Optional[bool] = None,
):
try:
text = str(orig)
except Exception as e:
text = "Error in str() of DB-API-generated exception: " + str(e)
StatementError.__init__(
self,
"(%s.%s) %s"
% (orig.__class__.__module__, orig.__class__.__name__, text),
statement,
params,
orig,
hide_parameters,
code=code,
ismulti=ismulti,
)
self.connection_invalidated = connection_invalidated
class InterfaceError(DBAPIError):
"""Wraps a DB-API InterfaceError."""
code = "rvf5"
class DatabaseError(DBAPIError):
"""Wraps a DB-API DatabaseError."""
code = "4xp6"
class DataError(DatabaseError):
"""Wraps a DB-API DataError."""
code = "9h9h"
class OperationalError(DatabaseError):
"""Wraps a DB-API OperationalError."""
code = "e3q8"
class IntegrityError(DatabaseError):
"""Wraps a DB-API IntegrityError."""
code = "gkpj"
class InternalError(DatabaseError):
"""Wraps a DB-API InternalError."""
code = "2j85"
class ProgrammingError(DatabaseError):
"""Wraps a DB-API ProgrammingError."""
code = "f405"
class NotSupportedError(DatabaseError):
"""Wraps a DB-API NotSupportedError."""
code = "tw8g"
# Warnings
class SATestSuiteWarning(Warning):
"""warning for a condition detected during tests that is non-fatal
Currently outside of SAWarning so that we can work around tools like
Alembic doing the wrong thing with warnings.
"""
class SADeprecationWarning(HasDescriptionCode, DeprecationWarning):
"""Issued for usage of deprecated APIs."""
deprecated_since: Optional[str] = None
"Indicates the version that started raising this deprecation warning"
class Base20DeprecationWarning(SADeprecationWarning):
"""Issued for usage of APIs specifically deprecated or legacy in
SQLAlchemy 2.0.
.. seealso::
:ref:`error_b8d9`.
:ref:`deprecation_20_mode`
"""
deprecated_since: Optional[str] = "1.4"
"Indicates the version that started raising this deprecation warning"
def __str__(self) -> str:
return (
super().__str__()
+ " (Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9)"
)
class LegacyAPIWarning(Base20DeprecationWarning):
"""indicates an API that is in 'legacy' status, a long term deprecation."""
class MovedIn20Warning(Base20DeprecationWarning):
"""Subtype of RemovedIn20Warning to indicate an API that moved only."""
class SAPendingDeprecationWarning(PendingDeprecationWarning):
"""A similar warning as :class:`_exc.SADeprecationWarning`, this warning
is not used in modern versions of SQLAlchemy.
"""
deprecated_since: Optional[str] = None
"Indicates the version that started raising this deprecation warning"
class SAWarning(HasDescriptionCode, RuntimeWarning):
"""Issued at runtime."""
_what_are_we = "warning"

View File

@@ -0,0 +1,175 @@
# inspection.py
# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php
"""The inspection module provides the :func:`_sa.inspect` function,
which delivers runtime information about a wide variety
of SQLAlchemy objects, both within the Core as well as the
ORM.
The :func:`_sa.inspect` function is the entry point to SQLAlchemy's
public API for viewing the configuration and construction
of in-memory objects. Depending on the type of object
passed to :func:`_sa.inspect`, the return value will either be
a related object which provides a known interface, or in many
cases it will return the object itself.
The rationale for :func:`_sa.inspect` is twofold. One is that
it replaces the need to be aware of a large variety of "information
getting" functions in SQLAlchemy, such as
:meth:`_reflection.Inspector.from_engine` (deprecated in 1.4),
:func:`.orm.attributes.instance_state`, :func:`_orm.class_mapper`,
and others. The other is that the return value of :func:`_sa.inspect`
is guaranteed to obey a documented API, thus allowing third party
tools which build on top of SQLAlchemy configurations to be constructed
in a forwards-compatible way.
"""
from __future__ import annotations
from typing import Any
from typing import Callable
from typing import Dict
from typing import Generic
from typing import Optional
from typing import overload
from typing import Type
from typing import TypeVar
from typing import Union
from . import exc
from .util.typing import Literal
from .util.typing import Protocol
_T = TypeVar("_T", bound=Any)
_TCov = TypeVar("_TCov", bound=Any, covariant=True)
_F = TypeVar("_F", bound=Callable[..., Any])
_IN = TypeVar("_IN", bound=Any)
_registrars: Dict[type, Union[Literal[True], Callable[[Any], Any]]] = {}
class Inspectable(Generic[_T]):
"""define a class as inspectable.
This allows typing to set up a linkage between an object that
can be inspected and the type of inspection it returns.
Unfortunately we cannot at the moment get all classes that are
returned by inspection to suit this interface as we get into
MRO issues.
"""
__slots__ = ()
class _InspectableTypeProtocol(Protocol[_TCov]):
"""a protocol defining a method that's used when a type (ie the class
itself) is passed to inspect().
"""
def _sa_inspect_type(self) -> _TCov: ...
class _InspectableProtocol(Protocol[_TCov]):
"""a protocol defining a method that's used when an instance is
passed to inspect().
"""
def _sa_inspect_instance(self) -> _TCov: ...
@overload
def inspect(
subject: Type[_InspectableTypeProtocol[_IN]], raiseerr: bool = True
) -> _IN: ...
@overload
def inspect(
subject: _InspectableProtocol[_IN], raiseerr: bool = True
) -> _IN: ...
@overload
def inspect(subject: Inspectable[_IN], raiseerr: bool = True) -> _IN: ...
@overload
def inspect(subject: Any, raiseerr: Literal[False] = ...) -> Optional[Any]: ...
@overload
def inspect(subject: Any, raiseerr: bool = True) -> Any: ...
def inspect(subject: Any, raiseerr: bool = True) -> Any:
"""Produce an inspection object for the given target.
The returned value in some cases may be the
same object as the one given, such as if a
:class:`_orm.Mapper` object is passed. In other
cases, it will be an instance of the registered
inspection type for the given object, such as
if an :class:`_engine.Engine` is passed, an
:class:`_reflection.Inspector` object is returned.
:param subject: the subject to be inspected.
:param raiseerr: When ``True``, if the given subject
does not
correspond to a known SQLAlchemy inspected type,
:class:`sqlalchemy.exc.NoInspectionAvailable`
is raised. If ``False``, ``None`` is returned.
"""
type_ = type(subject)
for cls in type_.__mro__:
if cls in _registrars:
reg = _registrars.get(cls, None)
if reg is None:
continue
elif reg is True:
return subject
ret = reg(subject)
if ret is not None:
return ret
else:
reg = ret = None
if raiseerr and (reg is None or ret is None):
raise exc.NoInspectionAvailable(
"No inspection system is "
"available for object of type %s" % type_
)
return ret
def _inspects(
*types: Type[Any],
) -> Callable[[_F], _F]:
def decorate(fn_or_cls: _F) -> _F:
for type_ in types:
if type_ in _registrars:
raise AssertionError("Type %s is already registered" % type_)
_registrars[type_] = fn_or_cls
return fn_or_cls
return decorate
_TT = TypeVar("_TT", bound="Type[Any]")
def _self_inspects(cls: _TT) -> _TT:
if cls in _registrars:
raise AssertionError("Type %s is already registered" % cls)
_registrars[cls] = True
return cls

View File

@@ -0,0 +1,288 @@
# log.py
# Copyright (C) 2006-2026 the SQLAlchemy authors and contributors
# <see AUTHORS file>
# Includes alterations by Vinay Sajip vinay_sajip@yahoo.co.uk
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php
"""Logging control and utilities.
Control of logging for SA can be performed from the regular python logging
module. The regular dotted module namespace is used, starting at
'sqlalchemy'. For class-level logging, the class name is appended.
The "echo" keyword parameter, available on SQLA :class:`_engine.Engine`
and :class:`_pool.Pool` objects, corresponds to a logger specific to that
instance only.
"""
from __future__ import annotations
import logging
import sys
from typing import Any
from typing import Optional
from typing import overload
from typing import Set
from typing import Type
from typing import TypeVar
from typing import Union
from .util import py311
from .util import py38
from .util.typing import Literal
if py38:
STACKLEVEL = True
# needed as of py3.11.0b1
# #8019
STACKLEVEL_OFFSET = 2 if py311 else 1
else:
STACKLEVEL = False
STACKLEVEL_OFFSET = 0
_IT = TypeVar("_IT", bound="Identified")
_EchoFlagType = Union[None, bool, Literal["debug"]]
# set initial level to WARN. This so that
# log statements don't occur in the absence of explicit
# logging being enabled for 'sqlalchemy'.
rootlogger = logging.getLogger("sqlalchemy")
if rootlogger.level == logging.NOTSET:
rootlogger.setLevel(logging.WARNING)
def _add_default_handler(logger: logging.Logger) -> None:
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(
logging.Formatter("%(asctime)s %(levelname)s %(name)s %(message)s")
)
logger.addHandler(handler)
_logged_classes: Set[Type[Identified]] = set()
def _qual_logger_name_for_cls(cls: Type[Identified]) -> str:
return (
getattr(cls, "_sqla_logger_namespace", None)
or cls.__module__ + "." + cls.__name__
)
def class_logger(cls: Type[_IT]) -> Type[_IT]:
logger = logging.getLogger(_qual_logger_name_for_cls(cls))
cls._should_log_debug = lambda self: logger.isEnabledFor( # type: ignore[method-assign] # noqa: E501
logging.DEBUG
)
cls._should_log_info = lambda self: logger.isEnabledFor( # type: ignore[method-assign] # noqa: E501
logging.INFO
)
cls.logger = logger
_logged_classes.add(cls)
return cls
_IdentifiedLoggerType = Union[logging.Logger, "InstanceLogger"]
class Identified:
__slots__ = ()
logging_name: Optional[str] = None
logger: _IdentifiedLoggerType
_echo: _EchoFlagType
def _should_log_debug(self) -> bool:
return self.logger.isEnabledFor(logging.DEBUG)
def _should_log_info(self) -> bool:
return self.logger.isEnabledFor(logging.INFO)
class InstanceLogger:
"""A logger adapter (wrapper) for :class:`.Identified` subclasses.
This allows multiple instances (e.g. Engine or Pool instances)
to share a logger, but have its verbosity controlled on a
per-instance basis.
The basic functionality is to return a logging level
which is based on an instance's echo setting.
Default implementation is:
'debug' -> logging.DEBUG
True -> logging.INFO
False -> Effective level of underlying logger (
logging.WARNING by default)
None -> same as False
"""
# Map echo settings to logger levels
_echo_map = {
None: logging.NOTSET,
False: logging.NOTSET,
True: logging.INFO,
"debug": logging.DEBUG,
}
_echo: _EchoFlagType
__slots__ = ("echo", "logger")
def __init__(self, echo: _EchoFlagType, name: str):
self.echo = echo
self.logger = logging.getLogger(name)
# if echo flag is enabled and no handlers,
# add a handler to the list
if self._echo_map[echo] <= logging.INFO and not self.logger.handlers:
_add_default_handler(self.logger)
#
# Boilerplate convenience methods
#
def debug(self, msg: str, *args: Any, **kwargs: Any) -> None:
"""Delegate a debug call to the underlying logger."""
self.log(logging.DEBUG, msg, *args, **kwargs)
def info(self, msg: str, *args: Any, **kwargs: Any) -> None:
"""Delegate an info call to the underlying logger."""
self.log(logging.INFO, msg, *args, **kwargs)
def warning(self, msg: str, *args: Any, **kwargs: Any) -> None:
"""Delegate a warning call to the underlying logger."""
self.log(logging.WARNING, msg, *args, **kwargs)
warn = warning
def error(self, msg: str, *args: Any, **kwargs: Any) -> None:
"""
Delegate an error call to the underlying logger.
"""
self.log(logging.ERROR, msg, *args, **kwargs)
def exception(self, msg: str, *args: Any, **kwargs: Any) -> None:
"""Delegate an exception call to the underlying logger."""
kwargs["exc_info"] = 1
self.log(logging.ERROR, msg, *args, **kwargs)
def critical(self, msg: str, *args: Any, **kwargs: Any) -> None:
"""Delegate a critical call to the underlying logger."""
self.log(logging.CRITICAL, msg, *args, **kwargs)
def log(self, level: int, msg: str, *args: Any, **kwargs: Any) -> None:
"""Delegate a log call to the underlying logger.
The level here is determined by the echo
flag as well as that of the underlying logger, and
logger._log() is called directly.
"""
# inline the logic from isEnabledFor(),
# getEffectiveLevel(), to avoid overhead.
if self.logger.manager.disable >= level:
return
selected_level = self._echo_map[self.echo]
if selected_level == logging.NOTSET:
selected_level = self.logger.getEffectiveLevel()
if level >= selected_level:
if STACKLEVEL:
kwargs["stacklevel"] = (
kwargs.get("stacklevel", 1) + STACKLEVEL_OFFSET
)
self.logger._log(level, msg, args, **kwargs)
def isEnabledFor(self, level: int) -> bool:
"""Is this logger enabled for level 'level'?"""
if self.logger.manager.disable >= level:
return False
return level >= self.getEffectiveLevel()
def getEffectiveLevel(self) -> int:
"""What's the effective level for this logger?"""
level = self._echo_map[self.echo]
if level == logging.NOTSET:
level = self.logger.getEffectiveLevel()
return level
def instance_logger(
instance: Identified, echoflag: _EchoFlagType = None
) -> None:
"""create a logger for an instance that implements :class:`.Identified`."""
if instance.logging_name:
name = "%s.%s" % (
_qual_logger_name_for_cls(instance.__class__),
instance.logging_name,
)
else:
name = _qual_logger_name_for_cls(instance.__class__)
instance._echo = echoflag # type: ignore
logger: Union[logging.Logger, InstanceLogger]
if echoflag in (False, None):
# if no echo setting or False, return a Logger directly,
# avoiding overhead of filtering
logger = logging.getLogger(name)
else:
# if a specified echo flag, return an EchoLogger,
# which checks the flag, overrides normal log
# levels by calling logger._log()
logger = InstanceLogger(echoflag, name)
instance.logger = logger # type: ignore
class echo_property:
__doc__ = """\
When ``True``, enable log output for this element.
This has the effect of setting the Python logging level for the namespace
of this element's class and object reference. A value of boolean ``True``
indicates that the loglevel ``logging.INFO`` will be set for the logger,
whereas the string value ``debug`` will set the loglevel to
``logging.DEBUG``.
"""
@overload
def __get__(
self, instance: Literal[None], owner: Type[Identified]
) -> echo_property: ...
@overload
def __get__(
self, instance: Identified, owner: Type[Identified]
) -> _EchoFlagType: ...
def __get__(
self, instance: Optional[Identified], owner: Type[Identified]
) -> Union[echo_property, _EchoFlagType]:
if instance is None:
return self
else:
return instance._echo
def __set__(self, instance: Identified, value: _EchoFlagType) -> None:
instance_logger(instance, echoflag=value)