@@ -192,20 +192,19 @@ def support_point(op, rv, *dist_params):
192192 return new_cls
193193
194194
195- class _class_or_instancemethod ( classmethod ):
196- """Allow a method to be called both as a classmethod and an instancemethod .
195+ class _class_or_instance_property ( property ):
196+ """Allow a property to be accessed from a class or an instance .
197197
198- Priority is given to the instancemethod .
198+ Priority is given to the instance .
199199
200200 This is used to allow extracting information from the signature of a SymbolicRandomVariable
201- which may be provided either as a class attribute or as an instance attribute.
201+ which may be available early as a class attribute or only later as an instance attribute.
202202
203- Adapted from https://stackoverflow.com/a/28238047
203+ Adapted from https://stackoverflow.com/a/13624858
204204 """
205205
206- def __get__ (self , instance , type_ ):
207- descr_get = super ().__get__ if instance is None else self .__func__ .__get__
208- return descr_get (instance , type_ )
206+ def __get__ (self , owner_self , owner_cls ):
207+ return self .fget (owner_self if owner_self is not None else owner_cls )
209208
210209
211210class SymbolicRandomVariable (MeasurableOp , OpFromGraph ):
@@ -241,8 +240,7 @@ class SymbolicRandomVariable(MeasurableOp, OpFromGraph):
241240 _print_name : tuple [str , str ] = ("Unknown" , "\\ operatorname{Unknown}" )
242241 """Tuple of (name, latex name) used for for pretty-printing variables of this type"""
243242
244- @_class_or_instancemethod
245- @property
243+ @_class_or_instance_property
246244 def signature (cls_or_self ) -> None | str :
247245 # Convert "expanded" signature into "vanilla" signature that has no rng and size tokens
248246 extended_signature = cls_or_self .extended_signature
@@ -257,40 +255,28 @@ def signature(cls_or_self) -> None | str:
257255
258256 return signature
259257
260- @_class_or_instancemethod
261- @property
258+ @_class_or_instance_property
262259 def ndims_params (cls_or_self ) -> Sequence [int ] | None :
263- """Number of core dimensions of the distribution's parameters."""
260+ """Return number of core dimensions of the distribution's parameters."""
264261 signature = cls_or_self .signature
265262 if signature is None :
266263 return None
267264 inputs_signature , _ = _parse_gufunc_signature (signature )
268265 return [len (sig ) for sig in inputs_signature ]
269266
270- @_class_or_instancemethod
271- @property
267+ @_class_or_instance_property
272268 def ndim_supp (cls_or_self ) -> int | None :
273- """Number of support dimensions of the RandomVariable.
269+ """Return number of support dimensions of the RandomVariable.
274270
275271 (0 for scalar, 1 for vector, ...)
276272 """
277273 signature = cls_or_self .signature
278274 if signature is None :
279- return None
275+ return getattr ( cls_or_self , "_ndim_supp" , None )
280276 _ , outputs_params_signature = _parse_gufunc_signature (signature )
281277 return max (len (out_sig ) for out_sig in outputs_params_signature )
282278
283- @_class_or_instancemethod
284- def _parse_extended_signature (cls_or_self ) -> tuple [tuple [str , ...], tuple [str , ...]] | None :
285- extended_signature = cls_or_self .extended_signature
286- if extended_signature is None :
287- return None
288-
289- fake_signature = extended_signature .replace ("[rng]" , "(rng)" ).replace ("[size]" , "(size)" )
290- return _parse_gufunc_signature (fake_signature )
291-
292- @_class_or_instancemethod
293- @property
279+ @_class_or_instance_property
294280 def default_output (cls_or_self ) -> int | None :
295281 extended_signature = cls_or_self .extended_signature
296282 if extended_signature is None :
@@ -374,7 +360,7 @@ def __init__(
374360 if "ndim_supp" in kwargs :
375361 # For backwards compatibility we allow passing ndim_supp without signature
376362 # This is the only variable that PyMC absolutely needs to work with SymbolicRandomVariables
377- self .ndim_supp = kwargs .pop ("ndim_supp" )
363+ self ._ndim_supp = kwargs .pop ("ndim_supp" )
378364
379365 if self .ndim_supp is None :
380366 raise ValueError ("ndim_supp or signature must be provided" )
0 commit comments