Загрузить файлы в «venv/Lib/site-packages/sqlalchemy/util»
This commit is contained in:
@@ -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())
|
||||||
|
|||||||
17
venv/Lib/site-packages/sqlalchemy/util/events.py
Normal file
17
venv/Lib/site-packages/sqlalchemy/util/events.py
Normal 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
|
||||||
833
venv/Lib/site-packages/sqlalchemy/util/exc.py
Normal file
833
venv/Lib/site-packages/sqlalchemy/util/exc.py
Normal 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"
|
||||||
175
venv/Lib/site-packages/sqlalchemy/util/inspection.py
Normal file
175
venv/Lib/site-packages/sqlalchemy/util/inspection.py
Normal 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
|
||||||
288
venv/Lib/site-packages/sqlalchemy/util/log.py
Normal file
288
venv/Lib/site-packages/sqlalchemy/util/log.py
Normal 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)
|
||||||
Reference in New Issue
Block a user