diff --git a/param/parameterized.py b/param/parameterized.py index ac0df034..8844d238 100644 --- a/param/parameterized.py +++ b/param/parameterized.py @@ -29,6 +29,7 @@ from itertools import chain from operator import itemgetter, attrgetter from types import FunctionType, MethodType +from typing import TypeVar, Generic from contextlib import contextmanager from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL @@ -52,6 +53,8 @@ gen_types, ) +T = TypeVar("T") + # Ideally setting param_pager would be in __init__.py but param_pager is # needed on import to create the Parameterized class, so it'd need to precede # importing parameterized.py in __init__.py which would be a little weird. @@ -1005,7 +1008,9 @@ def _sorter(p): cls.__signature__ = new_sig -class Parameter(_ParameterBase): + + +class Parameter(Generic[T], _ParameterBase): """ An attribute descriptor for declaring parameters. @@ -1431,7 +1436,7 @@ def _update_state(self): values, after the slot values have been set in the inheritance procedure. """ - def __get__(self, obj, objtype): # pylint: disable-msg=W0613 + def __get__(self, obj, objtype) -> T: """ Return the value for this Parameter. @@ -1455,7 +1460,7 @@ def __get__(self, obj, objtype): # pylint: disable-msg=W0613 return result @instance_descriptor - def __set__(self, obj, val): + def __set__(self, obj, val: T) -> None: """ Set the value for this Parameter. @@ -1603,7 +1608,7 @@ def __setstate__(self,state): # Define one particular type of Parameter that is used in this file -class String(Parameter): +class String(Parameter[T]): r""" A String Parameter, with a default value and optional regular expression (regex) matching. @@ -1624,7 +1629,7 @@ def __init__(self, default="0.0.0.0", allow_None=False, **kwargs): @typing.overload def __init__( self, - default="", *, regex=None, + default: T = "", *, regex=None, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, allow_None=False, per_instance=True, allow_refs=False, nested_refs=False @@ -1632,7 +1637,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, regex=Undefined, **kwargs): + def __init__(self, default: T = Undefined, *, regex=Undefined, **kwargs): super().__init__(default=default, **kwargs) self.regex = regex self._validate(self.default) diff --git a/param/parameters.py b/param/parameters.py index 0259e2ae..508159ac 100644 --- a/param/parameters.py +++ b/param/parameters.py @@ -15,6 +15,7 @@ parameter types (e.g. Number), and also imports the definition of Parameters and Parameterized classes. """ +from __future__ import annotations import collections import copy @@ -36,7 +37,7 @@ from .parameterized import ( Parameterized, Parameter, ParameterizedFunction, ParamOverrides, String, Undefined, get_logger, instance_descriptor, _dt_types, - _int_types, _identity_hook + _int_types, _identity_hook, T ) from ._utils import ( ParamFutureWarning as _ParamFutureWarning, @@ -451,7 +452,7 @@ def __exit__(self, exc, *args): #----------------------------------------------------------------------------- -class Dynamic(Parameter): +class Dynamic(Parameter[T]): """ Parameter whose value can be generated dynamically by a callable object. @@ -481,14 +482,14 @@ class Dynamic(Parameter): @typing.overload def __init__( - self, default=None, *, + self, default: T = None, *, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, allow_None=False, per_instance=True, allow_refs=False, nested_refs=False ): ... - def __init__(self, default=Undefined, **params): + def __init__(self, default: T = Undefined, **params): """ Call the superclass's __init__ and set instantiate=True if the default is dynamic. @@ -515,7 +516,7 @@ def _initialize_generator(self,gen,obj=None): gen._saved_Dynamic_time = [] - def __get__(self,obj,objtype): + def __get__(self, obj, objtype) -> T: """ Call the superclass's __get__; if the result is not dynamic return that result, otherwise ask that result to produce a @@ -530,7 +531,7 @@ def __get__(self,obj,objtype): @instance_descriptor - def __set__(self,obj,val): + def __set__(self, obj, val: T) -> None: """ Call the superclass's set and keep this parameter's instantiate value up to date (dynamic parameters @@ -624,7 +625,7 @@ def sig(self): _compute_set_hook = __compute_set_hook() -class Number(Dynamic): +class Number(Dynamic[T]): """ A numeric Dynamic Parameter, with a default value and optional bounds. @@ -679,7 +680,7 @@ class Number(Dynamic): @typing.overload def __init__( self, - default=0.0, *, bounds=None, softbounds=None, inclusive_bounds=(True,True), step=None, set_hook=None, + default: T = 0.0, *, bounds=None, softbounds=None, inclusive_bounds=(True,True), step=None, set_hook=None, allow_None=False, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -687,7 +688,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, bounds=Undefined, softbounds=Undefined, + def __init__(self, default: T =Undefined, *, bounds=Undefined, softbounds=Undefined, inclusive_bounds=Undefined, step=Undefined, set_hook=Undefined, **params): """ Initialize this parameter object and store the bounds. @@ -702,7 +703,7 @@ def __init__(self, default=Undefined, *, bounds=Undefined, softbounds=Undefined, self.step = step self._validate(self.default) - def __get__(self, obj, objtype): + def __get__(self, obj, objtype) -> T: """ Same as the superclass's __get__, but if the value was dynamically generated, check the bounds. @@ -838,11 +839,24 @@ def __setstate__(self,state): -class Integer(Number): +class Integer(Number[T]): """Numeric Parameter required to be an Integer""" _slot_defaults = dict(Number._slot_defaults, default=0) + @typing.overload + def __init__( + self, + default: T = 0, *, bounds=None, softbounds=None, inclusive_bounds=(True,True), step=None, set_hook=None, + allow_None=False, doc=None, label=None, precedence=None, instantiate=False, + constant=False, readonly=False, pickle_default_value=True, per_instance=True, + allow_refs=False, nested_refs=False + ): + ... + + def __init__(self, default: T = Undefined, *args, **kwargs): + super().__init__(default=default, *args, **kwargs) + def _validate_value(self, val, allow_None): if callable(val): return @@ -864,7 +878,7 @@ def _validate_step(self, val, step): ) -class Magnitude(Number): +class Magnitude(Number[T]): """Numeric Parameter required to be in the range [0.0-1.0].""" _slot_defaults = dict(Number._slot_defaults, default=1.0, bounds=(0.0,1.0)) @@ -872,14 +886,14 @@ class Magnitude(Number): @typing.overload def __init__( self, - default=1.0, *, bounds=(0.0, 1.0), softbounds=None, inclusive_bounds=(True,True), step=None, set_hook=None, + default: T = 1.0, *, bounds=(0.0, 1.0), softbounds=None, inclusive_bounds=(True,True), step=None, set_hook=None, allow_None=False, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False ): ... - def __init__(self, default=Undefined, *, bounds=Undefined, softbounds=Undefined, + def __init__(self, default: T = Undefined, *, bounds=Undefined, softbounds=Undefined, inclusive_bounds=Undefined, step=Undefined, set_hook=Undefined, **params): super().__init__( default=default, bounds=bounds, softbounds=softbounds, @@ -887,7 +901,7 @@ def __init__(self, default=Undefined, *, bounds=Undefined, softbounds=Undefined, ) -class Date(Number): +class Date(Number[T]): """Date parameter of datetime or date type.""" _slot_defaults = dict(Number._slot_defaults, default=None) @@ -895,14 +909,14 @@ class Date(Number): @typing.overload def __init__( self, - default=None, *, bounds=None, softbounds=None, inclusive_bounds=(True,True), step=None, set_hook=None, + default: T = None, *, bounds=None, softbounds=None, inclusive_bounds=(True,True), step=None, set_hook=None, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, allow_None=False, per_instance=True, allow_refs=False, nested_refs=False ): ... - def __init__(self, default=Undefined, **kwargs): + def __init__(self, default: T = Undefined, **kwargs): super().__init__(default=default, **kwargs) def _validate_value(self, val, allow_None): @@ -946,7 +960,7 @@ def deserialize(cls, value): return dt.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f") -class CalendarDate(Number): +class CalendarDate(Number[T]): """Parameter specifically allowing dates (not datetimes).""" _slot_defaults = dict(Number._slot_defaults, default=None) @@ -954,14 +968,14 @@ class CalendarDate(Number): @typing.overload def __init__( self, - default=None, *, bounds=None, softbounds=None, inclusive_bounds=(True,True), step=None, set_hook=None, + default: T = None, *, bounds=None, softbounds=None, inclusive_bounds=(True,True), step=None, set_hook=None, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, allow_None=False, per_instance=True, allow_refs=False, nested_refs=False ): ... - def __init__(self, default=Undefined, **kwargs): + def __init__(self, default: T = Undefined, **kwargs): super().__init__(default=default, **kwargs) def _validate_value(self, val, allow_None): @@ -1000,7 +1014,7 @@ def deserialize(cls, value): # Boolean #----------------------------------------------------------------------------- -class Boolean(Parameter): +class Boolean(Parameter[T]): """Binary or tristate Boolean Parameter.""" _slot_defaults = dict(Parameter._slot_defaults, default=False) @@ -1008,7 +1022,7 @@ class Boolean(Parameter): @typing.overload def __init__( self, - default=False, *, + default: T = False, *, allow_None=False, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -1016,7 +1030,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, **params): + def __init__(self, default: T = Undefined, **params): super().__init__(default=default, **params) self._validate(self.default) @@ -1037,7 +1051,7 @@ def _validate(self, val): self._validate_value(val, self.allow_None) -class Event(Boolean): +class Event(Boolean[T]): """ An Event Parameter is one whose value is intimately linked to the triggering of events for watchers to consume. Event has a Boolean @@ -1061,7 +1075,7 @@ class Event(Boolean): @typing.overload def __init__( self, - default=False, *, + default: T = False, *, allow_None=False, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -1069,7 +1083,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self,default=False,**params): + def __init__(self, default: T = False, **params): self._autotrigger_value = True self._autotrigger_reset_value = False self._mode = 'set-reset' @@ -1099,7 +1113,7 @@ def _reset_event(self, obj, val): self._post_setter(obj, val) @instance_descriptor - def __set__(self, obj, val): + def __set__(self, obj, val: T) -> None: if self._mode in ['set-reset', 'set']: super().__set__(obj, val) if self._mode in ['set-reset', 'reset']: @@ -1124,7 +1138,7 @@ def sig(self): _compute_length_of_default = __compute_length_of_default() -class Tuple(Parameter): +class Tuple(Parameter[T]): """A tuple Parameter (e.g. ('a',7.6,[3,5])) with a fixed tuple length.""" __slots__ = ['length'] @@ -1134,7 +1148,7 @@ class Tuple(Parameter): @typing.overload def __init__( self, - default=(0,0), *, length=None, + default: T = (0,0), *, length=None, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, allow_None=False, per_instance=True, allow_refs=False, nested_refs=False @@ -1142,7 +1156,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, length=Undefined, **params): + def __init__(self, default: T = Undefined, *, length=Undefined, **params): """ Initialize a tuple parameter with a fixed length (number of elements). The length is determined by the initial default @@ -1198,7 +1212,7 @@ def deserialize(cls, value): return tuple(value) # As JSON has no tuple representation -class NumericTuple(Tuple): +class NumericTuple(Tuple[T]): """A numeric tuple Parameter (e.g. (4.5,7.6,3)) with a fixed tuple length.""" def _validate_value(self, val, allow_None): @@ -1214,7 +1228,7 @@ def _validate_value(self, val, allow_None): ) -class XYCoordinates(NumericTuple): +class XYCoordinates(NumericTuple[T]): """A NumericTuple for an X,Y coordinate.""" _slot_defaults = dict(NumericTuple._slot_defaults, default=(0.0, 0.0)) @@ -1222,18 +1236,18 @@ class XYCoordinates(NumericTuple): @typing.overload def __init__( self, - default=(0.0, 0.0), *, length=None, + default: T = (0.0, 0.0), *, length=None, allow_None=False, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False ): ... - def __init__(self, default=Undefined, **params): + def __init__(self, default: T = Undefined, **params): super().__init__(default=default, length=2, **params) -class Range(NumericTuple): +class Range(NumericTuple[T]): """A numeric range with optional bounds and softbounds.""" __slots__ = ['bounds', 'inclusive_bounds', 'softbounds', 'step'] @@ -1246,7 +1260,7 @@ class Range(NumericTuple): @typing.overload def __init__( self, - default=None, *, bounds=None, softbounds=None, inclusive_bounds=(True,True), step=None, length=None, + default: T = None, *, bounds=None, softbounds=None, inclusive_bounds=(True,True), step=None, length=None, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, allow_None=False, per_instance=True, allow_refs=False, nested_refs=False @@ -1254,7 +1268,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, bounds=Undefined, softbounds=Undefined, + def __init__(self, default: T = Undefined, *, bounds=Undefined, softbounds=Undefined, inclusive_bounds=Undefined, step=Undefined, **params): self.bounds = bounds self.inclusive_bounds = inclusive_bounds @@ -1464,7 +1478,7 @@ def deserialize(cls, value): # Callable #----------------------------------------------------------------------------- -class Callable(Parameter): +class Callable(Parameter[T]): """ Parameter holding a value that is a callable object, such as a function. @@ -1477,7 +1491,7 @@ class Callable(Parameter): @typing.overload def __init__( self, - default=None, *, + default: T = None, *, allow_None=False, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -1485,7 +1499,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, **params): + def __init__(self, default: T = Undefined, **params): super().__init__(default=default, **params) self._validate(self.default) @@ -1546,7 +1560,7 @@ def __init__(self, *, attribs=Undefined, **kw): super().__init__(default=Undefined, **kw) self.attribs = attribs - def __get__(self, obj, objtype): + def __get__(self, obj, objtype) -> T: """Return the values of all the attribs, as a list.""" if obj is None: return [getattr(objtype, a) for a in self.attribs] @@ -1576,7 +1590,7 @@ def _post_setter(self, obj, val): # Selector #----------------------------------------------------------------------------- -class SelectorBase(Parameter): +class SelectorBase(Parameter[T]): """ Parameter whose value must be chosen from a list of possibilities. @@ -1811,7 +1825,7 @@ def _modified_slots_defaults(cls): return defaults -class Selector(SelectorBase, _SignatureSelector): +class Selector(SelectorBase[T], _SignatureSelector): """ Parameter whose value must be one object from a list of possible objects. @@ -1845,7 +1859,7 @@ class Selector(SelectorBase, _SignatureSelector): @typing.overload def __init__( self, - *, objects=[], default=None, instantiate=False, compute_default_fn=None, + *, objects=[], default: T = None, instantiate=False, compute_default_fn=None, check_on_set=None, allow_None=None, empty_default=False, doc=None, label=None, precedence=None, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -1855,7 +1869,7 @@ def __init__( # Selector is usually used to allow selection from a list of # existing objects, therefore instantiate is False by default. @_deprecate_positional_args - def __init__(self, *, objects=Undefined, default=Undefined, instantiate=Undefined, + def __init__(self, *, objects=Undefined, default: T = Undefined, instantiate=Undefined, compute_default_fn=Undefined, check_on_set=Undefined, allow_None=Undefined, empty_default=False, **params): @@ -1981,7 +1995,7 @@ def __init__(self, default=Undefined, *, objects=Undefined, **kwargs): empty_default=True, **kwargs) -class FileSelector(Selector): +class FileSelector(Selector[T]): """Given a path glob, allows one file to be selected from those matching.""" __slots__ = ['path'] @@ -1993,7 +2007,7 @@ class FileSelector(Selector): @typing.overload def __init__( self, - default=None, *, path="", objects=[], instantiate=False, compute_default_fn=None, + default: T =None, *, path="", objects=[], instantiate=False, compute_default_fn=None, check_on_set=None, allow_None=None, empty_default=False, doc=None, label=None, precedence=None, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -2001,7 +2015,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, path=Undefined, **kwargs): + def __init__(self, default: T = Undefined, *, path=Undefined, **kwargs): self.default = default self.path = path self.update(path=path) @@ -2032,7 +2046,7 @@ def get_range(self): return _abbreviate_paths(self.path,super().get_range()) -class ListSelector(Selector): +class ListSelector(Selector[T]): """ Variant of Selector where the value can be multiple objects from a list of possible objects. @@ -2041,7 +2055,7 @@ class ListSelector(Selector): @typing.overload def __init__( self, - default=None, *, objects=[], instantiate=False, compute_default_fn=None, + default: T =None, *, objects=[], instantiate=False, compute_default_fn=None, check_on_set=None, allow_None=None, empty_default=False, doc=None, label=None, precedence=None, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -2049,7 +2063,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, objects=Undefined, **kwargs): + def __init__(self, default: T = Undefined, *, objects=Undefined, **kwargs): super().__init__( objects=objects, default=default, empty_default=True, **kwargs) @@ -2090,7 +2104,7 @@ def _update_state(self): self._ensure_value_is_in_objects(o) -class MultiFileSelector(ListSelector): +class MultiFileSelector(ListSelector[T]): """Given a path glob, allows multiple files to be selected from the list of matches.""" __slots__ = ['path'] @@ -2102,7 +2116,7 @@ class MultiFileSelector(ListSelector): @typing.overload def __init__( self, - default=None, *, path="", objects=[], compute_default_fn=None, + default: T = None, *, path="", objects=[], compute_default_fn=None, check_on_set=None, allow_None=None, empty_default=False, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, @@ -2111,7 +2125,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, path=Undefined, **kwargs): + def __init__(self, default: T = Undefined, *, path=Undefined, **kwargs): self.default = default self.path = path self.update(path=path) @@ -2136,7 +2150,7 @@ def get_range(self): return _abbreviate_paths(self.path,super().get_range()) -class ClassSelector(SelectorBase): +class ClassSelector(SelectorBase[T]): """ Parameter allowing selection of either a subclass or an instance of a class or tuple of classes. By default, requires an instance, but if is_instance=False, accepts a class instead. @@ -2151,7 +2165,7 @@ class ClassSelector(SelectorBase): @typing.overload def __init__( self, - *, class_, default=None, instantiate=True, is_instance=True, + *, class_: tuple[type[T], ...] | type[T], default: T = None, instantiate=True, is_instance=True, allow_None=False, doc=None, label=None, precedence=None, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -2159,7 +2173,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, *, class_, default=Undefined, instantiate=Undefined, is_instance=Undefined, **params): + def __init__(self, *, class_: tuple[type[T], ...] | type[T], default: T = Undefined, instantiate=Undefined, is_instance=Undefined, **params): self.class_ = class_ self.is_instance = is_instance super().__init__(default=default,instantiate=instantiate,**params) @@ -2211,31 +2225,31 @@ class Dict(ClassSelector): @typing.overload def __init__( self, - default=None, *, is_instance=True, + default: T = None, *, is_instance=True, allow_None=False, doc=None, label=None, precedence=None, instantiate=True, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False ): ... - def __init__(self, default=Undefined, **params): + def __init__(self, default: T = Undefined, **params): super().__init__(default=default, class_=dict, **params) -class Array(ClassSelector): +class Array(ClassSelector[T]): """Parameter whose value is a numpy array.""" @typing.overload def __init__( self, - default=None, *, is_instance=True, + default: T = None, *, is_instance=True, allow_None=False, doc=None, label=None, precedence=None, instantiate=True, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False ): ... - def __init__(self, default=Undefined, **params): + def __init__(self, default: T = Undefined, **params): from numpy import ndarray super().__init__(default=default, class_=ndarray, **params) @@ -2259,7 +2273,7 @@ def deserialize(cls, value): return numpy.asarray(value) -class DataFrame(ClassSelector): +class DataFrame(ClassSelector[T]): """ Parameter whose value is a pandas DataFrame. @@ -2287,7 +2301,7 @@ class DataFrame(ClassSelector): @typing.overload def __init__( self, - default=None, *, rows=None, columns=None, ordered=None, is_instance=True, + default: T =None, *, rows=None, columns=None, ordered=None, is_instance=True, allow_None=False, doc=None, label=None, precedence=None, instantiate=True, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -2295,7 +2309,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, rows=Undefined, columns=Undefined, ordered=Undefined, **params): + def __init__(self, default: T = Undefined, *, rows=Undefined, columns=Undefined, ordered=Undefined, **params): from pandas import DataFrame as pdDFrame self.rows = rows self.columns = columns @@ -2385,7 +2399,7 @@ def deserialize(cls, value): return pandas.DataFrame(value) -class Series(ClassSelector): +class Series(ClassSelector[T]): """ Parameter whose value is a pandas Series. @@ -2403,7 +2417,7 @@ class Series(ClassSelector): @typing.overload def __init__( self, - default=None, *, rows=None, allow_None=False, is_instance=True, + default: T = None, *, rows=None, allow_None=False, is_instance=True, doc=None, label=None, precedence=None, instantiate=True, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -2411,7 +2425,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, rows=Undefined, allow_None=Undefined, **params): + def __init__(self, default: T = Undefined, *, rows=Undefined, allow_None=Undefined, **params): from pandas import Series as pdSeries self.rows = rows super().__init__(default=default, class_=pdSeries, allow_None=allow_None, @@ -2444,7 +2458,7 @@ def _validate(self, val): # List #----------------------------------------------------------------------------- -class List(Parameter): +class List(Parameter[T]): """ Parameter whose value is a list of objects, usually of a specified type. @@ -2467,7 +2481,7 @@ class List(Parameter): @typing.overload def __init__( self, - default=[], *, class_=None, item_type=None, instantiate=True, bounds=(0, None), + default: T = [], *, class_=None, item_type=None, instantiate=True, bounds=(0, None), allow_None=False, doc=None, label=None, precedence=None, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -2475,7 +2489,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, class_=Undefined, item_type=Undefined, + def __init__(self, default: T = Undefined, *, class_=Undefined, item_type=Undefined, instantiate=Undefined, bounds=Undefined, **params): if class_ is not Undefined: # PARAM3_DEPRECATION @@ -2670,7 +2684,7 @@ def __call__(self,path="",**params): -class Path(Parameter): +class Path(Parameter[T]): """ Parameter that can be set to a string specifying the path of a file or folder. @@ -2708,7 +2722,7 @@ class Path(Parameter): @typing.overload def __init__( self, - default=None, *, search_paths=None, check_exists=True, + default: T = None, *, search_paths=None, check_exists=True, allow_None=False, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -2716,7 +2730,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, search_paths=Undefined, check_exists=Undefined, **params): + def __init__(self, default: T = Undefined, *, search_paths=Undefined, check_exists=Undefined, **params): if search_paths is Undefined: search_paths = [] @@ -2743,7 +2757,7 @@ def _validate(self, val): if self.check_exists: raise OSError(e.args[0]) from None - def __get__(self, obj, objtype): + def __get__(self, obj, objtype) -> T: """Return an absolute, normalized path (see resolve_path).""" raw_path = super().__get__(obj,objtype) if raw_path is None: @@ -2816,7 +2830,7 @@ def _resolve(self, path): # Color #----------------------------------------------------------------------------- -class Color(Parameter): +class Color(Parameter[T]): """ Color parameter defined as a hex RGB string with an optional # prefix or (optionally) as a CSS3 color name. @@ -2866,7 +2880,7 @@ class Color(Parameter): @typing.overload def __init__( self, - default=None, *, allow_named=True, + default: T = None, *, allow_named=True, allow_None=False, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -2874,7 +2888,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, allow_named=Undefined, **kwargs): + def __init__(self, default: T = Undefined, *, allow_named=Undefined, **kwargs): super().__init__(default=default, **kwargs) self.allow_named = allow_named self._validate(self.default) @@ -2912,7 +2926,7 @@ def _validate_allow_named(self, val, allow_named): # Bytes #----------------------------------------------------------------------------- -class Bytes(Parameter): +class Bytes(Parameter[T]): """ A Bytes Parameter, with a default value and optional regular expression (regex) matching. @@ -2931,7 +2945,7 @@ class Bytes(Parameter): @typing.overload def __init__( self, - default=b"", *, regex=None, allow_None=False, + default: T = b"", *, regex=None, allow_None=False, doc=None, label=None, precedence=None, instantiate=False, constant=False, readonly=False, pickle_default_value=True, per_instance=True, allow_refs=False, nested_refs=False @@ -2939,7 +2953,7 @@ def __init__( ... @_deprecate_positional_args - def __init__(self, default=Undefined, *, regex=Undefined, allow_None=Undefined, **kwargs): + def __init__(self, default: T = Undefined, *, regex=Undefined, allow_None=Undefined, **kwargs): super().__init__(default=default, **kwargs) self.regex = regex self._validate(self.default)