param 2.4.0rc3__tar.gz → 2.4.1__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.
- {param-2.4.0rc3 → param-2.4.1}/.gitignore +1 -1
- {param-2.4.0rc3 → param-2.4.1}/PKG-INFO +1 -1
- {param-2.4.0rc3 → param-2.4.1}/numbergen/__init__.py +8 -8
- {param-2.4.0rc3 → param-2.4.1}/param/_utils.py +3 -1
- {param-2.4.0rc3 → param-2.4.1}/param/_version.py +2 -2
- {param-2.4.0rc3 → param-2.4.1}/param/ipython.py +1 -1
- param-2.4.1/param/mypy_plugin.py +95 -0
- {param-2.4.0rc3 → param-2.4.1}/param/parameterized.py +13 -13
- {param-2.4.0rc3 → param-2.4.1}/param/parameters.py +13 -11
- {param-2.4.0rc3 → param-2.4.1}/param/version.py +2 -2
- {param-2.4.0rc3 → param-2.4.1}/pyproject.toml +20 -2
- {param-2.4.0rc3 → param-2.4.1}/tests/assert_types.py +25 -25
- {param-2.4.0rc3 → param-2.4.1}/tests/testdefaultfactory.py +1 -1
- {param-2.4.0rc3 → param-2.4.1}/tests/testfiledeserialization.py +1 -1
- {param-2.4.0rc3 → param-2.4.1}/tests/testparameterizedobject.py +9 -9
- {param-2.4.0rc3 → param-2.4.1}/tests/testparameterizedrepr.py +1 -1
- {param-2.4.0rc3 → param-2.4.1}/tests/testpathparam.py +2 -2
- {param-2.4.0rc3 → param-2.4.1}/tests/testreactive.py +3 -3
- {param-2.4.0rc3 → param-2.4.1}/tests/testsignatures.py +3 -3
- {param-2.4.0rc3 → param-2.4.1}/tests/testwatch.py +1 -1
- {param-2.4.0rc3 → param-2.4.1}/LICENSE.txt +0 -0
- {param-2.4.0rc3 → param-2.4.1}/README.md +0 -0
- {param-2.4.0rc3 → param-2.4.1}/param/__init__.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/param/depends.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/param/display.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/param/py.typed +0 -0
- {param-2.4.0rc3 → param-2.4.1}/param/reactive.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/param/serializer.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/__init__.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/conftest.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/pyrightconfig-bare.json +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testaddparameter.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testbind.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testbooleanparam.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testbytesparam.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testcalendardateparam.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testcalendardaterangeparam.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testcallable.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testclassselector.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testcolorparameter.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testcomparator.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testcompositeparams.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testcustomparam.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testdateparam.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testdaterangeparam.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testdefaults.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testdeprecations.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testdynamicparams.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testfileselector.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testimports.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testipythonmagic.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testjsonserialization.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testlist.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testlistselector.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testmultifileselector.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testnumbergen.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testnumberparameter.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testnumpy.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testobjectselector.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testpandas.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testparamdepends.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testparameter.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testparamoutput.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testparamunion.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testpickle.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testrangeparameter.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testrefs.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testreprhtml.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testselector.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/teststringparam.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testtimedependent.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testtupleparam.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testutils.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/testversion.py +0 -0
- {param-2.4.0rc3 → param-2.4.1}/tests/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: param
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.1
|
|
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
|
-
|
|
247
|
+
numerator, denominator = val, 1
|
|
248
248
|
elif isinstance(val, fractions.Fraction):
|
|
249
|
-
|
|
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
|
-
|
|
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
|
-
(
|
|
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
|
-
|
|
261
|
-
return
|
|
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 (
|
|
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.
|
|
22
|
-
__version_tuple__ = version_tuple = (2, 4,
|
|
21
|
+
__version__ = version = '2.4.1'
|
|
22
|
+
__version_tuple__ = version_tuple = (2, 4, 1)
|
|
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
|
|
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
|
-
|
|
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
|
|
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,
|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
#
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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]
|
|
3644
|
-
default: list[t.Any]
|
|
3645
|
+
self: List[list[t.Any]],
|
|
3646
|
+
default: list[t.Any] = [],
|
|
3645
3647
|
*,
|
|
3646
|
-
|
|
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
|
-
|
|
3657
|
-
allow_None: t.Literal[False] = False,
|
|
3659
|
+
allow_None: t.Literal[True] = True,
|
|
3658
3660
|
**kwargs: Unpack[_ParameterKwargs]
|
|
3659
3661
|
) -> None:
|
|
3660
3662
|
...
|
|
@@ -162,7 +162,7 @@ class Version:
|
|
|
162
162
|
|
|
163
163
|
@property
|
|
164
164
|
def dirty(self):
|
|
165
|
-
"""True if there are
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
215
|
-
assert_type(
|
|
216
|
-
assert_type(
|
|
217
|
-
assert_type(
|
|
218
|
-
assert_type(
|
|
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
|
-
|
|
276
|
-
assert_type(
|
|
277
|
-
assert_type(
|
|
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
|
-
|
|
303
|
-
assert_type(
|
|
304
|
-
assert_type(
|
|
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
|
-
|
|
357
|
-
assert_type(
|
|
358
|
-
assert_type(
|
|
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
|
-
|
|
393
|
-
assert_type(
|
|
394
|
-
assert_type(
|
|
395
|
-
assert_type(
|
|
396
|
-
assert_type(
|
|
397
|
-
assert_type(
|
|
398
|
-
assert_type(
|
|
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
|
|
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:
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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(
|
|
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, (
|
|
561
|
-
base.rx.value =
|
|
562
|
-
assert transformed.rx.value ==
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|