-
|
The following setup is a # bear/bear_doubly_forward_b.py
from typing import TYPE_CHECKING, TypeAlias
from beartype.typing import Optional
if TYPE_CHECKING:
from bear.bear_doubly_forward_a import A
import bear.bear_doubly_forward_a
else:
A: TypeAlias = "bear.bear_doubly_forward_a.A"
class B:
def __init__(self, inner: "list[A | None]"):
self.inner = inner# bear_main.py
from bear.bear_doubly_forward_b import B
b = B([None])# bear/bear_doubly_forward_a.py
class A:
pass# bear/__init__.py
from beartype.claw import beartype_package
beartype_package("bear") |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 5 replies
-
|
Lol and I found the solution on my own again. from typing import TYPE_CHECKING, TypeAliasType, TypeAlias
if TYPE_CHECKING:
from bear.bear_doubly_forward_a import A
else:
A: TypeAlias = TypeAliasType("A", "bear.bear_doubly_forward_a.A")
class B:
def __init__(self, inner: list[A | None]):
self.inner = innerLearned this trick from #562 (comment) |
Beta Was this translation helpful? Give feedback.
-
|
Woah. That's a super-cool trick. There's so much useful weirdness going on there. Nobody else is ever gonna figure that out. That includes me. I'll need this someday (and won't be able to find it). Definitely feels like this madness should be documented with a FAQ entry. Forward references sure are brutal. Why Saturday night gotta be like this... 🥵 |
Beta Was this translation helpful? Give feedback.
-
|
So cool! This is fairly huge for Indeed, PEP 810 itself notes this obvious advantage:
PEP 810: So Big I Can No Longer See the SunPEP 810 is also literally huge. There are seven (!) authors on this beast. Because I am lazy by definition, I've only sped-read the standard. But it looks like @beartype should just implicitly support PEP 810 "out of the box." @beartype shouldn't need to do anything special here to support lazy imports. They just work on all existing @beartype versions. Way to go, PEP 810 authors! How often does that happen? 🤔 Actually, on second thought, @beartype might need to do something explicit here in outlier edge cases like: from beartype import beartype
from lazy import superfun_lazysun
from types import ModuleType
@beartype
def get_module_superfun_attr(superfun_module: ModuleType) -> object:
return getattr(superfun_module, 'superfun_attr')
# This should just work. But does it? Probably not. @beartype probably needs to do something here.
print(get_module_superfun_attr(superfun_lazysun))Specifically, @beartype should define a PEP 810-compliant reducer from I suppose what @beartype could do is define a PEP 810-compliant reducer from the simple type from types import (
LazyImportType, # <-- only do this under Python >= 3.15, obviously *sigh*
ModuleType,
)
class _BeartypeCrazyModuleCheckerMetaclass(type):
def __instancecheck__(cls: type, obj: object) -> bool:
if isinstance(obj, ModuleType):
return True
elif isinstance(obj, LazyImportType):
try:
obj.resolve()
return True
except:
pass
return False
class BeartypeCrazyModuleChecker(object, metaclass=_BeartypeCrazyModuleCheckerMetaclass):
passLet's ignore this until somebody justifiably complains about this. Will I even remember we had this discussion, though!?!? My memory is a guppy fish in motion. 🐠 <-- dumb @leycec so sad UPDATE: I just enshrined this as a new feature request. Please, nobody care... please. I'm begging you on a Monday night. 🥺 |
Beta Was this translation helpful? Give feedback.
Lol and I found the solution on my own again.
Learned this trick from #562 (comment)