param 2.4.0rc2__tar.gz → 2.4.1rc0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. {param-2.4.0rc2 → param-2.4.1rc0}/.gitignore +1 -1
  2. {param-2.4.0rc2 → param-2.4.1rc0}/PKG-INFO +1 -1
  3. {param-2.4.0rc2 → param-2.4.1rc0}/numbergen/__init__.py +8 -8
  4. {param-2.4.0rc2 → param-2.4.1rc0}/param/_utils.py +3 -1
  5. {param-2.4.0rc2 → param-2.4.1rc0}/param/_version.py +2 -2
  6. {param-2.4.0rc2 → param-2.4.1rc0}/param/ipython.py +1 -1
  7. param-2.4.1rc0/param/mypy_plugin.py +95 -0
  8. {param-2.4.0rc2 → param-2.4.1rc0}/param/parameterized.py +14 -14
  9. {param-2.4.0rc2 → param-2.4.1rc0}/param/parameters.py +15 -13
  10. {param-2.4.0rc2 → param-2.4.1rc0}/param/version.py +2 -2
  11. {param-2.4.0rc2 → param-2.4.1rc0}/pyproject.toml +20 -2
  12. {param-2.4.0rc2 → param-2.4.1rc0}/tests/assert_types.py +25 -25
  13. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testdefaultfactory.py +1 -1
  14. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testfiledeserialization.py +1 -1
  15. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testparameterizedobject.py +9 -9
  16. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testparameterizedrepr.py +1 -1
  17. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testpathparam.py +2 -2
  18. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testreactive.py +3 -3
  19. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testsignatures.py +3 -3
  20. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testwatch.py +1 -1
  21. {param-2.4.0rc2 → param-2.4.1rc0}/LICENSE.txt +0 -0
  22. {param-2.4.0rc2 → param-2.4.1rc0}/README.md +0 -0
  23. {param-2.4.0rc2 → param-2.4.1rc0}/param/__init__.py +0 -0
  24. {param-2.4.0rc2 → param-2.4.1rc0}/param/depends.py +0 -0
  25. {param-2.4.0rc2 → param-2.4.1rc0}/param/display.py +0 -0
  26. {param-2.4.0rc2 → param-2.4.1rc0}/param/py.typed +0 -0
  27. {param-2.4.0rc2 → param-2.4.1rc0}/param/reactive.py +0 -0
  28. {param-2.4.0rc2 → param-2.4.1rc0}/param/serializer.py +0 -0
  29. {param-2.4.0rc2 → param-2.4.1rc0}/tests/__init__.py +0 -0
  30. {param-2.4.0rc2 → param-2.4.1rc0}/tests/conftest.py +0 -0
  31. {param-2.4.0rc2 → param-2.4.1rc0}/tests/pyrightconfig-bare.json +0 -0
  32. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testaddparameter.py +0 -0
  33. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testbind.py +0 -0
  34. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testbooleanparam.py +0 -0
  35. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testbytesparam.py +0 -0
  36. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testcalendardateparam.py +0 -0
  37. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testcalendardaterangeparam.py +0 -0
  38. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testcallable.py +0 -0
  39. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testclassselector.py +0 -0
  40. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testcolorparameter.py +0 -0
  41. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testcomparator.py +0 -0
  42. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testcompositeparams.py +0 -0
  43. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testcustomparam.py +0 -0
  44. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testdateparam.py +0 -0
  45. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testdaterangeparam.py +0 -0
  46. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testdefaults.py +0 -0
  47. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testdeprecations.py +0 -0
  48. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testdynamicparams.py +0 -0
  49. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testfileselector.py +0 -0
  50. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testimports.py +0 -0
  51. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testipythonmagic.py +0 -0
  52. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testjsonserialization.py +0 -0
  53. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testlist.py +0 -0
  54. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testlistselector.py +0 -0
  55. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testmultifileselector.py +0 -0
  56. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testnumbergen.py +0 -0
  57. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testnumberparameter.py +0 -0
  58. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testnumpy.py +0 -0
  59. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testobjectselector.py +0 -0
  60. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testpandas.py +0 -0
  61. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testparamdepends.py +0 -0
  62. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testparameter.py +0 -0
  63. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testparamoutput.py +0 -0
  64. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testparamunion.py +0 -0
  65. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testpickle.py +0 -0
  66. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testrangeparameter.py +0 -0
  67. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testrefs.py +0 -0
  68. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testreprhtml.py +0 -0
  69. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testselector.py +0 -0
  70. {param-2.4.0rc2 → param-2.4.1rc0}/tests/teststringparam.py +0 -0
  71. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testtimedependent.py +0 -0
  72. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testtupleparam.py +0 -0
  73. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testutils.py +0 -0
  74. {param-2.4.0rc2 → param-2.4.1rc0}/tests/testversion.py +0 -0
  75. {param-2.4.0rc2 → param-2.4.1rc0}/tests/utils.py +0 -0
@@ -26,7 +26,7 @@ doc/reference/param/generated
26
26
  .coverage
27
27
  coverage.xml
28
28
 
29
- # Versionning
29
+ # Versioning
30
30
  param/_version.py
31
31
 
32
32
  # asv benchmark
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: param
3
- Version: 2.4.0rc2
3
+ Version: 2.4.1rc0
4
4
  Summary: Declarative parameters for robust Python classes and a rich API for reactive programming
5
5
  Project-URL: Homepage, https://param.holoviz.org/
6
6
  Project-URL: Tracker, https://github.com/holoviz/param/issues
@@ -244,21 +244,21 @@ class Hash:
244
244
  """Convert the given value to a rational, if necessary."""
245
245
  I32 = 4294967296 # Maximum 32 bit unsigned int (i.e. 'I') value
246
246
  if isinstance(val, int):
247
- numer, denom = val, 1
247
+ numerator, denominator = val, 1
248
248
  elif isinstance(val, fractions.Fraction):
249
- numer, denom = val.numerator, val.denominator
249
+ numerator, denominator = val.numerator, val.denominator
250
250
  elif hasattr(val, 'numerator') and hasattr(val, 'denominator'):
251
251
  # gmpy2 mpq objects have these attributes
252
- numer, denom = val.numerator, val.denominator
253
- elif hasattr(val, 'numer'):
252
+ numerator, denominator = val.numerator, val.denominator
253
+ elif hasattr(val, 'numer'): # typos: ignore
254
254
  # I think this branch supports gmpy (i.e. not gmpy2)
255
- (numer, denom) = (int(val.numer()), int(val.denom()))
255
+ (numerator, denominator) = (int(val.numer()), int(val.denom())) # typos: ignore
256
256
  else:
257
257
  param.main.param.log(param.WARNING, "Casting type '%s' to Fraction.fraction"
258
258
  % type(val).__name__)
259
259
  frac = fractions.Fraction(str(val))
260
- numer, denom = frac.numerator, frac.denominator
261
- return numer % I32, denom % I32
260
+ numerator, denominator = frac.numerator, frac.denominator
261
+ return numerator % I32, denominator % I32
262
262
 
263
263
  def __getstate__(self):
264
264
  """Avoid Hashlib.md5 TypeError in deepcopy (hashlib issue)."""
@@ -279,7 +279,7 @@ class Hash:
279
279
  Given integer or rational inputs, generate a cross-platform,
280
280
  architecture-independent 32-bit integer hash.
281
281
  """
282
- # Convert inputs to (numer, denom) pairs with integers
282
+ # Convert inputs to (numerator, denominator) pairs with integers
283
283
  # becoming (int, 1) pairs to match gmpy2.mpqs for int values.
284
284
  pairs = [self._rational(val) for val in vals]
285
285
  # Unpack pairs and fill struct with ints to update md5 hash
@@ -15,6 +15,8 @@ from textwrap import dedent
15
15
  from threading import get_ident
16
16
 
17
17
  if t.TYPE_CHECKING:
18
+ import asyncio
19
+
18
20
  from param.parameterized import Parameter
19
21
 
20
22
  _P = t.ParamSpec("_P")
@@ -604,7 +606,7 @@ def _in_ipython():
604
606
  except NameError:
605
607
  return False
606
608
 
607
- _running_tasks = set()
609
+ _running_tasks: set[asyncio.Task] = set()
608
610
 
609
611
  def async_executor(func):
610
612
  import asyncio
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '2.4.0rc2'
22
- __version_tuple__ = version_tuple = (2, 4, 0, 'rc2')
21
+ __version__ = version = '2.4.1rc0'
22
+ __version_tuple__ = version_tuple = (2, 4, 1, 'rc0')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -58,7 +58,7 @@ class ParamPager:
58
58
 
59
59
  def get_param_info(self, obj, include_super=True):
60
60
  """
61
- Get the parameter dictionary, the list of modifed parameters
61
+ Get the parameter dictionary, the list of modified parameters
62
62
  and the dictionary of parameter values. If include_super is
63
63
  True, parameters are also collected from the super classes.
64
64
  """
@@ -0,0 +1,95 @@
1
+ """Mypy plugin for param.
2
+
3
+ Works around mypy issue #9758: metaclass __setattr__ is not consulted
4
+ for class-level assignment to descriptor attributes. Without this plugin,
5
+ ``MyClass.flag = True`` on a Boolean parameter raises:
6
+
7
+ Incompatible types in assignment
8
+ (expression has type "bool", variable has type "Boolean[bool]")
9
+
10
+ The fix: intercept class-attribute access via get_class_attribute_hook and,
11
+ when it's an lvalue, return the Parameter's value type (the first type arg
12
+ of Parameter[_T]) instead of the raw descriptor type.
13
+
14
+ Usage: add ``plugins = ["param.mypy_plugin"]`` to your mypy configuration.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import typing as t
20
+
21
+ from mypy.nodes import TypeInfo, Var
22
+ from mypy.plugin import AttributeContext, Plugin
23
+ from mypy.types import AnyType, Instance, Type, TypeOfAny, get_proper_type
24
+
25
+
26
+ def _is_parameter_type(typ: Type) -> bool:
27
+ proper = get_proper_type(typ)
28
+ if not isinstance(proper, Instance):
29
+ return False
30
+ return any(
31
+ base.fullname == "param.parameterized.Parameter"
32
+ for base in proper.type.mro
33
+ )
34
+
35
+
36
+ def _is_parameterized_class(info: TypeInfo) -> bool:
37
+ return any(
38
+ base.fullname == "param.parameterized.Parameterized"
39
+ for base in info.mro
40
+ )
41
+
42
+
43
+ def _find_attr_in_mro(info: TypeInfo, name: str) -> Var | None:
44
+ for base in info.mro:
45
+ sym = base.names.get(name)
46
+ if sym is not None and isinstance(sym.node, Var):
47
+ return sym.node
48
+ return None
49
+
50
+
51
+ def _class_attribute_hook(ctx: AttributeContext) -> Type:
52
+ if not ctx.is_lvalue:
53
+ return ctx.default_attr_type
54
+
55
+ default_type = get_proper_type(ctx.default_attr_type)
56
+ if not isinstance(default_type, Instance):
57
+ return ctx.default_attr_type
58
+
59
+ if not _is_parameter_type(default_type):
60
+ return ctx.default_attr_type
61
+
62
+ if default_type.args:
63
+ return default_type.args[0]
64
+
65
+ return AnyType(TypeOfAny.special_form)
66
+
67
+
68
+ class _ParamPlugin(Plugin):
69
+ def get_class_attribute_hook(
70
+ self, fullname: str
71
+ ) -> t.Callable[[AttributeContext], Type] | None:
72
+ parts = fullname.rsplit(".", 1)
73
+ if len(parts) != 2:
74
+ return None
75
+ class_fullname, attr_name = parts
76
+
77
+ sym = self.lookup_fully_qualified(class_fullname)
78
+ if sym is None or not isinstance(sym.node, TypeInfo):
79
+ return None
80
+
81
+ info = sym.node
82
+ if not _is_parameterized_class(info):
83
+ return None
84
+
85
+ var = _find_attr_in_mro(info, attr_name)
86
+ if var is None or var.type is None:
87
+ return None
88
+ if not _is_parameter_type(var.type):
89
+ return None
90
+
91
+ return _class_attribute_hook
92
+
93
+
94
+ def plugin(version: str) -> type[Plugin]:
95
+ return _ParamPlugin
@@ -190,7 +190,7 @@ object_count = 0
190
190
  warning_count = 0
191
191
 
192
192
  # Hook to apply to depends and bind arguments to turn them into valid parameters
193
- _reference_transforms = []
193
+ _reference_transforms: list[t.Callable[[t.Any], t.Any]] = []
194
194
 
195
195
  def register_reference_transform(transform):
196
196
  """
@@ -1189,7 +1189,7 @@ class ParameterMetaclass(type):
1189
1189
  return type.__getattribute__(mcs, name)
1190
1190
 
1191
1191
 
1192
- _UDPATE_PARAMETER_SIGNATURE = _in_ipython() or (os.getenv("PARAM_PARAMETER_SIGNATURE", "false").lower() in ("1" , "true"))
1192
+ _UPDATE_PARAMETER_SIGNATURE = _in_ipython() or (os.getenv("PARAM_PARAMETER_SIGNATURE", "false").lower() in ("1" , "true"))
1193
1193
  _PARAMETER_CACHE_ATTRS = ('instantiate', 'constant', 'default_factory')
1194
1194
 
1195
1195
 
@@ -1208,7 +1208,7 @@ class _ParameterBase(metaclass=ParameterMetaclass):
1208
1208
  @classmethod
1209
1209
  def __init_subclass__(cls):
1210
1210
  super().__init_subclass__()
1211
- if not _UDPATE_PARAMETER_SIGNATURE:
1211
+ if not _UPDATE_PARAMETER_SIGNATURE:
1212
1212
  return
1213
1213
  # _update_signature has been tested against the Parameters available
1214
1214
  # in Param, we don't want to break the Parameters created elsewhere
@@ -1442,7 +1442,7 @@ class Parameter(_ParameterBase, t.Generic[_T]):
1442
1442
  if t.TYPE_CHECKING:
1443
1443
  @t.overload
1444
1444
  def __init__(
1445
- self,
1445
+ self: Parameter[t.Any],
1446
1446
  default: t.Any = ...,
1447
1447
  *,
1448
1448
  doc: str | None = None,
@@ -1462,7 +1462,7 @@ class Parameter(_ParameterBase, t.Generic[_T]):
1462
1462
 
1463
1463
  @t.overload
1464
1464
  def __init__(
1465
- self,
1465
+ self: Parameter[t.Any],
1466
1466
  default: t.Any | None = ...,
1467
1467
  *,
1468
1468
  allow_None: t.Literal[True] = True,
@@ -2255,7 +2255,7 @@ class String(Parameter[_T]):
2255
2255
  def _validate_regex(self, val: t.Any, regex: str | re.Pattern[str] | None):
2256
2256
  if val is None or regex is None:
2257
2257
  return
2258
- if re.fullmatch(regex, val) is None:
2258
+ if re.search(regex, val) is None:
2259
2259
  raise ValueError(
2260
2260
  f'{_validate_error_prefix(self)} value {val!r} does not '
2261
2261
  f'match regex {regex!r}.'
@@ -2323,7 +2323,7 @@ class Comparator:
2323
2323
  """
2324
2324
  Comparator defines methods for determining whether two objects
2325
2325
  should be considered equal. It works by registering custom
2326
- comparison functions, which may either be registed by type or with
2326
+ comparison functions, which may either be registered by type or with
2327
2327
  a predicate function. If no matching comparison can be found for
2328
2328
  the two objects the comparison will return False.
2329
2329
 
@@ -2761,7 +2761,7 @@ class Parameters:
2761
2761
  except Skip:
2762
2762
  pass
2763
2763
  finally:
2764
- # Ensure we clean up but only if the task matches the currrent task
2764
+ # Ensure we clean up but only if the task matches the current task
2765
2765
  if self_.self._param__private.async_refs.get(pname) is current_task:
2766
2766
  del self_.self._param__private.async_refs[pname]
2767
2767
 
@@ -3377,7 +3377,7 @@ class Parameters:
3377
3377
 
3378
3378
  Additionally, sets ``_Dynamic_time_fn=time_fn`` on this class or
3379
3379
  instance object, so that any future changes to Dynamic
3380
- Parmeters can inherit ``time_fn`` (e.g. if a :class:`param.Number` is changed
3380
+ Parameters can inherit ``time_fn`` (e.g. if a :class:`param.Number` is changed
3381
3381
  from a float to a number generator, the number generator will
3382
3382
  inherit ``time_fn``).
3383
3383
 
@@ -4659,7 +4659,7 @@ class Parameters:
4659
4659
  parameters = self.param.objects('existing')
4660
4660
  ordering = sorted(
4661
4661
  sorted(changed_params), # alphanumeric tie-breaker
4662
- key=lambda k: (- float('inf') # No precedence is lowest possible precendence
4662
+ key=lambda k: (- float('inf') # No precedence is lowest possible precedence
4663
4663
  if parameters[k].precedence is None else
4664
4664
  parameters[k].precedence))
4665
4665
 
@@ -4693,7 +4693,7 @@ class Parameters:
4693
4693
  arglist.append(value)
4694
4694
  elif k in kwargs or (spec.varkw is not None):
4695
4695
  # Explicit modified keywords or parameters in
4696
- # precendence order (if **kwargs present)
4696
+ # precedence order (if **kwargs present)
4697
4697
  keywords.append(f'{k}={value}')
4698
4698
 
4699
4699
  processed.append(k)
@@ -5121,7 +5121,7 @@ class ParameterizedMetaclass(type):
5121
5121
  f'made it invalid. Please fix the Parameter type.'
5122
5122
  )
5123
5123
  else:
5124
- # type_change and slot_overriden is not possible as when
5124
+ # type_change and slot_overridden is not possible as when
5125
5125
  # the type changes checking the slots is aborted for
5126
5126
  # performance reasons.
5127
5127
  pass
@@ -5512,7 +5512,7 @@ class _ClassPrivate:
5512
5512
  disable_instance_params: bool
5513
5513
  Whether to disable instance parameters
5514
5514
  renamed: bool
5515
- Whethe the class has been renamed by a super class
5515
+ Whether the class has been renamed by a super class
5516
5516
  params: dict
5517
5517
  Dict of parameter_name:parameter.
5518
5518
  """
@@ -5873,7 +5873,7 @@ class Parameterized(metaclass=ParameterizedMetaclass):
5873
5873
  explicit_no_refs=type(self)._param__private.explicit_no_refs
5874
5874
  )
5875
5875
  # Skip generating a custom instance name when a class in the hierarchy
5876
- # has overriden the default of the `name` Parameter.
5876
+ # has overridden the default of the `name` Parameter.
5877
5877
  if self.param.name.default == self.__class__.__name__:
5878
5878
  self.param._generate_name()
5879
5879
  refs, deps = self.param._setup_params(**params)
@@ -60,6 +60,8 @@ from ._utils import (
60
60
  #-----------------------------------------------------------------------------
61
61
 
62
62
  if t.TYPE_CHECKING:
63
+ from types import NoneType
64
+
63
65
  import numpy as np
64
66
  import pandas as pd
65
67
 
@@ -150,7 +152,7 @@ def param_union(*parameterizeds: Parameterized, warn: bool = True) -> dict[str,
150
152
  Parameters
151
153
  ----------
152
154
  warn : bool, optional
153
- Wether to warn if the same parameter have been given multiple values,
155
+ Whether to warn if the same parameter have been given multiple values,
154
156
  otherwise use the last value, by default True
155
157
 
156
158
  Returns
@@ -3175,7 +3177,7 @@ class ClassSelector(SelectorBase[_T]):
3175
3177
  # This will clobber separate classes with identical names.
3176
3178
  # Known historical issue, see https://github.com/holoviz/param/pull/1035
3177
3179
  all_classes.update({c.__name__: c for c in desc})
3178
- d = OrderedDict((name, class_) for name,class_ in all_classes.items())
3180
+ d: dict[str, type | NoneType] = OrderedDict((name, class_) for name,class_ in all_classes.items())
3179
3181
  if self.allow_None:
3180
3182
  d['None'] = None
3181
3183
  return d
@@ -3608,7 +3610,7 @@ class List(Parameter[_T]):
3608
3610
  self: List[list[LT]],
3609
3611
  default: list[LT] = [],
3610
3612
  *,
3611
- item_type: type[LT] | tuple[type[LT], ...] = (),
3613
+ item_type: type[LT] | tuple[type[LT], ...],
3612
3614
  bounds: tuple[int, int | None] | None = (0, None),
3613
3615
  is_instance: bool = True,
3614
3616
  allow_None: t.Literal[False] = False,
@@ -3632,7 +3634,7 @@ class List(Parameter[_T]):
3632
3634
  self: List[list[LT] | None],
3633
3635
  default: list[LT] | None = None,
3634
3636
  *,
3635
- item_type: type[LT] | tuple[type[LT], ...] = (),
3637
+ item_type: type[LT] | tuple[type[LT], ...],
3636
3638
  allow_None: t.Literal[True] = True,
3637
3639
  **kwargs: Unpack[_ParameterKwargs]
3638
3640
  ) -> None:
@@ -3640,21 +3642,21 @@ class List(Parameter[_T]):
3640
3642
 
3641
3643
  @t.overload
3642
3644
  def __init__(
3643
- self: List[list[t.Any] | None],
3644
- default: list[t.Any] | None = None,
3645
+ self: List[list[t.Any]],
3646
+ default: list[t.Any] = [],
3645
3647
  *,
3646
- allow_None: t.Literal[True] = True,
3648
+ item_type: None = None,
3649
+ allow_None: t.Literal[False] = False,
3647
3650
  **kwargs: Unpack[_ParameterKwargs]
3648
3651
  ) -> None:
3649
3652
  ...
3650
3653
 
3651
3654
  @t.overload
3652
3655
  def __init__(
3653
- self: List[list[t.Any]],
3654
- default: list[t.Any] = [],
3656
+ self: List[list[t.Any] | None],
3657
+ default: list[t.Any] | None = None,
3655
3658
  *,
3656
- item_type: None = None,
3657
- allow_None: t.Literal[False] = False,
3659
+ allow_None: t.Literal[True] = True,
3658
3660
  **kwargs: Unpack[_ParameterKwargs]
3659
3661
  ) -> None:
3660
3662
  ...
@@ -4236,7 +4238,7 @@ class Color(Parameter[_T]):
4236
4238
  def _validate_allow_named(self, val, allow_named):
4237
4239
  if val is None:
4238
4240
  return
4239
- is_hex = re.fullmatch('^#?(([0-9a-fA-F]{2}){3}|([0-9a-fA-F]){3})$', val)
4241
+ is_hex = re.search('^#?(([0-9a-fA-F]{2}){3}|([0-9a-fA-F]){3})$', val)
4240
4242
  if self.allow_named:
4241
4243
  if not is_hex and val.lower() not in self._named_colors:
4242
4244
  raise ValueError(
@@ -4319,7 +4321,7 @@ class Bytes(Parameter[_T]):
4319
4321
  def _validate_regex(self, val, regex):
4320
4322
  if val is None or regex is None:
4321
4323
  return
4322
- if re.fullmatch(regex, val) is None:
4324
+ if re.search(regex, val) is None:
4323
4325
  raise ValueError(
4324
4326
  f"{_validate_error_prefix(self)} value {val!r} "
4325
4327
  f"does not match regex {regex!r}."
@@ -162,7 +162,7 @@ class Version:
162
162
 
163
163
  @property
164
164
  def dirty(self):
165
- """True if there are uncommited changes, False otherwise."""
165
+ """True if there are uncommitted changes, False otherwise."""
166
166
  return self.fetch()._dirty
167
167
 
168
168
 
@@ -644,7 +644,7 @@ class OldDeprecatedVersion:
644
644
 
645
645
  @property
646
646
  def dirty(self):
647
- """True if there are uncommited changes, False otherwise."""
647
+ """True if there are uncommitted changes, False otherwise."""
648
648
  return self.fetch()._dirty
649
649
 
650
650
 
@@ -120,7 +120,7 @@ asyncio_mode = "auto"
120
120
  asyncio_default_fixture_loop_scope="function"
121
121
 
122
122
  [tool.coverage.report]
123
- omit = ["param/version.py", "tests/testimports.py"]
123
+ omit = ["param/version.py", "param/mypy_plugin.py", "tests/testimports.py"]
124
124
 
125
125
  [tool.ruff]
126
126
  fix = true
@@ -184,7 +184,7 @@ infer-with-first-use = false
184
184
 
185
185
  [tool.mypy]
186
186
  files = ["param"]
187
- follow_imports = "skip"
187
+ plugins = ["param.mypy_plugin"]
188
188
  disable_error_code = ["import-untyped", "import-not-found"]
189
189
 
190
190
  [tool.pyright]
@@ -201,3 +201,21 @@ ignore = [
201
201
  "**/node_modules",
202
202
  "**/.git",
203
203
  ]
204
+
205
+ [tool.typos.default]
206
+ extend-ignore-re = [
207
+ ".*(?:#|--|//|/*).*(?:typos):\\s?ignore[^\\n]*\\n",
208
+ ".*(?:typos):\\s?ignore-next-line[^\\n]*\\n[^\\n]*",
209
+ ]
210
+
211
+ [tool.typos.default.extend-words]
212
+ arange = "arange"
213
+ ba = "ba"
214
+ iy = "iy"
215
+ lod = "lod"
216
+ nd = "nd"
217
+ numbre = "numbre" # used as a spelling mistake in upgrade_guide.md
218
+ pn = "pn"
219
+ ser = "ser"
220
+ spreaded = "spreaded"
221
+ writeable = "writeable"
@@ -211,11 +211,11 @@ class DateTypes(param.Parameterized):
211
211
  calendar_date_param = param.CalendarDate(default=date(2024, 1, 1), allow_None=False)
212
212
  optional_calendar_date_param = param.CalendarDate(default=None, allow_None=True)
213
213
 
214
- dtypes = DateTypes()
215
- assert_type(dtypes.date_param, datetime | date)
216
- assert_type(dtypes.optional_date_param, datetime | date | None)
217
- assert_type(dtypes.calendar_date_param, date)
218
- assert_type(dtypes.optional_calendar_date_param, date | None)
214
+ datetypes = DateTypes()
215
+ assert_type(datetypes.date_param, datetime | date)
216
+ assert_type(datetypes.optional_date_param, datetime | date | None)
217
+ assert_type(datetypes.calendar_date_param, date)
218
+ assert_type(datetypes.optional_calendar_date_param, date | None)
219
219
 
220
220
  class DateRangeTypes(param.Parameterized):
221
221
  date_range = param.DateRange(
@@ -253,8 +253,8 @@ assert_type(ctypes.optional_foo, Foo | None)
253
253
  assert_type(ctypes.no_none_foo, Foo)
254
254
 
255
255
  class SelectorBaseTypes(param.Parameterized):
256
- selector_base = param.SelectorBase(default=1, allow_None=False)
257
- optional_selector_base = param.SelectorBase(default=None, allow_None=True)
256
+ selector_base = param.SelectorBase(default=1, allow_None=False) # type: ignore[var-annotated]
257
+ optional_selector_base = param.SelectorBase(default=None, allow_None=True) # type: ignore[var-annotated]
258
258
 
259
259
  sbtypes = SelectorBaseTypes()
260
260
  assert_type(sbtypes.selector_base, t.Any)
@@ -272,9 +272,9 @@ class TypeTypes(param.Parameterized):
272
272
  allow_None=True, is_instance=False, class_=Foo
273
273
  )
274
274
 
275
- ttypes = TypeTypes()
276
- assert_type(ttypes.type_param, type[Foo])
277
- assert_type(ttypes.optional_type_param, type[Foo] | None)
275
+ typtypes = TypeTypes()
276
+ assert_type(typtypes.type_param, type[Foo])
277
+ assert_type(typtypes.optional_type_param, type[Foo] | None)
278
278
 
279
279
 
280
280
  ##############
@@ -299,9 +299,9 @@ class SeriesTypes(param.Parameterized):
299
299
  series = param.Series(allow_None=False)
300
300
  optional_series = param.Series(allow_None=True)
301
301
 
302
- stypes = SeriesTypes()
303
- assert_type(stypes.series, pandas.Series)
304
- assert_type(stypes.optional_series, pandas.Series | None)
302
+ sertypes = SeriesTypes()
303
+ assert_type(sertypes.series, pandas.Series)
304
+ assert_type(sertypes.optional_series, pandas.Series | None)
305
305
 
306
306
  ###########
307
307
  # Array #
@@ -350,12 +350,12 @@ assert_type(comptypes.comp, list[t.Any])
350
350
  ##################
351
351
 
352
352
  class SelectorTypes(param.Parameterized):
353
- selector = param.Selector(objects=[1,2,3], allow_None=False)
354
- optional_selector = param.Selector(objects=[1,2,3], allow_None=True)
353
+ selector = param.Selector(objects=[1,2,3], allow_None=False) # type: ignore[var-annotated]
354
+ optional_selector = param.Selector(objects=[1,2,3], allow_None=True) # type: ignore[var-annotated]
355
355
 
356
- stypes = SelectorTypes()
357
- assert_type(stypes.selector, t.Any)
358
- assert_type(stypes.optional_selector, t.Any)
356
+ seltypes = SelectorTypes()
357
+ assert_type(seltypes.selector, t.Any)
358
+ assert_type(seltypes.optional_selector, t.Any)
359
359
 
360
360
  class ObjectSelectorTypes(param.Parameterized):
361
361
  object_selector = param.ObjectSelector(default=1, objects=[1, 2, 3], allow_None=False)
@@ -389,13 +389,13 @@ class PathTypes(param.Parameterized):
389
389
  foldername = param.Foldername(default=pathlib.Path("."), allow_None=False)
390
390
  optional_foldername = param.Foldername(default=None, allow_None=True)
391
391
 
392
- ptypes = PathTypes()
393
- assert_type(ptypes.path_param, os.PathLike | str)
394
- assert_type(ptypes.optional_path_param, os.PathLike | str | None)
395
- assert_type(ptypes.filename, os.PathLike | str)
396
- assert_type(ptypes.optional_filename, os.PathLike | str | None)
397
- assert_type(ptypes.foldername, os.PathLike | str)
398
- assert_type(ptypes.optional_foldername, os.PathLike | str | None)
392
+ pathtypes = PathTypes()
393
+ assert_type(pathtypes.path_param, os.PathLike | str)
394
+ assert_type(pathtypes.optional_path_param, os.PathLike | str | None)
395
+ assert_type(pathtypes.filename, os.PathLike | str)
396
+ assert_type(pathtypes.optional_filename, os.PathLike | str | None)
397
+ assert_type(pathtypes.foldername, os.PathLike | str)
398
+ assert_type(pathtypes.optional_foldername, os.PathLike | str | None)
399
399
 
400
400
  ##############
401
401
  # List Types #
@@ -282,7 +282,7 @@ def test_default_factory_object_auto_name():
282
282
 
283
283
  def factory(cls, self, parameter):
284
284
  if self:
285
- # When the class value is overriden.
285
+ # When the class value is overridden.
286
286
  if parameter and getattr(cls, parameter.name) != cls.__name__:
287
287
  return getattr(cls, parameter.name)
288
288
  else:
@@ -29,7 +29,7 @@ except ModuleNotFoundError:
29
29
  xlsxm = None
30
30
 
31
31
  try:
32
- import odf as ods
32
+ import odf as ods # typos: ignore
33
33
  except ModuleNotFoundError:
34
34
  ods = None
35
35
 
@@ -132,7 +132,7 @@ class TestParameterized(unittest.TestCase):
132
132
  with pytest.raises(AttributeError):
133
133
  testpo.param.const.name = 'notconst'
134
134
 
135
- def test_name_overriden(self):
135
+ def test_name_overridden(self):
136
136
  class P(param.Parameterized):
137
137
  name = param.String(default='other')
138
138
 
@@ -142,7 +142,7 @@ class TestParameterized(unittest.TestCase):
142
142
 
143
143
  assert p.name == 'other'
144
144
 
145
- def test_name_overriden_without_default(self):
145
+ def test_name_overridden_without_default(self):
146
146
  class A(param.Parameterized):
147
147
  pass
148
148
  class B(param.Parameterized):
@@ -156,7 +156,7 @@ class TestParameterized(unittest.TestCase):
156
156
  assert C.name == 'C'
157
157
  assert C.param.name.doc == 'some help'
158
158
 
159
- def test_name_overriden_constructor(self):
159
+ def test_name_overridden_constructor(self):
160
160
  class P(param.Parameterized):
161
161
  name = param.String(default='other')
162
162
 
@@ -164,7 +164,7 @@ class TestParameterized(unittest.TestCase):
164
164
 
165
165
  assert p.name == 'another'
166
166
 
167
- def test_name_overriden_subclasses(self):
167
+ def test_name_overridden_subclasses(self):
168
168
  class P(param.Parameterized):
169
169
  name = param.String(default='other')
170
170
 
@@ -195,7 +195,7 @@ class TestParameterized(unittest.TestCase):
195
195
  assert r2.name == 'last'
196
196
 
197
197
 
198
- def test_name_overriden_subclasses_name_set(self):
198
+ def test_name_overridden_subclasses_name_set(self):
199
199
  class P(param.Parameterized):
200
200
  name = param.String(default='other')
201
201
 
@@ -214,7 +214,7 @@ class TestParameterized(unittest.TestCase):
214
214
 
215
215
  assert q.name == 'yetanother'
216
216
 
217
- def test_name_overriden_error_not_String(self):
217
+ def test_name_overridden_error_not_String(self):
218
218
 
219
219
  msg = "Parameterized class 'P' cannot override the 'name' Parameter " \
220
220
  "with type <class 'str'>. Overriding 'name' is only allowed with " \
@@ -247,7 +247,7 @@ class TestParameterized(unittest.TestCase):
247
247
  assert C.name == 'C'
248
248
  assert D.name == 'D'
249
249
 
250
- def test_name_overriden_complex_hierarchy(self):
250
+ def test_name_overridden_complex_hierarchy(self):
251
251
  class Mixin1: pass
252
252
  class Mixin2: pass
253
253
  class Mixin3(param.Parameterized): pass
@@ -266,7 +266,7 @@ class TestParameterized(unittest.TestCase):
266
266
  assert C.name == 'another'
267
267
  assert D.name == 'another'
268
268
 
269
- def test_name_overriden_multiple(self):
269
+ def test_name_overridden_multiple(self):
270
270
  class A(param.Parameterized):
271
271
  name = param.String(default='AA')
272
272
  class B(param.Parameterized):
@@ -1409,7 +1409,7 @@ def test_inheritance_constant_behavior():
1409
1409
  assert b.param.p.constant is True
1410
1410
 
1411
1411
 
1412
- def test_inheritance_set_Parameter_instantiate_constant_before_instantation():
1412
+ def test_inheritance_set_Parameter_instantiate_constant_before_instantiation():
1413
1413
  # https://github.com/holoviz/param/issues/760
1414
1414
  class A(param.Parameterized):
1415
1415
  p0 = param.Parameter()
@@ -218,7 +218,7 @@ def test_script_repr_parameterized_other():
218
218
  assert param.script_repr('2') == "\n\n'2'"
219
219
 
220
220
 
221
- def test_pprint_signature_overriden():
221
+ def test_pprint_signature_overridden():
222
222
  # https://github.com/holoviz/param/issues/785
223
223
 
224
224
  class P(param.Parameterized):
@@ -133,7 +133,7 @@ class TestPathParameters(unittest.TestCase):
133
133
 
134
134
  # Inheritance isn't working great with search_paths and this test
135
135
  # isn't designed to be run from the tmpdir directory.
136
- startd = os.getcwd()
136
+ start_dir = os.getcwd()
137
137
  try:
138
138
  # a = param.Path()
139
139
  # b = param.Path(self.fb)
@@ -162,7 +162,7 @@ class TestPathParameters(unittest.TestCase):
162
162
  with pytest.raises(OSError, match='Path a.txt was not found'):
163
163
  assert b.c is None
164
164
  finally:
165
- os.chdir(startd)
165
+ os.chdir(start_dir)
166
166
 
167
167
  def test_notfound_instantiation_raises_error(self):
168
168
  with pytest.raises(
@@ -557,9 +557,9 @@ def test_reactive_clone_reevaluates(inputs: list[str], op: Callable[[rx], Any],
557
557
  assert transformed.rx.value == expecteds[0]
558
558
  assert fcalls == 1
559
559
 
560
- for prev_fcalls, (inpt, expec) in enumerate(zip(inputs[1:], expecteds[1:]), start=fcalls):
561
- base.rx.value = inpt
562
- assert transformed.rx.value == expec
560
+ for prev_fcalls, (input, expect) in enumerate(zip(inputs[1:], expecteds[1:]), start=fcalls):
561
+ base.rx.value = input
562
+ assert transformed.rx.value == expect
563
563
  assert fcalls == (prev_fcalls + 1)
564
564
 
565
565
  @pytest.mark.parametrize('lazy', [False, True])
@@ -50,10 +50,10 @@ def test_signature_parameters_constructors_overloaded_updated_match():
50
50
  init_overloads = typing.get_overloads(p_type.__init__)
51
51
  if not init_overloads:
52
52
  continue
53
- usig = inspect.signature(p_type)
53
+ sig = inspect.signature(p_type)
54
54
  if any(
55
55
  parameter.kind in (inspect.Parameter.VAR_KEYWORD, inspect.Parameter.VAR_POSITIONAL)
56
- for parameter in usig.parameters.values()
56
+ for parameter in sig.parameters.values()
57
57
  ):
58
58
  # Classes that still expose a variadic runtime signature cannot be
59
59
  # compared reliably to overload declarations.
@@ -68,7 +68,7 @@ def test_signature_parameters_constructors_overloaded_updated_match():
68
68
  and parameter.kind not in (inspect.Parameter.VAR_KEYWORD, inspect.Parameter.VAR_POSITIONAL)
69
69
  ]
70
70
  )
71
- if _is_overload_compatible(osig, usig):
71
+ if _is_overload_compatible(osig, sig):
72
72
  compatible = True
73
73
  break
74
74
  assert compatible, _
@@ -576,7 +576,7 @@ class TestWatch(unittest.TestCase):
576
576
  assert len(store) == 2
577
577
 
578
578
  p.x = 30
579
- # Watcher not triggerd on instance update
579
+ # Watcher not triggered on instance update
580
580
  assert len(store) == 2
581
581
 
582
582
  def test_param_watch_multiple_instances(self):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes