1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570 |
- import abc
- import builtins
- import collections
- import collections.abc
- import contextlib
- import enum
- import functools
- import inspect
- import keyword
- import operator
- import sys
- import types as _types
- import typing
- import warnings
- __all__ = [
- # Super-special typing primitives.
- 'Any',
- 'ClassVar',
- 'Concatenate',
- 'Final',
- 'LiteralString',
- 'ParamSpec',
- 'ParamSpecArgs',
- 'ParamSpecKwargs',
- 'Self',
- 'Type',
- 'TypeVar',
- 'TypeVarTuple',
- 'Unpack',
- # ABCs (from collections.abc).
- 'Awaitable',
- 'AsyncIterator',
- 'AsyncIterable',
- 'Coroutine',
- 'AsyncGenerator',
- 'AsyncContextManager',
- 'Buffer',
- 'ChainMap',
- # Concrete collection types.
- 'ContextManager',
- 'Counter',
- 'Deque',
- 'DefaultDict',
- 'NamedTuple',
- 'OrderedDict',
- 'TypedDict',
- # Structural checks, a.k.a. protocols.
- 'SupportsAbs',
- 'SupportsBytes',
- 'SupportsComplex',
- 'SupportsFloat',
- 'SupportsIndex',
- 'SupportsInt',
- 'SupportsRound',
- # One-off things.
- 'Annotated',
- 'assert_never',
- 'assert_type',
- 'clear_overloads',
- 'dataclass_transform',
- 'deprecated',
- 'Doc',
- 'evaluate_forward_ref',
- 'get_overloads',
- 'final',
- 'Format',
- 'get_annotations',
- 'get_args',
- 'get_origin',
- 'get_original_bases',
- 'get_protocol_members',
- 'get_type_hints',
- 'IntVar',
- 'is_protocol',
- 'is_typeddict',
- 'Literal',
- 'NewType',
- 'overload',
- 'override',
- 'Protocol',
- 'reveal_type',
- 'runtime',
- 'runtime_checkable',
- 'Text',
- 'TypeAlias',
- 'TypeAliasType',
- 'TypeForm',
- 'TypeGuard',
- 'TypeIs',
- 'TYPE_CHECKING',
- 'Never',
- 'NoReturn',
- 'ReadOnly',
- 'Required',
- 'NotRequired',
- 'NoDefault',
- 'NoExtraItems',
- # Pure aliases, have always been in typing
- 'AbstractSet',
- 'AnyStr',
- 'BinaryIO',
- 'Callable',
- 'Collection',
- 'Container',
- 'Dict',
- 'ForwardRef',
- 'FrozenSet',
- 'Generator',
- 'Generic',
- 'Hashable',
- 'IO',
- 'ItemsView',
- 'Iterable',
- 'Iterator',
- 'KeysView',
- 'List',
- 'Mapping',
- 'MappingView',
- 'Match',
- 'MutableMapping',
- 'MutableSequence',
- 'MutableSet',
- 'Optional',
- 'Pattern',
- 'Reversible',
- 'Sequence',
- 'Set',
- 'Sized',
- 'TextIO',
- 'Tuple',
- 'Union',
- 'ValuesView',
- 'cast',
- 'no_type_check',
- 'no_type_check_decorator',
- ]
- # for backward compatibility
- PEP_560 = True
- GenericMeta = type
- _PEP_696_IMPLEMENTED = sys.version_info >= (3, 13, 0, "beta")
- # Added with bpo-45166 to 3.10.1+ and some 3.9 versions
- _FORWARD_REF_HAS_CLASS = "__forward_is_class__" in typing.ForwardRef.__slots__
- # The functions below are modified copies of typing internal helpers.
- # They are needed by _ProtocolMeta and they provide support for PEP 646.
- class _Sentinel:
- def __repr__(self):
- return "<sentinel>"
- _marker = _Sentinel()
- if sys.version_info >= (3, 10):
- def _should_collect_from_parameters(t):
- return isinstance(
- t, (typing._GenericAlias, _types.GenericAlias, _types.UnionType)
- )
- elif sys.version_info >= (3, 9):
- def _should_collect_from_parameters(t):
- return isinstance(t, (typing._GenericAlias, _types.GenericAlias))
- else:
- def _should_collect_from_parameters(t):
- return isinstance(t, typing._GenericAlias) and not t._special
- NoReturn = typing.NoReturn
- # Some unconstrained type variables. These are used by the container types.
- # (These are not for export.)
- T = typing.TypeVar('T') # Any type.
- KT = typing.TypeVar('KT') # Key type.
- VT = typing.TypeVar('VT') # Value type.
- T_co = typing.TypeVar('T_co', covariant=True) # Any type covariant containers.
- T_contra = typing.TypeVar('T_contra', contravariant=True) # Ditto contravariant.
- if sys.version_info >= (3, 11):
- from typing import Any
- else:
- class _AnyMeta(type):
- def __instancecheck__(self, obj):
- if self is Any:
- raise TypeError("typing_extensions.Any cannot be used with isinstance()")
- return super().__instancecheck__(obj)
- def __repr__(self):
- if self is Any:
- return "typing_extensions.Any"
- return super().__repr__()
- class Any(metaclass=_AnyMeta):
- """Special type indicating an unconstrained type.
- - Any is compatible with every type.
- - Any assumed to have all methods.
- - All values assumed to be instances of Any.
- Note that all the above statements are true from the point of view of
- static type checkers. At runtime, Any should not be used with instance
- checks.
- """
- def __new__(cls, *args, **kwargs):
- if cls is Any:
- raise TypeError("Any cannot be instantiated")
- return super().__new__(cls, *args, **kwargs)
- ClassVar = typing.ClassVar
- class _ExtensionsSpecialForm(typing._SpecialForm, _root=True):
- def __repr__(self):
- return 'typing_extensions.' + self._name
- Final = typing.Final
- if sys.version_info >= (3, 11):
- final = typing.final
- else:
- # @final exists in 3.8+, but we backport it for all versions
- # before 3.11 to keep support for the __final__ attribute.
- # See https://bugs.python.org/issue46342
- def final(f):
- """This decorator can be used to indicate to type checkers that
- the decorated method cannot be overridden, and decorated class
- cannot be subclassed. For example:
- class Base:
- @final
- def done(self) -> None:
- ...
- class Sub(Base):
- def done(self) -> None: # Error reported by type checker
- ...
- @final
- class Leaf:
- ...
- class Other(Leaf): # Error reported by type checker
- ...
- There is no runtime checking of these properties. The decorator
- sets the ``__final__`` attribute to ``True`` on the decorated object
- to allow runtime introspection.
- """
- try:
- f.__final__ = True
- except (AttributeError, TypeError):
- # Skip the attribute silently if it is not writable.
- # AttributeError happens if the object has __slots__ or a
- # read-only property, TypeError if it's a builtin class.
- pass
- return f
- def IntVar(name):
- return typing.TypeVar(name)
- # A Literal bug was fixed in 3.11.0, 3.10.1 and 3.9.8
- if sys.version_info >= (3, 10, 1):
- Literal = typing.Literal
- else:
- def _flatten_literal_params(parameters):
- """An internal helper for Literal creation: flatten Literals among parameters"""
- params = []
- for p in parameters:
- if isinstance(p, _LiteralGenericAlias):
- params.extend(p.__args__)
- else:
- params.append(p)
- return tuple(params)
- def _value_and_type_iter(params):
- for p in params:
- yield p, type(p)
- class _LiteralGenericAlias(typing._GenericAlias, _root=True):
- def __eq__(self, other):
- if not isinstance(other, _LiteralGenericAlias):
- return NotImplemented
- these_args_deduped = set(_value_and_type_iter(self.__args__))
- other_args_deduped = set(_value_and_type_iter(other.__args__))
- return these_args_deduped == other_args_deduped
- def __hash__(self):
- return hash(frozenset(_value_and_type_iter(self.__args__)))
- class _LiteralForm(_ExtensionsSpecialForm, _root=True):
- def __init__(self, doc: str):
- self._name = 'Literal'
- self._doc = self.__doc__ = doc
- def __getitem__(self, parameters):
- if not isinstance(parameters, tuple):
- parameters = (parameters,)
- parameters = _flatten_literal_params(parameters)
- val_type_pairs = list(_value_and_type_iter(parameters))
- try:
- deduped_pairs = set(val_type_pairs)
- except TypeError:
- # unhashable parameters
- pass
- else:
- # similar logic to typing._deduplicate on Python 3.9+
- if len(deduped_pairs) < len(val_type_pairs):
- new_parameters = []
- for pair in val_type_pairs:
- if pair in deduped_pairs:
- new_parameters.append(pair[0])
- deduped_pairs.remove(pair)
- assert not deduped_pairs, deduped_pairs
- parameters = tuple(new_parameters)
- return _LiteralGenericAlias(self, parameters)
- Literal = _LiteralForm(doc="""\
- A type that can be used to indicate to type checkers
- that the corresponding value has a value literally equivalent
- to the provided parameter. For example:
- var: Literal[4] = 4
- The type checker understands that 'var' is literally equal to
- the value 4 and no other value.
- Literal[...] cannot be subclassed. There is no runtime
- checking verifying that the parameter is actually a value
- instead of a type.""")
- _overload_dummy = typing._overload_dummy
- if hasattr(typing, "get_overloads"): # 3.11+
- overload = typing.overload
- get_overloads = typing.get_overloads
- clear_overloads = typing.clear_overloads
- else:
- # {module: {qualname: {firstlineno: func}}}
- _overload_registry = collections.defaultdict(
- functools.partial(collections.defaultdict, dict)
- )
- def overload(func):
- """Decorator for overloaded functions/methods.
- In a stub file, place two or more stub definitions for the same
- function in a row, each decorated with @overload. For example:
- @overload
- def utf8(value: None) -> None: ...
- @overload
- def utf8(value: bytes) -> bytes: ...
- @overload
- def utf8(value: str) -> bytes: ...
- In a non-stub file (i.e. a regular .py file), do the same but
- follow it with an implementation. The implementation should *not*
- be decorated with @overload. For example:
- @overload
- def utf8(value: None) -> None: ...
- @overload
- def utf8(value: bytes) -> bytes: ...
- @overload
- def utf8(value: str) -> bytes: ...
- def utf8(value):
- # implementation goes here
- The overloads for a function can be retrieved at runtime using the
- get_overloads() function.
- """
- # classmethod and staticmethod
- f = getattr(func, "__func__", func)
- try:
- _overload_registry[f.__module__][f.__qualname__][
- f.__code__.co_firstlineno
- ] = func
- except AttributeError:
- # Not a normal function; ignore.
- pass
- return _overload_dummy
- def get_overloads(func):
- """Return all defined overloads for *func* as a sequence."""
- # classmethod and staticmethod
- f = getattr(func, "__func__", func)
- if f.__module__ not in _overload_registry:
- return []
- mod_dict = _overload_registry[f.__module__]
- if f.__qualname__ not in mod_dict:
- return []
- return list(mod_dict[f.__qualname__].values())
- def clear_overloads():
- """Clear all overloads in the registry."""
- _overload_registry.clear()
- # This is not a real generic class. Don't use outside annotations.
- Type = typing.Type
- # Various ABCs mimicking those in collections.abc.
- # A few are simply re-exported for completeness.
- Awaitable = typing.Awaitable
- Coroutine = typing.Coroutine
- AsyncIterable = typing.AsyncIterable
- AsyncIterator = typing.AsyncIterator
- Deque = typing.Deque
- DefaultDict = typing.DefaultDict
- OrderedDict = typing.OrderedDict
- Counter = typing.Counter
- ChainMap = typing.ChainMap
- Text = typing.Text
- TYPE_CHECKING = typing.TYPE_CHECKING
- if sys.version_info >= (3, 13, 0, "beta"):
- from typing import AsyncContextManager, AsyncGenerator, ContextManager, Generator
- else:
- def _is_dunder(attr):
- return attr.startswith('__') and attr.endswith('__')
- # Python <3.9 doesn't have typing._SpecialGenericAlias
- _special_generic_alias_base = getattr(
- typing, "_SpecialGenericAlias", typing._GenericAlias
- )
- class _SpecialGenericAlias(_special_generic_alias_base, _root=True):
- def __init__(self, origin, nparams, *, inst=True, name=None, defaults=()):
- if _special_generic_alias_base is typing._GenericAlias:
- # Python <3.9
- self.__origin__ = origin
- self._nparams = nparams
- super().__init__(origin, nparams, special=True, inst=inst, name=name)
- else:
- # Python >= 3.9
- super().__init__(origin, nparams, inst=inst, name=name)
- self._defaults = defaults
- def __setattr__(self, attr, val):
- allowed_attrs = {'_name', '_inst', '_nparams', '_defaults'}
- if _special_generic_alias_base is typing._GenericAlias:
- # Python <3.9
- allowed_attrs.add("__origin__")
- if _is_dunder(attr) or attr in allowed_attrs:
- object.__setattr__(self, attr, val)
- else:
- setattr(self.__origin__, attr, val)
- @typing._tp_cache
- def __getitem__(self, params):
- if not isinstance(params, tuple):
- params = (params,)
- msg = "Parameters to generic types must be types."
- params = tuple(typing._type_check(p, msg) for p in params)
- if (
- self._defaults
- and len(params) < self._nparams
- and len(params) + len(self._defaults) >= self._nparams
- ):
- params = (*params, *self._defaults[len(params) - self._nparams:])
- actual_len = len(params)
- if actual_len != self._nparams:
- if self._defaults:
- expected = f"at least {self._nparams - len(self._defaults)}"
- else:
- expected = str(self._nparams)
- if not self._nparams:
- raise TypeError(f"{self} is not a generic class")
- raise TypeError(
- f"Too {'many' if actual_len > self._nparams else 'few'}"
- f" arguments for {self};"
- f" actual {actual_len}, expected {expected}"
- )
- return self.copy_with(params)
- _NoneType = type(None)
- Generator = _SpecialGenericAlias(
- collections.abc.Generator, 3, defaults=(_NoneType, _NoneType)
- )
- AsyncGenerator = _SpecialGenericAlias(
- collections.abc.AsyncGenerator, 2, defaults=(_NoneType,)
- )
- ContextManager = _SpecialGenericAlias(
- contextlib.AbstractContextManager,
- 2,
- name="ContextManager",
- defaults=(typing.Optional[bool],)
- )
- AsyncContextManager = _SpecialGenericAlias(
- contextlib.AbstractAsyncContextManager,
- 2,
- name="AsyncContextManager",
- defaults=(typing.Optional[bool],)
- )
- _PROTO_ALLOWLIST = {
- 'collections.abc': [
- 'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable',
- 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', 'Buffer',
- ],
- 'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'],
- 'typing_extensions': ['Buffer'],
- }
- _EXCLUDED_ATTRS = frozenset(typing.EXCLUDED_ATTRIBUTES) | {
- "__match_args__", "__protocol_attrs__", "__non_callable_proto_members__",
- "__final__",
- }
- def _get_protocol_attrs(cls):
- attrs = set()
- for base in cls.__mro__[:-1]: # without object
- if base.__name__ in {'Protocol', 'Generic'}:
- continue
- annotations = getattr(base, '__annotations__', {})
- for attr in (*base.__dict__, *annotations):
- if (not attr.startswith('_abc_') and attr not in _EXCLUDED_ATTRS):
- attrs.add(attr)
- return attrs
- def _caller(depth=2):
- try:
- return sys._getframe(depth).f_globals.get('__name__', '__main__')
- except (AttributeError, ValueError): # For platforms without _getframe()
- return None
- # `__match_args__` attribute was removed from protocol members in 3.13,
- # we want to backport this change to older Python versions.
- if sys.version_info >= (3, 13):
- Protocol = typing.Protocol
- else:
- def _allow_reckless_class_checks(depth=3):
- """Allow instance and class checks for special stdlib modules.
- The abc and functools modules indiscriminately call isinstance() and
- issubclass() on the whole MRO of a user class, which may contain protocols.
- """
- return _caller(depth) in {'abc', 'functools', None}
- def _no_init(self, *args, **kwargs):
- if type(self)._is_protocol:
- raise TypeError('Protocols cannot be instantiated')
- def _type_check_issubclass_arg_1(arg):
- """Raise TypeError if `arg` is not an instance of `type`
- in `issubclass(arg, <protocol>)`.
- In most cases, this is verified by type.__subclasscheck__.
- Checking it again unnecessarily would slow down issubclass() checks,
- so, we don't perform this check unless we absolutely have to.
- For various error paths, however,
- we want to ensure that *this* error message is shown to the user
- where relevant, rather than a typing.py-specific error message.
- """
- if not isinstance(arg, type):
- # Same error message as for issubclass(1, int).
- raise TypeError('issubclass() arg 1 must be a class')
- # Inheriting from typing._ProtocolMeta isn't actually desirable,
- # but is necessary to allow typing.Protocol and typing_extensions.Protocol
- # to mix without getting TypeErrors about "metaclass conflict"
- class _ProtocolMeta(type(typing.Protocol)):
- # This metaclass is somewhat unfortunate,
- # but is necessary for several reasons...
- #
- # NOTE: DO NOT call super() in any methods in this class
- # That would call the methods on typing._ProtocolMeta on Python 3.8-3.11
- # and those are slow
- def __new__(mcls, name, bases, namespace, **kwargs):
- if name == "Protocol" and len(bases) < 2:
- pass
- elif {Protocol, typing.Protocol} & set(bases):
- for base in bases:
- if not (
- base in {object, typing.Generic, Protocol, typing.Protocol}
- or base.__name__ in _PROTO_ALLOWLIST.get(base.__module__, [])
- or is_protocol(base)
- ):
- raise TypeError(
- f"Protocols can only inherit from other protocols, "
- f"got {base!r}"
- )
- return abc.ABCMeta.__new__(mcls, name, bases, namespace, **kwargs)
- def __init__(cls, *args, **kwargs):
- abc.ABCMeta.__init__(cls, *args, **kwargs)
- if getattr(cls, "_is_protocol", False):
- cls.__protocol_attrs__ = _get_protocol_attrs(cls)
- def __subclasscheck__(cls, other):
- if cls is Protocol:
- return type.__subclasscheck__(cls, other)
- if (
- getattr(cls, '_is_protocol', False)
- and not _allow_reckless_class_checks()
- ):
- if not getattr(cls, '_is_runtime_protocol', False):
- _type_check_issubclass_arg_1(other)
- raise TypeError(
- "Instance and class checks can only be used with "
- "@runtime_checkable protocols"
- )
- if (
- # this attribute is set by @runtime_checkable:
- cls.__non_callable_proto_members__
- and cls.__dict__.get("__subclasshook__") is _proto_hook
- ):
- _type_check_issubclass_arg_1(other)
- non_method_attrs = sorted(cls.__non_callable_proto_members__)
- raise TypeError(
- "Protocols with non-method members don't support issubclass()."
- f" Non-method members: {str(non_method_attrs)[1:-1]}."
- )
- return abc.ABCMeta.__subclasscheck__(cls, other)
- def __instancecheck__(cls, instance):
- # We need this method for situations where attributes are
- # assigned in __init__.
- if cls is Protocol:
- return type.__instancecheck__(cls, instance)
- if not getattr(cls, "_is_protocol", False):
- # i.e., it's a concrete subclass of a protocol
- return abc.ABCMeta.__instancecheck__(cls, instance)
- if (
- not getattr(cls, '_is_runtime_protocol', False) and
- not _allow_reckless_class_checks()
- ):
- raise TypeError("Instance and class checks can only be used with"
- " @runtime_checkable protocols")
- if abc.ABCMeta.__instancecheck__(cls, instance):
- return True
- for attr in cls.__protocol_attrs__:
- try:
- val = inspect.getattr_static(instance, attr)
- except AttributeError:
- break
- # this attribute is set by @runtime_checkable:
- if val is None and attr not in cls.__non_callable_proto_members__:
- break
- else:
- return True
- return False
- def __eq__(cls, other):
- # Hack so that typing.Generic.__class_getitem__
- # treats typing_extensions.Protocol
- # as equivalent to typing.Protocol
- if abc.ABCMeta.__eq__(cls, other) is True:
- return True
- return cls is Protocol and other is typing.Protocol
- # This has to be defined, or the abc-module cache
- # complains about classes with this metaclass being unhashable,
- # if we define only __eq__!
- def __hash__(cls) -> int:
- return type.__hash__(cls)
- @classmethod
- def _proto_hook(cls, other):
- if not cls.__dict__.get('_is_protocol', False):
- return NotImplemented
- for attr in cls.__protocol_attrs__:
- for base in other.__mro__:
- # Check if the members appears in the class dictionary...
- if attr in base.__dict__:
- if base.__dict__[attr] is None:
- return NotImplemented
- break
- # ...or in annotations, if it is a sub-protocol.
- annotations = getattr(base, '__annotations__', {})
- if (
- isinstance(annotations, collections.abc.Mapping)
- and attr in annotations
- and is_protocol(other)
- ):
- break
- else:
- return NotImplemented
- return True
- class Protocol(typing.Generic, metaclass=_ProtocolMeta):
- __doc__ = typing.Protocol.__doc__
- __slots__ = ()
- _is_protocol = True
- _is_runtime_protocol = False
- def __init_subclass__(cls, *args, **kwargs):
- super().__init_subclass__(*args, **kwargs)
- # Determine if this is a protocol or a concrete subclass.
- if not cls.__dict__.get('_is_protocol', False):
- cls._is_protocol = any(b is Protocol for b in cls.__bases__)
- # Set (or override) the protocol subclass hook.
- if '__subclasshook__' not in cls.__dict__:
- cls.__subclasshook__ = _proto_hook
- # Prohibit instantiation for protocol classes
- if cls._is_protocol and cls.__init__ is Protocol.__init__:
- cls.__init__ = _no_init
- if sys.version_info >= (3, 13):
- runtime_checkable = typing.runtime_checkable
- else:
- def runtime_checkable(cls):
- """Mark a protocol class as a runtime protocol.
- Such protocol can be used with isinstance() and issubclass().
- Raise TypeError if applied to a non-protocol class.
- This allows a simple-minded structural check very similar to
- one trick ponies in collections.abc such as Iterable.
- For example::
- @runtime_checkable
- class Closable(Protocol):
- def close(self): ...
- assert isinstance(open('/some/file'), Closable)
- Warning: this will check only the presence of the required methods,
- not their type signatures!
- """
- if not issubclass(cls, typing.Generic) or not getattr(cls, '_is_protocol', False):
- raise TypeError(f'@runtime_checkable can be only applied to protocol classes,'
- f' got {cls!r}')
- cls._is_runtime_protocol = True
- # typing.Protocol classes on <=3.11 break if we execute this block,
- # because typing.Protocol classes on <=3.11 don't have a
- # `__protocol_attrs__` attribute, and this block relies on the
- # `__protocol_attrs__` attribute. Meanwhile, typing.Protocol classes on 3.12.2+
- # break if we *don't* execute this block, because *they* assume that all
- # protocol classes have a `__non_callable_proto_members__` attribute
- # (which this block sets)
- if isinstance(cls, _ProtocolMeta) or sys.version_info >= (3, 12, 2):
- # PEP 544 prohibits using issubclass()
- # with protocols that have non-method members.
- # See gh-113320 for why we compute this attribute here,
- # rather than in `_ProtocolMeta.__init__`
- cls.__non_callable_proto_members__ = set()
- for attr in cls.__protocol_attrs__:
- try:
- is_callable = callable(getattr(cls, attr, None))
- except Exception as e:
- raise TypeError(
- f"Failed to determine whether protocol member {attr!r} "
- "is a method member"
- ) from e
- else:
- if not is_callable:
- cls.__non_callable_proto_members__.add(attr)
- return cls
- # The "runtime" alias exists for backwards compatibility.
- runtime = runtime_checkable
- # Our version of runtime-checkable protocols is faster on Python 3.8-3.11
- if sys.version_info >= (3, 12):
- SupportsInt = typing.SupportsInt
- SupportsFloat = typing.SupportsFloat
- SupportsComplex = typing.SupportsComplex
- SupportsBytes = typing.SupportsBytes
- SupportsIndex = typing.SupportsIndex
- SupportsAbs = typing.SupportsAbs
- SupportsRound = typing.SupportsRound
- else:
- @runtime_checkable
- class SupportsInt(Protocol):
- """An ABC with one abstract method __int__."""
- __slots__ = ()
- @abc.abstractmethod
- def __int__(self) -> int:
- pass
- @runtime_checkable
- class SupportsFloat(Protocol):
- """An ABC with one abstract method __float__."""
- __slots__ = ()
- @abc.abstractmethod
- def __float__(self) -> float:
- pass
- @runtime_checkable
- class SupportsComplex(Protocol):
- """An ABC with one abstract method __complex__."""
- __slots__ = ()
- @abc.abstractmethod
- def __complex__(self) -> complex:
- pass
- @runtime_checkable
- class SupportsBytes(Protocol):
- """An ABC with one abstract method __bytes__."""
- __slots__ = ()
- @abc.abstractmethod
- def __bytes__(self) -> bytes:
- pass
- @runtime_checkable
- class SupportsIndex(Protocol):
- __slots__ = ()
- @abc.abstractmethod
- def __index__(self) -> int:
- pass
- @runtime_checkable
- class SupportsAbs(Protocol[T_co]):
- """
- An ABC with one abstract method __abs__ that is covariant in its return type.
- """
- __slots__ = ()
- @abc.abstractmethod
- def __abs__(self) -> T_co:
- pass
- @runtime_checkable
- class SupportsRound(Protocol[T_co]):
- """
- An ABC with one abstract method __round__ that is covariant in its return type.
- """
- __slots__ = ()
- @abc.abstractmethod
- def __round__(self, ndigits: int = 0) -> T_co:
- pass
- def _ensure_subclassable(mro_entries):
- def inner(func):
- if sys.implementation.name == "pypy" and sys.version_info < (3, 9):
- cls_dict = {
- "__call__": staticmethod(func),
- "__mro_entries__": staticmethod(mro_entries)
- }
- t = type(func.__name__, (), cls_dict)
- return functools.update_wrapper(t(), func)
- else:
- func.__mro_entries__ = mro_entries
- return func
- return inner
- _NEEDS_SINGLETONMETA = (
- not hasattr(typing, "NoDefault") or not hasattr(typing, "NoExtraItems")
- )
- if _NEEDS_SINGLETONMETA:
- class SingletonMeta(type):
- def __setattr__(cls, attr, value):
- # TypeError is consistent with the behavior of NoneType
- raise TypeError(
- f"cannot set {attr!r} attribute of immutable type {cls.__name__!r}"
- )
- if hasattr(typing, "NoDefault"):
- NoDefault = typing.NoDefault
- else:
- class NoDefaultType(metaclass=SingletonMeta):
- """The type of the NoDefault singleton."""
- __slots__ = ()
- def __new__(cls):
- return globals().get("NoDefault") or object.__new__(cls)
- def __repr__(self):
- return "typing_extensions.NoDefault"
- def __reduce__(self):
- return "NoDefault"
- NoDefault = NoDefaultType()
- del NoDefaultType
- if hasattr(typing, "NoExtraItems"):
- NoExtraItems = typing.NoExtraItems
- else:
- class NoExtraItemsType(metaclass=SingletonMeta):
- """The type of the NoExtraItems singleton."""
- __slots__ = ()
- def __new__(cls):
- return globals().get("NoExtraItems") or object.__new__(cls)
- def __repr__(self):
- return "typing_extensions.NoExtraItems"
- def __reduce__(self):
- return "NoExtraItems"
- NoExtraItems = NoExtraItemsType()
- del NoExtraItemsType
- if _NEEDS_SINGLETONMETA:
- del SingletonMeta
- # Update this to something like >=3.13.0b1 if and when
- # PEP 728 is implemented in CPython
- _PEP_728_IMPLEMENTED = False
- if _PEP_728_IMPLEMENTED:
- # The standard library TypedDict in Python 3.8 does not store runtime information
- # about which (if any) keys are optional. See https://bugs.python.org/issue38834
- # The standard library TypedDict in Python 3.9.0/1 does not honour the "total"
- # keyword with old-style TypedDict(). See https://bugs.python.org/issue42059
- # The standard library TypedDict below Python 3.11 does not store runtime
- # information about optional and required keys when using Required or NotRequired.
- # Generic TypedDicts are also impossible using typing.TypedDict on Python <3.11.
- # Aaaand on 3.12 we add __orig_bases__ to TypedDict
- # to enable better runtime introspection.
- # On 3.13 we deprecate some odd ways of creating TypedDicts.
- # Also on 3.13, PEP 705 adds the ReadOnly[] qualifier.
- # PEP 728 (still pending) makes more changes.
- TypedDict = typing.TypedDict
- _TypedDictMeta = typing._TypedDictMeta
- is_typeddict = typing.is_typeddict
- else:
- # 3.10.0 and later
- _TAKES_MODULE = "module" in inspect.signature(typing._type_check).parameters
- def _get_typeddict_qualifiers(annotation_type):
- while True:
- annotation_origin = get_origin(annotation_type)
- if annotation_origin is Annotated:
- annotation_args = get_args(annotation_type)
- if annotation_args:
- annotation_type = annotation_args[0]
- else:
- break
- elif annotation_origin is Required:
- yield Required
- annotation_type, = get_args(annotation_type)
- elif annotation_origin is NotRequired:
- yield NotRequired
- annotation_type, = get_args(annotation_type)
- elif annotation_origin is ReadOnly:
- yield ReadOnly
- annotation_type, = get_args(annotation_type)
- else:
- break
- class _TypedDictMeta(type):
- def __new__(cls, name, bases, ns, *, total=True, closed=None,
- extra_items=NoExtraItems):
- """Create new typed dict class object.
- This method is called when TypedDict is subclassed,
- or when TypedDict is instantiated. This way
- TypedDict supports all three syntax forms described in its docstring.
- Subclasses and instances of TypedDict return actual dictionaries.
- """
- for base in bases:
- if type(base) is not _TypedDictMeta and base is not typing.Generic:
- raise TypeError('cannot inherit from both a TypedDict type '
- 'and a non-TypedDict base class')
- if closed is not None and extra_items is not NoExtraItems:
- raise TypeError(f"Cannot combine closed={closed!r} and extra_items")
- if any(issubclass(b, typing.Generic) for b in bases):
- generic_base = (typing.Generic,)
- else:
- generic_base = ()
- # typing.py generally doesn't let you inherit from plain Generic, unless
- # the name of the class happens to be "Protocol"
- tp_dict = type.__new__(_TypedDictMeta, "Protocol", (*generic_base, dict), ns)
- tp_dict.__name__ = name
- if tp_dict.__qualname__ == "Protocol":
- tp_dict.__qualname__ = name
- if not hasattr(tp_dict, '__orig_bases__'):
- tp_dict.__orig_bases__ = bases
- annotations = {}
- if "__annotations__" in ns:
- own_annotations = ns["__annotations__"]
- elif "__annotate__" in ns:
- # TODO: Use inspect.VALUE here, and make the annotations lazily evaluated
- own_annotations = ns["__annotate__"](1)
- else:
- own_annotations = {}
- msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
- if _TAKES_MODULE:
- own_annotations = {
- n: typing._type_check(tp, msg, module=tp_dict.__module__)
- for n, tp in own_annotations.items()
- }
- else:
- own_annotations = {
- n: typing._type_check(tp, msg)
- for n, tp in own_annotations.items()
- }
- required_keys = set()
- optional_keys = set()
- readonly_keys = set()
- mutable_keys = set()
- extra_items_type = extra_items
- for base in bases:
- base_dict = base.__dict__
- annotations.update(base_dict.get('__annotations__', {}))
- required_keys.update(base_dict.get('__required_keys__', ()))
- optional_keys.update(base_dict.get('__optional_keys__', ()))
- readonly_keys.update(base_dict.get('__readonly_keys__', ()))
- mutable_keys.update(base_dict.get('__mutable_keys__', ()))
- # This was specified in an earlier version of PEP 728. Support
- # is retained for backwards compatibility, but only for Python
- # 3.13 and lower.
- if (closed and sys.version_info < (3, 14)
- and "__extra_items__" in own_annotations):
- annotation_type = own_annotations.pop("__extra_items__")
- qualifiers = set(_get_typeddict_qualifiers(annotation_type))
- if Required in qualifiers:
- raise TypeError(
- "Special key __extra_items__ does not support "
- "Required"
- )
- if NotRequired in qualifiers:
- raise TypeError(
- "Special key __extra_items__ does not support "
- "NotRequired"
- )
- extra_items_type = annotation_type
- annotations.update(own_annotations)
- for annotation_key, annotation_type in own_annotations.items():
- qualifiers = set(_get_typeddict_qualifiers(annotation_type))
- if Required in qualifiers:
- required_keys.add(annotation_key)
- elif NotRequired in qualifiers:
- optional_keys.add(annotation_key)
- elif total:
- required_keys.add(annotation_key)
- else:
- optional_keys.add(annotation_key)
- if ReadOnly in qualifiers:
- mutable_keys.discard(annotation_key)
- readonly_keys.add(annotation_key)
- else:
- mutable_keys.add(annotation_key)
- readonly_keys.discard(annotation_key)
- tp_dict.__annotations__ = annotations
- tp_dict.__required_keys__ = frozenset(required_keys)
- tp_dict.__optional_keys__ = frozenset(optional_keys)
- tp_dict.__readonly_keys__ = frozenset(readonly_keys)
- tp_dict.__mutable_keys__ = frozenset(mutable_keys)
- tp_dict.__total__ = total
- tp_dict.__closed__ = closed
- tp_dict.__extra_items__ = extra_items_type
- return tp_dict
- __call__ = dict # static method
- def __subclasscheck__(cls, other):
- # Typed dicts are only for static structural subtyping.
- raise TypeError('TypedDict does not support instance and class checks')
- __instancecheck__ = __subclasscheck__
- _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
- @_ensure_subclassable(lambda bases: (_TypedDict,))
- def TypedDict(
- typename,
- fields=_marker,
- /,
- *,
- total=True,
- closed=None,
- extra_items=NoExtraItems,
- **kwargs
- ):
- """A simple typed namespace. At runtime it is equivalent to a plain dict.
- TypedDict creates a dictionary type such that a type checker will expect all
- instances to have a certain set of keys, where each key is
- associated with a value of a consistent type. This expectation
- is not checked at runtime.
- Usage::
- class Point2D(TypedDict):
- x: int
- y: int
- label: str
- a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK
- b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check
- assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
- The type info can be accessed via the Point2D.__annotations__ dict, and
- the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.
- TypedDict supports an additional equivalent form::
- Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
- By default, all keys must be present in a TypedDict. It is possible
- to override this by specifying totality::
- class Point2D(TypedDict, total=False):
- x: int
- y: int
- This means that a Point2D TypedDict can have any of the keys omitted. A type
- checker is only expected to support a literal False or True as the value of
- the total argument. True is the default, and makes all items defined in the
- class body be required.
- The Required and NotRequired special forms can also be used to mark
- individual keys as being required or not required::
- class Point2D(TypedDict):
- x: int # the "x" key must always be present (Required is the default)
- y: NotRequired[int] # the "y" key can be omitted
- See PEP 655 for more details on Required and NotRequired.
- """
- if fields is _marker or fields is None:
- if fields is _marker:
- deprecated_thing = "Failing to pass a value for the 'fields' parameter"
- else:
- deprecated_thing = "Passing `None` as the 'fields' parameter"
- example = f"`{typename} = TypedDict({typename!r}, {{}})`"
- deprecation_msg = (
- f"{deprecated_thing} is deprecated and will be disallowed in "
- "Python 3.15. To create a TypedDict class with 0 fields "
- "using the functional syntax, pass an empty dictionary, e.g. "
- ) + example + "."
- warnings.warn(deprecation_msg, DeprecationWarning, stacklevel=2)
- # Support a field called "closed"
- if closed is not False and closed is not True and closed is not None:
- kwargs["closed"] = closed
- closed = None
- # Or "extra_items"
- if extra_items is not NoExtraItems:
- kwargs["extra_items"] = extra_items
- extra_items = NoExtraItems
- fields = kwargs
- elif kwargs:
- raise TypeError("TypedDict takes either a dict or keyword arguments,"
- " but not both")
- if kwargs:
- if sys.version_info >= (3, 13):
- raise TypeError("TypedDict takes no keyword arguments")
- warnings.warn(
- "The kwargs-based syntax for TypedDict definitions is deprecated "
- "in Python 3.11, will be removed in Python 3.13, and may not be "
- "understood by third-party type checkers.",
- DeprecationWarning,
- stacklevel=2,
- )
- ns = {'__annotations__': dict(fields)}
- module = _caller()
- if module is not None:
- # Setting correct module is necessary to make typed dict classes pickleable.
- ns['__module__'] = module
- td = _TypedDictMeta(typename, (), ns, total=total, closed=closed,
- extra_items=extra_items)
- td.__orig_bases__ = (TypedDict,)
- return td
- if hasattr(typing, "_TypedDictMeta"):
- _TYPEDDICT_TYPES = (typing._TypedDictMeta, _TypedDictMeta)
- else:
- _TYPEDDICT_TYPES = (_TypedDictMeta,)
- def is_typeddict(tp):
- """Check if an annotation is a TypedDict class
- For example::
- class Film(TypedDict):
- title: str
- year: int
- is_typeddict(Film) # => True
- is_typeddict(Union[list, str]) # => False
- """
- # On 3.8, this would otherwise return True
- if hasattr(typing, "TypedDict") and tp is typing.TypedDict:
- return False
- return isinstance(tp, _TYPEDDICT_TYPES)
- if hasattr(typing, "assert_type"):
- assert_type = typing.assert_type
- else:
- def assert_type(val, typ, /):
- """Assert (to the type checker) that the value is of the given type.
- When the type checker encounters a call to assert_type(), it
- emits an error if the value is not of the specified type::
- def greet(name: str) -> None:
- assert_type(name, str) # ok
- assert_type(name, int) # type checker error
- At runtime this returns the first argument unchanged and otherwise
- does nothing.
- """
- return val
- if hasattr(typing, "ReadOnly"): # 3.13+
- get_type_hints = typing.get_type_hints
- else: # <=3.13
- # replaces _strip_annotations()
- def _strip_extras(t):
- """Strips Annotated, Required and NotRequired from a given type."""
- if isinstance(t, _AnnotatedAlias):
- return _strip_extras(t.__origin__)
- if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired, ReadOnly):
- return _strip_extras(t.__args__[0])
- if isinstance(t, typing._GenericAlias):
- stripped_args = tuple(_strip_extras(a) for a in t.__args__)
- if stripped_args == t.__args__:
- return t
- return t.copy_with(stripped_args)
- if hasattr(_types, "GenericAlias") and isinstance(t, _types.GenericAlias):
- stripped_args = tuple(_strip_extras(a) for a in t.__args__)
- if stripped_args == t.__args__:
- return t
- return _types.GenericAlias(t.__origin__, stripped_args)
- if hasattr(_types, "UnionType") and isinstance(t, _types.UnionType):
- stripped_args = tuple(_strip_extras(a) for a in t.__args__)
- if stripped_args == t.__args__:
- return t
- return functools.reduce(operator.or_, stripped_args)
- return t
- def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
- """Return type hints for an object.
- This is often the same as obj.__annotations__, but it handles
- forward references encoded as string literals, adds Optional[t] if a
- default value equal to None is set and recursively replaces all
- 'Annotated[T, ...]', 'Required[T]' or 'NotRequired[T]' with 'T'
- (unless 'include_extras=True').
- The argument may be a module, class, method, or function. The annotations
- are returned as a dictionary. For classes, annotations include also
- inherited members.
- TypeError is raised if the argument is not of a type that can contain
- annotations, and an empty dictionary is returned if no annotations are
- present.
- BEWARE -- the behavior of globalns and localns is counterintuitive
- (unless you are familiar with how eval() and exec() work). The
- search order is locals first, then globals.
- - If no dict arguments are passed, an attempt is made to use the
- globals from obj (or the respective module's globals for classes),
- and these are also used as the locals. If the object does not appear
- to have globals, an empty dictionary is used.
- - If one dict argument is passed, it is used for both globals and
- locals.
- - If two dict arguments are passed, they specify globals and
- locals, respectively.
- """
- if hasattr(typing, "Annotated"): # 3.9+
- hint = typing.get_type_hints(
- obj, globalns=globalns, localns=localns, include_extras=True
- )
- else: # 3.8
- hint = typing.get_type_hints(obj, globalns=globalns, localns=localns)
- if sys.version_info < (3, 11):
- _clean_optional(obj, hint, globalns, localns)
- if sys.version_info < (3, 9):
- # In 3.8 eval_type does not flatten Optional[ForwardRef] correctly
- # This will recreate and and cache Unions.
- hint = {
- k: (t
- if get_origin(t) != Union
- else Union[t.__args__])
- for k, t in hint.items()
- }
- if include_extras:
- return hint
- return {k: _strip_extras(t) for k, t in hint.items()}
- _NoneType = type(None)
- def _could_be_inserted_optional(t):
- """detects Union[..., None] pattern"""
- # 3.8+ compatible checking before _UnionGenericAlias
- if get_origin(t) is not Union:
- return False
- # Assume if last argument is not None they are user defined
- if t.__args__[-1] is not _NoneType:
- return False
- return True
- # < 3.11
- def _clean_optional(obj, hints, globalns=None, localns=None):
- # reverts injected Union[..., None] cases from typing.get_type_hints
- # when a None default value is used.
- # see https://github.com/python/typing_extensions/issues/310
- if not hints or isinstance(obj, type):
- return
- defaults = typing._get_defaults(obj) # avoid accessing __annotations___
- if not defaults:
- return
- original_hints = obj.__annotations__
- for name, value in hints.items():
- # Not a Union[..., None] or replacement conditions not fullfilled
- if (not _could_be_inserted_optional(value)
- or name not in defaults
- or defaults[name] is not None
- ):
- continue
- original_value = original_hints[name]
- # value=NoneType should have caused a skip above but check for safety
- if original_value is None:
- original_value = _NoneType
- # Forward reference
- if isinstance(original_value, str):
- if globalns is None:
- if isinstance(obj, _types.ModuleType):
- globalns = obj.__dict__
- else:
- nsobj = obj
- # Find globalns for the unwrapped object.
- while hasattr(nsobj, '__wrapped__'):
- nsobj = nsobj.__wrapped__
- globalns = getattr(nsobj, '__globals__', {})
- if localns is None:
- localns = globalns
- elif localns is None:
- localns = globalns
- if sys.version_info < (3, 9):
- original_value = ForwardRef(original_value)
- else:
- original_value = ForwardRef(
- original_value,
- is_argument=not isinstance(obj, _types.ModuleType)
- )
- original_evaluated = typing._eval_type(original_value, globalns, localns)
- if sys.version_info < (3, 9) and get_origin(original_evaluated) is Union:
- # Union[str, None, "str"] is not reduced to Union[str, None]
- original_evaluated = Union[original_evaluated.__args__]
- # Compare if values differ. Note that even if equal
- # value might be cached by typing._tp_cache contrary to original_evaluated
- if original_evaluated != value or (
- # 3.10: ForwardRefs of UnionType might be turned into _UnionGenericAlias
- hasattr(_types, "UnionType")
- and isinstance(original_evaluated, _types.UnionType)
- and not isinstance(value, _types.UnionType)
- ):
- hints[name] = original_evaluated
- # Python 3.9+ has PEP 593 (Annotated)
- if hasattr(typing, 'Annotated'):
- Annotated = typing.Annotated
- # Not exported and not a public API, but needed for get_origin() and get_args()
- # to work.
- _AnnotatedAlias = typing._AnnotatedAlias
- # 3.8
- else:
- class _AnnotatedAlias(typing._GenericAlias, _root=True):
- """Runtime representation of an annotated type.
- At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't'
- with extra annotations. The alias behaves like a normal typing alias,
- instantiating is the same as instantiating the underlying type, binding
- it to types is also the same.
- """
- def __init__(self, origin, metadata):
- if isinstance(origin, _AnnotatedAlias):
- metadata = origin.__metadata__ + metadata
- origin = origin.__origin__
- super().__init__(origin, origin)
- self.__metadata__ = metadata
- def copy_with(self, params):
- assert len(params) == 1
- new_type = params[0]
- return _AnnotatedAlias(new_type, self.__metadata__)
- def __repr__(self):
- return (f"typing_extensions.Annotated[{typing._type_repr(self.__origin__)}, "
- f"{', '.join(repr(a) for a in self.__metadata__)}]")
- def __reduce__(self):
- return operator.getitem, (
- Annotated, (self.__origin__, *self.__metadata__)
- )
- def __eq__(self, other):
- if not isinstance(other, _AnnotatedAlias):
- return NotImplemented
- if self.__origin__ != other.__origin__:
- return False
- return self.__metadata__ == other.__metadata__
- def __hash__(self):
- return hash((self.__origin__, self.__metadata__))
- class Annotated:
- """Add context specific metadata to a type.
- Example: Annotated[int, runtime_check.Unsigned] indicates to the
- hypothetical runtime_check module that this type is an unsigned int.
- Every other consumer of this type can ignore this metadata and treat
- this type as int.
- The first argument to Annotated must be a valid type (and will be in
- the __origin__ field), the remaining arguments are kept as a tuple in
- the __extra__ field.
- Details:
- - It's an error to call `Annotated` with less than two arguments.
- - Nested Annotated are flattened::
- Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3]
- - Instantiating an annotated type is equivalent to instantiating the
- underlying type::
- Annotated[C, Ann1](5) == C(5)
- - Annotated can be used as a generic type alias::
- Optimized = Annotated[T, runtime.Optimize()]
- Optimized[int] == Annotated[int, runtime.Optimize()]
- OptimizedList = Annotated[List[T], runtime.Optimize()]
- OptimizedList[int] == Annotated[List[int], runtime.Optimize()]
- """
- __slots__ = ()
- def __new__(cls, *args, **kwargs):
- raise TypeError("Type Annotated cannot be instantiated.")
- @typing._tp_cache
- def __class_getitem__(cls, params):
- if not isinstance(params, tuple) or len(params) < 2:
- raise TypeError("Annotated[...] should be used "
- "with at least two arguments (a type and an "
- "annotation).")
- allowed_special_forms = (ClassVar, Final)
- if get_origin(params[0]) in allowed_special_forms:
- origin = params[0]
- else:
- msg = "Annotated[t, ...]: t must be a type."
- origin = typing._type_check(params[0], msg)
- metadata = tuple(params[1:])
- return _AnnotatedAlias(origin, metadata)
- def __init_subclass__(cls, *args, **kwargs):
- raise TypeError(
- f"Cannot subclass {cls.__module__}.Annotated"
- )
- # Python 3.8 has get_origin() and get_args() but those implementations aren't
- # Annotated-aware, so we can't use those. Python 3.9's versions don't support
- # ParamSpecArgs and ParamSpecKwargs, so only Python 3.10's versions will do.
- if sys.version_info[:2] >= (3, 10):
- get_origin = typing.get_origin
- get_args = typing.get_args
- # 3.8-3.9
- else:
- try:
- # 3.9+
- from typing import _BaseGenericAlias
- except ImportError:
- _BaseGenericAlias = typing._GenericAlias
- try:
- # 3.9+
- from typing import GenericAlias as _typing_GenericAlias
- except ImportError:
- _typing_GenericAlias = typing._GenericAlias
- def get_origin(tp):
- """Get the unsubscripted version of a type.
- This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar
- and Annotated. Return None for unsupported types. Examples::
- get_origin(Literal[42]) is Literal
- get_origin(int) is None
- get_origin(ClassVar[int]) is ClassVar
- get_origin(Generic) is Generic
- get_origin(Generic[T]) is Generic
- get_origin(Union[T, int]) is Union
- get_origin(List[Tuple[T, T]][int]) == list
- get_origin(P.args) is P
- """
- if isinstance(tp, _AnnotatedAlias):
- return Annotated
- if isinstance(tp, (typing._GenericAlias, _typing_GenericAlias, _BaseGenericAlias,
- ParamSpecArgs, ParamSpecKwargs)):
- return tp.__origin__
- if tp is typing.Generic:
- return typing.Generic
- return None
- def get_args(tp):
- """Get type arguments with all substitutions performed.
- For unions, basic simplifications used by Union constructor are performed.
- Examples::
- get_args(Dict[str, int]) == (str, int)
- get_args(int) == ()
- get_args(Union[int, Union[T, int], str][int]) == (int, str)
- get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
- get_args(Callable[[], T][int]) == ([], int)
- """
- if isinstance(tp, _AnnotatedAlias):
- return (tp.__origin__, *tp.__metadata__)
- if isinstance(tp, (typing._GenericAlias, _typing_GenericAlias)):
- if getattr(tp, "_special", False):
- return ()
- res = tp.__args__
- if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis:
- res = (list(res[:-1]), res[-1])
- return res
- return ()
- # 3.10+
- if hasattr(typing, 'TypeAlias'):
- TypeAlias = typing.TypeAlias
- # 3.9
- elif sys.version_info[:2] >= (3, 9):
- @_ExtensionsSpecialForm
- def TypeAlias(self, parameters):
- """Special marker indicating that an assignment should
- be recognized as a proper type alias definition by type
- checkers.
- For example::
- Predicate: TypeAlias = Callable[..., bool]
- It's invalid when used anywhere except as in the example above.
- """
- raise TypeError(f"{self} is not subscriptable")
- # 3.8
- else:
- TypeAlias = _ExtensionsSpecialForm(
- 'TypeAlias',
- doc="""Special marker indicating that an assignment should
- be recognized as a proper type alias definition by type
- checkers.
- For example::
- Predicate: TypeAlias = Callable[..., bool]
- It's invalid when used anywhere except as in the example
- above."""
- )
- def _set_default(type_param, default):
- type_param.has_default = lambda: default is not NoDefault
- type_param.__default__ = default
- def _set_module(typevarlike):
- # for pickling:
- def_mod = _caller(depth=3)
- if def_mod != 'typing_extensions':
- typevarlike.__module__ = def_mod
- class _DefaultMixin:
- """Mixin for TypeVarLike defaults."""
- __slots__ = ()
- __init__ = _set_default
- # Classes using this metaclass must provide a _backported_typevarlike ClassVar
- class _TypeVarLikeMeta(type):
- def __instancecheck__(cls, __instance: Any) -> bool:
- return isinstance(__instance, cls._backported_typevarlike)
- if _PEP_696_IMPLEMENTED:
- from typing import TypeVar
- else:
- # Add default and infer_variance parameters from PEP 696 and 695
- class TypeVar(metaclass=_TypeVarLikeMeta):
- """Type variable."""
- _backported_typevarlike = typing.TypeVar
- def __new__(cls, name, *constraints, bound=None,
- covariant=False, contravariant=False,
- default=NoDefault, infer_variance=False):
- if hasattr(typing, "TypeAliasType"):
- # PEP 695 implemented (3.12+), can pass infer_variance to typing.TypeVar
- typevar = typing.TypeVar(name, *constraints, bound=bound,
- covariant=covariant, contravariant=contravariant,
- infer_variance=infer_variance)
- else:
- typevar = typing.TypeVar(name, *constraints, bound=bound,
- covariant=covariant, contravariant=contravariant)
- if infer_variance and (covariant or contravariant):
- raise ValueError("Variance cannot be specified with infer_variance.")
- typevar.__infer_variance__ = infer_variance
- _set_default(typevar, default)
- _set_module(typevar)
- def _tvar_prepare_subst(alias, args):
- if (
- typevar.has_default()
- and alias.__parameters__.index(typevar) == len(args)
- ):
- args += (typevar.__default__,)
- return args
- typevar.__typing_prepare_subst__ = _tvar_prepare_subst
- return typevar
- def __init_subclass__(cls) -> None:
- raise TypeError(f"type '{__name__}.TypeVar' is not an acceptable base type")
- # Python 3.10+ has PEP 612
- if hasattr(typing, 'ParamSpecArgs'):
- ParamSpecArgs = typing.ParamSpecArgs
- ParamSpecKwargs = typing.ParamSpecKwargs
- # 3.8-3.9
- else:
- class _Immutable:
- """Mixin to indicate that object should not be copied."""
- __slots__ = ()
- def __copy__(self):
- return self
- def __deepcopy__(self, memo):
- return self
- class ParamSpecArgs(_Immutable):
- """The args for a ParamSpec object.
- Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.
- ParamSpecArgs objects have a reference back to their ParamSpec:
- P.args.__origin__ is P
- This type is meant for runtime introspection and has no special meaning to
- static type checkers.
- """
- def __init__(self, origin):
- self.__origin__ = origin
- def __repr__(self):
- return f"{self.__origin__.__name__}.args"
- def __eq__(self, other):
- if not isinstance(other, ParamSpecArgs):
- return NotImplemented
- return self.__origin__ == other.__origin__
- class ParamSpecKwargs(_Immutable):
- """The kwargs for a ParamSpec object.
- Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.
- ParamSpecKwargs objects have a reference back to their ParamSpec:
- P.kwargs.__origin__ is P
- This type is meant for runtime introspection and has no special meaning to
- static type checkers.
- """
- def __init__(self, origin):
- self.__origin__ = origin
- def __repr__(self):
- return f"{self.__origin__.__name__}.kwargs"
- def __eq__(self, other):
- if not isinstance(other, ParamSpecKwargs):
- return NotImplemented
- return self.__origin__ == other.__origin__
- if _PEP_696_IMPLEMENTED:
- from typing import ParamSpec
- # 3.10+
- elif hasattr(typing, 'ParamSpec'):
- # Add default parameter - PEP 696
- class ParamSpec(metaclass=_TypeVarLikeMeta):
- """Parameter specification."""
- _backported_typevarlike = typing.ParamSpec
- def __new__(cls, name, *, bound=None,
- covariant=False, contravariant=False,
- infer_variance=False, default=NoDefault):
- if hasattr(typing, "TypeAliasType"):
- # PEP 695 implemented, can pass infer_variance to typing.TypeVar
- paramspec = typing.ParamSpec(name, bound=bound,
- covariant=covariant,
- contravariant=contravariant,
- infer_variance=infer_variance)
- else:
- paramspec = typing.ParamSpec(name, bound=bound,
- covariant=covariant,
- contravariant=contravariant)
- paramspec.__infer_variance__ = infer_variance
- _set_default(paramspec, default)
- _set_module(paramspec)
- def _paramspec_prepare_subst(alias, args):
- params = alias.__parameters__
- i = params.index(paramspec)
- if i == len(args) and paramspec.has_default():
- args = [*args, paramspec.__default__]
- if i >= len(args):
- raise TypeError(f"Too few arguments for {alias}")
- # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612.
- if len(params) == 1 and not typing._is_param_expr(args[0]):
- assert i == 0
- args = (args,)
- # Convert lists to tuples to help other libraries cache the results.
- elif isinstance(args[i], list):
- args = (*args[:i], tuple(args[i]), *args[i + 1:])
- return args
- paramspec.__typing_prepare_subst__ = _paramspec_prepare_subst
- return paramspec
- def __init_subclass__(cls) -> None:
- raise TypeError(f"type '{__name__}.ParamSpec' is not an acceptable base type")
- # 3.8-3.9
- else:
- # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
- class ParamSpec(list, _DefaultMixin):
- """Parameter specification variable.
- Usage::
- P = ParamSpec('P')
- Parameter specification variables exist primarily for the benefit of static
- type checkers. They are used to forward the parameter types of one
- callable to another callable, a pattern commonly found in higher order
- functions and decorators. They are only valid when used in ``Concatenate``,
- or s the first argument to ``Callable``. In Python 3.10 and higher,
- they are also supported in user-defined Generics at runtime.
- See class Generic for more information on generic types. An
- example for annotating a decorator::
- T = TypeVar('T')
- P = ParamSpec('P')
- def add_logging(f: Callable[P, T]) -> Callable[P, T]:
- '''A type-safe decorator to add logging to a function.'''
- def inner(*args: P.args, **kwargs: P.kwargs) -> T:
- logging.info(f'{f.__name__} was called')
- return f(*args, **kwargs)
- return inner
- @add_logging
- def add_two(x: float, y: float) -> float:
- '''Add two numbers together.'''
- return x + y
- Parameter specification variables defined with covariant=True or
- contravariant=True can be used to declare covariant or contravariant
- generic types. These keyword arguments are valid, but their actual semantics
- are yet to be decided. See PEP 612 for details.
- Parameter specification variables can be introspected. e.g.:
- P.__name__ == 'T'
- P.__bound__ == None
- P.__covariant__ == False
- P.__contravariant__ == False
- Note that only parameter specification variables defined in global scope can
- be pickled.
- """
- # Trick Generic __parameters__.
- __class__ = typing.TypeVar
- @property
- def args(self):
- return ParamSpecArgs(self)
- @property
- def kwargs(self):
- return ParamSpecKwargs(self)
- def __init__(self, name, *, bound=None, covariant=False, contravariant=False,
- infer_variance=False, default=NoDefault):
- list.__init__(self, [self])
- self.__name__ = name
- self.__covariant__ = bool(covariant)
- self.__contravariant__ = bool(contravariant)
- self.__infer_variance__ = bool(infer_variance)
- if bound:
- self.__bound__ = typing._type_check(bound, 'Bound must be a type.')
- else:
- self.__bound__ = None
- _DefaultMixin.__init__(self, default)
- # for pickling:
- def_mod = _caller()
- if def_mod != 'typing_extensions':
- self.__module__ = def_mod
- def __repr__(self):
- if self.__infer_variance__:
- prefix = ''
- elif self.__covariant__:
- prefix = '+'
- elif self.__contravariant__:
- prefix = '-'
- else:
- prefix = '~'
- return prefix + self.__name__
- def __hash__(self):
- return object.__hash__(self)
- def __eq__(self, other):
- return self is other
- def __reduce__(self):
- return self.__name__
- # Hack to get typing._type_check to pass.
- def __call__(self, *args, **kwargs):
- pass
- # 3.8-3.9
- if not hasattr(typing, 'Concatenate'):
- # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
- # 3.9.0-1
- if not hasattr(typing, '_type_convert'):
- def _type_convert(arg, module=None, *, allow_special_forms=False):
- """For converting None to type(None), and strings to ForwardRef."""
- if arg is None:
- return type(None)
- if isinstance(arg, str):
- if sys.version_info <= (3, 9, 6):
- return ForwardRef(arg)
- if sys.version_info <= (3, 9, 7):
- return ForwardRef(arg, module=module)
- return ForwardRef(arg, module=module, is_class=allow_special_forms)
- return arg
- else:
- _type_convert = typing._type_convert
- class _ConcatenateGenericAlias(list):
- # Trick Generic into looking into this for __parameters__.
- __class__ = typing._GenericAlias
- # Flag in 3.8.
- _special = False
- def __init__(self, origin, args):
- super().__init__(args)
- self.__origin__ = origin
- self.__args__ = args
- def __repr__(self):
- _type_repr = typing._type_repr
- return (f'{_type_repr(self.__origin__)}'
- f'[{", ".join(_type_repr(arg) for arg in self.__args__)}]')
- def __hash__(self):
- return hash((self.__origin__, self.__args__))
- # Hack to get typing._type_check to pass in Generic.
- def __call__(self, *args, **kwargs):
- pass
- @property
- def __parameters__(self):
- return tuple(
- tp for tp in self.__args__ if isinstance(tp, (typing.TypeVar, ParamSpec))
- )
- # 3.8; needed for typing._subst_tvars
- # 3.9 used by __getitem__ below
- def copy_with(self, params):
- if isinstance(params[-1], _ConcatenateGenericAlias):
- params = (*params[:-1], *params[-1].__args__)
- elif isinstance(params[-1], (list, tuple)):
- return (*params[:-1], *params[-1])
- elif (not (params[-1] is ... or isinstance(params[-1], ParamSpec))):
- raise TypeError("The last parameter to Concatenate should be a "
- "ParamSpec variable or ellipsis.")
- return self.__class__(self.__origin__, params)
- # 3.9; accessed during GenericAlias.__getitem__ when substituting
- def __getitem__(self, args):
- if self.__origin__ in (Generic, Protocol):
- # Can't subscript Generic[...] or Protocol[...].
- raise TypeError(f"Cannot subscript already-subscripted {self}")
- if not self.__parameters__:
- raise TypeError(f"{self} is not a generic class")
- if not isinstance(args, tuple):
- args = (args,)
- args = _unpack_args(*(_type_convert(p) for p in args))
- params = self.__parameters__
- for param in params:
- prepare = getattr(param, "__typing_prepare_subst__", None)
- if prepare is not None:
- args = prepare(self, args)
- # 3.8 - 3.9 & typing.ParamSpec
- elif isinstance(param, ParamSpec):
- i = params.index(param)
- if (
- i == len(args)
- and getattr(param, '__default__', NoDefault) is not NoDefault
- ):
- args = [*args, param.__default__]
- if i >= len(args):
- raise TypeError(f"Too few arguments for {self}")
- # Special case for Z[[int, str, bool]] == Z[int, str, bool]
- if len(params) == 1 and not _is_param_expr(args[0]):
- assert i == 0
- args = (args,)
- elif (
- isinstance(args[i], list)
- # 3.8 - 3.9
- # This class inherits from list do not convert
- and not isinstance(args[i], _ConcatenateGenericAlias)
- ):
- args = (*args[:i], tuple(args[i]), *args[i + 1:])
- alen = len(args)
- plen = len(params)
- if alen != plen:
- raise TypeError(
- f"Too {'many' if alen > plen else 'few'} arguments for {self};"
- f" actual {alen}, expected {plen}"
- )
- subst = dict(zip(self.__parameters__, args))
- # determine new args
- new_args = []
- for arg in self.__args__:
- if isinstance(arg, type):
- new_args.append(arg)
- continue
- if isinstance(arg, TypeVar):
- arg = subst[arg]
- if (
- (isinstance(arg, typing._GenericAlias) and _is_unpack(arg))
- or (
- hasattr(_types, "GenericAlias")
- and isinstance(arg, _types.GenericAlias)
- and getattr(arg, "__unpacked__", False)
- )
- ):
- raise TypeError(f"{arg} is not valid as type argument")
- elif isinstance(arg,
- typing._GenericAlias
- if not hasattr(_types, "GenericAlias") else
- (typing._GenericAlias, _types.GenericAlias)
- ):
- subparams = arg.__parameters__
- if subparams:
- subargs = tuple(subst[x] for x in subparams)
- arg = arg[subargs]
- new_args.append(arg)
- return self.copy_with(tuple(new_args))
- # 3.10+
- else:
- _ConcatenateGenericAlias = typing._ConcatenateGenericAlias
- # 3.10
- if sys.version_info < (3, 11):
- class _ConcatenateGenericAlias(typing._ConcatenateGenericAlias, _root=True):
- # needed for checks in collections.abc.Callable to accept this class
- __module__ = "typing"
- def copy_with(self, params):
- if isinstance(params[-1], (list, tuple)):
- return (*params[:-1], *params[-1])
- if isinstance(params[-1], typing._ConcatenateGenericAlias):
- params = (*params[:-1], *params[-1].__args__)
- elif not (params[-1] is ... or isinstance(params[-1], ParamSpec)):
- raise TypeError("The last parameter to Concatenate should be a "
- "ParamSpec variable or ellipsis.")
- return super(typing._ConcatenateGenericAlias, self).copy_with(params)
- def __getitem__(self, args):
- value = super().__getitem__(args)
- if isinstance(value, tuple) and any(_is_unpack(t) for t in value):
- return tuple(_unpack_args(*(n for n in value)))
- return value
- # 3.8-3.9.2
- class _EllipsisDummy: ...
- # 3.8-3.10
- def _create_concatenate_alias(origin, parameters):
- if parameters[-1] is ... and sys.version_info < (3, 9, 2):
- # Hack: Arguments must be types, replace it with one.
- parameters = (*parameters[:-1], _EllipsisDummy)
- if sys.version_info >= (3, 10, 3):
- concatenate = _ConcatenateGenericAlias(origin, parameters,
- _typevar_types=(TypeVar, ParamSpec),
- _paramspec_tvars=True)
- else:
- concatenate = _ConcatenateGenericAlias(origin, parameters)
- if parameters[-1] is not _EllipsisDummy:
- return concatenate
- # Remove dummy again
- concatenate.__args__ = tuple(p if p is not _EllipsisDummy else ...
- for p in concatenate.__args__)
- if sys.version_info < (3, 10):
- # backport needs __args__ adjustment only
- return concatenate
- concatenate.__parameters__ = tuple(p for p in concatenate.__parameters__
- if p is not _EllipsisDummy)
- return concatenate
- # 3.8-3.10
- @typing._tp_cache
- def _concatenate_getitem(self, parameters):
- if parameters == ():
- raise TypeError("Cannot take a Concatenate of no types.")
- if not isinstance(parameters, tuple):
- parameters = (parameters,)
- if not (parameters[-1] is ... or isinstance(parameters[-1], ParamSpec)):
- raise TypeError("The last parameter to Concatenate should be a "
- "ParamSpec variable or ellipsis.")
- msg = "Concatenate[arg, ...]: each arg must be a type."
- parameters = (*(typing._type_check(p, msg) for p in parameters[:-1]),
- parameters[-1])
- return _create_concatenate_alias(self, parameters)
- # 3.11+; Concatenate does not accept ellipsis in 3.10
- if sys.version_info >= (3, 11):
- Concatenate = typing.Concatenate
- # 3.9-3.10
- elif sys.version_info[:2] >= (3, 9):
- @_ExtensionsSpecialForm
- def Concatenate(self, parameters):
- """Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a
- higher order function which adds, removes or transforms parameters of a
- callable.
- For example::
- Callable[Concatenate[int, P], int]
- See PEP 612 for detailed information.
- """
- return _concatenate_getitem(self, parameters)
- # 3.8
- else:
- class _ConcatenateForm(_ExtensionsSpecialForm, _root=True):
- def __getitem__(self, parameters):
- return _concatenate_getitem(self, parameters)
- Concatenate = _ConcatenateForm(
- 'Concatenate',
- doc="""Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a
- higher order function which adds, removes or transforms parameters of a
- callable.
- For example::
- Callable[Concatenate[int, P], int]
- See PEP 612 for detailed information.
- """)
- # 3.10+
- if hasattr(typing, 'TypeGuard'):
- TypeGuard = typing.TypeGuard
- # 3.9
- elif sys.version_info[:2] >= (3, 9):
- @_ExtensionsSpecialForm
- def TypeGuard(self, parameters):
- """Special typing form used to annotate the return type of a user-defined
- type guard function. ``TypeGuard`` only accepts a single type argument.
- At runtime, functions marked this way should return a boolean.
- ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static
- type checkers to determine a more precise type of an expression within a
- program's code flow. Usually type narrowing is done by analyzing
- conditional code flow and applying the narrowing to a block of code. The
- conditional expression here is sometimes referred to as a "type guard".
- Sometimes it would be convenient to use a user-defined boolean function
- as a type guard. Such a function should use ``TypeGuard[...]`` as its
- return type to alert static type checkers to this intention.
- Using ``-> TypeGuard`` tells the static type checker that for a given
- function:
- 1. The return value is a boolean.
- 2. If the return value is ``True``, the type of its argument
- is the type inside ``TypeGuard``.
- For example::
- def is_str(val: Union[str, float]):
- # "isinstance" type guard
- if isinstance(val, str):
- # Type of ``val`` is narrowed to ``str``
- ...
- else:
- # Else, type of ``val`` is narrowed to ``float``.
- ...
- Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower
- form of ``TypeA`` (it can even be a wider form) and this may lead to
- type-unsafe results. The main reason is to allow for things like
- narrowing ``List[object]`` to ``List[str]`` even though the latter is not
- a subtype of the former, since ``List`` is invariant. The responsibility of
- writing type-safe type guards is left to the user.
- ``TypeGuard`` also works with type variables. For more information, see
- PEP 647 (User-Defined Type Guards).
- """
- item = typing._type_check(parameters, f'{self} accepts only a single type.')
- return typing._GenericAlias(self, (item,))
- # 3.8
- else:
- class _TypeGuardForm(_ExtensionsSpecialForm, _root=True):
- def __getitem__(self, parameters):
- item = typing._type_check(parameters,
- f'{self._name} accepts only a single type')
- return typing._GenericAlias(self, (item,))
- TypeGuard = _TypeGuardForm(
- 'TypeGuard',
- doc="""Special typing form used to annotate the return type of a user-defined
- type guard function. ``TypeGuard`` only accepts a single type argument.
- At runtime, functions marked this way should return a boolean.
- ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static
- type checkers to determine a more precise type of an expression within a
- program's code flow. Usually type narrowing is done by analyzing
- conditional code flow and applying the narrowing to a block of code. The
- conditional expression here is sometimes referred to as a "type guard".
- Sometimes it would be convenient to use a user-defined boolean function
- as a type guard. Such a function should use ``TypeGuard[...]`` as its
- return type to alert static type checkers to this intention.
- Using ``-> TypeGuard`` tells the static type checker that for a given
- function:
- 1. The return value is a boolean.
- 2. If the return value is ``True``, the type of its argument
- is the type inside ``TypeGuard``.
- For example::
- def is_str(val: Union[str, float]):
- # "isinstance" type guard
- if isinstance(val, str):
- # Type of ``val`` is narrowed to ``str``
- ...
- else:
- # Else, type of ``val`` is narrowed to ``float``.
- ...
- Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower
- form of ``TypeA`` (it can even be a wider form) and this may lead to
- type-unsafe results. The main reason is to allow for things like
- narrowing ``List[object]`` to ``List[str]`` even though the latter is not
- a subtype of the former, since ``List`` is invariant. The responsibility of
- writing type-safe type guards is left to the user.
- ``TypeGuard`` also works with type variables. For more information, see
- PEP 647 (User-Defined Type Guards).
- """)
- # 3.13+
- if hasattr(typing, 'TypeIs'):
- TypeIs = typing.TypeIs
- # 3.9
- elif sys.version_info[:2] >= (3, 9):
- @_ExtensionsSpecialForm
- def TypeIs(self, parameters):
- """Special typing form used to annotate the return type of a user-defined
- type narrower function. ``TypeIs`` only accepts a single type argument.
- At runtime, functions marked this way should return a boolean.
- ``TypeIs`` aims to benefit *type narrowing* -- a technique used by static
- type checkers to determine a more precise type of an expression within a
- program's code flow. Usually type narrowing is done by analyzing
- conditional code flow and applying the narrowing to a block of code. The
- conditional expression here is sometimes referred to as a "type guard".
- Sometimes it would be convenient to use a user-defined boolean function
- as a type guard. Such a function should use ``TypeIs[...]`` as its
- return type to alert static type checkers to this intention.
- Using ``-> TypeIs`` tells the static type checker that for a given
- function:
- 1. The return value is a boolean.
- 2. If the return value is ``True``, the type of its argument
- is the intersection of the type inside ``TypeIs`` and the argument's
- previously known type.
- For example::
- def is_awaitable(val: object) -> TypeIs[Awaitable[Any]]:
- return hasattr(val, '__await__')
- def f(val: Union[int, Awaitable[int]]) -> int:
- if is_awaitable(val):
- assert_type(val, Awaitable[int])
- else:
- assert_type(val, int)
- ``TypeIs`` also works with type variables. For more information, see
- PEP 742 (Narrowing types with TypeIs).
- """
- item = typing._type_check(parameters, f'{self} accepts only a single type.')
- return typing._GenericAlias(self, (item,))
- # 3.8
- else:
- class _TypeIsForm(_ExtensionsSpecialForm, _root=True):
- def __getitem__(self, parameters):
- item = typing._type_check(parameters,
- f'{self._name} accepts only a single type')
- return typing._GenericAlias(self, (item,))
- TypeIs = _TypeIsForm(
- 'TypeIs',
- doc="""Special typing form used to annotate the return type of a user-defined
- type narrower function. ``TypeIs`` only accepts a single type argument.
- At runtime, functions marked this way should return a boolean.
- ``TypeIs`` aims to benefit *type narrowing* -- a technique used by static
- type checkers to determine a more precise type of an expression within a
- program's code flow. Usually type narrowing is done by analyzing
- conditional code flow and applying the narrowing to a block of code. The
- conditional expression here is sometimes referred to as a "type guard".
- Sometimes it would be convenient to use a user-defined boolean function
- as a type guard. Such a function should use ``TypeIs[...]`` as its
- return type to alert static type checkers to this intention.
- Using ``-> TypeIs`` tells the static type checker that for a given
- function:
- 1. The return value is a boolean.
- 2. If the return value is ``True``, the type of its argument
- is the intersection of the type inside ``TypeIs`` and the argument's
- previously known type.
- For example::
- def is_awaitable(val: object) -> TypeIs[Awaitable[Any]]:
- return hasattr(val, '__await__')
- def f(val: Union[int, Awaitable[int]]) -> int:
- if is_awaitable(val):
- assert_type(val, Awaitable[int])
- else:
- assert_type(val, int)
- ``TypeIs`` also works with type variables. For more information, see
- PEP 742 (Narrowing types with TypeIs).
- """)
- # 3.14+?
- if hasattr(typing, 'TypeForm'):
- TypeForm = typing.TypeForm
- # 3.9
- elif sys.version_info[:2] >= (3, 9):
- class _TypeFormForm(_ExtensionsSpecialForm, _root=True):
- # TypeForm(X) is equivalent to X but indicates to the type checker
- # that the object is a TypeForm.
- def __call__(self, obj, /):
- return obj
- @_TypeFormForm
- def TypeForm(self, parameters):
- """A special form representing the value that results from the evaluation
- of a type expression. This value encodes the information supplied in the
- type expression, and it represents the type described by that type expression.
- When used in a type expression, TypeForm describes a set of type form objects.
- It accepts a single type argument, which must be a valid type expression.
- ``TypeForm[T]`` describes the set of all type form objects that represent
- the type T or types that are assignable to T.
- Usage:
- def cast[T](typ: TypeForm[T], value: Any) -> T: ...
- reveal_type(cast(int, "x")) # int
- See PEP 747 for more information.
- """
- item = typing._type_check(parameters, f'{self} accepts only a single type.')
- return typing._GenericAlias(self, (item,))
- # 3.8
- else:
- class _TypeFormForm(_ExtensionsSpecialForm, _root=True):
- def __getitem__(self, parameters):
- item = typing._type_check(parameters,
- f'{self._name} accepts only a single type')
- return typing._GenericAlias(self, (item,))
- def __call__(self, obj, /):
- return obj
- TypeForm = _TypeFormForm(
- 'TypeForm',
- doc="""A special form representing the value that results from the evaluation
- of a type expression. This value encodes the information supplied in the
- type expression, and it represents the type described by that type expression.
- When used in a type expression, TypeForm describes a set of type form objects.
- It accepts a single type argument, which must be a valid type expression.
- ``TypeForm[T]`` describes the set of all type form objects that represent
- the type T or types that are assignable to T.
- Usage:
- def cast[T](typ: TypeForm[T], value: Any) -> T: ...
- reveal_type(cast(int, "x")) # int
- See PEP 747 for more information.
- """)
- # Vendored from cpython typing._SpecialFrom
- class _SpecialForm(typing._Final, _root=True):
- __slots__ = ('_name', '__doc__', '_getitem')
- def __init__(self, getitem):
- self._getitem = getitem
- self._name = getitem.__name__
- self.__doc__ = getitem.__doc__
- def __getattr__(self, item):
- if item in {'__name__', '__qualname__'}:
- return self._name
- raise AttributeError(item)
- def __mro_entries__(self, bases):
- raise TypeError(f"Cannot subclass {self!r}")
- def __repr__(self):
- return f'typing_extensions.{self._name}'
- def __reduce__(self):
- return self._name
- def __call__(self, *args, **kwds):
- raise TypeError(f"Cannot instantiate {self!r}")
- def __or__(self, other):
- return typing.Union[self, other]
- def __ror__(self, other):
- return typing.Union[other, self]
- def __instancecheck__(self, obj):
- raise TypeError(f"{self} cannot be used with isinstance()")
- def __subclasscheck__(self, cls):
- raise TypeError(f"{self} cannot be used with issubclass()")
- @typing._tp_cache
- def __getitem__(self, parameters):
- return self._getitem(self, parameters)
- if hasattr(typing, "LiteralString"): # 3.11+
- LiteralString = typing.LiteralString
- else:
- @_SpecialForm
- def LiteralString(self, params):
- """Represents an arbitrary literal string.
- Example::
- from typing_extensions import LiteralString
- def query(sql: LiteralString) -> ...:
- ...
- query("SELECT * FROM table") # ok
- query(f"SELECT * FROM {input()}") # not ok
- See PEP 675 for details.
- """
- raise TypeError(f"{self} is not subscriptable")
- if hasattr(typing, "Self"): # 3.11+
- Self = typing.Self
- else:
- @_SpecialForm
- def Self(self, params):
- """Used to spell the type of "self" in classes.
- Example::
- from typing import Self
- class ReturnsSelf:
- def parse(self, data: bytes) -> Self:
- ...
- return self
- """
- raise TypeError(f"{self} is not subscriptable")
- if hasattr(typing, "Never"): # 3.11+
- Never = typing.Never
- else:
- @_SpecialForm
- def Never(self, params):
- """The bottom type, a type that has no members.
- This can be used to define a function that should never be
- called, or a function that never returns::
- from typing_extensions import Never
- def never_call_me(arg: Never) -> None:
- pass
- def int_or_str(arg: int | str) -> None:
- never_call_me(arg) # type checker error
- match arg:
- case int():
- print("It's an int")
- case str():
- print("It's a str")
- case _:
- never_call_me(arg) # ok, arg is of type Never
- """
- raise TypeError(f"{self} is not subscriptable")
- if hasattr(typing, 'Required'): # 3.11+
- Required = typing.Required
- NotRequired = typing.NotRequired
- elif sys.version_info[:2] >= (3, 9): # 3.9-3.10
- @_ExtensionsSpecialForm
- def Required(self, parameters):
- """A special typing construct to mark a key of a total=False TypedDict
- as required. For example:
- class Movie(TypedDict, total=False):
- title: Required[str]
- year: int
- m = Movie(
- title='The Matrix', # typechecker error if key is omitted
- year=1999,
- )
- There is no runtime checking that a required key is actually provided
- when instantiating a related TypedDict.
- """
- item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
- return typing._GenericAlias(self, (item,))
- @_ExtensionsSpecialForm
- def NotRequired(self, parameters):
- """A special typing construct to mark a key of a TypedDict as
- potentially missing. For example:
- class Movie(TypedDict):
- title: str
- year: NotRequired[int]
- m = Movie(
- title='The Matrix', # typechecker error if key is omitted
- year=1999,
- )
- """
- item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
- return typing._GenericAlias(self, (item,))
- else: # 3.8
- class _RequiredForm(_ExtensionsSpecialForm, _root=True):
- def __getitem__(self, parameters):
- item = typing._type_check(parameters,
- f'{self._name} accepts only a single type.')
- return typing._GenericAlias(self, (item,))
- Required = _RequiredForm(
- 'Required',
- doc="""A special typing construct to mark a key of a total=False TypedDict
- as required. For example:
- class Movie(TypedDict, total=False):
- title: Required[str]
- year: int
- m = Movie(
- title='The Matrix', # typechecker error if key is omitted
- year=1999,
- )
- There is no runtime checking that a required key is actually provided
- when instantiating a related TypedDict.
- """)
- NotRequired = _RequiredForm(
- 'NotRequired',
- doc="""A special typing construct to mark a key of a TypedDict as
- potentially missing. For example:
- class Movie(TypedDict):
- title: str
- year: NotRequired[int]
- m = Movie(
- title='The Matrix', # typechecker error if key is omitted
- year=1999,
- )
- """)
- if hasattr(typing, 'ReadOnly'):
- ReadOnly = typing.ReadOnly
- elif sys.version_info[:2] >= (3, 9): # 3.9-3.12
- @_ExtensionsSpecialForm
- def ReadOnly(self, parameters):
- """A special typing construct to mark an item of a TypedDict as read-only.
- For example:
- class Movie(TypedDict):
- title: ReadOnly[str]
- year: int
- def mutate_movie(m: Movie) -> None:
- m["year"] = 1992 # allowed
- m["title"] = "The Matrix" # typechecker error
- There is no runtime checking for this property.
- """
- item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
- return typing._GenericAlias(self, (item,))
- else: # 3.8
- class _ReadOnlyForm(_ExtensionsSpecialForm, _root=True):
- def __getitem__(self, parameters):
- item = typing._type_check(parameters,
- f'{self._name} accepts only a single type.')
- return typing._GenericAlias(self, (item,))
- ReadOnly = _ReadOnlyForm(
- 'ReadOnly',
- doc="""A special typing construct to mark a key of a TypedDict as read-only.
- For example:
- class Movie(TypedDict):
- title: ReadOnly[str]
- year: int
- def mutate_movie(m: Movie) -> None:
- m["year"] = 1992 # allowed
- m["title"] = "The Matrix" # typechecker error
- There is no runtime checking for this propery.
- """)
- _UNPACK_DOC = """\
- Type unpack operator.
- The type unpack operator takes the child types from some container type,
- such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For
- example:
- # For some generic class `Foo`:
- Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str]
- Ts = TypeVarTuple('Ts')
- # Specifies that `Bar` is generic in an arbitrary number of types.
- # (Think of `Ts` as a tuple of an arbitrary number of individual
- # `TypeVar`s, which the `Unpack` is 'pulling out' directly into the
- # `Generic[]`.)
- class Bar(Generic[Unpack[Ts]]): ...
- Bar[int] # Valid
- Bar[int, str] # Also valid
- From Python 3.11, this can also be done using the `*` operator:
- Foo[*tuple[int, str]]
- class Bar(Generic[*Ts]): ...
- The operator can also be used along with a `TypedDict` to annotate
- `**kwargs` in a function signature. For instance:
- class Movie(TypedDict):
- name: str
- year: int
- # This function expects two keyword arguments - *name* of type `str` and
- # *year* of type `int`.
- def foo(**kwargs: Unpack[Movie]): ...
- Note that there is only some runtime checking of this operator. Not
- everything the runtime allows may be accepted by static type checkers.
- For more information, see PEP 646 and PEP 692.
- """
- if sys.version_info >= (3, 12): # PEP 692 changed the repr of Unpack[]
- Unpack = typing.Unpack
- def _is_unpack(obj):
- return get_origin(obj) is Unpack
- elif sys.version_info[:2] >= (3, 9): # 3.9+
- class _UnpackSpecialForm(_ExtensionsSpecialForm, _root=True):
- def __init__(self, getitem):
- super().__init__(getitem)
- self.__doc__ = _UNPACK_DOC
- class _UnpackAlias(typing._GenericAlias, _root=True):
- if sys.version_info < (3, 11):
- # needed for compatibility with Generic[Unpack[Ts]]
- __class__ = typing.TypeVar
- @property
- def __typing_unpacked_tuple_args__(self):
- assert self.__origin__ is Unpack
- assert len(self.__args__) == 1
- arg, = self.__args__
- if isinstance(arg, (typing._GenericAlias, _types.GenericAlias)):
- if arg.__origin__ is not tuple:
- raise TypeError("Unpack[...] must be used with a tuple type")
- return arg.__args__
- return None
- @property
- def __typing_is_unpacked_typevartuple__(self):
- assert self.__origin__ is Unpack
- assert len(self.__args__) == 1
- return isinstance(self.__args__[0], TypeVarTuple)
- def __getitem__(self, args):
- if self.__typing_is_unpacked_typevartuple__:
- return args
- return super().__getitem__(args)
- @_UnpackSpecialForm
- def Unpack(self, parameters):
- item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
- return _UnpackAlias(self, (item,))
- def _is_unpack(obj):
- return isinstance(obj, _UnpackAlias)
- else: # 3.8
- class _UnpackAlias(typing._GenericAlias, _root=True):
- __class__ = typing.TypeVar
- @property
- def __typing_unpacked_tuple_args__(self):
- assert self.__origin__ is Unpack
- assert len(self.__args__) == 1
- arg, = self.__args__
- if isinstance(arg, typing._GenericAlias):
- if arg.__origin__ is not tuple:
- raise TypeError("Unpack[...] must be used with a tuple type")
- return arg.__args__
- return None
- @property
- def __typing_is_unpacked_typevartuple__(self):
- assert self.__origin__ is Unpack
- assert len(self.__args__) == 1
- return isinstance(self.__args__[0], TypeVarTuple)
- def __getitem__(self, args):
- if self.__typing_is_unpacked_typevartuple__:
- return args
- return super().__getitem__(args)
- class _UnpackForm(_ExtensionsSpecialForm, _root=True):
- def __getitem__(self, parameters):
- item = typing._type_check(parameters,
- f'{self._name} accepts only a single type.')
- return _UnpackAlias(self, (item,))
- Unpack = _UnpackForm('Unpack', doc=_UNPACK_DOC)
- def _is_unpack(obj):
- return isinstance(obj, _UnpackAlias)
- def _unpack_args(*args):
- newargs = []
- for arg in args:
- subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
- if subargs is not None and (not (subargs and subargs[-1] is ...)):
- newargs.extend(subargs)
- else:
- newargs.append(arg)
- return newargs
- if _PEP_696_IMPLEMENTED:
- from typing import TypeVarTuple
- elif hasattr(typing, "TypeVarTuple"): # 3.11+
- # Add default parameter - PEP 696
- class TypeVarTuple(metaclass=_TypeVarLikeMeta):
- """Type variable tuple."""
- _backported_typevarlike = typing.TypeVarTuple
- def __new__(cls, name, *, default=NoDefault):
- tvt = typing.TypeVarTuple(name)
- _set_default(tvt, default)
- _set_module(tvt)
- def _typevartuple_prepare_subst(alias, args):
- params = alias.__parameters__
- typevartuple_index = params.index(tvt)
- for param in params[typevartuple_index + 1:]:
- if isinstance(param, TypeVarTuple):
- raise TypeError(
- f"More than one TypeVarTuple parameter in {alias}"
- )
- alen = len(args)
- plen = len(params)
- left = typevartuple_index
- right = plen - typevartuple_index - 1
- var_tuple_index = None
- fillarg = None
- for k, arg in enumerate(args):
- if not isinstance(arg, type):
- subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
- if subargs and len(subargs) == 2 and subargs[-1] is ...:
- if var_tuple_index is not None:
- raise TypeError(
- "More than one unpacked "
- "arbitrary-length tuple argument"
- )
- var_tuple_index = k
- fillarg = subargs[0]
- if var_tuple_index is not None:
- left = min(left, var_tuple_index)
- right = min(right, alen - var_tuple_index - 1)
- elif left + right > alen:
- raise TypeError(f"Too few arguments for {alias};"
- f" actual {alen}, expected at least {plen - 1}")
- if left == alen - right and tvt.has_default():
- replacement = _unpack_args(tvt.__default__)
- else:
- replacement = args[left: alen - right]
- return (
- *args[:left],
- *([fillarg] * (typevartuple_index - left)),
- replacement,
- *([fillarg] * (plen - right - left - typevartuple_index - 1)),
- *args[alen - right:],
- )
- tvt.__typing_prepare_subst__ = _typevartuple_prepare_subst
- return tvt
- def __init_subclass__(self, *args, **kwds):
- raise TypeError("Cannot subclass special typing classes")
- else: # <=3.10
- class TypeVarTuple(_DefaultMixin):
- """Type variable tuple.
- Usage::
- Ts = TypeVarTuple('Ts')
- In the same way that a normal type variable is a stand-in for a single
- type such as ``int``, a type variable *tuple* is a stand-in for a *tuple*
- type such as ``Tuple[int, str]``.
- Type variable tuples can be used in ``Generic`` declarations.
- Consider the following example::
- class Array(Generic[*Ts]): ...
- The ``Ts`` type variable tuple here behaves like ``tuple[T1, T2]``,
- where ``T1`` and ``T2`` are type variables. To use these type variables
- as type parameters of ``Array``, we must *unpack* the type variable tuple using
- the star operator: ``*Ts``. The signature of ``Array`` then behaves
- as if we had simply written ``class Array(Generic[T1, T2]): ...``.
- In contrast to ``Generic[T1, T2]``, however, ``Generic[*Shape]`` allows
- us to parameterise the class with an *arbitrary* number of type parameters.
- Type variable tuples can be used anywhere a normal ``TypeVar`` can.
- This includes class definitions, as shown above, as well as function
- signatures and variable annotations::
- class Array(Generic[*Ts]):
- def __init__(self, shape: Tuple[*Ts]):
- self._shape: Tuple[*Ts] = shape
- def get_shape(self) -> Tuple[*Ts]:
- return self._shape
- shape = (Height(480), Width(640))
- x: Array[Height, Width] = Array(shape)
- y = abs(x) # Inferred type is Array[Height, Width]
- z = x + x # ... is Array[Height, Width]
- x.get_shape() # ... is tuple[Height, Width]
- """
- # Trick Generic __parameters__.
- __class__ = typing.TypeVar
- def __iter__(self):
- yield self.__unpacked__
- def __init__(self, name, *, default=NoDefault):
- self.__name__ = name
- _DefaultMixin.__init__(self, default)
- # for pickling:
- def_mod = _caller()
- if def_mod != 'typing_extensions':
- self.__module__ = def_mod
- self.__unpacked__ = Unpack[self]
- def __repr__(self):
- return self.__name__
- def __hash__(self):
- return object.__hash__(self)
- def __eq__(self, other):
- return self is other
- def __reduce__(self):
- return self.__name__
- def __init_subclass__(self, *args, **kwds):
- if '_root' not in kwds:
- raise TypeError("Cannot subclass special typing classes")
- if hasattr(typing, "reveal_type"): # 3.11+
- reveal_type = typing.reveal_type
- else: # <=3.10
- def reveal_type(obj: T, /) -> T:
- """Reveal the inferred type of a variable.
- When a static type checker encounters a call to ``reveal_type()``,
- it will emit the inferred type of the argument::
- x: int = 1
- reveal_type(x)
- Running a static type checker (e.g., ``mypy``) on this example
- will produce output similar to 'Revealed type is "builtins.int"'.
- At runtime, the function prints the runtime type of the
- argument and returns it unchanged.
- """
- print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr)
- return obj
- if hasattr(typing, "_ASSERT_NEVER_REPR_MAX_LENGTH"): # 3.11+
- _ASSERT_NEVER_REPR_MAX_LENGTH = typing._ASSERT_NEVER_REPR_MAX_LENGTH
- else: # <=3.10
- _ASSERT_NEVER_REPR_MAX_LENGTH = 100
- if hasattr(typing, "assert_never"): # 3.11+
- assert_never = typing.assert_never
- else: # <=3.10
- def assert_never(arg: Never, /) -> Never:
- """Assert to the type checker that a line of code is unreachable.
- Example::
- def int_or_str(arg: int | str) -> None:
- match arg:
- case int():
- print("It's an int")
- case str():
- print("It's a str")
- case _:
- assert_never(arg)
- If a type checker finds that a call to assert_never() is
- reachable, it will emit an error.
- At runtime, this throws an exception when called.
- """
- value = repr(arg)
- if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH:
- value = value[:_ASSERT_NEVER_REPR_MAX_LENGTH] + '...'
- raise AssertionError(f"Expected code to be unreachable, but got: {value}")
- if sys.version_info >= (3, 12): # 3.12+
- # dataclass_transform exists in 3.11 but lacks the frozen_default parameter
- dataclass_transform = typing.dataclass_transform
- else: # <=3.11
- def dataclass_transform(
- *,
- eq_default: bool = True,
- order_default: bool = False,
- kw_only_default: bool = False,
- frozen_default: bool = False,
- field_specifiers: typing.Tuple[
- typing.Union[typing.Type[typing.Any], typing.Callable[..., typing.Any]],
- ...
- ] = (),
- **kwargs: typing.Any,
- ) -> typing.Callable[[T], T]:
- """Decorator that marks a function, class, or metaclass as providing
- dataclass-like behavior.
- Example:
- from typing_extensions import dataclass_transform
- _T = TypeVar("_T")
- # Used on a decorator function
- @dataclass_transform()
- def create_model(cls: type[_T]) -> type[_T]:
- ...
- return cls
- @create_model
- class CustomerModel:
- id: int
- name: str
- # Used on a base class
- @dataclass_transform()
- class ModelBase: ...
- class CustomerModel(ModelBase):
- id: int
- name: str
- # Used on a metaclass
- @dataclass_transform()
- class ModelMeta(type): ...
- class ModelBase(metaclass=ModelMeta): ...
- class CustomerModel(ModelBase):
- id: int
- name: str
- Each of the ``CustomerModel`` classes defined in this example will now
- behave similarly to a dataclass created with the ``@dataclasses.dataclass``
- decorator. For example, the type checker will synthesize an ``__init__``
- method.
- The arguments to this decorator can be used to customize this behavior:
- - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be
- True or False if it is omitted by the caller.
- - ``order_default`` indicates whether the ``order`` parameter is
- assumed to be True or False if it is omitted by the caller.
- - ``kw_only_default`` indicates whether the ``kw_only`` parameter is
- assumed to be True or False if it is omitted by the caller.
- - ``frozen_default`` indicates whether the ``frozen`` parameter is
- assumed to be True or False if it is omitted by the caller.
- - ``field_specifiers`` specifies a static list of supported classes
- or functions that describe fields, similar to ``dataclasses.field()``.
- At runtime, this decorator records its arguments in the
- ``__dataclass_transform__`` attribute on the decorated object.
- See PEP 681 for details.
- """
- def decorator(cls_or_fn):
- cls_or_fn.__dataclass_transform__ = {
- "eq_default": eq_default,
- "order_default": order_default,
- "kw_only_default": kw_only_default,
- "frozen_default": frozen_default,
- "field_specifiers": field_specifiers,
- "kwargs": kwargs,
- }
- return cls_or_fn
- return decorator
- if hasattr(typing, "override"): # 3.12+
- override = typing.override
- else: # <=3.11
- _F = typing.TypeVar("_F", bound=typing.Callable[..., typing.Any])
- def override(arg: _F, /) -> _F:
- """Indicate that a method is intended to override a method in a base class.
- Usage:
- class Base:
- def method(self) -> None:
- pass
- class Child(Base):
- @override
- def method(self) -> None:
- super().method()
- When this decorator is applied to a method, the type checker will
- validate that it overrides a method with the same name on a base class.
- This helps prevent bugs that may occur when a base class is changed
- without an equivalent change to a child class.
- There is no runtime checking of these properties. The decorator
- sets the ``__override__`` attribute to ``True`` on the decorated object
- to allow runtime introspection.
- See PEP 698 for details.
- """
- try:
- arg.__override__ = True
- except (AttributeError, TypeError):
- # Skip the attribute silently if it is not writable.
- # AttributeError happens if the object has __slots__ or a
- # read-only property, TypeError if it's a builtin class.
- pass
- return arg
- if hasattr(warnings, "deprecated"):
- deprecated = warnings.deprecated
- else:
- _T = typing.TypeVar("_T")
- class deprecated:
- """Indicate that a class, function or overload is deprecated.
- When this decorator is applied to an object, the type checker
- will generate a diagnostic on usage of the deprecated object.
- Usage:
- @deprecated("Use B instead")
- class A:
- pass
- @deprecated("Use g instead")
- def f():
- pass
- @overload
- @deprecated("int support is deprecated")
- def g(x: int) -> int: ...
- @overload
- def g(x: str) -> int: ...
- The warning specified by *category* will be emitted at runtime
- on use of deprecated objects. For functions, that happens on calls;
- for classes, on instantiation and on creation of subclasses.
- If the *category* is ``None``, no warning is emitted at runtime.
- The *stacklevel* determines where the
- warning is emitted. If it is ``1`` (the default), the warning
- is emitted at the direct caller of the deprecated object; if it
- is higher, it is emitted further up the stack.
- Static type checker behavior is not affected by the *category*
- and *stacklevel* arguments.
- The deprecation message passed to the decorator is saved in the
- ``__deprecated__`` attribute on the decorated object.
- If applied to an overload, the decorator
- must be after the ``@overload`` decorator for the attribute to
- exist on the overload as returned by ``get_overloads()``.
- See PEP 702 for details.
- """
- def __init__(
- self,
- message: str,
- /,
- *,
- category: typing.Optional[typing.Type[Warning]] = DeprecationWarning,
- stacklevel: int = 1,
- ) -> None:
- if not isinstance(message, str):
- raise TypeError(
- "Expected an object of type str for 'message', not "
- f"{type(message).__name__!r}"
- )
- self.message = message
- self.category = category
- self.stacklevel = stacklevel
- def __call__(self, arg: _T, /) -> _T:
- # Make sure the inner functions created below don't
- # retain a reference to self.
- msg = self.message
- category = self.category
- stacklevel = self.stacklevel
- if category is None:
- arg.__deprecated__ = msg
- return arg
- elif isinstance(arg, type):
- import functools
- from types import MethodType
- original_new = arg.__new__
- @functools.wraps(original_new)
- def __new__(cls, *args, **kwargs):
- if cls is arg:
- warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
- if original_new is not object.__new__:
- return original_new(cls, *args, **kwargs)
- # Mirrors a similar check in object.__new__.
- elif cls.__init__ is object.__init__ and (args or kwargs):
- raise TypeError(f"{cls.__name__}() takes no arguments")
- else:
- return original_new(cls)
- arg.__new__ = staticmethod(__new__)
- original_init_subclass = arg.__init_subclass__
- # We need slightly different behavior if __init_subclass__
- # is a bound method (likely if it was implemented in Python)
- if isinstance(original_init_subclass, MethodType):
- original_init_subclass = original_init_subclass.__func__
- @functools.wraps(original_init_subclass)
- def __init_subclass__(*args, **kwargs):
- warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
- return original_init_subclass(*args, **kwargs)
- arg.__init_subclass__ = classmethod(__init_subclass__)
- # Or otherwise, which likely means it's a builtin such as
- # object's implementation of __init_subclass__.
- else:
- @functools.wraps(original_init_subclass)
- def __init_subclass__(*args, **kwargs):
- warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
- return original_init_subclass(*args, **kwargs)
- arg.__init_subclass__ = __init_subclass__
- arg.__deprecated__ = __new__.__deprecated__ = msg
- __init_subclass__.__deprecated__ = msg
- return arg
- elif callable(arg):
- import asyncio.coroutines
- import functools
- import inspect
- @functools.wraps(arg)
- def wrapper(*args, **kwargs):
- warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
- return arg(*args, **kwargs)
- if asyncio.coroutines.iscoroutinefunction(arg):
- if sys.version_info >= (3, 12):
- wrapper = inspect.markcoroutinefunction(wrapper)
- else:
- wrapper._is_coroutine = asyncio.coroutines._is_coroutine
- arg.__deprecated__ = wrapper.__deprecated__ = msg
- return wrapper
- else:
- raise TypeError(
- "@deprecated decorator with non-None category must be applied to "
- f"a class or callable, not {arg!r}"
- )
- if sys.version_info < (3, 10):
- def _is_param_expr(arg):
- return arg is ... or isinstance(
- arg, (tuple, list, ParamSpec, _ConcatenateGenericAlias)
- )
- else:
- def _is_param_expr(arg):
- return arg is ... or isinstance(
- arg,
- (
- tuple,
- list,
- ParamSpec,
- _ConcatenateGenericAlias,
- typing._ConcatenateGenericAlias,
- ),
- )
- # We have to do some monkey patching to deal with the dual nature of
- # Unpack/TypeVarTuple:
- # - We want Unpack to be a kind of TypeVar so it gets accepted in
- # Generic[Unpack[Ts]]
- # - We want it to *not* be treated as a TypeVar for the purposes of
- # counting generic parameters, so that when we subscript a generic,
- # the runtime doesn't try to substitute the Unpack with the subscripted type.
- if not hasattr(typing, "TypeVarTuple"):
- def _check_generic(cls, parameters, elen=_marker):
- """Check correct count for parameters of a generic cls (internal helper).
- This gives a nice error message in case of count mismatch.
- """
- # If substituting a single ParamSpec with multiple arguments
- # we do not check the count
- if (inspect.isclass(cls) and issubclass(cls, typing.Generic)
- and len(cls.__parameters__) == 1
- and isinstance(cls.__parameters__[0], ParamSpec)
- and parameters
- and not _is_param_expr(parameters[0])
- ):
- # Generic modifies parameters variable, but here we cannot do this
- return
- if not elen:
- raise TypeError(f"{cls} is not a generic class")
- if elen is _marker:
- if not hasattr(cls, "__parameters__") or not cls.__parameters__:
- raise TypeError(f"{cls} is not a generic class")
- elen = len(cls.__parameters__)
- alen = len(parameters)
- if alen != elen:
- expect_val = elen
- if hasattr(cls, "__parameters__"):
- parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
- num_tv_tuples = sum(isinstance(p, TypeVarTuple) for p in parameters)
- if (num_tv_tuples > 0) and (alen >= elen - num_tv_tuples):
- return
- # deal with TypeVarLike defaults
- # required TypeVarLikes cannot appear after a defaulted one.
- if alen < elen:
- # since we validate TypeVarLike default in _collect_type_vars
- # or _collect_parameters we can safely check parameters[alen]
- if (
- getattr(parameters[alen], '__default__', NoDefault)
- is not NoDefault
- ):
- return
- num_default_tv = sum(getattr(p, '__default__', NoDefault)
- is not NoDefault for p in parameters)
- elen -= num_default_tv
- expect_val = f"at least {elen}"
- things = "arguments" if sys.version_info >= (3, 10) else "parameters"
- raise TypeError(f"Too {'many' if alen > elen else 'few'} {things}"
- f" for {cls}; actual {alen}, expected {expect_val}")
- else:
- # Python 3.11+
- def _check_generic(cls, parameters, elen):
- """Check correct count for parameters of a generic cls (internal helper).
- This gives a nice error message in case of count mismatch.
- """
- if not elen:
- raise TypeError(f"{cls} is not a generic class")
- alen = len(parameters)
- if alen != elen:
- expect_val = elen
- if hasattr(cls, "__parameters__"):
- parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
- # deal with TypeVarLike defaults
- # required TypeVarLikes cannot appear after a defaulted one.
- if alen < elen:
- # since we validate TypeVarLike default in _collect_type_vars
- # or _collect_parameters we can safely check parameters[alen]
- if (
- getattr(parameters[alen], '__default__', NoDefault)
- is not NoDefault
- ):
- return
- num_default_tv = sum(getattr(p, '__default__', NoDefault)
- is not NoDefault for p in parameters)
- elen -= num_default_tv
- expect_val = f"at least {elen}"
- raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments"
- f" for {cls}; actual {alen}, expected {expect_val}")
- if not _PEP_696_IMPLEMENTED:
- typing._check_generic = _check_generic
- def _has_generic_or_protocol_as_origin() -> bool:
- try:
- frame = sys._getframe(2)
- # - Catch AttributeError: not all Python implementations have sys._getframe()
- # - Catch ValueError: maybe we're called from an unexpected module
- # and the call stack isn't deep enough
- except (AttributeError, ValueError):
- return False # err on the side of leniency
- else:
- # If we somehow get invoked from outside typing.py,
- # also err on the side of leniency
- if frame.f_globals.get("__name__") != "typing":
- return False
- origin = frame.f_locals.get("origin")
- # Cannot use "in" because origin may be an object with a buggy __eq__ that
- # throws an error.
- return origin is typing.Generic or origin is Protocol or origin is typing.Protocol
- _TYPEVARTUPLE_TYPES = {TypeVarTuple, getattr(typing, "TypeVarTuple", None)}
- def _is_unpacked_typevartuple(x) -> bool:
- if get_origin(x) is not Unpack:
- return False
- args = get_args(x)
- return (
- bool(args)
- and len(args) == 1
- and type(args[0]) in _TYPEVARTUPLE_TYPES
- )
- # Python 3.11+ _collect_type_vars was renamed to _collect_parameters
- if hasattr(typing, '_collect_type_vars'):
- def _collect_type_vars(types, typevar_types=None):
- """Collect all type variable contained in types in order of
- first appearance (lexicographic order). For example::
- _collect_type_vars((T, List[S, T])) == (T, S)
- """
- if typevar_types is None:
- typevar_types = typing.TypeVar
- tvars = []
- # A required TypeVarLike cannot appear after a TypeVarLike with a default
- # if it was a direct call to `Generic[]` or `Protocol[]`
- enforce_default_ordering = _has_generic_or_protocol_as_origin()
- default_encountered = False
- # Also, a TypeVarLike with a default cannot appear after a TypeVarTuple
- type_var_tuple_encountered = False
- for t in types:
- if _is_unpacked_typevartuple(t):
- type_var_tuple_encountered = True
- elif (
- isinstance(t, typevar_types) and not isinstance(t, _UnpackAlias)
- and t not in tvars
- ):
- if enforce_default_ordering:
- has_default = getattr(t, '__default__', NoDefault) is not NoDefault
- if has_default:
- if type_var_tuple_encountered:
- raise TypeError('Type parameter with a default'
- ' follows TypeVarTuple')
- default_encountered = True
- elif default_encountered:
- raise TypeError(f'Type parameter {t!r} without a default'
- ' follows type parameter with a default')
- tvars.append(t)
- if _should_collect_from_parameters(t):
- tvars.extend([t for t in t.__parameters__ if t not in tvars])
- elif isinstance(t, tuple):
- # Collect nested type_vars
- # tuple wrapped by _prepare_paramspec_params(cls, params)
- for x in t:
- for collected in _collect_type_vars([x]):
- if collected not in tvars:
- tvars.append(collected)
- return tuple(tvars)
- typing._collect_type_vars = _collect_type_vars
- else:
- def _collect_parameters(args):
- """Collect all type variables and parameter specifications in args
- in order of first appearance (lexicographic order).
- For example::
- assert _collect_parameters((T, Callable[P, T])) == (T, P)
- """
- parameters = []
- # A required TypeVarLike cannot appear after a TypeVarLike with default
- # if it was a direct call to `Generic[]` or `Protocol[]`
- enforce_default_ordering = _has_generic_or_protocol_as_origin()
- default_encountered = False
- # Also, a TypeVarLike with a default cannot appear after a TypeVarTuple
- type_var_tuple_encountered = False
- for t in args:
- if isinstance(t, type):
- # We don't want __parameters__ descriptor of a bare Python class.
- pass
- elif isinstance(t, tuple):
- # `t` might be a tuple, when `ParamSpec` is substituted with
- # `[T, int]`, or `[int, *Ts]`, etc.
- for x in t:
- for collected in _collect_parameters([x]):
- if collected not in parameters:
- parameters.append(collected)
- elif hasattr(t, '__typing_subst__'):
- if t not in parameters:
- if enforce_default_ordering:
- has_default = (
- getattr(t, '__default__', NoDefault) is not NoDefault
- )
- if type_var_tuple_encountered and has_default:
- raise TypeError('Type parameter with a default'
- ' follows TypeVarTuple')
- if has_default:
- default_encountered = True
- elif default_encountered:
- raise TypeError(f'Type parameter {t!r} without a default'
- ' follows type parameter with a default')
- parameters.append(t)
- else:
- if _is_unpacked_typevartuple(t):
- type_var_tuple_encountered = True
- for x in getattr(t, '__parameters__', ()):
- if x not in parameters:
- parameters.append(x)
- return tuple(parameters)
- if not _PEP_696_IMPLEMENTED:
- typing._collect_parameters = _collect_parameters
- # Backport typing.NamedTuple as it exists in Python 3.13.
- # In 3.11, the ability to define generic `NamedTuple`s was supported.
- # This was explicitly disallowed in 3.9-3.10, and only half-worked in <=3.8.
- # On 3.12, we added __orig_bases__ to call-based NamedTuples
- # On 3.13, we deprecated kwargs-based NamedTuples
- if sys.version_info >= (3, 13):
- NamedTuple = typing.NamedTuple
- else:
- def _make_nmtuple(name, types, module, defaults=()):
- fields = [n for n, t in types]
- annotations = {n: typing._type_check(t, f"field {n} annotation must be a type")
- for n, t in types}
- nm_tpl = collections.namedtuple(name, fields,
- defaults=defaults, module=module)
- nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = annotations
- # The `_field_types` attribute was removed in 3.9;
- # in earlier versions, it is the same as the `__annotations__` attribute
- if sys.version_info < (3, 9):
- nm_tpl._field_types = annotations
- return nm_tpl
- _prohibited_namedtuple_fields = typing._prohibited
- _special_namedtuple_fields = frozenset({'__module__', '__name__', '__annotations__'})
- class _NamedTupleMeta(type):
- def __new__(cls, typename, bases, ns):
- assert _NamedTuple in bases
- for base in bases:
- if base is not _NamedTuple and base is not typing.Generic:
- raise TypeError(
- 'can only inherit from a NamedTuple type and Generic')
- bases = tuple(tuple if base is _NamedTuple else base for base in bases)
- if "__annotations__" in ns:
- types = ns["__annotations__"]
- elif "__annotate__" in ns:
- # TODO: Use inspect.VALUE here, and make the annotations lazily evaluated
- types = ns["__annotate__"](1)
- else:
- types = {}
- default_names = []
- for field_name in types:
- if field_name in ns:
- default_names.append(field_name)
- elif default_names:
- raise TypeError(f"Non-default namedtuple field {field_name} "
- f"cannot follow default field"
- f"{'s' if len(default_names) > 1 else ''} "
- f"{', '.join(default_names)}")
- nm_tpl = _make_nmtuple(
- typename, types.items(),
- defaults=[ns[n] for n in default_names],
- module=ns['__module__']
- )
- nm_tpl.__bases__ = bases
- if typing.Generic in bases:
- if hasattr(typing, '_generic_class_getitem'): # 3.12+
- nm_tpl.__class_getitem__ = classmethod(typing._generic_class_getitem)
- else:
- class_getitem = typing.Generic.__class_getitem__.__func__
- nm_tpl.__class_getitem__ = classmethod(class_getitem)
- # update from user namespace without overriding special namedtuple attributes
- for key, val in ns.items():
- if key in _prohibited_namedtuple_fields:
- raise AttributeError("Cannot overwrite NamedTuple attribute " + key)
- elif key not in _special_namedtuple_fields:
- if key not in nm_tpl._fields:
- setattr(nm_tpl, key, ns[key])
- try:
- set_name = type(val).__set_name__
- except AttributeError:
- pass
- else:
- try:
- set_name(val, nm_tpl, key)
- except BaseException as e:
- msg = (
- f"Error calling __set_name__ on {type(val).__name__!r} "
- f"instance {key!r} in {typename!r}"
- )
- # BaseException.add_note() existed on py311,
- # but the __set_name__ machinery didn't start
- # using add_note() until py312.
- # Making sure exceptions are raised in the same way
- # as in "normal" classes seems most important here.
- if sys.version_info >= (3, 12):
- e.add_note(msg)
- raise
- else:
- raise RuntimeError(msg) from e
- if typing.Generic in bases:
- nm_tpl.__init_subclass__()
- return nm_tpl
- _NamedTuple = type.__new__(_NamedTupleMeta, 'NamedTuple', (), {})
- def _namedtuple_mro_entries(bases):
- assert NamedTuple in bases
- return (_NamedTuple,)
- @_ensure_subclassable(_namedtuple_mro_entries)
- def NamedTuple(typename, fields=_marker, /, **kwargs):
- """Typed version of namedtuple.
- Usage::
- class Employee(NamedTuple):
- name: str
- id: int
- This is equivalent to::
- Employee = collections.namedtuple('Employee', ['name', 'id'])
- The resulting class has an extra __annotations__ attribute, giving a
- dict that maps field names to types. (The field names are also in
- the _fields attribute, which is part of the namedtuple API.)
- An alternative equivalent functional syntax is also accepted::
- Employee = NamedTuple('Employee', [('name', str), ('id', int)])
- """
- if fields is _marker:
- if kwargs:
- deprecated_thing = "Creating NamedTuple classes using keyword arguments"
- deprecation_msg = (
- "{name} is deprecated and will be disallowed in Python {remove}. "
- "Use the class-based or functional syntax instead."
- )
- else:
- deprecated_thing = "Failing to pass a value for the 'fields' parameter"
- example = f"`{typename} = NamedTuple({typename!r}, [])`"
- deprecation_msg = (
- "{name} is deprecated and will be disallowed in Python {remove}. "
- "To create a NamedTuple class with 0 fields "
- "using the functional syntax, "
- "pass an empty list, e.g. "
- ) + example + "."
- elif fields is None:
- if kwargs:
- raise TypeError(
- "Cannot pass `None` as the 'fields' parameter "
- "and also specify fields using keyword arguments"
- )
- else:
- deprecated_thing = "Passing `None` as the 'fields' parameter"
- example = f"`{typename} = NamedTuple({typename!r}, [])`"
- deprecation_msg = (
- "{name} is deprecated and will be disallowed in Python {remove}. "
- "To create a NamedTuple class with 0 fields "
- "using the functional syntax, "
- "pass an empty list, e.g. "
- ) + example + "."
- elif kwargs:
- raise TypeError("Either list of fields or keywords"
- " can be provided to NamedTuple, not both")
- if fields is _marker or fields is None:
- warnings.warn(
- deprecation_msg.format(name=deprecated_thing, remove="3.15"),
- DeprecationWarning,
- stacklevel=2,
- )
- fields = kwargs.items()
- nt = _make_nmtuple(typename, fields, module=_caller())
- nt.__orig_bases__ = (NamedTuple,)
- return nt
- if hasattr(collections.abc, "Buffer"):
- Buffer = collections.abc.Buffer
- else:
- class Buffer(abc.ABC): # noqa: B024
- """Base class for classes that implement the buffer protocol.
- The buffer protocol allows Python objects to expose a low-level
- memory buffer interface. Before Python 3.12, it is not possible
- to implement the buffer protocol in pure Python code, or even
- to check whether a class implements the buffer protocol. In
- Python 3.12 and higher, the ``__buffer__`` method allows access
- to the buffer protocol from Python code, and the
- ``collections.abc.Buffer`` ABC allows checking whether a class
- implements the buffer protocol.
- To indicate support for the buffer protocol in earlier versions,
- inherit from this ABC, either in a stub file or at runtime,
- or use ABC registration. This ABC provides no methods, because
- there is no Python-accessible methods shared by pre-3.12 buffer
- classes. It is useful primarily for static checks.
- """
- # As a courtesy, register the most common stdlib buffer classes.
- Buffer.register(memoryview)
- Buffer.register(bytearray)
- Buffer.register(bytes)
- # Backport of types.get_original_bases, available on 3.12+ in CPython
- if hasattr(_types, "get_original_bases"):
- get_original_bases = _types.get_original_bases
- else:
- def get_original_bases(cls, /):
- """Return the class's "original" bases prior to modification by `__mro_entries__`.
- Examples::
- from typing import TypeVar, Generic
- from typing_extensions import NamedTuple, TypedDict
- T = TypeVar("T")
- class Foo(Generic[T]): ...
- class Bar(Foo[int], float): ...
- class Baz(list[str]): ...
- Eggs = NamedTuple("Eggs", [("a", int), ("b", str)])
- Spam = TypedDict("Spam", {"a": int, "b": str})
- assert get_original_bases(Bar) == (Foo[int], float)
- assert get_original_bases(Baz) == (list[str],)
- assert get_original_bases(Eggs) == (NamedTuple,)
- assert get_original_bases(Spam) == (TypedDict,)
- assert get_original_bases(int) == (object,)
- """
- try:
- return cls.__dict__.get("__orig_bases__", cls.__bases__)
- except AttributeError:
- raise TypeError(
- f'Expected an instance of type, not {type(cls).__name__!r}'
- ) from None
- # NewType is a class on Python 3.10+, making it pickleable
- # The error message for subclassing instances of NewType was improved on 3.11+
- if sys.version_info >= (3, 11):
- NewType = typing.NewType
- else:
- class NewType:
- """NewType creates simple unique types with almost zero
- runtime overhead. NewType(name, tp) is considered a subtype of tp
- by static type checkers. At runtime, NewType(name, tp) returns
- a dummy callable that simply returns its argument. Usage::
- UserId = NewType('UserId', int)
- def name_by_id(user_id: UserId) -> str:
- ...
- UserId('user') # Fails type check
- name_by_id(42) # Fails type check
- name_by_id(UserId(42)) # OK
- num = UserId(5) + 1 # type: int
- """
- def __call__(self, obj, /):
- return obj
- def __init__(self, name, tp):
- self.__qualname__ = name
- if '.' in name:
- name = name.rpartition('.')[-1]
- self.__name__ = name
- self.__supertype__ = tp
- def_mod = _caller()
- if def_mod != 'typing_extensions':
- self.__module__ = def_mod
- def __mro_entries__(self, bases):
- # We defined __mro_entries__ to get a better error message
- # if a user attempts to subclass a NewType instance. bpo-46170
- supercls_name = self.__name__
- class Dummy:
- def __init_subclass__(cls):
- subcls_name = cls.__name__
- raise TypeError(
- f"Cannot subclass an instance of NewType. "
- f"Perhaps you were looking for: "
- f"`{subcls_name} = NewType({subcls_name!r}, {supercls_name})`"
- )
- return (Dummy,)
- def __repr__(self):
- return f'{self.__module__}.{self.__qualname__}'
- def __reduce__(self):
- return self.__qualname__
- if sys.version_info >= (3, 10):
- # PEP 604 methods
- # It doesn't make sense to have these methods on Python <3.10
- def __or__(self, other):
- return typing.Union[self, other]
- def __ror__(self, other):
- return typing.Union[other, self]
- if sys.version_info >= (3, 14):
- TypeAliasType = typing.TypeAliasType
- # 3.8-3.13
- else:
- def _is_unionable(obj):
- """Corresponds to is_unionable() in unionobject.c in CPython."""
- return obj is None or isinstance(obj, (
- type,
- _types.GenericAlias,
- _types.UnionType,
- TypeAliasType,
- ))
- if sys.version_info < (3, 10):
- # Copied and pasted from https://github.com/python/cpython/blob/986a4e1b6fcae7fe7a1d0a26aea446107dd58dd2/Objects/genericaliasobject.c#L568-L582,
- # so that we emulate the behaviour of `types.GenericAlias`
- # on the latest versions of CPython
- _ATTRIBUTE_DELEGATION_EXCLUSIONS = frozenset({
- "__class__",
- "__bases__",
- "__origin__",
- "__args__",
- "__unpacked__",
- "__parameters__",
- "__typing_unpacked_tuple_args__",
- "__mro_entries__",
- "__reduce_ex__",
- "__reduce__",
- "__copy__",
- "__deepcopy__",
- })
- class _TypeAliasGenericAlias(typing._GenericAlias, _root=True):
- def __getattr__(self, attr):
- if attr in _ATTRIBUTE_DELEGATION_EXCLUSIONS:
- return object.__getattr__(self, attr)
- return getattr(self.__origin__, attr)
- if sys.version_info < (3, 9):
- def __getitem__(self, item):
- result = super().__getitem__(item)
- result.__class__ = type(self)
- return result
- class TypeAliasType:
- """Create named, parameterized type aliases.
- This provides a backport of the new `type` statement in Python 3.12:
- type ListOrSet[T] = list[T] | set[T]
- is equivalent to:
- T = TypeVar("T")
- ListOrSet = TypeAliasType("ListOrSet", list[T] | set[T], type_params=(T,))
- The name ListOrSet can then be used as an alias for the type it refers to.
- The type_params argument should contain all the type parameters used
- in the value of the type alias. If the alias is not generic, this
- argument is omitted.
- Static type checkers should only support type aliases declared using
- TypeAliasType that follow these rules:
- - The first argument (the name) must be a string literal.
- - The TypeAliasType instance must be immediately assigned to a variable
- of the same name. (For example, 'X = TypeAliasType("Y", int)' is invalid,
- as is 'X, Y = TypeAliasType("X", int), TypeAliasType("Y", int)').
- """
- def __init__(self, name: str, value, *, type_params=()):
- if not isinstance(name, str):
- raise TypeError("TypeAliasType name must be a string")
- if not isinstance(type_params, tuple):
- raise TypeError("type_params must be a tuple")
- self.__value__ = value
- self.__type_params__ = type_params
- default_value_encountered = False
- parameters = []
- for type_param in type_params:
- if (
- not isinstance(type_param, (TypeVar, TypeVarTuple, ParamSpec))
- # 3.8-3.11
- # Unpack Backport passes isinstance(type_param, TypeVar)
- or _is_unpack(type_param)
- ):
- raise TypeError(f"Expected a type param, got {type_param!r}")
- has_default = (
- getattr(type_param, '__default__', NoDefault) is not NoDefault
- )
- if default_value_encountered and not has_default:
- raise TypeError(f"non-default type parameter '{type_param!r}'"
- " follows default type parameter")
- if has_default:
- default_value_encountered = True
- if isinstance(type_param, TypeVarTuple):
- parameters.extend(type_param)
- else:
- parameters.append(type_param)
- self.__parameters__ = tuple(parameters)
- def_mod = _caller()
- if def_mod != 'typing_extensions':
- self.__module__ = def_mod
- # Setting this attribute closes the TypeAliasType from further modification
- self.__name__ = name
- def __setattr__(self, name: str, value: object, /) -> None:
- if hasattr(self, "__name__"):
- self._raise_attribute_error(name)
- super().__setattr__(name, value)
- def __delattr__(self, name: str, /) -> Never:
- self._raise_attribute_error(name)
- def _raise_attribute_error(self, name: str) -> Never:
- # Match the Python 3.12 error messages exactly
- if name == "__name__":
- raise AttributeError("readonly attribute")
- elif name in {"__value__", "__type_params__", "__parameters__", "__module__"}:
- raise AttributeError(
- f"attribute '{name}' of 'typing.TypeAliasType' objects "
- "is not writable"
- )
- else:
- raise AttributeError(
- f"'typing.TypeAliasType' object has no attribute '{name}'"
- )
- def __repr__(self) -> str:
- return self.__name__
- if sys.version_info < (3, 11):
- def _check_single_param(self, param, recursion=0):
- # Allow [], [int], [int, str], [int, ...], [int, T]
- if param is ...:
- return ...
- if param is None:
- return None
- # Note in <= 3.9 _ConcatenateGenericAlias inherits from list
- if isinstance(param, list) and recursion == 0:
- return [self._check_single_param(arg, recursion+1)
- for arg in param]
- return typing._type_check(
- param, f'Subscripting {self.__name__} requires a type.'
- )
- def _check_parameters(self, parameters):
- if sys.version_info < (3, 11):
- return tuple(
- self._check_single_param(item)
- for item in parameters
- )
- return tuple(typing._type_check(
- item, f'Subscripting {self.__name__} requires a type.'
- )
- for item in parameters
- )
- def __getitem__(self, parameters):
- if not self.__type_params__:
- raise TypeError("Only generic type aliases are subscriptable")
- if not isinstance(parameters, tuple):
- parameters = (parameters,)
- # Using 3.9 here will create problems with Concatenate
- if sys.version_info >= (3, 10):
- return _types.GenericAlias(self, parameters)
- type_vars = _collect_type_vars(parameters)
- parameters = self._check_parameters(parameters)
- alias = _TypeAliasGenericAlias(self, parameters)
- # alias.__parameters__ is not complete if Concatenate is present
- # as it is converted to a list from which no parameters are extracted.
- if alias.__parameters__ != type_vars:
- alias.__parameters__ = type_vars
- return alias
- def __reduce__(self):
- return self.__name__
- def __init_subclass__(cls, *args, **kwargs):
- raise TypeError(
- "type 'typing_extensions.TypeAliasType' is not an acceptable base type"
- )
- # The presence of this method convinces typing._type_check
- # that TypeAliasTypes are types.
- def __call__(self):
- raise TypeError("Type alias is not callable")
- if sys.version_info >= (3, 10):
- def __or__(self, right):
- # For forward compatibility with 3.12, reject Unions
- # that are not accepted by the built-in Union.
- if not _is_unionable(right):
- return NotImplemented
- return typing.Union[self, right]
- def __ror__(self, left):
- if not _is_unionable(left):
- return NotImplemented
- return typing.Union[left, self]
- if hasattr(typing, "is_protocol"):
- is_protocol = typing.is_protocol
- get_protocol_members = typing.get_protocol_members
- else:
- def is_protocol(tp: type, /) -> bool:
- """Return True if the given type is a Protocol.
- Example::
- >>> from typing_extensions import Protocol, is_protocol
- >>> class P(Protocol):
- ... def a(self) -> str: ...
- ... b: int
- >>> is_protocol(P)
- True
- >>> is_protocol(int)
- False
- """
- return (
- isinstance(tp, type)
- and getattr(tp, '_is_protocol', False)
- and tp is not Protocol
- and tp is not typing.Protocol
- )
- def get_protocol_members(tp: type, /) -> typing.FrozenSet[str]:
- """Return the set of members defined in a Protocol.
- Example::
- >>> from typing_extensions import Protocol, get_protocol_members
- >>> class P(Protocol):
- ... def a(self) -> str: ...
- ... b: int
- >>> get_protocol_members(P)
- frozenset({'a', 'b'})
- Raise a TypeError for arguments that are not Protocols.
- """
- if not is_protocol(tp):
- raise TypeError(f'{tp!r} is not a Protocol')
- if hasattr(tp, '__protocol_attrs__'):
- return frozenset(tp.__protocol_attrs__)
- return frozenset(_get_protocol_attrs(tp))
- if hasattr(typing, "Doc"):
- Doc = typing.Doc
- else:
- class Doc:
- """Define the documentation of a type annotation using ``Annotated``, to be
- used in class attributes, function and method parameters, return values,
- and variables.
- The value should be a positional-only string literal to allow static tools
- like editors and documentation generators to use it.
- This complements docstrings.
- The string value passed is available in the attribute ``documentation``.
- Example::
- >>> from typing_extensions import Annotated, Doc
- >>> def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: ...
- """
- def __init__(self, documentation: str, /) -> None:
- self.documentation = documentation
- def __repr__(self) -> str:
- return f"Doc({self.documentation!r})"
- def __hash__(self) -> int:
- return hash(self.documentation)
- def __eq__(self, other: object) -> bool:
- if not isinstance(other, Doc):
- return NotImplemented
- return self.documentation == other.documentation
- _CapsuleType = getattr(_types, "CapsuleType", None)
- if _CapsuleType is None:
- try:
- import _socket
- except ImportError:
- pass
- else:
- _CAPI = getattr(_socket, "CAPI", None)
- if _CAPI is not None:
- _CapsuleType = type(_CAPI)
- if _CapsuleType is not None:
- CapsuleType = _CapsuleType
- __all__.append("CapsuleType")
- # Using this convoluted approach so that this keeps working
- # whether we end up using PEP 649 as written, PEP 749, or
- # some other variation: in any case, inspect.get_annotations
- # will continue to exist and will gain a `format` parameter.
- _PEP_649_OR_749_IMPLEMENTED = (
- hasattr(inspect, 'get_annotations')
- and inspect.get_annotations.__kwdefaults__ is not None
- and "format" in inspect.get_annotations.__kwdefaults__
- )
- class Format(enum.IntEnum):
- VALUE = 1
- FORWARDREF = 2
- STRING = 3
- if _PEP_649_OR_749_IMPLEMENTED:
- get_annotations = inspect.get_annotations
- else:
- def get_annotations(obj, *, globals=None, locals=None, eval_str=False,
- format=Format.VALUE):
- """Compute the annotations dict for an object.
- obj may be a callable, class, or module.
- Passing in an object of any other type raises TypeError.
- Returns a dict. get_annotations() returns a new dict every time
- it's called; calling it twice on the same object will return two
- different but equivalent dicts.
- This is a backport of `inspect.get_annotations`, which has been
- in the standard library since Python 3.10. See the standard library
- documentation for more:
- https://docs.python.org/3/library/inspect.html#inspect.get_annotations
- This backport adds the *format* argument introduced by PEP 649. The
- three formats supported are:
- * VALUE: the annotations are returned as-is. This is the default and
- it is compatible with the behavior on previous Python versions.
- * FORWARDREF: return annotations as-is if possible, but replace any
- undefined names with ForwardRef objects. The implementation proposed by
- PEP 649 relies on language changes that cannot be backported; the
- typing-extensions implementation simply returns the same result as VALUE.
- * STRING: return annotations as strings, in a format close to the original
- source. Again, this behavior cannot be replicated directly in a backport.
- As an approximation, typing-extensions retrieves the annotations under
- VALUE semantics and then stringifies them.
- The purpose of this backport is to allow users who would like to use
- FORWARDREF or STRING semantics once PEP 649 is implemented, but who also
- want to support earlier Python versions, to simply write:
- typing_extensions.get_annotations(obj, format=Format.FORWARDREF)
- """
- format = Format(format)
- if eval_str and format is not Format.VALUE:
- raise ValueError("eval_str=True is only supported with format=Format.VALUE")
- if isinstance(obj, type):
- # class
- obj_dict = getattr(obj, '__dict__', None)
- if obj_dict and hasattr(obj_dict, 'get'):
- ann = obj_dict.get('__annotations__', None)
- if isinstance(ann, _types.GetSetDescriptorType):
- ann = None
- else:
- ann = None
- obj_globals = None
- module_name = getattr(obj, '__module__', None)
- if module_name:
- module = sys.modules.get(module_name, None)
- if module:
- obj_globals = getattr(module, '__dict__', None)
- obj_locals = dict(vars(obj))
- unwrap = obj
- elif isinstance(obj, _types.ModuleType):
- # module
- ann = getattr(obj, '__annotations__', None)
- obj_globals = obj.__dict__
- obj_locals = None
- unwrap = None
- elif callable(obj):
- # this includes types.Function, types.BuiltinFunctionType,
- # types.BuiltinMethodType, functools.partial, functools.singledispatch,
- # "class funclike" from Lib/test/test_inspect... on and on it goes.
- ann = getattr(obj, '__annotations__', None)
- obj_globals = getattr(obj, '__globals__', None)
- obj_locals = None
- unwrap = obj
- elif hasattr(obj, '__annotations__'):
- ann = obj.__annotations__
- obj_globals = obj_locals = unwrap = None
- else:
- raise TypeError(f"{obj!r} is not a module, class, or callable.")
- if ann is None:
- return {}
- if not isinstance(ann, dict):
- raise ValueError(f"{obj!r}.__annotations__ is neither a dict nor None")
- if not ann:
- return {}
- if not eval_str:
- if format is Format.STRING:
- return {
- key: value if isinstance(value, str) else typing._type_repr(value)
- for key, value in ann.items()
- }
- return dict(ann)
- if unwrap is not None:
- while True:
- if hasattr(unwrap, '__wrapped__'):
- unwrap = unwrap.__wrapped__
- continue
- if isinstance(unwrap, functools.partial):
- unwrap = unwrap.func
- continue
- break
- if hasattr(unwrap, "__globals__"):
- obj_globals = unwrap.__globals__
- if globals is None:
- globals = obj_globals
- if locals is None:
- locals = obj_locals or {}
- # "Inject" type parameters into the local namespace
- # (unless they are shadowed by assignments *in* the local namespace),
- # as a way of emulating annotation scopes when calling `eval()`
- if type_params := getattr(obj, "__type_params__", ()):
- locals = {param.__name__: param for param in type_params} | locals
- return_value = {key:
- value if not isinstance(value, str) else eval(value, globals, locals)
- for key, value in ann.items() }
- return return_value
- if hasattr(typing, "evaluate_forward_ref"):
- evaluate_forward_ref = typing.evaluate_forward_ref
- else:
- # Implements annotationlib.ForwardRef.evaluate
- def _eval_with_owner(
- forward_ref, *, owner=None, globals=None, locals=None, type_params=None
- ):
- if forward_ref.__forward_evaluated__:
- return forward_ref.__forward_value__
- if getattr(forward_ref, "__cell__", None) is not None:
- try:
- value = forward_ref.__cell__.cell_contents
- except ValueError:
- pass
- else:
- forward_ref.__forward_evaluated__ = True
- forward_ref.__forward_value__ = value
- return value
- if owner is None:
- owner = getattr(forward_ref, "__owner__", None)
- if (
- globals is None
- and getattr(forward_ref, "__forward_module__", None) is not None
- ):
- globals = getattr(
- sys.modules.get(forward_ref.__forward_module__, None), "__dict__", None
- )
- if globals is None:
- globals = getattr(forward_ref, "__globals__", None)
- if globals is None:
- if isinstance(owner, type):
- module_name = getattr(owner, "__module__", None)
- if module_name:
- module = sys.modules.get(module_name, None)
- if module:
- globals = getattr(module, "__dict__", None)
- elif isinstance(owner, _types.ModuleType):
- globals = getattr(owner, "__dict__", None)
- elif callable(owner):
- globals = getattr(owner, "__globals__", None)
- # If we pass None to eval() below, the globals of this module are used.
- if globals is None:
- globals = {}
- if locals is None:
- locals = {}
- if isinstance(owner, type):
- locals.update(vars(owner))
- if type_params is None and owner is not None:
- # "Inject" type parameters into the local namespace
- # (unless they are shadowed by assignments *in* the local namespace),
- # as a way of emulating annotation scopes when calling `eval()`
- type_params = getattr(owner, "__type_params__", None)
- # type parameters require some special handling,
- # as they exist in their own scope
- # but `eval()` does not have a dedicated parameter for that scope.
- # For classes, names in type parameter scopes should override
- # names in the global scope (which here are called `localns`!),
- # but should in turn be overridden by names in the class scope
- # (which here are called `globalns`!)
- if type_params is not None:
- globals = dict(globals)
- locals = dict(locals)
- for param in type_params:
- param_name = param.__name__
- if (
- _FORWARD_REF_HAS_CLASS and not forward_ref.__forward_is_class__
- ) or param_name not in globals:
- globals[param_name] = param
- locals.pop(param_name, None)
- arg = forward_ref.__forward_arg__
- if arg.isidentifier() and not keyword.iskeyword(arg):
- if arg in locals:
- value = locals[arg]
- elif arg in globals:
- value = globals[arg]
- elif hasattr(builtins, arg):
- return getattr(builtins, arg)
- else:
- raise NameError(arg)
- else:
- code = forward_ref.__forward_code__
- value = eval(code, globals, locals)
- forward_ref.__forward_evaluated__ = True
- forward_ref.__forward_value__ = value
- return value
- def _lax_type_check(
- value, msg, is_argument=True, *, module=None, allow_special_forms=False
- ):
- """
- A lax Python 3.11+ like version of typing._type_check
- """
- if hasattr(typing, "_type_convert"):
- if (
- sys.version_info >= (3, 10, 3)
- or (3, 9, 10) < sys.version_info[:3] < (3, 10)
- ):
- # allow_special_forms introduced later cpython/#30926 (bpo-46539)
- type_ = typing._type_convert(
- value,
- module=module,
- allow_special_forms=allow_special_forms,
- )
- # module was added with bpo-41249 before is_class (bpo-46539)
- elif "__forward_module__" in typing.ForwardRef.__slots__:
- type_ = typing._type_convert(value, module=module)
- else:
- type_ = typing._type_convert(value)
- else:
- if value is None:
- return type(None)
- if isinstance(value, str):
- return ForwardRef(value)
- type_ = value
- invalid_generic_forms = (Generic, Protocol)
- if not allow_special_forms:
- invalid_generic_forms += (ClassVar,)
- if is_argument:
- invalid_generic_forms += (Final,)
- if (
- isinstance(type_, typing._GenericAlias)
- and get_origin(type_) in invalid_generic_forms
- ):
- raise TypeError(f"{type_} is not valid as type argument") from None
- if type_ in (Any, LiteralString, NoReturn, Never, Self, TypeAlias):
- return type_
- if allow_special_forms and type_ in (ClassVar, Final):
- return type_
- if (
- isinstance(type_, (_SpecialForm, typing._SpecialForm))
- or type_ in (Generic, Protocol)
- ):
- raise TypeError(f"Plain {type_} is not valid as type argument") from None
- if type(type_) is tuple: # lax version with tuple instead of callable
- raise TypeError(f"{msg} Got {type_!r:.100}.")
- return type_
- def evaluate_forward_ref(
- forward_ref,
- *,
- owner=None,
- globals=None,
- locals=None,
- type_params=None,
- format=Format.VALUE,
- _recursive_guard=frozenset(),
- ):
- """Evaluate a forward reference as a type hint.
- This is similar to calling the ForwardRef.evaluate() method,
- but unlike that method, evaluate_forward_ref() also:
- * Recursively evaluates forward references nested within the type hint.
- * Rejects certain objects that are not valid type hints.
- * Replaces type hints that evaluate to None with types.NoneType.
- * Supports the *FORWARDREF* and *STRING* formats.
- *forward_ref* must be an instance of ForwardRef. *owner*, if given,
- should be the object that holds the annotations that the forward reference
- derived from, such as a module, class object, or function. It is used to
- infer the namespaces to use for looking up names. *globals* and *locals*
- can also be explicitly given to provide the global and local namespaces.
- *type_params* is a tuple of type parameters that are in scope when
- evaluating the forward reference. This parameter must be provided (though
- it may be an empty tuple) if *owner* is not given and the forward reference
- does not already have an owner set. *format* specifies the format of the
- annotation and is a member of the annotationlib.Format enum.
- """
- if format == Format.STRING:
- return forward_ref.__forward_arg__
- if forward_ref.__forward_arg__ in _recursive_guard:
- return forward_ref
- # Evaluate the forward reference
- try:
- value = _eval_with_owner(
- forward_ref,
- owner=owner,
- globals=globals,
- locals=locals,
- type_params=type_params,
- )
- except NameError:
- if format == Format.FORWARDREF:
- return forward_ref
- else:
- raise
- msg = "Forward references must evaluate to types."
- if not _FORWARD_REF_HAS_CLASS:
- allow_special_forms = not forward_ref.__forward_is_argument__
- else:
- allow_special_forms = forward_ref.__forward_is_class__
- type_ = _lax_type_check(
- value,
- msg,
- is_argument=forward_ref.__forward_is_argument__,
- allow_special_forms=allow_special_forms,
- )
- # Recursively evaluate the type
- if isinstance(type_, ForwardRef):
- if getattr(type_, "__forward_module__", True) is not None:
- globals = None
- return evaluate_forward_ref(
- type_,
- globals=globals,
- locals=locals,
- type_params=type_params, owner=owner,
- _recursive_guard=_recursive_guard, format=format
- )
- if sys.version_info < (3, 12, 5) and type_params:
- # Make use of type_params
- locals = dict(locals) if locals else {}
- for tvar in type_params:
- if tvar.__name__ not in locals: # lets not overwrite something present
- locals[tvar.__name__] = tvar
- if sys.version_info < (3, 9):
- return typing._eval_type(
- type_,
- globals,
- locals,
- )
- if sys.version_info < (3, 12, 5):
- return typing._eval_type(
- type_,
- globals,
- locals,
- recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},
- )
- if sys.version_info < (3, 14):
- return typing._eval_type(
- type_,
- globals,
- locals,
- type_params,
- recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},
- )
- return typing._eval_type(
- type_,
- globals,
- locals,
- type_params,
- recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},
- format=format,
- owner=owner,
- )
- # Aliases for items that have always been in typing.
- # Explicitly assign these (rather than using `from typing import *` at the top),
- # so that we get a CI error if one of these is deleted from typing.py
- # in a future version of Python
- AbstractSet = typing.AbstractSet
- AnyStr = typing.AnyStr
- BinaryIO = typing.BinaryIO
- Callable = typing.Callable
- Collection = typing.Collection
- Container = typing.Container
- Dict = typing.Dict
- ForwardRef = typing.ForwardRef
- FrozenSet = typing.FrozenSet
- Generic = typing.Generic
- Hashable = typing.Hashable
- IO = typing.IO
- ItemsView = typing.ItemsView
- Iterable = typing.Iterable
- Iterator = typing.Iterator
- KeysView = typing.KeysView
- List = typing.List
- Mapping = typing.Mapping
- MappingView = typing.MappingView
- Match = typing.Match
- MutableMapping = typing.MutableMapping
- MutableSequence = typing.MutableSequence
- MutableSet = typing.MutableSet
- Optional = typing.Optional
- Pattern = typing.Pattern
- Reversible = typing.Reversible
- Sequence = typing.Sequence
- Set = typing.Set
- Sized = typing.Sized
- TextIO = typing.TextIO
- Tuple = typing.Tuple
- Union = typing.Union
- ValuesView = typing.ValuesView
- cast = typing.cast
- no_type_check = typing.no_type_check
- no_type_check_decorator = typing.no_type_check_decorator
|