+
    ,i"                     F  a  R[ t^0 t R t^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHtH	t	H
t
 ^ RIHt ^ RIHt ^ RIHt ^ RIHtHtHt ^ RIt^ RIHt ^ RIHt ^ RIHtHtHtHtH t!H"t#H$t%H&t'H(t)H*t+H,t- ^ R	I.H/t/ ^ R
I0H1t1 . R\Ot2]Pf                  Pi                  RR4      t5] ^ k ]Pf                  Pi                  RR4      t6R]5R]6/t7]t8] ^k ]8]Pr                  ,          t9] ^k R R lt:R R lt;R R lt<R]RRRRRR/R R lllt=RR/R R llt>]! R4      t?] ^k ]R R l4       t@R^R ltAR R!R"R!R#R!R$R!/R% ltBR& tCR R!R"R!R#R!R$R!R'R(RR/R) ltDR*RR+^ R R!R"R!R#R!R$R!R'R(RR/R, ltER R!R"R!R#R!R$R!R'R(R-R!RR/R. ltFR_R/ ltGR`R0 ltHR1 R2 ltIR3 R4 ltJR5 R6 ltKR7RR8RR9^RR/R: R; lltLRR/R< R= lltMR^R> ltNR?R/R@ ltORARR?R/RB ltPR^RC RD lltQRE tRRF tSRG tT]P                  ! RRH7       ! RI RJ4      4       tVRbRK ltWRL tXRMRRNRaRORaRPRRQRRRRRSRaRTRaRURRVR!/
RW ltYRMR/RX ltZRMR/RY lt[RMR/RZ lt\/ t]R# )ca6  Utility functions to use Python Array API compatible libraries.

For the context about the Array API see:
https://data-apis.org/array-api/latest/purpose_and_scope.html

The SciPy use case of the Array API is described on the following page:
https://data-apis.org/array-api/latest/use_cases.html#use-case-scipy
N)	GeneratorIterableIterator)contextmanager)
ContextVar
ModuleType)AnyLiteral	TypeAlias)array_api_compat)is_array_api_objis_lazy_arraysizenumpydeviceis_numpy_namespaceis_cupy_namespaceis_torch_namespaceis_jax_namespaceis_dask_namespaceis_array_api_strict_namespace)issparse)FunctionDocSCIPY_ARRAY_APISCIPY_DEVICEFcpuc                \    V ^8  d   QhR\         \        ,          R\        \        ,          /#    arraysreturn)r   	ArrayLiker   Array)formats   "7/usr/lib/python3/dist-packages/scipy/_lib/_array_api.py__annotate__r&   D   s#     5 5hy1 5huo 5    c              #  &  "   V  EF  pVf   K
  \        V4      '       d   Rp\        V4      h\        V\        P                  P
                  4      '       d   \        R4      h\        V\        P                  4      '       d   \        R4      h\        V\        P                  \        P                  ,          4      '       ds   VP                  p\        P                  ! V\        P                  4      '       g<   \        P                  ! V\        P                  4      '       g   \        RV: R24      h\        V4      '       d   Vx  EKG   \        P                  ! V4      pTP                  p\        P                  ! T\        P                  4      '       g>   \        P                  ! T\        P                  4      '       g   RT: R2p\        T4      hTP                   '       g   EK  Tx  EK  	  R#   \         d    \        R4      hi ; i5i)	a  Raise exceptions on known-bad subclasses. Discard 0-dimensional ArrayLikes
and convert 1+-dimensional ArrayLikes to numpy.

The following subclasses are not supported and raise and error:
- `numpy.ma.MaskedArray`
- `numpy.matrix`
- NumPy arrays which do not have a boolean or numerical dtype
- Any array-like which is neither array API compatible nor coercible by NumPy
- Any array-like which is coerced by NumPy to an unsupported dtype
NzSparse arrays/matrices are not supported by this function. Perhaps one of the `scipy.sparse.linalg` functions would work instead.z8Inputs of type `numpy.ma.MaskedArray` are not supported.z0Inputs of type `numpy.matrix` are not supported.zAn argument has dtype `z3`; only boolean and numerical dtypes are supported.zCAn argument is neither array API compatible nor coercible by NumPy.z1An argument was coerced to an unsupported dtype `)r   
ValueError
isinstancenpmaMaskedArray	TypeErrormatrixndarraygenericdtype
issubdtypenumberbool_r   
asanyarrayndim)r    arraymsgr2   messages   &    r%   _compliance_scipyr;   D   s     = E??)C S/!eRUU..//VWWeRYY''NOOeRZZ"**455KKEMM%33r}}UBHH7U7U"9% CS !T U U E""K7e, KKEMM%33r}}UBHH7U7UGy QG H   (( zzzU 8  7 !6 7 77s<   C6H9*H$(HG7#6H*H!H,H7HHc                4    V ^8  d   QhR\         R\        RR/# )r   r8   xpr!   Nr#   r   )r$   s   "r%   r&   r&   |   s!       J 4 r'   c                l    VP                  VP                  V 4      4      '       g   Rp\        V4      hR# )zCheck for NaNs or Infs.z#array must not contain infs or NaNsN)allisfiniter)   )r8   r=   r9   s   && r%   _check_finiterB   |   s.    66"++e$%%3o &r'   c                0    V ^8  d   QhR\         R\        /# r   r>   )r$   s   "r%   r&   r&      s     $ $U $z $r'   c                     \         R,          '       g   \        # \        \        V 4      4      pV'       d   \        P
                  ! V!  # \        # )a  Get the array API compatible namespace for the arrays xs.

Parameters
----------
*arrays : sequence of array_like
    Arrays used to infer the common namespace.

Returns
-------
namespace : module
    Common namespace.

Notes
-----
Thin wrapper around `array_api_compat.array_namespace`.

1. Check for the global switch: SCIPY_ARRAY_API. This can also be accessed
   dynamically through ``_GLOBAL_CONFIG['SCIPY_ARRAY_API']``.
2. `_compliance_scipy` raise exceptions on known-bad subclasses. See
   its definition for more details.

When the global switch is False, it defaults to the `numpy` namespace.
In that case, there is no compliance check. This is a convenience to
ease the adoption. Otherwise, arrays must comply with the new rules.
r   )_GLOBAL_CONFIG	np_compatlistr;   r   array_namespace)r    
api_arrayss   * r%   rH   rH      sB    4 +,,'/0J //<<r'   r=   check_finitesubokc                    V ^8  d   QhR\         R\        R\        R
,          R,          R\        R,          R\        R,          R\        R\        R	\
        /# )r   r8   r2   orderNcopyr=   rJ   rK   r!   )KACF)r"   r	   r
   boolr   r#   )r$   s   "r%   r&   r&      sl     , ,,, )*T1, Tk	, , , , 
,r'   c                  Vf   \        V 4      p\        V4      '       dZ   VRJ d   \        P                  ! WWR7      p MNV'       d   \        P                  ! WVR7      p M-\        P
                  ! WVR7      p M VP                  WVR7      p V'       d   \        W4       V #   \         d1    \        TP                  ^4      4      pTP                  YTR7      p  LOi ; i)a8  SciPy-specific replacement for `np.asarray` with `order`, `check_finite`, and
`subok`.

Memory layout parameter `order` is not exposed in the Array API standard.
`order` is only enforced if the input array implementation
is NumPy based, otherwise `order` is just silently ignored.

`check_finite` is also not a keyword in the array API standard; included
here for convenience rather than that having to be a separate function
call inside SciPy functions.

`subok` is included to allow this function to preserve the behaviour of
`np.asanyarray` for NumPy based inputs.
T)rM   r2   rK   )rM   r2   )r2   rN   )rH   is_numpyr+   r8   r6   asarrayr.   rB   )r8   r2   rM   rN   r=   rJ   rK   
coerced_xps   &&&&$$$ r%   _asarrayrX      s    0 
zU#||4<HHUuJEMM%EBEJJu?E	FJJuJ=E
 e L  	F(A7J&&u&EE	Fs   ;B# #8CCc                J    V ^8  d   QhR\         R\        R,          R\         /# r   xr=   Nr!   r>   )r$   s   "r%   r&   r&      s&     ) )u )Z$. )% )r'   c               <    Vf   \        V 4      p\        V RVR7      # )z
Copies an array.

Parameters
----------
x : array

xp : array_namespace

Returns
-------
copy : array
    Copied array

Notes
-----
This copy function does not offer all the semantics of `np.copy`, i.e. the
`subok` and `order` keywords are not used.
T)rN   r=   )rH   rX   r[   r=   s   &$r%   xp_copyr^      s"    , 
zQADR((r'   _default_xpc                >    V ^8  d   QhR\         R\        R,          /# )r   r=   r!   NNN)r   r   )r$   s   "r%   r&   r&      s      ( (: (),<"= (r'   c              #     "   \         P                  V 4      p Rx  \         P                  V4       R#   \         P                  T4       i ; i5i)a  In all ``xp_assert_*`` and ``assert_*`` function calls executed within this
context manager, test by default that the array namespace is
the provided across all arrays, unless one explicitly passes the ``xp=``
parameter or ``check_namespace=False``.

Without this context manager, the default value for `xp` is the namespace
for the desired array (the second parameter of the tests).
N)_default_xp_ctxvarsetreset)r=   tokens   & r%   
default_xprg      s<      ""2&E(  '  's   A4 AAAc                ~    ^ RI pRp\        V 4      '       d   \        P                  ! 4       # VP	                  WR7      # )z@pytest.warns context manager, but only if x is not a lazy array.NF)match)pytestr   
contextlibnullcontextwarns)r[   warning_typeri   rj   __thread_safe__s   &&&  r%   eager_warnsrp     s7     OQ%%''<<<22r'   check_namespaceTcheck_dtypecheck_shapecheck_0dc                   R pVf    \         P                  4       pV'       d   \	        WV4       \        V4      '       d   V'       d~   R\        V 4       R\        V4       2pVP                  V 4      '       d   VP                  V4      '       g6   VP                  V 4      '       g   VP                  V4      '       d   Q V4       hVP                  V 4      p VP                  V4      pV'       d?   RV P                   RVP                   2pV P                  VP                  8X  g   Q V4       hV'       dp   \        V4      '       d!   V P                  4        VP                  4        RV P                   RVP                   2pV P                  VP                  8X  g   Q V4       hVP                  WP                  4      pWV3#   \         d    \        T4      p ELi ; i)Tz$Array-ness does not match:
 Actual: z
 Desired: zdtypes do not match.
Actual: 

Desired: zShapes do not match.
Actual: )rc   getLookupErrorrH   _assert_matching_namespacerU   typeisscalarrV   r2   is_daskcompute_chunk_sizesshapebroadcast_to)	actualdesiredr=   rq   rr   rs   rt   __tracebackhide___msgs	   &&&$$$$  r%   _strict_checkr     s    	z	*#'')B "6B7 ||7<.T']O=V$$W)=)=F++BKK4H4H	QLP	Q J ZZFjj!G/~[X||w}},2d2,2;;&&('')/~[X||w}},2d2,oog||4GB;  	* )B	*s   G GGc                     R p\        V4      pRVP                   RVP                   2pWB8X  g   Q V4       h\        V 4      pRVP                   RVP                   2pWb8X  g   Q V4       hR# )TzNamespace of desired array does not match expectations set by the `default_xp` context manager or by the `xp`pytest fixture.
Desired array's space: z
Expected namespace: z=Namespace of actual and desired arrays do not match.
Actual: rv   N)rH   __name__)r   r   r=   r   desired_arr_spacer   actual_arr_spaces   &&&    r%   ry   ry   ;  s    '0& '8&@&@%A B##%;;-	1D
 "(D("&v.'001 2}&D !'4'!r'   err_msg c          
      B   R p\        WWrW4VR7      w  rp\        V4      '       d   VP                  P                  WVR7      # \	        V4      '       d-   VR8X  d   RMTpVP                  P                  W^ ^ R RVR7      # \        P                  P                  WVR7      # )Trq   rr   rs   rt   )r   r   NFrtolatol	equal_nanrr   r9   )r   is_cupytestingassert_array_equalis_torchassert_closer+   )	r   r   rq   rr   rs   rt   r   r=   r   s	   &&$$$$$$ r%   xp_assert_equalr   M  s    'FR r{{zz,,Vg,NN	" "R-$Wzz&&vQQRV38g ' G 	G ::(('(JJr'   r   r   c          
         R p
\        WV	WEWgR7      w  rp	V	P                  V P                  R	4      pVf=   V'       d5   V	P                  V P                  4      P                  R,          ^,          pMVf   Rp\        V	4      '       d   V	P                  P                  WVW8R7      # \        V	4      '       d,   VR8X  d   RMTpV	P                  P                  WW#R RVR7      # \        P                  P                  WVW8R7      # )
Tr   N      ?gHz>)r   r   r   r   Fr   real floatingcomplex floating)r   isdtyper2   finfoepsr   r   assert_allcloser   r   r+   )r   r   r   r   rq   rr   rs   rt   r   r=   r   floatings   &&$$$$$$$$  r%   xp_assert_closer   c  s    ''FR zz&,,(MNH| xx%))3.2	r{{zz))&/3 * F 	F	"!R-$Wzz&&vT155g ' W 	W ::%%fD+/ & B Br'   verbosec          
         R p	\        WWW4VR7      w  rp\        V4      '       d   VP                  P                  WWgR7      # \	        V4      '       dW   V P
                  P                  R8w  d   V P                  4       p VP
                  P                  R8w  d   VP                  4       p\        P                  P                  WWgR7      # )Tr   )r   r   r   )	r   r   r   assert_array_lessr   r   rz   r   r+   )
r   r   rq   rr   rs   rt   r   r   r=   r   s
   &&$$$$$$$ r%   xp_assert_lessr     s    'FR r{{zz++F4; , N 	N	"==&ZZ\F>>%'kkmG::''07 ( J Jr'   c                T    ^ R^
V) ,          ,          re\        W.VO5RVRVRRRR/VB # zPBackwards compatible replacement. In new code, use xp_assert_close instead.
    g      ?r   r   rr   Frs   r   r   r   decimalargskwdsr   r   s   &&&*,  r%   assert_array_almost_equalr     U     CgX&$6 * * $*+/*=B*PU*$(* *r'   c                T    ^ R^
V) ,          ,          re\        W.VO5RVRVRRRR/VB # r   r   r   s   &&&*,  r%   assert_almost_equalr     r   r'   c                0    V ^8  d   QhR\         R\        /# )r   paramr!   )r	   str)r$   s   "r%   r&   r&     s     F FC FC Fr'   c                     R V : R2# )z
Providing z$ is only supported for numpy arrays. )r   s   &r%   xp_unsupported_param_msgr     s    y DEEr'   c                <    V ^8  d   QhR\         R\        R\        /# )r   r[   r=   r!   )r#   r   rS   )r$   s   "r%   r&   r&     s!     3 3% 3Z 3D 3r'   c                 :    VP                  V P                  R 4      # )r   )r   r2   r]   s   &&r%   
is_complexr     s    ::agg122r'   c                >    V ^8  d   QhR\         R\         R,          /# )r   r=   r!   Nr   )r$   s   "r%   r&   r&     s      J :+< r'   c                    \        V 4      '       d   ^ RIpVP                  # \        V 4      '       d   ^ RIpVP                  # \        V 4      '       d   V # R# )a   Return the `scipy`-like namespace of a non-NumPy backend

That is, return the namespace corresponding with backend `xp` that contains
`scipy` sub-namespaces like `linalg` and `special`. If no such namespace
exists, return ``None``. Useful for dispatching.
N)r   cupyxscipyis_jaxjaxr   )r=   r   r   s   &  r%   scipy_namespace_forr     sA     r{{{{bzzyy||	r'   axiskeepdimsordc                    V ^8  d   QhR\         R\        \        \        ,          ,          R,          R\        R\        \        ,          R\
        R,          R\         /# )r   r[   r   Nr   r   r=   r!   )r#   inttuplerS   floatr   )r$   s   "r%   r&   r&     s`     H He HuSz)D0H!H eH "D(	H 5:	Hr'   c               `   Vf   \        V 4      MTp\        '       dr   \        VR4      '       d   VP                  P	                  WW#R7      # V^8w  d   \        R4      hVP                  VP                  V 4      V ,          WR7      R,          # \        P                  P                  WWR7      # )Nlinalg)r   r   r   zonly the Euclidean norm (`ord=2`) is currently supported in `xp_vector_norm` for backends not implementing the `linalg` extension.)r   r   r   )r   r   r   )
rH   r   hasattrr   vector_normr)   sumconjr+   norm)r[   r   r   r   r=   s   "$$$$r%   xp_vector_normr     s    
  "z	rB2x  99(((RRax !  66"''!*q.t6GLL yy~~at~GGr'   c                J    V ^8  d   QhR\         R\        R,          R\         /# rZ   r>   )r$   s   "r%   r&   r&     s&          d!2  e  r'   c               H    Vf   \        V 4      MTpVP                  V R4      # )N))rH   reshaper]   s   "$r%   xp_ravelr     s%      "z	rB::ar'   c                     Vf   \        V 4      MTp\        \        V P                  4      4      pWB,          WA,          uWA&   WB&   VP	                  W4      p V # N)rH   rG   ranger7   permute_dims)aaxis1axis2r=   axess   &&&& r%   xp_swapaxesr     sK    !z	rBaffD#{DKDK
 AHr'   force_floatingc           	     ,   V Uu. uF/  p\         P                  ! V4      '       d   \        VRVR7      MTNK1  	  ppV Uu. uF
  q3f   K  VNK  	  ppV '       d   VP                  R4       \	        V4      '       dQ   VP
                  R8  d@   V Uu. uF#  p\        VR^ 4      ^8X  d   VP                  MTNK%  	  ppVP                  ! V!  #  VP                  ! V!  # u upi u upi u upi   \         d    T '       g   h . pT Fj  p\         P                  ! T4      '       d   TP                  T4      MTp\        TRT4      pTP                  TR4      '       g   KY  TP                  T4       Kl  	  TP                  ! . TO\        T4      N5!  u # i ; i)a  
Returns the dtype that results from applying type promotion rules
(see Array API Standard Type Promotion Rules) to the arguments. Augments
standard `result_type` in a few ways:

- There is a `force_floating` argument that ensures that the result type
  is floating point, even when all args are integer.
- When a TypeError is raised (e.g. due to an unsupported promotion)
  and `force_floating=True`, we define a custom rule: use the result type
  of the default float and any other floats passed. See
  https://github.com/scipy/scipy/pull/22695/files#r1997905891
  for rationale.
- This function accepts array-like iterables, which are immediately converted
  to the namespace's arrays before result type calculation. Consequently, the
  result dtype may be different when an argument is `1.` vs `[1.]`.

Typically, this function will be called shortly after `array_namespace`
on a subset of the arguments passed to `array_namespace`.
TrK   r=   g      ?z2.0r   r2   r   )r+   iterablerX   appendrU   __version__getattrr2   result_typer.   r{   rV   r   xp_default_dtype)r   r=   r   argargs_not_none
float_args	arg_arrayr2   s   $$*     r%   xp_result_typer     s{   *  24S1A1AXc"-sJ 	 $(<DSSSDM<S!||. %23$1S '.c61&=&BK$1 	 3~~}--A~~}--<3  A
 
 C+-;;s+;+;

3IIw4Ezz%!FGG!!#&	 !
 ~~@z@+;B+?@@As;    CC C"
C")C'C, ,F?AF3FF	broadcastc           
        V Uu. uF/  p\         P                  ! V4      '       d   \        VRVR7      MTNK1  	  pp\        VRVRV/ pV Uu. uF  pVe   \        WERVR7      MTNK  	  ppV '       g%   \	        V4      ^8X  d
   V^ ,          # \        V4      # V Uu. uF
  qDf   K  VNK  	  ppV Uu0 uF  qDP                  kK  	  pp \	        V4      ^8w  d   \         P                  ! V!  MV^ ,          P                  p. pT F  pTf   TP                  T4       K  TP                  T8w  d+   \        T4      '       d   RR/M/ pTP                  ! YH3/ TB pTP                  T8w  d   TP                  YE4      pTP                  T4       K  	  \	        T4      ^8X  d
   T^ ,          # \        T4      # u upi u upi u upi u upi   \         d   p	Rp
\        T
4      T	hRp	?	ii ; i)	aw  
Promotes elements of *args to result dtype, ignoring `None`s.
Includes options for forcing promotion to floating point and
broadcasting the arrays, again ignoring `None`s.
Type promotion rules follow `xp_result_type` instead of `xp.result_type`.

Typically, this function will be called shortly after `array_namespace`
on a subset of the arguments passed to `array_namespace`.

This function accepts array-like iterables, which are immediately converted
to the namespace's arrays before result type calculation. Consequently, the
result dtype may be different when an argument is `1.` vs `[1.]`.

See Also
--------
xp_result_type
Tr   r   r=   N)r2   rK   r=   z/Array shapes are incompatible for broadcasting.rK   )r+   r   rX   r   lenr   r~   broadcast_shapesr)   r   rU   r   r2   astype)r   r   r=   r   r   r2   r   shapesr~   er:   outkwargss   $$$*         r%   
xp_promoter   )  s   &  24S1A1AXc"-sJ 	  DGGBGE  ?BoXcdr:SVV 	  d)Q,tAw7E$K7$(<DSSSDM< $11=Cii=F1)14V1A$$f-#A&,, 	 C;JJsO
 99(0gt_"F//#77C 99))C'C

3! $ Xq[3q60eCj0S
 = 2  )C!q()s:    F4F4F9F>&F>2G	7G G&G!!G&c                J    V ^8  d   QhR\         R\        R,          R\         /# )r   arrr=   Nr!   r>   )r$   s   "r%   r&   r&   g  s&      U 
T(9 U r'   c                 "   Vf   \        V 4      MTpV P                  pVP                  W!P                  4      '       d   VP	                  WP
                  4      p V # VP                  VR4      '       d   VP	                  WP                  4      p V # )Nr   )rH   r2   r   float32r   	complex64
complex128)r   r=   	arr_dtypes   && r%   xp_float_to_complexr   g  ss    !#	B		I 
zz)ZZ((ii\\* J 
I	/	/ii]]+Jr'   c                \    \        V 4      '       d   V P                  4       # V P                  # )z@Query the namespace-dependent default floating-point dtype.
    )r   get_default_dtypefloat64r=   s   &r%   r   r   u  s(     ||##%% zzr'   c                 T    V  F!  p\        V4      '       g   K  \        V4      u # 	  R# )zReturn the device of an array in `args`, for the purpose of
input-output device propagation.
If there are multiple devices, return an arbitrary one.
If there are no arrays, return None (this typically happens only on NumPy).
N)r   	xp_device)r   r   s   * r%   xp_result_devicer    s*      C  S>!	 
 r'   c                     RV P                   9   # )z=Returns True if `xp` is an MArray namespace; False otherwise.marray)r   r  s   &r%   	is_marrayr    s    r{{""r'   )reprc                   ^   a  ] tR tRt o ]P
                  ! ]R7      tR tR t	V 3R lt
RtV tR# )_XPSphinxCapabilityi  )default_factoryc                    Vf   R# V'       g   R# V P                   '       d<   RRP                  V P                   4      ,           p\        V4      ^8:  g   Q R4       hV# R# )Nzn/au   ⛔u   ⚠️ z; zWarnings too longu   ✅)warningsjoinr   )selfvalueress   && r%   _render_XPSphinxCapability._render  sN    ====dii66Cs8r>6#66>Jr'   c                    V P                  V P                  4      pV P                  V P                  4      pVR  RVR  2# )20z  )r  r   gpu)r  r   r  s   &  r%   __str___XPSphinxCapability.__str__  s;    ll488$ll488$bC8$$r'   c                j   < V ^8  d   Qh/ S[ R,          ;R&   S[ R,          ;R&   S[S[,          ;R&   # )r   Nr   r  r  )rS   rG   r   )r$   __classdict__s   "r%   r&    _XPSphinxCapability.__annotate__  s6     	  
  3iA	 r'   r   N)r   
__module____qualname____firstlineno__dataclassesfieldrG   r  r  r  __annotate_func____static_attributes____classdictcell__)r  s   @r%   r
  r
    s(      &++DAH	%#  r'   r
  c	                    \        V4      pR \        RRR7      R\        RRR7      R\        RRR7      R\        RRR7      R\        RRV'       d   . MR.R	7      R
\        RRV'       d   R.M. R	7      /p	\        V 4      \        V4      ,            F9  w  rW,          pVP                  e   RVn        VP                  f   K2  RVn        K;  	  V	P                  4        Fr  w  rV'       d=   WR 0,          9  d/   VP                  e   RVn        VP                  e
   RVn        KG  KI  V'       g   KS  W9  g   K[  VP                  f   Kk  RVn        Kt  	  V F(  w  rW,          pVP                  P                  V4       K*  	  V	# )r   TN)r   r  array_api_strictcupytorch	jax.numpyzno JIT)r   r  r  
dask.arrayzcomputes graphF)rd   r
  rG   r   r  itemsr  r   )skip_backendsxfail_backendscpu_onlynp_only
exceptionsallow_dask_computejax_jitr  reasoncapabilitiesmodule_backendwarnings   &&&&&&&&&     r%   _make_sphinx_capabilitiesr8    sc    ZJ 	$48/DdC#$7$48(Tt"R
4 	)d+=&'2G
L -(4+???	&;;"GK;;"GK @ (--/v7)%;;{{&#{{&# 'X&2w{{7NGK 0 $&( $ r'   c                     R V  RVR,           RVR,           RVR,           RVR,           R	VR
,           R2p\         P                  ! V4      # )z
    `aG  ` has experimental support for Python Array API Standard compatible
    backends in addition to NumPy. Please consider testing these features
    by setting an environment variable ``SCIPY_ARRAY_API=1`` and providing
    CuPy, PyTorch, JAX, or Dask arrays as array arguments. The following
    combinations of backend and device (or other capability) are supported.

    ====================  ====================  ====================
    Library               CPU                   GPU
    ====================  ====================  ====================
    NumPy                 r   z
    CuPy                  r&  z
    PyTorch               r'  z
    JAX                   r(  z
    Dask                  r)  z}
    ====================  ====================  ====================

    See :ref:`dev-arrayapi` for more information.
    )textwrapdedent)fun_namer3  notes   && r%   _make_capabilities_noter>    s    Z 	 (0D E'/D E'0D E'4D E'5D ED& ??4  r'   capabilities_tabler+  r,  r-  r.  r2  r/  r  r0  r1  c        
        r   a aa S f   \         MS o \        VVVVVVVV	VR7	      o\        R/ SB oVV V3R lp
V
# )aI  Decorator for a function that states its support among various
Array API compatible backends.

This decorator has two effects:
1. It allows tagging tests with ``@make_xp_test_case`` or
   ``make_xp_pytest_param`` (see below) to automatically generate
   SKIP/XFAIL markers and perform additional backend-specific
   testing, such as extra validation for Dask and JAX;
2. It automatically adds a note to the function's docstring, containing
   a table matching what has been tested.    

See Also
--------
make_xp_test_case
make_xp_pytest_param
array_api_extra.testing.lazy_xp_function
)	r+  r,  r-  r.  r2  r/  r0  r1  r  c                    < SSV &   \        V P                  S4      p\        V 4      pVR ,          P                  V4       \	        V4      P                  R^4      ^,          p W n        V #   \         d     T # i ; i)Notes
)r>  r   r   r   r   split__doc__AttributeError)fr=  docr3  r?  sphinx_capabilitiess   &  r%   	decorator"xp_capabilities.<locals>.decorator&  s     !-1&qzz3FG!nGD!#hnnT1%a(	I   	 	s   #A+ +A:9A:r   )xp_capabilities_tabledictr8  )r?  r+  r,  r-  r.  r2  r/  r  r0  r1  rJ  r3  rI  s   d$$$$$$$$$ @@r%   xp_capabilitiesrN    s\    B 4F3M/1  #%-
L 4ClC  r'   c           	         V f   \         MT p ^ R Ip^ RIHp . pV EF/  pW,          pVR,          pVR,          pVR,          '       d-   VP	                  VP
                  P                  RWxR7      4       VR,          '       d-   VP	                  VP
                  P                  RWxR7      4       VR	,           F0  w  rVP	                  VP
                  P                  WR
7      4       K2  	  VR,           F0  w  rVP	                  VP
                  P                  WR
7      4       K2  	  R U
u/ uF  p
WV
,          bK  	  pp
V! V3/ VB  EK2  	  V# u up
i )N)lazy_xp_functionr/  r2  r-  T)r-  r/  r2  r.  )r.  r/  r2  r+  )r2  r,  )r0  r1  )rL  rj   "scipy._lib.array_api_extra.testingrP  r   markskip_xp_backendsxfail_xp_backends)r?  funcsrj   rP  marksfuncr3  r/  r2  mod_nameklazy_kwargss   $*          r%   _make_xp_pytest_marksr[  9  s[   3E3M/1 CE)/!,/
h'
##LL55* 6 E F	""LL55 6 D E !-_ = =HLL55h5NO !> ,-= > >HLL66x6OP !? !BC A1 q/) A 	 C--' * L	Cs   -Ec                 @   a V f   \         MT p  \        VRV / oV3R l# )Nr?  c                 6   < \         P                  ! R  SV 4      # )c                     V! V 4      # r   r   )rG  gs   &&r%   <lambda>5make_xp_test_case.<locals>.<lambda>.<locals>.<lambda>m  s    adr'   )	functoolsreduce)rW  rV  s   &r%   r`  #make_xp_test_case.<locals>.<lambda>m  s    	(():E4Hr'   )rL  r[  )r?  rU  rV  s   $*@r%   make_xp_test_casere  X  s1    3E3M/1 " "5P=OPEHHr'   c               f    ^ RI p\        WR7      pVP                  ! V .VO5RVRV P                  / # )a  Variant of ``make_xp_test_case`` that returns a pytest.param for a function,
with all necessary skip_xp_backends and xfail_xp_backends marks applied::

    @pytest.mark.parametrize(
        "func", [make_xp_pytest_param(f1), make_xp_pytest_param(f2)]
    )
    def test(func, xp):
        ...

The above is equivalent to::

    @pytest.mark.parametrize(
        "func", [
            pytest.param(f1, marks=[
                pytest.mark.skip_xp_backends(...),
                pytest.mark.xfail_xp_backends(...), ...]),
            pytest.param(f2, marks=[
                pytest.mark.skip_xp_backends(...),
                pytest.mark.xfail_xp_backends(...), ...]),
    )
    def test(func, xp):
        ...

Parameters
----------
func : Callable
    Function to be tested. It must be decorated with ``@xp_capabilities``.
*args : Any, optional
    Extra pytest parameters for the use case, e.g.::

    @pytest.mark.parametrize("func,verb", [
        make_xp_pytest_param(f1, "hello"),
        make_xp_pytest_param(f2, "world")])
    def test(func, verb, xp):
        # iterates on (func=f1, verb="hello")
        # and (func=f2, verb="world")

See Also
--------
xp_capabilities
make_xp_test_case
array_api_extra.testing.lazy_xp_function
N)r?  rV  id)rj   r[  r   r   )rW  r?  r   rj   rV  s   &$*  r%   make_xp_pytest_paramrh  p  s4    X !$NE<<CtC5CT]]CCr'   c                    V ^8  d   Qh/ ^ \         9   d   \        \        ,          ;R&   ^\         9   d
   \        ;R&   ^\         9   d
   \        ;R&   ^\         9   d   \        \
        ,          ;R&   # )r   r   r#   r"   rc   )__conditional_annotations__r   rS   r   r   r   )r$   s   "r%   r&   r&      sg      j G Ft Fk~  y @ - ,9 ,Ah G FJz* Fir'   )rX   rH   r   r   rg   rp   r   r  is_array_api_strictr   r   r   rU   r   r   r   r   r   r   r   r^   r  r   xp_sizer   r   rN  r   r   ra   r   )   )   r   )	r   r   FFr   FTr   N)_rj  rE  rk   r  rb  osr:  collections.abcr   r   r   r   contextvarsr   typesr   typingr	   r
   r   r   r+   numpy.typingnpt
scipy._libr   scipy._lib.array_api_compatr   r   r   rl  rF   r   r  r   rU   r   r   r   r   r   r   r   r|   r   rk  scipy._lib._sparser   scipy._lib._docscraper   __all__environrw   r   r   rE   r#   r"   r;   rB   rH   rX   r^   rc   rg   rp   r   ry   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  	dataclassr
  r8  r>  rN  r[  re  rh  rL  r&   )rj  s   @r%   <module>r}     s      	  9 9 % "  * *   '    ( -	 !jjnn->F Fzz~~ne4 L  s}},	 ,5p$N, !%, #, , ,^) )8 .8-F  F( ( 3%"&%48%FJ%%P($K K$ K $K/3K=?KDHK,BT B B4 B $B26BAEBB#'B@Jt J J#J.2J<>JHLJQUJ.**F3.H37H$)H '(H ,0	H4 T  /A /Ad;1 ;1e ;1|#
 E"% % #%,0f!0A 	A A &(A A "A +/A <>A A A '+AHT >I I0/D /Df  r'   