Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/attr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from functools import partial
from typing import Callable, Literal, Protocol

from . import converters, exceptions, filters, setters, validators
from . import exceptions, filters, setters
from ._cmp import cmp_using
from ._config import get_run_validators, set_run_validators
from ._funcs import asdict, assoc, astuple, has, resolve_types
Expand Down Expand Up @@ -78,13 +78,23 @@ class AttrsInstance(Protocol):
]


_LAZY_SUBMODULES = {"converters", "validators"}


def _make_getattr(mod_name: str) -> Callable:
"""
Create a metadata proxy for packaging information that uses *mod_name* in
its warnings and errors.
"""

def __getattr__(name: str) -> str:
if name in _LAZY_SUBMODULES:
import importlib

mod = importlib.import_module(f".{name}", mod_name)
globals()[name] = mod
return mod

if name not in ("__version__", "__version_info__"):
msg = f"module {mod_name} has no attribute {name}"
raise AttributeError(msg)
Expand Down
7 changes: 6 additions & 1 deletion src/attr/_compat.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# SPDX-License-Identifier: MIT

import inspect
import platform
import sys
import threading
Expand Down Expand Up @@ -46,6 +45,8 @@ class _AnnotationExtractor:
__slots__ = ["sig"]

def __init__(self, callable):
import inspect

try:
self.sig = inspect.signature(callable)
except (ValueError, TypeError): # inspect failed
Expand All @@ -55,6 +56,8 @@ def get_first_param_type(self):
"""
Return the type annotation of the first argument if it's not empty.
"""
import inspect

if not self.sig:
return None

Expand All @@ -68,6 +71,8 @@ def get_return_type(self):
"""
Return the return type if it's not empty.
"""
import inspect

if (
self.sig
and self.sig.return_annotation is not inspect.Signature.empty
Expand Down
5 changes: 4 additions & 1 deletion src/attr/_make.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import contextlib
import copy
import enum
import inspect
import itertools
import linecache
import sys
Expand Down Expand Up @@ -705,6 +704,8 @@ def __init__(
if self._has_pre_init:
# Check if the pre init method has more arguments than just `self`
# We want to pass arguments if pre init expects arguments
import inspect

pre_init_func = cls.__attrs_pre_init__
pre_init_signature = inspect.signature(pre_init_func)
self._pre_init_has_args = len(pre_init_signature.parameters) > 1
Expand Down Expand Up @@ -920,6 +921,8 @@ def _create_slots_class(self):
# To know to update them.
additional_closure_functions_to_update = []
if cached_properties:
import inspect

class_annotations = _get_annotations(self._cls)
for name, func in cached_properties.items():
# Add cached properties to names for slotting.
Expand Down
2 changes: 1 addition & 1 deletion src/attrs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from attr._make import ClassProps
from attr._next_gen import asdict, astuple, inspect

from . import converters, exceptions, filters, setters, validators
from . import exceptions, filters, setters


__all__ = [
Expand Down