Codebase list python-param / 4a4f15f
New upstream release. Debian Janitor 1 year, 1 month ago
48 changed file(s) with 2984 addition(s) and 73 deletion(s). Raw diff Collapse all Expand all
8080 python setup.py sdist bdist_wheel
8181 - name: Publish package to PyPI
8282 if: github.event_name == 'push'
83 uses: pypa/gh-action-pypi-publish@master
83 uses: pypa/gh-action-pypi-publish@release/v1
8484 with:
8585 user: ${{ secrets.PPU }}
8686 password: ${{ secrets.PPP }}
11 on:
22 push:
33 branches:
4 - master
4 - main
55 pull_request:
66 branches:
77 - '*'
2929 - uses: actions/checkout@v3
3030 with:
3131 fetch-depth: "100"
32 - name: Fetch unshallow
33 run: git fetch --prune --tags --unshallow -f
3234 - name: Set up Python ${{ matrix.python-version }}
3335 uses: actions/setup-python@v4
3436 with:
0 # Code of Conduct
1
2 For the code of conduct, see [HoloViz/HoloViz - CODE_OF_CONDUCT.md](https://github.com/holoviz/holoviz/blob/param-gov/CODE_OF_CONDUCT.md).
3
4 The Param Project’s equivalently named documents take precedence over any external materials referenced within this linked document above.
0 <img src="https://raw.githubusercontent.com/holoviz/param/master/doc/_static/logo_horizontal.png" width=250>
0 <img src="https://raw.githubusercontent.com/holoviz/param/main/doc/_static/logo_horizontal.png" width=250>
11
22 | | |
33 | --- | --- |
44 | Build Status | [![Linux/MacOS/Windows Build Status](https://github.com/holoviz/param/workflows/pytest/badge.svg)](https://github.com/holoviz/param/actions/workflows/test.yml)
5 | Coverage | [![codecov](https://codecov.io/gh/holoviz/param/branch/master/graph/badge.svg)](https://codecov.io/gh/holoviz/param) ||
5 | Coverage | [![codecov](https://codecov.io/gh/holoviz/param/branch/main/graph/badge.svg)](https://codecov.io/gh/holoviz/param) ||
66 | Latest dev release | [![Github tag](https://img.shields.io/github/v/tag/holoviz/param.svg?label=tag&colorB=11ccbb)](https://github.com/holoviz/param/tags) [![dev-site](https://img.shields.io/website-up-down-green-red/https/pyviz-dev.github.io/param.svg?label=dev%20website)](https://pyviz-dev.github.io/param/) |
77 | Latest release | [![Github release](https://img.shields.io/github/release/holoviz/param.svg?label=tag&colorB=11ccbb)](https://github.com/holoviz/param/releases) [![PyPI version](https://img.shields.io/pypi/v/param.svg?colorB=cc77dd)](https://pypi.python.org/pypi/param) [![param version](https://img.shields.io/conda/v/pyviz/param.svg?colorB=4488ff&style=flat)](https://anaconda.org/pyviz/param) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/param.svg?label=conda%7Cconda-forge&colorB=4488ff)](https://anaconda.org/conda-forge/param) [![defaults version](https://img.shields.io/conda/v/anaconda/param.svg?label=conda%7Cdefaults&style=flat&colorB=4488ff)](https://anaconda.org/anaconda/param) |
88 | Python | [![Python support](https://img.shields.io/pypi/pyversions/param.svg)](https://pypi.org/project/param/)
99 | Docs | [![gh-pages](https://img.shields.io/github/last-commit/holoviz/param/gh-pages.svg)](https://github.com/holoviz/param/tree/gh-pages) [![site](https://img.shields.io/website-up-down-green-red/https/param.holoviz.org.svg)](https://param.holoviz.org) |
10 | Binder | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/holoviz/param/master?labpath=examples) |
10 | Binder | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/holoviz/param/main?labpath=examples) |
1111 | Support | [![Discourse](https://img.shields.io/discourse/status?server=https%3A%2F%2Fdiscourse.holoviz.org)](https://discourse.holoviz.org/) |
1212
1313 Param is a library providing Parameters: Python attributes extended to have features such as type and range checking, dynamically generated values, documentation strings, default values, etc., each of which is inherited from parent classes if not specified in a subclass.
0 python-param (1.13.0-1) UNRELEASED; urgency=low
1
2 * New upstream release.
3
4 -- Debian Janitor <janitor@jelmer.uk> Sun, 02 Apr 2023 20:51:55 -0000
5
06 python-param (1.12.3-1) unstable; urgency=medium
17
28 * Team upload.
00 # About
11
2 Param is completely open source, available under a [BSD license](https://github.com/holoviz/param/blob/master/LICENSE.txt), freely for both commercial and non-commercial use. Param was originally developed at the University of Texas at Austin and the University of Edinburgh with funding from the US National Institutes of Health grant 1R01-MH66991. Param is now maintained by [Anaconda Inc.](https://anaconda.com) and by community contributors.
2 Param is completely open source, available under a [BSD license](https://github.com/holoviz/param/blob/main/LICENSE.txt), freely for both commercial and non-commercial use. Param was originally developed at the University of Texas at Austin and the University of Edinburgh with funding from the US National Institutes of Health grant 1R01-MH66991. Param is now maintained by [Anaconda Inc.](https://anaconda.com) and by community contributors.
33
44 Param is maintained as part of the [HoloViz](https://holoviz.org) family of tools. The [holoviz.org](https://holoviz.org) website shows how to use Param together with other libraries to solve complex problems, with detailed tutorials and examples. Each of the HoloViz tools builds on Param, as do many of the example projects at [examples.pyviz.org](https://examples.pyviz.org).
55
0 # Contributing
1
2 For the contributing policy, see [HoloViz/HoloViz - CONTRIBUTING.md](https://github.com/holoviz/holoviz/blob/param-gov/doc/governance/project-docs/CONTRIBUTING.md).
3
4 The Param Project’s equivalently named documents take precedence over any external materials referenced within this linked document above.
0 # Governance Policy
1
2 The "Project" is herein defined as the activities related to this specific GitHub repository [`Param`](https://github.com/holoviz/param), within the `HoloViz` GitHub Organization.
3
4 This Project adopts the governance specified by all of the numbered sections of [HoloViz/HoloViz - GOVERNANCE.md](https://github.com/holoviz/holoviz/blob/param-gov/doc/governance/project-docs/GOVERNANCE.md).
5
6 The Param Project’s equivalently named documents take precedence over any external materials referenced within this linked document above.
0 # License
1
2 For the license, see [HoloViz/Param - LICENSE.txt](https://github.com/holoviz/param/blob/main/LICENSE.txt).
0 # Maintainers
1
2 For member policy, see the description at the top of [HoloViz/HoloViz - MEMBERS.md](https://github.com/holoviz/holoviz/blob/param-gov/doc/governance/project-docs/MEMBERS.md)
3
4 The Param Project’s equivalently named documents take precedence over any external materials referenced within this linked document above.
5
6 | **NAME** | **Role** | **GitHub Handle** |
7 | --- | --- | --- |
8 | James Bednar | Project Director | [jbednar](https://github.com/jbednar) |
9 | Jean-Luc Stevens | Maintainer | [jlstevens](https://github.com/jlstevens) |
10 | Philipp Rudiger | Maintainer | [philippjfr](https://github.com/philippjfr) |
00 # Releases
1
2 ## Version 1.13.0
3
4 Date: 2023-03-14
5
6 The `1.13.0` is the last release of Param before the 2.0 release. However, Param 1.13 is meant to receive long-term support; security patches and fixes to critical bugs are planned to be backported to the 1.13.x series.
7
8 This release includes a new `Bytes` *Parameter* and a few important bug fixes. This release is also marked by the adoption of a formal project governance, ensuring Param's future as a healthy open-source project. Many thanks to @ovidner and @droumis for their first contributions! And to @maximlt, @Hoxbro, @jlstevens, @philippjfr and @jbednar for their continuing support to fixing and improving Param.
9
10 Bug fixes:
11
12 * Fix copying when having watchers on e.g. bounds on inherited Parameter types ([#675](https://github.com/holoviz/param/pull/675))
13 * Allow JSON serialization to work with `json.dumps` ([#655](https://github.com/holoviz/param/pull/655))
14 * `ListSelector` restricted to `list` type objects ([#531](https://github.com/holoviz/param/pull/531))
15 * Fix `depends` async wrapper ([#684](https://github.com/holoviz/param/pull/684))
16 * Allow named colors to be any case ([#711](https://github.com/holoviz/param/pull/711))
17
18 New features:
19
20 * Add Bytes parameter ([#542](https://github.com/holoviz/param/pull/542))
21
22 Documentation:
23
24 * Fix param module link ([#682](https://github.com/holoviz/param/pull/682))
25
26 Project governance:
27
28 * Create initial project governance docs ([#674](https://github.com/holoviz/param/pull/674))
29
30 Maintenance:
31
32 * Rename `master` branch to `main` ([#672](https://github.com/holoviz/param/pull/672))
33 * Add more tests ([#710](https://github.com/holoviz/param/pull/710))
34 * Various CI related fixes ([#680](https://github.com/holoviz/param/pull/680), [#683](https://github.com/holoviz/param/pull/683) and [#709](https://github.com/holoviz/param/pull/709))
135
236 ## Version 1.12.3
337
33 "cell_type": "markdown",
44 "metadata": {},
55 "source": [
6 "<img src=\"https://raw.githubusercontent.com/holoviz/param/master/doc/_static/logo_horizontal.png\" style=\"display:block;margin-left:auto;margin-right:auto;width:50%;max-width:500px\">"
6 "<img src=\"https://raw.githubusercontent.com/holoviz/param/main/doc/_static/logo_horizontal.png\" style=\"display:block;margin-left:auto;margin-right:auto;width:50%;max-width:500px\">"
77 ]
88 },
99 {
274274 "- named functions don't support internal state and need to be stored in a named module somewhere for them to be picklable, potentially resulting in a large number of one-off functions to keep track of\n",
275275 "- making a new object with a `__call__` method is verbose and error-prone, and again needs to be stored in a formal module if it is to be picklable.\n",
276276 "\n",
277 "To make using Dynamic parameters more convenient, Param includes a separate module [Numbergen](https://github.com/holoviz/param/blob/master/numbergen/__init__.py) that provides ready-to-use, picklable, composable, and interchangeable callable objects producing numeric values. Numbergen relies only on Param and the Python standard library, so it should be easy to add to any project. \n",
277 "To make using Dynamic parameters more convenient, Param includes a separate module [Numbergen](https://github.com/holoviz/param/blob/main/numbergen/__init__.py) that provides ready-to-use, picklable, composable, and interchangeable callable objects producing numeric values. Numbergen relies only on Param and the Python standard library, so it should be easy to add to any project. \n",
278278 "\n",
279279 "Numbergen objects are designed to work seamlessly as Dynamic parameter values, providing easy access to various temporal distributions, along with tools for combining and configuring number generators without having to write custom functions or classes. Moreover, because all of these objects are Parameterized objects sharing the same usage interface (each provides a numeric value when called, regardless of how many or which parameters are required to configure that distribution), using them together with Param's Dynamic support provides a huge amount of power over the values parameters take over time, without requiring any extra complexity in your program. Without Dynamic support and numbergen, your Parameterized classes could of course provide their own support for e.g. a normal random distribution by accepting a mean and variance, but it would then be limited to that specific random distribution, whereas Dynamic parameters can accept _any_ current or future number generator object as configured by a user for their own purposes, neatly separating your Parameterized's requirements (\"a positive integer value\") from the user's requirements (\"let's see what happens when the value starts at 1 and doubles every iteration\").\n",
280280 "\n",
370370 "\n",
371371 "A TimeAware object also has access to a `time_fn` and has a `time_dependent` parameter, but either sets `time_dependent=False` (indicating that values are never a strict function of time) or allows either True or False (switching into and out of a time dependent mode). All current `TimeAware` NumberGenerator objects are random number generators that support both possible values of `time_dependent`. For `time_dependent=False` (the default), they return a new value on each call, while for `time_dependent=True`, they return pseudorandom values that follow the indicated distribution but are also a strict function of the time, in that the same number will be returned for a given time value even if time skips ahead or backwards. \n",
372372 "\n",
373 "These random values are thus very tightly controlled to allow reproducible, repeatable results, with values determined by both a seed value (to choose the overall set of random values) and by the current time. Effectively, when `time_dependent=True`, these numbers provide a random value seeded by the generator's `name` parameter, the global `param.random_seed`, the `seed` parameter of the NumberGenerator, _and_ the NumberGenerator's current `time_fn()` value. The resulting generated values should be the same for a given object and a given `time_fn` value, even across platforms and machine-word sizes (see the [Hash](https://github.com/holoviz/param/blob/master/numbergen/__init__.py#L176), TimeAwareRandomState, and RandomDistribution classes for more details). \n",
373 "These random values are thus very tightly controlled to allow reproducible, repeatable results, with values determined by both a seed value (to choose the overall set of random values) and by the current time. Effectively, when `time_dependent=True`, these numbers provide a random value seeded by the generator's `name` parameter, the global `param.random_seed`, the `seed` parameter of the NumberGenerator, _and_ the NumberGenerator's current `time_fn()` value. The resulting generated values should be the same for a given object and a given `time_fn` value, even across platforms and machine-word sizes (see the [Hash](https://github.com/holoviz/param/blob/main/numbergen/__init__.py#L176), TimeAwareRandomState, and RandomDistribution classes for more details). \n",
374374 "\n",
375375 "For best results, you should provide an explicit unique name to any such generator and preserve that name over time, so that results will be reproducible across program runs. By default, the underlying random numbers are generated using Python's [random](https://docs.python.org/3/library/random.html) module (which see for details of the number generation), but you can substitute an instance of `numpy.random.RandomState` or similar compatible object for `self.random_generator` for higher performance or to generate time-dependent array values.\n",
376376 "\n",
4949 "cell_type": "markdown",
5050 "metadata": {},
5151 "source": [
52 "The full behavior of these types is covered in the [Reference Manual](https://param.holoviz.org/Reference_Manual/param.html). Here we will discuss the major categories of Parameter type and how to use them, including examples of what each type does _not_ allow (labeled `with param.exceptions_summarized():`). Each of these classes is also suitable for subclassing to create more specialized types enforcing your own specific constraints. After reading about Parameters in general, feel free to skip around in this page and only look at the Parameter types of interest to you!"
52 "The full behavior of these types is covered in the [Reference Manual](https://param.holoviz.org/reference.html#param-module). Here we will discuss the major categories of Parameter type and how to use them, including examples of what each type does _not_ allow (labeled `with param.exceptions_summarized():`). Each of these classes is also suitable for subclassing to create more specialized types enforcing your own specific constraints. After reading about Parameters in general, feel free to skip around in this page and only look at the Parameter types of interest to you!"
5353 ]
5454 },
5555 {
4242 # only two required files.
4343 try:
4444 from .version import Version
45 __version__ = str(Version(fpath=__file__, archive_commit="897687f71", reponame="param"))
45 __version__ = str(Version(fpath=__file__, archive_commit="782a03c4", reponame="param"))
4646 except:
4747 __version__ = "0.0.0+unknown"
4848
734734 return (l, u)
735735
736736
737 class Bytes(Parameter):
738 """
739 A Bytes Parameter, with a default value and optional regular
740 expression (regex) matching.
741
742 Similar to the String parameter, but instead of type basestring
743 this parameter only allows objects of type bytes (e.g. b'bytes').
744 """
745
746 __slots__ = ['regex']
747
748 def __init__(self, default=b"", regex=None, allow_None=False, **kwargs):
749 super(Bytes, self).__init__(default=default, allow_None=allow_None, **kwargs)
750 self.regex = regex
751 self.allow_None = (default is None or allow_None)
752 self._validate(default)
753
754 def _validate_regex(self, val, regex):
755 if (val is None and self.allow_None):
756 return
757 if regex is not None and re.match(regex, val) is None:
758 raise ValueError("Bytes parameter %r value %r does not match regex %r."
759 % (self.name, val, regex))
760
761 def _validate_value(self, val, allow_None):
762 if allow_None and val is None:
763 return
764 if not isinstance(val, bytes):
765 raise ValueError("Bytes parameter %r only takes a byte string value, "
766 "not value of type %s." % (self.name, type(val)))
767
768 def _validate(self, val):
769 self._validate_value(val, self.allow_None)
770 self._validate_regex(val, self.regex)
771
772
737773 class Number(Dynamic):
738774 """
739775 A numeric Dynamic Parameter, with a default value and optional bounds.
10211057 @classmethod
10221058 def serialize(cls, value):
10231059 if value is None:
1024 return 'null'
1060 return None
10251061 return list(value) # As JSON has no tuple representation
10261062
10271063 @classmethod
10281064 def deserialize(cls, value):
1029 if value == 'null':
1065 if value == 'null' or value is None:
10301066 return None
10311067 return tuple(value) # As JSON has no tuple representation
10321068
14821518 @classmethod
14831519 def serialize(cls, value):
14841520 if value is None:
1485 return 'null'
1521 return None
14861522 return value.tolist()
14871523
14881524 @classmethod
14891525 def deserialize(cls, value):
1490 if value == 'null':
1526 if value == 'null' or value is None:
14911527 return None
14921528 from numpy import asarray
14931529 return asarray(value)
15691605 @classmethod
15701606 def serialize(cls, value):
15711607 if value is None:
1572 return 'null'
1608 return None
15731609 return value.to_dict('records')
15741610
15751611 @classmethod
15761612 def deserialize(cls, value):
1577 if value == 'null':
1613 if value == 'null' or value is None:
15781614 return None
15791615 from pandas import DataFrame as pdDFrame
15801616 return pdDFrame(value)
18771913 def _validate(self, val):
18781914 if (val is None and self.allow_None):
18791915 return
1916 if not isinstance(val, list):
1917 raise ValueError("ListSelector parameter %r only takes list "
1918 "types, not %r." % (self.name, val))
18801919 for o in val:
18811920 super(ListSelector, self)._validate(o)
18821921
19411980 @classmethod
19421981 def serialize(cls, value):
19431982 if value is None:
1944 return 'null'
1983 return None
19451984 if not isinstance(value, (dt.datetime, dt.date)): # i.e np.datetime64
19461985 value = value.astype(dt.datetime)
19471986 return value.strftime("%Y-%m-%dT%H:%M:%S.%f")
19481987
19491988 @classmethod
19501989 def deserialize(cls, value):
1951 if value == 'null':
1990 if value == 'null' or value is None:
19521991 return None
19531992 return dt.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
19541993
19792018 @classmethod
19802019 def serialize(cls, value):
19812020 if value is None:
1982 return 'null'
2021 return None
19832022 return value.strftime("%Y-%m-%d")
19842023
19852024 @classmethod
19862025 def deserialize(cls, value):
1987 if value == 'null':
2026 if value == 'null' or value is None:
19882027 return None
19892028 return dt.datetime.strptime(value, "%Y-%m-%d").date()
19902029
20552094 return
20562095 is_hex = re.match('^#?(([0-9a-fA-F]{2}){3}|([0-9a-fA-F]){3})$', val)
20572096 if self.allow_named:
2058 if not is_hex and val not in self._named_colors:
2097 if not is_hex and val.lower() not in self._named_colors:
20592098 raise ValueError("Color '%s' only takes RGB hex codes "
20602099 "or named colors, received '%s'." % (self.name, val))
20612100 elif not is_hex:
21392178 @classmethod
21402179 def serialize(cls, value):
21412180 if value is None:
2142 return 'null'
2181 return None
21432182 # List as JSON has no tuple representation
21442183 serialized = []
21452184 for v in value:
21542193 return serialized
21552194
21562195 def deserialize(cls, value):
2157 if value == 'null':
2196 if value == 'null' or value is None:
21582197 return None
21592198 deserialized = []
21602199 for v in value:
21902229 @classmethod
21912230 def serialize(cls, value):
21922231 if value is None:
2193 return 'null'
2232 return None
21942233 # As JSON has no tuple representation
21952234 return [v.strftime("%Y-%m-%d") for v in value]
21962235
21972236 @classmethod
21982237 def deserialize(cls, value):
2199 if value == 'null':
2238 if value == 'null' or value is None:
22002239 return None
22012240 # As JSON has no tuple representation
22022241 return tuple([dt.datetime.strptime(v, "%Y-%m-%d").date() for v in value])
22 by param internal callbacks. These are defined in a separate file due
33 to py2 incompatibility with both `async/await` and `yield from` syntax.
44 """
5 from functools import wraps
56
67 def generate_depends(func):
8 @wraps(func)
79 async def _depends(*args, **kw): # noqa: E999
8 await func(*args, **kw) # noqa: E999
10 return await func(*args, **kw) # noqa: E999
911 return _depends
1012
1113 def generate_caller(function, what='value', changed=None, callback=None, skip_event=None):
11161116 "it has been bound to a Parameterized.")
11171117
11181118 implemented = (attribute != "default" and hasattr(self, 'watchers') and attribute in self.watchers)
1119 slot_attribute = attribute in self.__slots__
1119 slot_attribute = attribute in get_all_slots(type(self))
11201120 try:
11211121 old = getattr(self, attribute) if implemented else NotImplemented
11221122 if slot_attribute:
399399 prefix = reponame + '-' # Prefix to match
400400 if setup_dir.startswith(prefix):
401401 tag = setup_dir[len(prefix):]
402 # Assuming the tag is a version if it isn't empty, 'master' and has a dot in it
403 if tag not in ['', 'master'] and ('.' in tag):
402 # Assuming the tag is a version if it isn't empty, 'master' or 'main' and has a dot in it
403 if tag not in ['', 'master', 'main'] and ('.' in tag):
404404 return tag
405405 return None
406406
1919 # (https://github.com/pypa/pip/issues/1197)
2020 'tests': [
2121 'pytest',
22 'pytest-cov',
22 'coverage',
2323 'flake8',
2424 ],
2525 'doc': [
5252 p.g = [7]
5353 try:
5454 p.g = None
55 except TypeError:
55 except ValueError:
5656 pass
5757 else:
5858 raise AssertionError("Object set outside range.")
109109 ### new tests (not copied from testobjectselector)
110110
111111 def test_bad_default(self):
112 with self.assertRaises(TypeError):
112 with self.assertRaises(ValueError):
113113 class Q(param.Parameterized):
114114 r = param.ListSelector(default=6,check_on_set=True)
115115
116116 def test_implied_check_on_set(self):
117 with self.assertRaises(TypeError):
117 with self.assertRaises(ValueError):
118118 class Q(param.Parameterized):
119119 r = param.ListSelector(default=7,objects=[7,8])
120120
134134 class Q(param.Parameterized):
135135 r = param.ListSelector(default=6,check_on_set=False)
136136
137 with self.assertRaises(TypeError):
137 with self.assertRaises(ValueError):
138138 Q.r = 6
139139 ##########################
140140
0 """
1 Unit test for Boolean parameters.
2 """
3 import datetime as dt
4
5 import param
6
7 from . import API1TestCase
8 from .utils import check_defaults
9
10
11 class TestBooleanParameters(API1TestCase):
12
13 def setUp(self):
14 super(TestBooleanParameters, self).setUp()
15 class P(param.Parameterized):
16 e = param.Boolean()
17 f = param.Boolean(default=None)
18
19 self.P = P
20
21 def _check_defaults(self, p):
22 assert p.default is False
23 assert p.allow_None is False
24 assert p.bounds == (0, 1)
25
26 def test_defaults_class(self):
27 class A(param.Parameterized):
28 b = param.Boolean()
29
30 check_defaults(A.param.b, label='B')
31 self._check_defaults(A.param.b)
32
33 def test_defaults_inst(self):
34 class A(param.Parameterized):
35 b = param.Boolean()
36
37 a = A()
38
39 check_defaults(a.param.b, label='B')
40 self._check_defaults(a.param.b)
41
42 def test_defaults_unbound(self):
43 b = param.Boolean()
44
45 check_defaults(b, label=None)
46 self._check_defaults(b)
47
48 def test_default_is_None(self):
49 p = self.P()
50 assert p.f is None
51 assert p.param.f.allow_None is True
52
53 p.f = True
54 p.f = None
55 assert p.f is None
56
57 def test_raise_None_when_not_allowed(self):
58 p = self.P()
59
60 msg = r"Boolean parameter 'e' must be True or False, not None"
61 with self.assertRaisesRegex(ValueError, msg):
62 p.e = None
63
64 with self.assertRaisesRegex(ValueError, msg):
65 self.P.e = None
66
67 def test_bad_type(self):
68 msg = r"Boolean parameter 'e' must be True or False, not test"
69
70 with self.assertRaisesRegex(ValueError, msg):
71 self.P.e = 'test'
72
73 with self.assertRaisesRegex(ValueError, msg):
74 self.P(e='test')
75
76 p = self.P()
77
78 with self.assertRaisesRegex(ValueError, msg):
79 p.e = 'test'
80
81
82 class TestEventParameters(API1TestCase):
83
84 def setUp(self):
85 super(TestEventParameters, self).setUp()
86 class P(param.Parameterized):
87 e = param.Event()
88 f = param.Event(default=None)
89
90 self.P = P
91
92 def _check_defaults(self, p):
93 assert p.default is False
94 assert p.allow_None is False
95 assert p.bounds == (0, 1)
96
97 def test_defaults_class(self):
98 class A(param.Parameterized):
99 b = param.Event()
100
101 check_defaults(A.param.b, label='B')
102 self._check_defaults(A.param.b)
103
104 def test_defaults_inst(self):
105 class A(param.Parameterized):
106 b = param.Event()
107
108 a = A()
109
110 check_defaults(a.param.b, label='B')
111 self._check_defaults(a.param.b)
112
113 def test_defaults_unbound(self):
114 b = param.Event()
115
116 check_defaults(b, label=None)
117 self._check_defaults(b)
118
119 def test_resets_to_false(self):
120 p = self.P()
121 p.e = True
122 assert p.e is False
123
124 def test_default_is_None(self):
125 p = self.P()
126 assert p.f is None
127 assert p.param.f.allow_None is True
128
129 p.f = None
130 assert p.f is False
131
132 def test_raise_None_when_not_allowed(self):
133 p = self.P()
134
135 msg = r"Boolean parameter 'e' must be True or False, not None"
136 with self.assertRaisesRegex(ValueError, msg):
137 p.e = None
138
139 with self.assertRaisesRegex(ValueError, msg):
140 self.P.e = None
141
142 def test_bad_type(self):
143 msg = r"Boolean parameter 'e' must be True or False, not test"
144
145 with self.assertRaisesRegex(ValueError, msg):
146 self.P.e = 'test'
147
148 with self.assertRaisesRegex(ValueError, msg):
149 self.P(e='test')
150
151 p = self.P()
152
153 with self.assertRaisesRegex(ValueError, msg):
154 p.e = 'test'
0 """
1 Unit test for Bytes parameters
2 """
3 import sys
4
5 import pytest
6
7 from . import API1TestCase
8 from .utils import check_defaults
9
10 import param
11
12
13 ip_regex = br'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
14
15 class TestBytesParameters(API1TestCase):
16
17 def _check_defaults(self, p):
18 assert p.default == b''
19 assert p.allow_None is False
20 assert p.regex is None
21
22 def test_defaults_class(self):
23 class A(param.Parameterized):
24 b = param.Bytes()
25
26 check_defaults(A.param.b, label='B')
27 self._check_defaults(A.param.b)
28
29 def test_defaults_inst(self):
30 class A(param.Parameterized):
31 b = param.Bytes()
32
33 a = A()
34
35 check_defaults(a.param.b, label='B')
36 self._check_defaults(a.param.b)
37
38 def test_defaults_unbound(self):
39 b = param.Bytes()
40
41 check_defaults(b, label=None)
42 self._check_defaults(b)
43
44 def test_bytes_default_type(self):
45 if sys.version_info.major < 3:
46 pytest.skip()
47
48 with pytest.raises(ValueError):
49 class A(param.Parameterized):
50 s = param.Bytes('abc')
51
52 def test_bytes_value_type(self):
53 if sys.version_info.major < 3:
54 pytest.skip()
55
56 class A(param.Parameterized):
57 s = param.Bytes()
58
59 with pytest.raises(ValueError):
60 A(s='abc')
61
62
63 def test_regex_ok(self):
64 class A(param.Parameterized):
65 s = param.Bytes(b'0.0.0.0', ip_regex)
66
67 a = A()
68 a.s = b'123.123.0.1'
69
70 def test_reject_none(self):
71 class A(param.Parameterized):
72 s = param.Bytes(b'0.0.0.0', ip_regex)
73
74 a = A()
75
76 cls = 'class' if sys.version_info.major > 2 else 'type'
77 exception = "Bytes parameter 's' only takes a byte string value, not value of type <%s 'NoneType'>." % cls
78 with self.assertRaisesRegex(ValueError, exception):
79 a.s = None # because allow_None should be False
80
81 def test_default_none(self):
82 class A(param.Parameterized):
83 s = param.Bytes(None, ip_regex)
84
85 a = A()
86 a.s = b'123.123.0.1'
87 a.s = None # because allow_None should be True with default of None
88
89 def test_regex_incorrect(self):
90 class A(param.Parameterized):
91 s = param.Bytes(b'0.0.0.0', regex=ip_regex)
92
93 a = A()
94
95 b = 'b' if sys.version_info.major > 2 else ''
96 exception = "Bytes parameter 's' value %s'123.123.0.256' does not match regex %r." % (b, ip_regex)
97 with self.assertRaises(ValueError) as e:
98 a.s = b'123.123.0.256'
99 self.assertEqual(str(e.exception), exception)
100
101 def test_regex_incorrect_default(self):
102 b = 'b' if sys.version_info.major > 2 else ''
103 exception = "Bytes parameter None value %s'' does not match regex %r." % (b, ip_regex)
104 with self.assertRaises(ValueError) as e:
105 class A(param.Parameterized):
106 s = param.Bytes(regex=ip_regex) # default value '' does not match regular expression
107 self.assertEqual(str(e.exception), exception)
66 import pytest
77 import param
88 from . import API1TestCase
9 from .utils import check_defaults
910
1011
1112 class TestDateTimeParameters(API1TestCase):
13
14 def _check_defaults(self, p):
15 assert p.default is None
16 assert p.allow_None is True
17 assert p.bounds is None
18 assert p.softbounds is None
19 assert p.inclusive_bounds == (True, True)
20 assert p.step is None
21
22 def test_defaults_class(self):
23 class A(param.Parameterized):
24 d = param.CalendarDate()
25
26 check_defaults(A.param.d, label='D')
27 self._check_defaults(A.param.d)
28
29 def test_defaults_inst(self):
30 class A(param.Parameterized):
31 d = param.CalendarDate()
32
33 a = A()
34
35 check_defaults(a.param.d, label='D')
36 self._check_defaults(a.param.d)
37
38 def test_defaults_unbound(self):
39 d = param.CalendarDate()
40
41 check_defaults(d, label=None)
42 self._check_defaults(d)
1243
1344 def test_initialization_out_of_bounds(self):
1445 try:
5687 def test_datetime_not_accepted(self):
5788 with pytest.raises(ValueError):
5889 param.CalendarDate(dt.datetime(2021, 8, 16, 10))
90
91 def test_step_invalid_type_parameter(self):
92 exception = "Step can only be None or a date type"
93 with self.assertRaisesRegex(ValueError, exception):
94 param.CalendarDate(dt.date(2017,2,27), step=3.2)
99 # test date range.
1010
1111 class TestDateTimeRange(API1TestCase):
12
13 def _check_defaults(self, p):
14 assert p.default is None
15 assert p.allow_None is True
16 assert p.length == 2
17 assert p.bounds is None
18 assert p.softbounds is None
19 assert p.inclusive_bounds == (True, True)
20 assert p.step is None
21
22 def test_defaults_class(self):
23 class P(param.Parameterized):
24 r = param.CalendarDateRange()
25
26 self._check_defaults(P.param.r)
27
28 def test_defaults_inst(self):
29 class P(param.Parameterized):
30 r = param.CalendarDateRange()
31
32 p = P()
33
34 self._check_defaults(p.param.r)
35
36 def test_defaults_unbound(self):
37 r = param.CalendarDateRange()
38
39 self._check_defaults(r)
1240
1341 bad_range = (dt.date(2017,2,27),dt.date(2017,2,26))
1442
66
77 import param
88 from . import API1TestCase
9 from .utils import check_defaults
910
1011 class TestClassSelectorParameters(API1TestCase):
1112
1819 h = param.ClassSelector(default=int,class_=(int,str), is_instance=False)
1920
2021 self.P = P
22
23 def _check_defaults(self, p):
24 assert p.default is None
25 assert p.allow_None is True
26 assert p.instantiate is True
27 assert p.is_instance is True
28
29 def test_defaults_class(self):
30 class P(param.Parameterized):
31 s = param.ClassSelector(int)
32
33 check_defaults(P.param.s, label='S', skip=['instantiate'])
34 self._check_defaults(P.param.s)
35 assert P.param.s.class_ is int
36
37 def test_defaults_inst(self):
38 class P(param.Parameterized):
39 s = param.ClassSelector(int)
40
41 p = P()
42
43 check_defaults(p.param.s, label='S', skip=['instantiate'])
44 self._check_defaults(p.param.s)
45 assert p.param.s.class_ is int
46
47 def test_defaults_unbound(self):
48 s = param.ClassSelector(int)
49
50 check_defaults(s, label=None, skip=['instantiate'])
51 self._check_defaults(s)
52 assert s.class_ is int
2153
2254 def test_single_class_instance_constructor(self):
2355 p = self.P(e=6)
72104
73105 class TestDictParameters(API1TestCase):
74106
107 def _check_defaults(self, p):
108 assert p.default is None
109 assert p.allow_None is True
110 assert p.instantiate is True
111 assert p.is_instance is True
112 assert p.class_ == dict
113
114 def test_defaults_class(self):
115 class P(param.Parameterized):
116 s = param.Dict()
117
118 check_defaults(P.param.s, label='S', skip=['instantiate'])
119 self._check_defaults(P.param.s)
120
121 def test_defaults_inst(self):
122 class P(param.Parameterized):
123 s = param.Dict()
124
125 p = P()
126
127 check_defaults(p.param.s, label='S', skip=['instantiate'])
128 self._check_defaults(p.param.s)
129
130 def test_defaults_unbound(self):
131 s = param.Dict()
132
133 check_defaults(s, label=None, skip=['instantiate'])
134 self._check_defaults(s)
135
75136 def test_valid_dict_parameter(self):
76137 valid_dict = {1:2, 3:3}
77138
22 """
33 import param
44 from . import API1TestCase
5 from .utils import check_defaults
56
67 class TestColorParameters(API1TestCase):
8
9 def _check_defaults(self, p):
10 assert p.default is None
11 assert p.allow_None is True
12 assert p.allow_named is True
13
14 def test_defaults_class(self):
15 class A(param.Parameterized):
16 c = param.Color()
17
18 check_defaults(A.param.c, label='C')
19 self._check_defaults(A.param.c)
20
21 def test_defaults_inst(self):
22 class A(param.Parameterized):
23 c = param.Color()
24
25 a = A()
26
27 check_defaults(a.param.c, label='C')
28 self._check_defaults(a.param.c)
29
30 def test_defaults_unbound(self):
31 c = param.Color()
32
33 check_defaults(c, label=None)
34 self._check_defaults(c)
735
836 def test_initialization_invalid_string(self):
937 try:
6189 q = param.Color(allow_named=True)
6290 Q.q = 'indianred'
6391 self.assertEqual(Q.q, 'indianred')
92
93 def test_valid_named_color_mixed_case(self):
94 class Q(param.Parameterized):
95 q = param.Color(allow_named=True)
96 Q.q = 'WhiteSmoke'
97 self.assertEqual(Q.q, 'WhiteSmoke')
66
77 import param
88 from . import API1TestCase
9 from .utils import check_defaults
910
1011 class TestCompositeParameters(API1TestCase):
1112
3233
3334 self.SomeSequence = SomeSequence
3435
36 def _check_defaults(self, p):
37 assert p.default is None
38 assert p.allow_None is True
39 assert p.attribs == []
40
41 def test_defaults_class(self):
42 class P(param.Parameterized):
43 c = param.Composite()
44
45 check_defaults(P.param.c, label='C')
46 self._check_defaults(P.param.c)
47 assert P.param.c.objtype is P
48
49 def test_defaults_inst(self):
50 class P(param.Parameterized):
51 c = param.Composite()
52
53 p = P()
54
55 check_defaults(p.param.c, label='C')
56 self._check_defaults(p.param.c)
57 assert p.param.c.objtype is P
58
59 def test_defaults_unbound(self):
60 c = param.Composite()
61
62 check_defaults(c, label=None)
63 self._check_defaults(c)
64 assert not hasattr(c, 'objtype')
65
3566 def test_initialization(self):
3667 "Make an instance and do default checks"
3768 self.assertEqual(self.a.x, 0)
3869 self.assertEqual(self.a.y, 0)
3970 self.assertEqual(self.a.xy, [0,0])
40
4171
4272 def test_set_component(self):
4373 self.a.x = 1
00 """
11 Unit test for Date parameters.
22 """
3
4
3 import sys
4 import json
55 import datetime as dt
66 import param
77 from . import API1TestCase
8 from .utils import check_defaults
89
910 class TestDateParameters(API1TestCase):
11
12 def _check_defaults(self, p):
13 assert p.default is None
14 assert p.allow_None is True
15 assert p.bounds is None
16 assert p.softbounds is None
17 assert p.inclusive_bounds == (True, True)
18 assert p.step is None
19
20 def test_defaults_class(self):
21 class A(param.Parameterized):
22 d = param.Date()
23
24 check_defaults(A.param.d, label='D')
25 self._check_defaults(A.param.d)
26
27 def test_defaults_inst(self):
28 class A(param.Parameterized):
29 d = param.Date()
30
31 a = A()
32
33 check_defaults(a.param.d, label='D')
34 self._check_defaults(a.param.d)
35
36 def test_defaults_unbound(self):
37 d = param.Date()
38
39 check_defaults(d, label=None)
40 self._check_defaults(d)
1041
1142 def test_initialization_out_of_bounds(self):
1243 try:
5182 self.assertEqual(q.get_soft_bounds(), (dt.datetime(2017,2,1),
5283 dt.datetime(2017,2,25)))
5384
85 def test_step_invalid_type_datetime_parameter(self):
86 exception = "Step can only be None, a datetime or datetime type"
87 with self.assertRaisesRegex(ValueError, exception):
88 param.Date(dt.datetime(2017,2,27), step=3.2)
89
90
91 def test_date_serialization():
92 class User(param.Parameterized):
93 A = param.Date(default=None)
94
95 # Validate round is possible
96 User.param.deserialize_parameters(User.param.serialize_parameters())
97
98 if sys.version_info.major == 2:
99 return
100
101 serialized_data = '{"name": "User", "A": null}'
102 deserialized_data = {"name": "User", "A": None}
103
104 assert serialized_data == json.dumps(deserialized_data)
105 assert serialized_data == User.param.serialize_parameters()
106 assert deserialized_data == User.param.deserialize_parameters(serialized_data)
77 import pytest
88
99 from . import API1TestCase
10 from .utils import check_defaults
1011
1112 try:
1213 import numpy as np
1718 # test date range.
1819
1920 class TestDateRange(API1TestCase):
21
22 def _check_defaults(self, p):
23 assert p.default is None
24 assert p.allow_None is True
25 assert p.length == 2
26 assert p.bounds is None
27 assert p.softbounds is None
28 assert p.inclusive_bounds == (True, True)
29 assert p.step is None
30
31 def test_defaults_class(self):
32 class P(param.Parameterized):
33 r = param.DateRange()
34
35 self._check_defaults(P.param.r)
36
37 def test_defaults_inst(self):
38 class P(param.Parameterized):
39 r = param.DateRange()
40
41 p = P()
42
43 self._check_defaults(p.param.r)
44
45 def test_defaults_unbound(self):
46 r = param.DateRange()
47
48 self._check_defaults(r)
2049
2150 bad_range = (dt.datetime(2017,2,27),dt.datetime(2017,2,26))
2251
11 Do all subclasses of Parameter supply a valid default?
22 """
33 import pytest
4
5 import param
46
57 from param.parameterized import add_metaclass
68 from param import concrete_descendents, Parameter
911 from param import * # noqa
1012 from param import ClassSelector
1113 from . import API1TestCase
14 from .utils import check_defaults
1215
1316 positional_args = {
1417 # ClassSelector: (object,)
4952 @add_metaclass(DefaultsMetaclassTest)
5053 class TestDefaults(API1TestCase):
5154 pass
55
56
57 def test_defaults_parameter_inst():
58 class A(param.Parameterized):
59 s = param.Parameter()
60
61 a = A()
62
63 check_defaults(a.param.s, label='S')
64 assert a.param.s.default is None
65 assert a.param.s.allow_None is True
66
67 def test_defaults_parameter_class():
68 class A(param.Parameterized):
69 s = param.Parameter()
70
71 check_defaults(A.param.s, label='S')
72 assert A.param.s.default is None
73 assert A.param.s.allow_None is True
74
75 def test_defaults_parameter_unbound():
76 s = param.Parameter()
77
78 check_defaults(s, label=None)
79 assert s.default is None
80 assert s.allow_None is True
81
82 def test_defaults_parameter_inst_allow_None():
83 class A(param.Parameterized):
84 s1 = param.Parameter(default='not None')
85 s2 = param.Parameter(default='not None', allow_None=False)
86 s3 = param.Parameter(default='not None', allow_None=True)
87 s4 = param.Parameter(default=None)
88 s5 = param.Parameter(default=None, allow_None=False)
89 s6 = param.Parameter(default=None, allow_None=True)
90
91 a = A()
92
93 assert a.param.s1.allow_None is False
94 assert a.param.s2.allow_None is False
95 assert a.param.s3.allow_None is True
96 assert a.param.s4.allow_None is True
97 assert a.param.s5.allow_None is True
98 assert a.param.s6.allow_None is True
99
100
101 def test_defaults_parameter_class_allow_None():
102 class A(param.Parameterized):
103 s1 = param.Parameter(default='not None')
104 s2 = param.Parameter(default='not None', allow_None=False)
105 s3 = param.Parameter(default='not None', allow_None=True)
106 s4 = param.Parameter(default=None)
107 s5 = param.Parameter(default=None, allow_None=False)
108 s6 = param.Parameter(default=None, allow_None=True)
109
110 assert A.param.s1.allow_None is False
111 assert A.param.s2.allow_None is False
112 assert A.param.s3.allow_None is True
113 assert A.param.s4.allow_None is True
114 assert A.param.s5.allow_None is True
115 assert A.param.s6.allow_None is True
116
117
118 def test_defaults_parameter_unbound_allow_None():
119 s1 = param.Parameter(default='not None')
120 s2 = param.Parameter(default='not None', allow_None=False)
121 s3 = param.Parameter(default='not None', allow_None=True)
122 s4 = param.Parameter(default=None)
123 s5 = param.Parameter(default=None, allow_None=False)
124 s6 = param.Parameter(default=None, allow_None=True)
125
126 assert s1.allow_None is False
127 assert s2.allow_None is False
128 assert s3.allow_None is True
129 assert s4.allow_None is True
130 assert s5.allow_None is True
131 assert s6.allow_None is True
0 import os
1 import shutil
2 import tempfile
3
4 import param
5
6 from . import API1TestCase
7 from .utils import check_defaults
8
9
10 class TestFileSelectorParameters(API1TestCase):
11
12 def setUp(self):
13 super(TestFileSelectorParameters, self).setUp()
14
15 tmpdir1 = tempfile.mkdtemp()
16 fa = os.path.join(tmpdir1, 'a.txt')
17 fb = os.path.join(tmpdir1, 'b.txt')
18 glob1 = os.path.join(tmpdir1, '*')
19 open(fa, 'w').close()
20 open(fb, 'w').close()
21 tmpdir2 = tempfile.mkdtemp()
22 fc = os.path.join(tmpdir2, 'c.txt')
23 fd = os.path.join(tmpdir2, 'd.txt')
24 glob2 = os.path.join(tmpdir2, '*')
25 open(fc, 'w').close()
26 open(fd, 'w').close()
27
28 self.tmpdir1 = tmpdir1
29 self.tmpdir2 = tmpdir2
30 self.fa = fa
31 self.fb = fb
32 self.fc = fc
33 self.fd = fd
34 self.glob1 = glob1
35 self.glob2 = glob2
36
37 class P(param.Parameterized):
38 a = param.FileSelector(path=glob1)
39 b = param.FileSelector(default=fa, path=glob1)
40
41 self.P = P
42
43 def tearDown(self):
44 shutil.rmtree(self.tmpdir1)
45 shutil.rmtree(self.tmpdir2)
46
47 def _check_defaults(self, p):
48 assert p.default is None
49 assert p.allow_None is None
50 assert p.objects == []
51 assert p.compute_default_fn is None
52 assert p.check_on_set is False
53 assert p.names is None
54 assert p.path == ""
55
56 def test_defaults_class(self):
57 class P(param.Parameterized):
58 s = param.FileSelector()
59
60 check_defaults(P.param.s, label='S')
61 self._check_defaults(P.param.s)
62
63 def test_defaults_inst(self):
64 class P(param.Parameterized):
65 s = param.FileSelector()
66
67 p = P()
68
69 check_defaults(p.param.s, label='S')
70 self._check_defaults(p.param.s)
71
72 def test_defaults_unbound(self):
73 s = param.FileSelector()
74
75 check_defaults(s, label=None)
76 self._check_defaults(s)
77
78 def test_default_is_None(self):
79 p = self.P()
80 assert p.a is None
81 assert p.param.a.default is None
82
83 def test_default_is_honored(self):
84 p = self.P()
85 assert p.b == self.fa
86 assert p.param.b.default in [self.fa, self.fb]
87
88 def test_allow_default_None(self):
89 class P(param.Parameterized):
90 a = param.FileSelector(default=None)
91
92 def test_default_not_in_glob(self):
93 with self.assertRaises(ValueError):
94 class P(param.Parameterized):
95 a = param.FileSelector(default='not/in/glob', path=self.glob1)
96
97 def test_objects_auto_set(self):
98 p = self.P()
99 assert p.param.a.objects == [self.fa, self.fb]
100
101 def test_set_object_constructor(self):
102 p = self.P(a=self.fb)
103 assert p.a == self.fb
104
105 def test_set_object_outside_bounds(self):
106 p = self.P()
107 with self.assertRaises(ValueError):
108 p.a = '/not/in/glob'
109
110 def test_set_path_and_update(self):
111 p = self.P()
112 p.param.b.path = self.glob2
113 p.param.b.update()
114 assert p.param.b.objects == [self.fc, self.fd]
115 assert p.param.b.default in [self.fc, self.fd]
116 # Default updated but not the value itself
117 assert p.b == self.fa
118
119 def test_get_range(self):
120 p = self.P()
121 r = p.param.a.get_range()
122 assert r['a.txt'] == self.fa
123 assert r['b.txt'] == self.fb
124 p.param.a.path = self.glob2
125 p.param.a.update()
126 r = p.param.a.get_range()
127 assert r['c.txt'] == self.fc
128 assert r['d.txt'] == self.fd
129
130 def test_update_file_removed(self):
131 p = self.P()
132 assert p.param.b.objects == [self.fa, self.fb]
133 assert p.param.b.default in [self.fa, self.fb]
134 os.remove(self.fa)
135 p.param.b.update()
136 assert p.param.b.objects == [self.fb]
137 assert p.param.b.default == self.fb
00 import param
11 from . import API1TestCase
2 from .utils import check_defaults
23 # TODO: I copied the tests from testobjectselector, although I
34 # struggled to understand some of them. Both files should be reviewed
45 # and cleaned up together.
1516 l = param.List(["red","green","blue"], item_type=str, bounds=(0,10))
1617
1718 self.P = P
19
20 def _check_defaults(self, p):
21 assert p.default == []
22 assert p.allow_None is False
23 assert p.class_ is None
24 assert p.item_type is None
25 assert p.bounds == (0, None)
26 assert p.instantiate is True
27
28 def test_defaults_class(self):
29 class P(param.Parameterized):
30 l = param.List()
31
32 check_defaults(P.param.l, label='L', skip=['instantiate'])
33 self._check_defaults(P.param.l)
34
35 def test_defaults_inst(self):
36 class P(param.Parameterized):
37 l = param.List()
38
39 p = P()
40
41 check_defaults(p.param.l, label='L', skip=['instantiate'])
42 self._check_defaults(p.param.l)
43
44 def test_defaults_unbound(self):
45 l = param.List()
46
47 check_defaults(l, label=None, skip=['instantiate'])
48 self._check_defaults(l)
1849
1950 def test_default_None(self):
2051 class Q(param.Parameterized):
5081 pass
5182 else:
5283 raise AssertionError("Object set outside range.")
84
85
86 class TestHookListParameters(API1TestCase):
87
88 def setUp(self):
89 super(TestHookListParameters, self).setUp()
90 class P(param.Parameterized):
91 e = param.HookList([abs])
92 l = param.HookList(bounds=(0,10))
93
94 self.P = P
95
96 def _check_defaults(self, p):
97 assert p.default == []
98 assert p.allow_None is False
99 assert p.class_ is None
100 assert p.item_type is None
101 assert p.bounds == (0, None)
102 assert p.instantiate is True
103
104 def test_defaults_class(self):
105 class P(param.Parameterized):
106 l = param.HookList()
107
108 check_defaults(P.param.l, label='L', skip=['instantiate'])
109 self._check_defaults(P.param.l)
110
111 def test_defaults_inst(self):
112 class P(param.Parameterized):
113 l = param.HookList()
114
115 p = P()
116
117 check_defaults(p.param.l, label='L', skip=['instantiate'])
118 self._check_defaults(p.param.l)
119
120 def test_defaults_unbound(self):
121 l = param.HookList()
122
123 check_defaults(l, label=None, skip=['instantiate'])
124 self._check_defaults(l)
125
126 def test_default_None(self):
127 class Q(param.Parameterized):
128 r = param.HookList(default=[]) # Also check None)
129
130 def test_set_object_constructor(self):
131 p = self.P(e=[abs])
132 self.assertEqual(p.e, [abs])
133
134 def test_set_object_outside_bounds(self):
135 p = self.P()
136 try:
137 p.l = [abs]*11
138 except ValueError:
139 pass
140 else:
141 raise AssertionError("Object set outside range.")
142
143 def test_set_object_wrong_type_foo(self):
144 p = self.P()
145 try:
146 p.e = ['s']
147 except ValueError:
148 pass
149 else:
150 raise AssertionError("Object allowed of wrong type.")
151
152 def test_set_object_not_None(self):
153 p = self.P()
154 try:
155 p.e = None
156 except ValueError:
157 pass
158 else:
159 raise AssertionError("Object set outside range.")
00 import param
11 from . import API1TestCase
2 from .utils import check_defaults
23 # TODO: I copied the tests from testobjectselector, although I
34 # struggled to understand some of them. Both files should be reviewed
45 # and cleaned up together.
1920
2021 self.P = P
2122
23 def _check_defaults(self, p):
24 assert p.default is None
25 assert p.allow_None is None
26 assert p.objects == []
27 assert p.compute_default_fn is None
28 assert p.check_on_set is False
29 assert p.names is None
30
31 def test_defaults_class(self):
32 class P(param.Parameterized):
33 s = param.ListSelector()
34
35 check_defaults(P.param.s, label='S')
36 self._check_defaults(P.param.s)
37
38 def test_defaults_inst(self):
39 class P(param.Parameterized):
40 s = param.ListSelector()
41
42 p = P()
43
44 check_defaults(p.param.s, label='S')
45 self._check_defaults(p.param.s)
46
47 def test_defaults_unbound(self):
48 s = param.ListSelector()
49
50 check_defaults(s, label=None)
51 self._check_defaults(s)
52
2253 def test_default_None(self):
2354 class Q(param.Parameterized):
2455 r = param.ListSelector(default=None)
2657 def test_set_object_constructor(self):
2758 p = self.P(e=[6])
2859 self.assertEqual(p.e, [6])
60
61 def test_allow_None_is_None(self):
62 p = self.P()
63 assert p.param.e.allow_None is None
64 assert p.param.f.allow_None is None
65 assert p.param.g.allow_None is None
66 assert p.param.h.allow_None is None
67 assert p.param.i.allow_None is None
68
2969
3070 def test_set_object_outside_bounds(self):
3171 p = self.P(e=[6])
5191 p.g = [7]
5292 try:
5393 p.g = None
54 except TypeError:
94 except ValueError:
5595 pass
5696 else:
5797 raise AssertionError("Object set outside range.")
108148 ### new tests (not copied from testobjectselector)
109149
110150 def test_bad_default(self):
111 with self.assertRaises(TypeError):
151 with self.assertRaises(ValueError):
112152 class Q(param.Parameterized):
113153 r = param.ListSelector(default=6,check_on_set=True)
114154
115155 def test_implied_check_on_set(self):
116 with self.assertRaises(TypeError):
156 with self.assertRaises(ValueError):
117157 class Q(param.Parameterized):
118158 r = param.ListSelector(default=7,objects=[7,8])
119159
133173 class Q(param.Parameterized):
134174 r = param.ListSelector(default=6,check_on_set=False)
135175
136 with self.assertRaises(TypeError):
176 with self.assertRaises(ValueError):
137177 Q.r = 6
138178 ##########################
139179
153193
154194 with self.assertRaises(TypeError):
155195 Q.param.params('r').compute_default()
196
197 def test_initialization_bad_iterable(self):
198 with self.assertRaises(ValueError):
199 class Q(param.Parameterized):
200 j = param.ListSelector('ab', ['a', 'b', 'c', 'd'])
201
202 def test_set_bad_iterable(self):
203 class Q(param.Parameterized):
204 r = param.ListSelector(objects=['a', 'b', 'c', 'd'])
205
206 q = Q()
207 with self.assertRaises(ValueError):
208 q.r = 'ab'
0 import os
1 import shutil
2 import tempfile
3
4 import param
5
6 from . import API1TestCase
7 from .utils import check_defaults
8
9
10 class TestMultiFileSelectorParameters(API1TestCase):
11
12 def setUp(self):
13 super(TestMultiFileSelectorParameters, self).setUp()
14
15 tmpdir1 = tempfile.mkdtemp()
16 fa = os.path.join(tmpdir1, 'a.txt')
17 fb = os.path.join(tmpdir1, 'b.txt')
18 glob1 = os.path.join(tmpdir1, '*')
19 open(fa, 'w').close()
20 open(fb, 'w').close()
21 tmpdir2 = tempfile.mkdtemp()
22 fc = os.path.join(tmpdir2, 'c.txt')
23 fd = os.path.join(tmpdir2, 'd.txt')
24 glob2 = os.path.join(tmpdir2, '*')
25 open(fc, 'w').close()
26 open(fd, 'w').close()
27
28 self.tmpdir1 = tmpdir1
29 self.tmpdir2 = tmpdir2
30 self.fa = fa
31 self.fb = fb
32 self.fc = fc
33 self.fd = fd
34 self.glob1 = glob1
35 self.glob2 = glob2
36
37 class P(param.Parameterized):
38 a = param.MultiFileSelector(path=glob1)
39 b = param.MultiFileSelector(default=[fa], path=glob1)
40
41 self.P = P
42
43 def tearDown(self):
44 shutil.rmtree(self.tmpdir1)
45 shutil.rmtree(self.tmpdir2)
46
47 def _check_defaults(self, p):
48 assert p.default is None
49 assert p.allow_None is None
50 assert p.objects == []
51 assert p.compute_default_fn is None
52 assert p.check_on_set is False
53 assert p.names is None
54 assert p.path == ''
55
56 def test_defaults_class(self):
57 class P(param.Parameterized):
58 s = param.MultiFileSelector()
59
60 check_defaults(P.param.s, label='S')
61 self._check_defaults(P.param.s)
62
63 def test_defaults_inst(self):
64 class P(param.Parameterized):
65 s = param.MultiFileSelector()
66
67 p = P()
68
69 check_defaults(p.param.s, label='S')
70 self._check_defaults(p.param.s)
71
72 def test_defaults_unbound(self):
73 s = param.MultiFileSelector()
74
75 check_defaults(s, label=None)
76 self._check_defaults(s)
77
78 def test_default_is_None(self):
79 p = self.P()
80 assert p.a is None
81 assert p.param.a.default is None
82
83 def test_default_is_honored(self):
84 p = self.P()
85 assert p.b == [self.fa]
86 assert p.param.b.default ==[self.fa]
87
88 def test_allow_default_None(self):
89 class P(param.Parameterized):
90 a = param.MultiFileSelector(default=None)
91
92 def test_objects_auto_set(self):
93 p = self.P()
94 assert p.param.a.objects == [self.fa, self.fb]
95
96 def test_default_not_in_glob(self):
97 with self.assertRaises(ValueError):
98 class P(param.Parameterized):
99 a = param.MultiFileSelector(default=['not/in/glob'], path=self.glob1)
100
101 def test_objects_auto_set(self):
102 p = self.P()
103 assert sorted(p.param.a.objects) == sorted([self.fa, self.fb])
104
105 def test_set_object_constructor(self):
106 p = self.P(a=[self.fb])
107 assert p.a == [self.fb]
108
109 def test_set_object_outside_bounds(self):
110 p = self.P()
111 with self.assertRaises(ValueError):
112 p.a = ['/not/in/glob']
113
114 def test_set_path_and_update(self):
115 p = self.P()
116 p.param.b.path = self.glob2
117 p.param.b.update()
118 assert sorted(p.param.b.objects) == sorted([self.fc, self.fd])
119 assert sorted(p.param.b.default) == sorted([self.fc, self.fd])
120 # Default updated but not the value itself
121 assert p.b == [self.fa]
122
123 def test_get_range(self):
124 p = self.P()
125 r = p.param.a.get_range()
126 assert r['a.txt'] == self.fa
127 assert r['b.txt'] == self.fb
128 p.param.a.path = self.glob2
129 p.param.a.update()
130 r = p.param.a.get_range()
131 assert r['c.txt'] == self.fc
132 assert r['d.txt'] == self.fd
133
134 def test_update_file_removed(self):
135 p = self.P()
136 assert p.param.b.objects == [self.fa, self.fb]
137 assert p.param.b.default == [self.fa]
138 os.remove(self.fa)
139 p.param.b.update()
140 assert p.param.b.objects == [self.fb]
141 assert p.param.b.default == [self.fb]
11 Unit test for Number parameters and their subclasses.
22 """
33 import param
4 import datetime as dt
54 from . import API1TestCase
5 from .utils import check_defaults
66
77
88 class TestNumberParameters(API1TestCase):
9
10 def setUp(self):
11 super(TestNumberParameters, self).setUp()
12 class P(param.Parameterized):
13 b = param.Number(allow_None=False)
14 c = param.Number(default=1, allow_None=True)
15 d = param.Number(default=None)
16 e = param.Number(default=1)
17 f = param.Number(default=1, step=0.5)
18 g = param.Number(default=lambda: 1)
19 h = param.Number(default=1, bounds=(0, 2))
20 i = param.Number(bounds=(-1, 1))
21 j = param.Number(bounds=(-1, 1), inclusive_bounds=(False, True))
22 k = param.Number(bounds=(-1, 1), inclusive_bounds=(True, False))
23 l = param.Number(bounds=(-1, 1), inclusive_bounds=(False, False))
24 m = param.Number(bounds=(-1, None))
25 n = param.Number(bounds=(None, 1))
26
27 self.P = P
28
29 def _check_defaults(self, p):
30 assert p.default == 0.0
31 assert p.allow_None is False
32 assert p.bounds is None
33 assert p.softbounds is None
34 assert p.inclusive_bounds == (True, True)
35 assert p.step is None
36
37 def test_defaults_class(self):
38 class A(param.Parameterized):
39 n = param.Number()
40
41 check_defaults(A.param.n, label='N')
42 self._check_defaults(A.param.n)
43
44 def test_defaults_inst(self):
45 class A(param.Parameterized):
46 n = param.Number()
47
48 a = A()
49
50 check_defaults(a.param.n, label='N')
51 self._check_defaults(a.param.n)
52
53 def test_defaults_unbound(self):
54 n = param.Number()
55
56 check_defaults(n, label=None)
57 self._check_defaults(n)
58
59 def test_allow_None_class(self):
60 self.P.c = None
61 assert self.P.c is None
62 self.P.d = None
63 assert self.P.d is None
64
65 exception = "Parameter 'b' only takes numeric values, not type <(class|type) 'NoneType'>."
66 with self.assertRaisesRegex(ValueError, exception):
67 self.P.b = None
68
69 def test_allow_None_inst(self):
70 p = self.P()
71 p.c = None
72 assert p.c is None
73 p.d = None
74 assert p.d is None
75
76 exception = "Parameter 'b' only takes numeric values, not type <(class|type) 'NoneType'>."
77 with self.assertRaisesRegex(ValueError, exception):
78 p.b = None
79
80 def test_initialization_without_step_class(self):
81 self.assertEqual(self.P.param['e'].step, None)
82
83 def test_initialization_with_step_class(self):
84 self.assertEqual(self.P.param['f'].step, 0.5)
85
86 def test_initialization_without_step_instance(self):
87 p = self.P()
88 self.assertEqual(p.param['e'].step, None)
89
90 def test_initialization_with_step_instance(self):
91 p = self.P()
92 self.assertEqual(p.param['f'].step, 0.5)
93
94 def test_step_invalid_type_number_parameter(self):
95 exception = "Step can only be None or a numeric value"
96 with self.assertRaisesRegex(ValueError, exception):
97 param.Number(step='invalid value')
98
99 def test_outside_bounds(self):
100 exception = "Parameter 'h' must be at most 2, not 10."
101 with self.assertRaisesRegex(ValueError, exception):
102 self.P.h = 10
103
104 p = self.P()
105
106 with self.assertRaisesRegex(ValueError, exception):
107 p.h = 10
108
109 def test_unbounded_side_class(self):
110 self.P.m = 10
111 assert self.P.m == 10
112
113 exception = "Parameter 'm' must be at least -1, not -10."
114 with self.assertRaisesRegex(ValueError, exception):
115 self.P.m = -10
116
117 self.P.n = -10
118 assert self.P.n == -10
119
120 exception = "Parameter 'n' must be at most 1, not 10."
121 with self.assertRaisesRegex(ValueError, exception):
122 self.P.n = 10
123
124 def test_unbounded_side_inst(self):
125 p = self.P()
126
127 p.m = 10
128 assert p.m == 10
129
130 exception = "Parameter 'm' must be at least -1, not -10."
131 with self.assertRaisesRegex(ValueError, exception):
132 p.m = -10
133
134 p.n = -10
135 assert p.n == -10
136
137 exception = "Parameter 'n' must be at most 1, not 10."
138 with self.assertRaisesRegex(ValueError, exception):
139 p.n = 10
140
141 def test_inclusive_bounds_no_error_class(self):
142 self.P.i = -1
143 assert self.P.i == -1
144 self.P.i = 1
145 assert self.P.i == 1
146
147 self.P.j = 1
148 assert self.P.j == 1
149
150 self.P.k = -1
151 assert self.P.k == -1
152
153 def test_inclusive_bounds_no_error_inst(self):
154 p = self.P()
155 p.i = -1
156 assert p.i == -1
157 p.i = 1
158 assert p.i == 1
159
160 p.j = 1
161 assert p.j == 1
162
163 p.k = -1
164 assert p.k == -1
165
166 def test_inclusive_bounds_error_on_bounds(self):
167 p = self.P()
168 exception = "Parameter 'j' must be greater than -1, not -1."
169 with self.assertRaisesRegex(ValueError, exception):
170 self.P.j = -1
171 with self.assertRaisesRegex(ValueError, exception):
172 p.j = -1
173
174 exception = "Parameter 'k' must be less than 1, not 1."
175 with self.assertRaisesRegex(ValueError, exception):
176 self.P.k = 1
177 with self.assertRaisesRegex(ValueError, exception):
178 p.k = 1
179
180 exception = "Parameter 'l' must be greater than -1, not -1."
181 with self.assertRaisesRegex(ValueError, exception):
182 self.P.l = -1
183 with self.assertRaisesRegex(ValueError, exception):
184 p.l = -1
185 exception = "Parameter 'l' must be less than 1, not 1."
186 with self.assertRaisesRegex(ValueError, exception):
187 self.P.l = 1
188 with self.assertRaisesRegex(ValueError, exception):
189 p.l = 1
190
191 def test_inclusive_bounds_error_on_bounds_post(self):
192 exception = "Parameter None must be greater than -1, not -1."
193 with self.assertRaisesRegex(ValueError, exception):
194 class P(param.Parameterized):
195 j = param.Number(default=-1, bounds=(-1, 1), inclusive_bounds=(False, True))
196
197 exception = "Parameter None must be less than 1, not 1"
198 with self.assertRaisesRegex(ValueError, exception):
199 class P(param.Parameterized):
200 j = param.Number(default=1, bounds=(-1, 1), inclusive_bounds=(True, False))
201
202 exception = "Parameter None must be greater than -1, not -1."
203 with self.assertRaisesRegex(ValueError, exception):
204 class P(param.Parameterized):
205 j = param.Number(default=-1, bounds=(-1, 1), inclusive_bounds=(False, False))
206
207 exception = "Parameter None must be less than 1, not 1."
208 with self.assertRaisesRegex(ValueError, exception):
209 class P(param.Parameterized):
210 j = param.Number(default=1, bounds=(-1, 1), inclusive_bounds=(False, False))
211
212 def test_invalid_default_for_bounds(self):
213 exception = "Parameter None must be at least 10, not 0.0."
214 with self.assertRaisesRegex(ValueError, exception):
215 class P(param.Parameterized):
216 n = param.Number(bounds=(10, 20))
217
218 def test_callable(self):
219 assert self.P.g == 1
220 p = self.P()
221 assert p.g == 1
222
223 def test_callable_wrong_type(self):
224 class Q(param.Parameterized):
225 q = param.Number(default=lambda: 'test')
226
227 exception = "Parameter 'q' only takes numeric values, not type <(class|type) 'str'>."
228 with self.assertRaisesRegex(ValueError, exception):
229 Q.q
230
231 q = Q()
232
233 with self.assertRaisesRegex(ValueError, exception):
234 q.q
235
236 def test_callable_outside_bounds(self):
237 class Q(param.Parameterized):
238 q = param.Number(default=lambda: 2, bounds=(0, 1))
239
240 exception = "Parameter 'q' must be at most 1, not 2."
241 with self.assertRaisesRegex(ValueError, exception):
242 Q.q
243
244 q = Q()
245
246 with self.assertRaisesRegex(ValueError, exception):
247 q.q
248
249 def test_crop_to_bounds(self):
250 p = self.P()
251
252 # when allow_None is True
253 assert p.param.d.crop_to_bounds(None) is None
254
255 # no bounds
256 assert p.param.e.crop_to_bounds(10000) == 10000
257
258 # with concrete bounds
259 assert p.param.h.crop_to_bounds(10) == 2
260 assert p.param.h.crop_to_bounds(-10) == 0
261
262 # return default if non numerical
263 assert p.param.e.crop_to_bounds('test') == 1
264
265 # Unbound
266 assert p.param.m.crop_to_bounds(10) == 10
267 assert p.param.n.crop_to_bounds(-10) == -10
268
269
270 class TestIntegerParameters(API1TestCase):
271
272 def setUp(self):
273 super(TestIntegerParameters, self).setUp()
274 class P(param.Parameterized):
275 b = param.Integer(allow_None=False)
276 c = param.Integer(default=1, allow_None=True)
277 d = param.Integer(default=None)
278 e = param.Integer(default=1)
279 f = param.Integer(default=1, step=1)
280 g = param.Integer(default=lambda: 1)
281 h = param.Integer(default=1, bounds=(0, 2))
282 i = param.Integer(bounds=(-1, 1))
283 j = param.Integer(bounds=(-1, 1), inclusive_bounds=(False, True))
284 k = param.Integer(bounds=(-1, 1), inclusive_bounds=(True, False))
285 l = param.Integer(bounds=(-1, 1), inclusive_bounds=(False, False))
286 m = param.Integer(bounds=(-1, None))
287 n = param.Integer(bounds=(None, 1))
288
289 self.P = P
290
291 def _check_defaults(self, p):
292 assert isinstance(p.default, int)
293 assert p.default == 0
294 assert p.allow_None is False
295 assert p.bounds is None
296 assert p.softbounds is None
297 assert p.inclusive_bounds == (True, True)
298 assert p.step is None
299
300 def test_defaults_class(self):
301 class A(param.Parameterized):
302 n = param.Integer()
303
304 check_defaults(A.param.n, label='N')
305 self._check_defaults(A.param.n)
306
307 def test_defaults_inst(self):
308 class A(param.Parameterized):
309 n = param.Integer()
310
311 a = A()
312
313 check_defaults(a.param.n, label='N')
314 self._check_defaults(a.param.n)
315
316 def test_defaults_unbound(self):
317 n = param.Integer()
318
319 check_defaults(n, label=None)
320 self._check_defaults(n)
321
322 def test_allow_None_class(self):
323 self.P.c = None
324 assert self.P.c is None
325 self.P.d = None
326 assert self.P.d is None
327
328 exception = "Integer parameter 'b' must be an integer, not type <(class|type) 'NoneType'>."
329 with self.assertRaisesRegex(ValueError, exception):
330 self.P.b = None
331
332 def test_allow_None_inst(self):
333 p = self.P()
334 p.c = None
335 assert p.c is None
336 p.d = None
337 assert p.d is None
338
339 exception = "Integer parameter 'b' must be an integer, not type <(class|type) 'NoneType'>."
340 with self.assertRaisesRegex(ValueError, exception):
341 p.b = None
9342
10343 def test_initialization_without_step_class(self):
11344 class Q(param.Parameterized):
12 q = param.Number(default=1)
345 q = param.Integer(default=1)
13346
14347 self.assertEqual(Q.param['q'].step, None)
15348
349
350 def test_initialization_without_step_class(self):
351 self.assertEqual(self.P.param['e'].step, None)
352
16353 def test_initialization_with_step_class(self):
17 class Q(param.Parameterized):
18 q = param.Number(default=1, step=0.5)
19
20 self.assertEqual(Q.param['q'].step, 0.5)
354 self.assertEqual(self.P.param['f'].step, 1)
21355
22356 def test_initialization_without_step_instance(self):
23 class Q(param.Parameterized):
24 q = param.Number(default=1)
25
26 qobj = Q()
27 self.assertEqual(qobj.param['q'].step, None)
357 p = self.P()
358 self.assertEqual(p.param['e'].step, None)
28359
29360 def test_initialization_with_step_instance(self):
30 class Q(param.Parameterized):
31 q = param.Number(default=1, step=0.5)
32
33 qobj = Q()
34 self.assertEqual(qobj.param['q'].step, 0.5)
361 p = self.P()
362 self.assertEqual(p.param['f'].step, 1)
35363
36364 def test_step_invalid_type_number_parameter(self):
37 exception = "Step can only be None or a numeric value"
38 with self.assertRaisesRegex(ValueError, exception):
39 param.Number(step='invalid value')
365 exception = "Step can only be None or an integer value"
366 with self.assertRaisesRegex(ValueError, exception):
367 param.Integer(step='invalid value')
40368
41369 def test_step_invalid_type_integer_parameter(self):
42370 exception = "Step can only be None or an integer value"
43371 with self.assertRaisesRegex(ValueError, exception):
44372 param.Integer(step=3.4)
45373
46 def test_step_invalid_type_datetime_parameter(self):
47 exception = "Step can only be None, a datetime or datetime type"
48 with self.assertRaisesRegex(ValueError, exception):
49 param.Date(dt.datetime(2017,2,27), step=3.2)
50
51 def test_step_invalid_type_date_parameter(self):
52 exception = "Step can only be None or a date type"
53 with self.assertRaisesRegex(ValueError, exception):
54 param.CalendarDate(dt.date(2017,2,27), step=3.2)
374 def test_outside_bounds(self):
375 exception = "Parameter 'h' must be at most 2, not 10."
376 with self.assertRaisesRegex(ValueError, exception):
377 self.P.h = 10
378
379 p = self.P()
380
381 with self.assertRaisesRegex(ValueError, exception):
382 p.h = 10
383
384 def test_unbounded_side_class(self):
385 self.P.m = 10
386 assert self.P.m == 10
387
388 exception = "Parameter 'm' must be at least -1, not -10."
389 with self.assertRaisesRegex(ValueError, exception):
390 self.P.m = -10
391
392 self.P.n = -10
393 assert self.P.n == -10
394
395 exception = "Parameter 'n' must be at most 1, not 10."
396 with self.assertRaisesRegex(ValueError, exception):
397 self.P.n = 10
398
399 def test_unbounded_side_inst(self):
400 p = self.P()
401
402 p.m = 10
403 assert p.m == 10
404
405 exception = "Parameter 'm' must be at least -1, not -10."
406 with self.assertRaisesRegex(ValueError, exception):
407 p.m = -10
408
409 p.n = -10
410 assert p.n == -10
411
412 exception = "Parameter 'n' must be at most 1, not 10."
413 with self.assertRaisesRegex(ValueError, exception):
414 p.n = 10
415
416 def test_inclusive_bounds_no_error_class(self):
417 self.P.i = -1
418 assert self.P.i == -1
419 self.P.i = 1
420 assert self.P.i == 1
421
422 self.P.j = 1
423 assert self.P.j == 1
424
425 self.P.k = -1
426 assert self.P.k == -1
427
428 def test_inclusive_bounds_no_error_inst(self):
429 p = self.P()
430 p.i = -1
431 assert p.i == -1
432 p.i = 1
433 assert p.i == 1
434
435 p.j = 1
436 assert p.j == 1
437
438 p.k = -1
439 assert p.k == -1
440
441 def test_inclusive_bounds_error_on_bounds(self):
442 p = self.P()
443 exception = "Parameter 'j' must be greater than -1, not -1."
444 with self.assertRaisesRegex(ValueError, exception):
445 self.P.j = -1
446 with self.assertRaisesRegex(ValueError, exception):
447 p.j = -1
448
449 exception = "Parameter 'k' must be less than 1, not 1."
450 with self.assertRaisesRegex(ValueError, exception):
451 self.P.k = 1
452 with self.assertRaisesRegex(ValueError, exception):
453 p.k = 1
454
455 exception = "Parameter 'l' must be greater than -1, not -1."
456 with self.assertRaisesRegex(ValueError, exception):
457 self.P.l = -1
458 with self.assertRaisesRegex(ValueError, exception):
459 p.l = -1
460 exception = "Parameter 'l' must be less than 1, not 1."
461 with self.assertRaisesRegex(ValueError, exception):
462 self.P.l = 1
463 with self.assertRaisesRegex(ValueError, exception):
464 p.l = 1
465
466 def test_inclusive_bounds_error_on_bounds_post(self):
467 exception = "Parameter None must be greater than -1, not -1."
468 with self.assertRaisesRegex(ValueError, exception):
469 class P(param.Parameterized):
470 j = param.Integer(default=-1, bounds=(-1, 1), inclusive_bounds=(False, True))
471
472 exception = "Parameter None must be less than 1, not 1"
473 with self.assertRaisesRegex(ValueError, exception):
474 class P(param.Parameterized):
475 j = param.Integer(default=1, bounds=(-1, 1), inclusive_bounds=(True, False))
476
477 exception = "Parameter None must be greater than -1, not -1."
478 with self.assertRaisesRegex(ValueError, exception):
479 class P(param.Parameterized):
480 j = param.Integer(default=-1, bounds=(-1, 1), inclusive_bounds=(False, False))
481
482 exception = "Parameter None must be less than 1, not 1."
483 with self.assertRaisesRegex(ValueError, exception):
484 class P(param.Parameterized):
485 j = param.Integer(default=1, bounds=(-1, 1), inclusive_bounds=(False, False))
486
487 def test_invalid_default_for_bounds(self):
488 exception = "Parameter None must be at least 10, not 0."
489 with self.assertRaisesRegex(ValueError, exception):
490 class P(param.Parameterized):
491 n = param.Integer(bounds=(10, 20))
492
493 def test_callable(self):
494 assert self.P.g == 1
495 p = self.P()
496 assert p.g == 1
497
498 def test_callable_wrong_type(self):
499 class Q(param.Parameterized):
500 q = param.Integer(default=lambda: 'test')
501
502 exception = "Integer parameter 'q' must be an integer, not type <(class|type) 'str'>."
503 with self.assertRaisesRegex(ValueError, exception):
504 Q.q
505
506 q = Q()
507
508 with self.assertRaisesRegex(ValueError, exception):
509 q.q
510
511 def test_callable_outside_bounds(self):
512 class Q(param.Parameterized):
513 q = param.Integer(default=lambda: 2, bounds=(0, 1))
514
515 exception = "Parameter 'q' must be at most 1, not 2."
516 with self.assertRaisesRegex(ValueError, exception):
517 Q.q
518
519 q = Q()
520
521 with self.assertRaisesRegex(ValueError, exception):
522 q.q
523
524 def test_crop_to_bounds(self):
525 p = self.P()
526
527 # when allow_None is True
528 assert p.param.d.crop_to_bounds(None) is None
529
530 # no bounds
531 assert p.param.e.crop_to_bounds(10000) == 10000
532
533 # with concrete bounds
534 assert p.param.h.crop_to_bounds(10) == 2
535 assert p.param.h.crop_to_bounds(-10) == 0
536
537 # return default if non numerical
538 assert p.param.e.crop_to_bounds('test') == 1
539
540 # Unbound
541 assert p.param.m.crop_to_bounds(10) == 10
542 assert p.param.n.crop_to_bounds(-10) == -10
543
544
545 class TestMagnitudeParameters(API1TestCase):
546
547 def _check_defaults(self, p):
548 assert p.default == 1.0
549 assert p.allow_None is False
550 assert p.bounds == (0.0, 1.0)
551 assert p.softbounds is None
552 assert p.inclusive_bounds == (True, True)
553 assert p.step is None
554
555 def test_defaults_class(self):
556 class A(param.Parameterized):
557 n = param.Magnitude()
558
559 check_defaults(A.param.n, label='N')
560 self._check_defaults(A.param.n)
561
562 def test_defaults_inst(self):
563 class A(param.Parameterized):
564 n = param.Magnitude()
565
566 a = A()
567
568 check_defaults(a.param.n, label='N')
569 self._check_defaults(a.param.n)
570
571 def test_defaults_unbound(self):
572 n = param.Magnitude()
573
574 check_defaults(n, label=None)
575 self._check_defaults(n)
55
66 import param
77 from . import API1TestCase
8 from .utils import check_defaults
89
910 try:
1011 import numpy
2324
2425 # TODO: incomplete
2526 class TestNumpy(API1TestCase):
27
28 def _check_defaults(self, p):
29 assert p.default is None
30 assert p.allow_None is True
31 assert p.instantiate is True
32 assert p.is_instance is True
33 assert p.class_ == numpy.ndarray
34
35 def test_defaults_class(self):
36 class P(param.Parameterized):
37 s = param.Array()
38
39 check_defaults(P.param.s, label='S', skip=['instantiate'])
40 self._check_defaults(P.param.s)
41
42 def test_defaults_inst(self):
43 class P(param.Parameterized):
44 s = param.Array()
45
46 p = P()
47
48 check_defaults(p.param.s, label='S', skip=['instantiate'])
49 self._check_defaults(p.param.s)
50
51 def test_defaults_unbound(self):
52 s = param.Array()
53
54 check_defaults(s, label=None, skip=['instantiate'])
55 self._check_defaults(s)
56
2657 def test_array_param(self):
2758 class Z(param.Parameterized):
2859 z = param.Array(default=numpy.array([1]))
66
77 import param
88 from . import API1TestCase
9 from .utils import check_defaults
910 from collections import OrderedDict
1011
1112
2728
2829 self.P = P
2930
31 def _check_defaults(self, p):
32 assert p.default is None
33 assert p.allow_None is None
34 assert p.objects == []
35 assert p.compute_default_fn is None
36 assert p.check_on_set is False
37 assert p.names is None
38
39 def test_defaults_class(self):
40 class P(param.Parameterized):
41 s = param.ObjectSelector()
42
43 check_defaults(P.param.s, label='S')
44 self._check_defaults(P.param.s)
45
46 def test_defaults_inst(self):
47 class P(param.Parameterized):
48 s = param.ObjectSelector()
49
50 p = P()
51
52 check_defaults(p.param.s, label='S')
53 self._check_defaults(p.param.s)
54
55 def test_defaults_unbound(self):
56 s = param.ObjectSelector()
57
58 check_defaults(s, label=None)
59 self._check_defaults(s)
60
3061 def test_set_object_constructor(self):
3162 p = self.P(e=6)
3263 self.assertEqual(p.e, 6)
64
65 def test_allow_None_is_None(self):
66 p = self.P()
67 assert p.param.e.allow_None is None
68 assert p.param.f.allow_None is None
69 assert p.param.g.allow_None is None
70 assert p.param.h.allow_None is None
71 assert p.param.i.allow_None is None
72 assert p.param.s.allow_None is None
73 assert p.param.d.allow_None is None
3374
3475 def test_get_range_list(self):
3576 r = self.P.param.params("g").get_range()
55
66 import param
77 from . import API1TestCase
8 from .utils import check_defaults
89
910 try:
1011 import pandas
1718
1819 class TestDataFrame(API1TestCase):
1920
21 def _check_defaults(self, p):
22 assert p.default is None
23 assert p.allow_None is True
24 assert p.instantiate is True
25 assert p.is_instance is True
26 assert p.rows is None
27 assert p.columns is None
28 assert p.ordered is None
29 assert p.class_ == pandas.DataFrame
30
31 def test_defaults_class(self):
32 class P(param.Parameterized):
33 s = param.DataFrame()
34
35 check_defaults(P.param.s, label='S', skip=['instantiate'])
36 self._check_defaults(P.param.s)
37
38 def test_defaults_inst(self):
39 class P(param.Parameterized):
40 s = param.DataFrame()
41
42 p = P()
43
44 check_defaults(p.param.s, label='S', skip=['instantiate'])
45 self._check_defaults(p.param.s)
46
47 def test_defaults_unbound(self):
48 s = param.DataFrame()
49
50 check_defaults(s, label=None, skip=['instantiate'])
51 self._check_defaults(s)
52
2053 def test_dataframe_positional_argument(self):
2154 valid_df = pandas.DataFrame({'a':[1,2], 'b':[2,3], 'c':[4,5]},
2255 columns=['b', 'a', 'c'])
162195
163196 class TestSeries(API1TestCase):
164197
198 def _check_defaults(self, p):
199 assert p.default is None
200 assert p.allow_None is True
201 assert p.instantiate is True
202 assert p.is_instance is True
203 assert p.rows is None
204 assert p.class_ == pandas.Series
205
206 def test_defaults_class(self):
207 class P(param.Parameterized):
208 s = param.Series()
209
210 check_defaults(P.param.s, label='S', skip=['instantiate'])
211 self._check_defaults(P.param.s)
212
213 def test_defaults_inst(self):
214 class P(param.Parameterized):
215 s = param.Series()
216
217 p = P()
218
219 check_defaults(p.param.s, label='S', skip=['instantiate'])
220 self._check_defaults(p.param.s)
221
222 def test_defaults_unbound(self):
223 s = param.Series()
224
225 check_defaults(s, label=None, skip=['instantiate'])
226 self._check_defaults(s)
227
165228 def test_series_positional_argument(self):
166229 valid_series = pandas.Series([1,2])
167230 class Test(param.Parameterized):
0 import os
1 import shutil
2 import tempfile
3
4 import param
5
6 from . import API1TestCase
7 from .utils import check_defaults
8
9
10 class TestPathParameters(API1TestCase):
11
12 def setUp(self):
13 super(TestPathParameters, self).setUp()
14
15 tmpdir1 = tempfile.mkdtemp()
16 fa = os.path.join(tmpdir1, 'a.txt')
17 fb = os.path.join(tmpdir1, 'b.txt')
18 open(fa, 'w').close()
19 open(fb, 'w').close()
20
21 self.tmpdir1 = tmpdir1
22 self.fa = fa
23 self.fb = fb
24
25 class P(param.Parameterized):
26 a = param.Path()
27 b = param.Path(self.fb)
28 c = param.Path('a.txt', search_paths=[tmpdir1])
29
30 self.P = P
31
32 def tearDown(self):
33 shutil.rmtree(self.tmpdir1)
34
35 def _check_defaults(self, p):
36 assert p.default is None
37 assert p.allow_None is True
38 assert p.search_paths == []
39
40 def test_defaults_class(self):
41 class P(param.Parameterized):
42 p = param.Path()
43
44 check_defaults(P.param.p, label='P')
45 self._check_defaults(P.param.p)
46
47 def test_defaults_inst(self):
48 class P(param.Parameterized):
49 p = param.Path()
50
51 p = P()
52
53 check_defaults(p.param.p, label='P')
54 self._check_defaults(p.param.p)
55
56 def test_defaults_unbound(self):
57 p = param.Path()
58
59 check_defaults(p, label=None)
60 self._check_defaults(p)
61
62 def test_no_path_class(self):
63 assert self.P.a is None
64
65 def test_no_path_class(self):
66 p = self.P()
67 assert p.a is None
68
69 def test_inst_with_path(self):
70 p = self.P(a=self.fa)
71 assert isinstance(p.a, str)
72 assert os.path.isfile(p.a)
73 assert os.path.isabs(p.a)
74 assert p.a == self.fa
75
76 def test_set_to_None_allowed(self):
77 p = self.P()
78
79 assert p.param.b.allow_None is False
80 # This should probably raise an error (#708)
81 p.b = None
82
83 def test_search_paths(self):
84 p = self.P()
85
86 assert isinstance(p.c, str)
87 assert os.path.isfile(p.c)
88 assert os.path.isabs(p.c)
89 assert p.c == self.fa
90
91
92 class TestFilenameParameters(API1TestCase):
93
94 def setUp(self):
95 super(TestFilenameParameters, self).setUp()
96
97 tmpdir1 = tempfile.mkdtemp()
98 fa = os.path.join(tmpdir1, 'a.txt')
99 fb = os.path.join(tmpdir1, 'b.txt')
100 open(fa, 'w').close()
101 open(fb, 'w').close()
102
103 self.tmpdir1 = tmpdir1
104 self.fa = fa
105 self.fb = fb
106
107 class P(param.Parameterized):
108 a = param.Filename()
109 b = param.Filename(self.fb)
110 c = param.Filename('a.txt', search_paths=[tmpdir1])
111
112 self.P = P
113
114 def tearDown(self):
115 shutil.rmtree(self.tmpdir1)
116
117 def _check_defaults(self, p):
118 assert p.default is None
119 assert p.allow_None is True
120 assert p.search_paths == []
121
122 def test_defaults_class(self):
123 class P(param.Parameterized):
124 p = param.Filename()
125
126 check_defaults(P.param.p, label='P')
127 self._check_defaults(P.param.p)
128
129 def test_defaults_inst(self):
130 class P(param.Parameterized):
131 p = param.Filename()
132
133 p = P()
134
135 check_defaults(p.param.p, label='P')
136 self._check_defaults(p.param.p)
137
138 def test_defaults_unbound(self):
139 p = param.Filename()
140
141 check_defaults(p, label=None)
142 self._check_defaults(p)
143
144 def test_no_path_class(self):
145 assert self.P.a is None
146
147 def test_no_path_class(self):
148 p = self.P()
149 assert p.a is None
150
151 def test_inst_with_path(self):
152 p = self.P(a=self.fa)
153 assert isinstance(p.a, str)
154 assert os.path.isfile(p.a)
155 assert os.path.isabs(p.a)
156 assert p.a == self.fa
157
158 def test_set_to_None_allowed(self):
159 p = self.P()
160
161 assert p.param.b.allow_None is False
162 # This should probably raise an error (#708)
163 p.b = None
164
165 def test_search_paths(self):
166 p = self.P()
167
168 assert isinstance(p.c, str)
169 assert os.path.isfile(p.c)
170 assert os.path.isabs(p.c)
171 assert p.c == self.fa
172
173
174 class TestFoldernameParameters(API1TestCase):
175
176 def setUp(self):
177 super(TestFoldernameParameters, self).setUp()
178
179 tmpdir1 = tempfile.mkdtemp()
180 da = os.path.join(tmpdir1, 'da')
181 os.mkdir(da)
182
183 self.tmpdir1 = tmpdir1
184 self.da = da
185
186 class P(param.Parameterized):
187 a = param.Foldername()
188 b = param.Foldername(tmpdir1)
189 c = param.Path('da', search_paths=[tmpdir1])
190
191 self.P = P
192
193 def tearDown(self):
194 shutil.rmtree(self.tmpdir1)
195
196 def _check_defaults(self, p):
197 assert p.default is None
198 assert p.allow_None is True
199 assert p.search_paths == []
200
201 def test_defaults_class(self):
202 class P(param.Parameterized):
203 p = param.Foldername()
204
205 check_defaults(P.param.p, label='P')
206 self._check_defaults(P.param.p)
207
208 def test_defaults_inst(self):
209 class P(param.Parameterized):
210 p = param.Foldername()
211
212 p = P()
213
214 check_defaults(p.param.p, label='P')
215 self._check_defaults(p.param.p)
216
217 def test_defaults_unbound(self):
218 p = param.Foldername()
219
220 check_defaults(p, label=None)
221 self._check_defaults(p)
222
223 def test_no_path_class(self):
224 assert self.P.a is None
225
226 def test_no_path_class(self):
227 p = self.P()
228 assert p.a is None
229
230 def test_inst_with_path(self):
231 p = self.P(a=self.da)
232 assert isinstance(p.a, str)
233 assert os.path.isdir(p.a)
234 assert os.path.isabs(p.a)
235 assert p.a == self.da
236
237 def test_set_to_None_allowed(self):
238 p = self.P()
239
240 assert p.param.b.allow_None is False
241 # This should probably raise an error (#708)
242 p.b = None
243
244 def test_search_paths(self):
245 p = self.P()
246
247 assert isinstance(p.c, str)
248 assert os.path.isdir(p.c)
249 assert os.path.isabs(p.c)
250 assert p.c == self.da
55
66
77 class TestRangeParameters(API1TestCase):
8
9 def setUp(self):
10 super(TestRangeParameters, self).setUp()
11 class P(param.Parameterized):
12 e = param.Range()
13 f = param.Range(default=(0, 1), allow_None=True)
14 g = param.Range(default=(0, 1))
15
16 self.P = P
17
18 def _check_defaults(self, p):
19 assert p.default is None
20 assert p.allow_None is True
21 assert p.length == 2
22 assert p.bounds is None
23 assert p.softbounds is None
24 assert p.inclusive_bounds == (True, True)
25 assert p.step is None
26
27 def test_defaults_class(self):
28 class P(param.Parameterized):
29 r = param.Range()
30
31 self._check_defaults(P.param.r)
32
33 def test_defaults_inst(self):
34 class P(param.Parameterized):
35 r = param.Range()
36
37 p = P()
38
39 self._check_defaults(p.param.r)
40
41 def test_defaults_unbound(self):
42 r = param.Range()
43
44 self._check_defaults(r)
45
46 def test_set_object_constructor(self):
47 p = self.P(e=(0, 20))
48 assert p.e == (0, 20)
49
50 def test_raise_not_2_tuple(self):
51 p = self.P()
52 msg = r"Tuple parameter 'e' is not of the correct length \(3 instead of 2\)"
53 with self.assertRaisesRegex(ValueError, msg):
54 p.e = (1, 2, 3)
55
56 def test_raise_if_value_bad_length_constructor(self):
57 msg = r"Tuple parameter 'e' is not of the correct length \(3 instead of 2\)"
58 with self.assertRaisesRegex(ValueError, msg):
59 self.P(e=(1, 1, 1))
60
61 def test_raise_if_value_bad_length_setattr(self):
62 p = self.P()
63 msg = r"Tuple parameter 'e' is not of the correct length \(3 instead of 2\)"
64 with self.assertRaisesRegex(ValueError, msg):
65 p.e = (1, 1, 1)
66
67 def test_raise_if_default_is_None_and_no_length(self):
68 msg = "length must be specified if no default is supplied"
69 with self.assertRaisesRegex(ValueError, msg):
70 class P(param.Parameterized):
71 t = param.NumericTuple(default=None)
72
73 def test_bad_type(self):
74 msg = r"Tuple parameter 'e' only takes a tuple value, not <(class|type) 'str'>."
75
76 with self.assertRaisesRegex(ValueError, msg):
77 self.P.e = 'test'
78
79 with self.assertRaisesRegex(ValueError, msg):
80 self.P(e='test')
81
82 p = self.P()
83
84 with self.assertRaisesRegex(ValueError, msg):
85 p.e = 'test'
86
87 msg = r"Tuple parameter None only takes a tuple value, not <(class|type) 'str'>."
88 with self.assertRaisesRegex(ValueError, msg):
89 class P(param.Parameterized):
90 e = param.NumericTuple(default='test')
91
92 def test_support_allow_None_True(self):
93 p = self.P()
94 assert p.f == (0, 1)
95 p.f = None
96 assert p.f is None
97
98 class P(param.Parameterized):
99 f = param.Range(default=(0, 1), allow_None=True)
100
101 P.f = None
102 assert P.f is None
103
104 def test_support_allow_None_False(self):
105 p = self.P()
106 msg = "Tuple parameter 'g' only takes a tuple value, not <(class|type) 'NoneType'>."
107 with self.assertRaisesRegex(ValueError, msg):
108 p.g = None
109
110 msg = "Tuple parameter 'g' only takes a tuple value, not <(class|type) 'NoneType'>."
111 with self.assertRaisesRegex(ValueError, msg):
112 self.P.g = None
8113
9114 def test_initialization_out_of_bounds(self):
10115 try:
66
77 import param
88 from . import API1TestCase
9 from.utils import check_defaults
910 from collections import OrderedDict
1011
1112
2728
2829 self.P = P
2930
31 def _check_defaults(self, p):
32 assert p.default is None
33 assert p.allow_None is None
34 assert p.objects == []
35 assert p.compute_default_fn is None
36 assert p.check_on_set is False
37 assert p.names is None
38
39 def test_defaults_class(self):
40 class P(param.Parameterized):
41 s = param.Selector()
42
43 check_defaults(P.param.s, label='S')
44 self._check_defaults(P.param.s)
45
46 def test_defaults_inst(self):
47 class P(param.Parameterized):
48 s = param.Selector()
49
50 p = P()
51
52 check_defaults(p.param.s, label='S')
53 self._check_defaults(p.param.s)
54
55 def test_defaults_unbound(self):
56 s = param.Selector()
57
58 check_defaults(s, label=None)
59 self._check_defaults(s)
60
3061 def test_set_object_constructor(self):
3162 p = self.P(e=6)
3263 self.assertEqual(p.e, 6)
64
65 def test_allow_None_is_None(self):
66 p = self.P()
67 assert p.param.e.allow_None is None
68 assert p.param.f.allow_None is None
69 assert p.param.g.allow_None is None
70 assert p.param.h.allow_None is None
71 assert p.param.i.allow_None is None
72 assert p.param.s.allow_None is None
73 assert p.param.d.allow_None is None
3374
3475 def test_get_range_list(self):
3576 r = self.P.param.params("g").get_range()
33 import sys
44
55 from . import API1TestCase
6 from .utils import check_defaults
67
78 import param
89
1011 ip_regex = r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
1112
1213 class TestStringParameters(API1TestCase):
14
15 def _check_defaults(self, p):
16 assert p.default == ''
17 assert p.allow_None is False
18 assert p.regex is None
19
20 def test_defaults_class(self):
21 class A(param.Parameterized):
22 s = param.String()
23
24 check_defaults(A.param.s, label='S')
25 self._check_defaults(A.param.s)
26
27 def test_defaults_inst(self):
28 class A(param.Parameterized):
29 s = param.String()
30
31 a = A()
32
33 check_defaults(a.param.s, label='S')
34 self._check_defaults(a.param.s)
35
36 def test_defaults_unbound(self):
37 s = param.String()
38
39 check_defaults(s, label=None)
40 self._check_defaults(s)
1341
1442 def test_regex_ok(self):
1543 class A(param.Parameterized):
0 from . import API1TestCase
1 from .utils import check_defaults
2
3 import param
4 import pytest
5
6 try:
7 import numpy as np
8 except:
9 np = None
10
11
12 class TestTupleParameters(API1TestCase):
13
14 def setUp(self):
15 super(TestTupleParameters, self).setUp()
16 class P(param.Parameterized):
17 e = param.Tuple(default=(1, 1))
18 f = param.Tuple(default=(0, 0, 0))
19 g = param.Tuple(default=None, length=3)
20 h = param.Tuple(length=2, allow_None=True)
21
22 self.P = P
23
24 def _check_defaults(self, p):
25 assert p.default == (0, 0)
26 assert p.length == 2
27 assert p.allow_None is False
28
29 def test_defaults_class(self):
30 class P(param.Parameterized):
31 t = param.Tuple()
32
33 check_defaults(P.param.t, label='T')
34 self._check_defaults(P.param.t)
35
36 def test_defaults_inst(self):
37 class P(param.Parameterized):
38 t = param.Tuple()
39
40 p = P()
41
42 check_defaults(p.param.t, label='T')
43 self._check_defaults(p.param.t)
44
45 def test_defaults_unbound(self):
46 t = param.Tuple()
47
48 check_defaults(t, label=None)
49 self._check_defaults(t)
50
51 def test_set_object_constructor(self):
52 p = self.P(e=(2, 2))
53 self.assertEqual(p.e, (2, 2))
54
55 def test_length_inferred_from_default(self):
56 p = self.P()
57 assert p.param.f.length == 3
58
59 def test_raise_if_value_bad_length_constructor(self):
60 msg = r"Tuple parameter 'e' is not of the correct length \(3 instead of 2\)"
61 with self.assertRaisesRegex(ValueError, msg):
62 self.P(e=(1, 1, 'extra'))
63
64 def test_raise_if_value_bad_length_setattr(self):
65 p = self.P()
66 msg = r"Tuple parameter 'e' is not of the correct length \(3 instead of 2\)"
67 with self.assertRaisesRegex(ValueError, msg):
68 p.e = (1, 1, 'extra')
69
70 def test_raise_if_default_is_None_and_no_length(self):
71 msg = "length must be specified if no default is supplied"
72 with self.assertRaisesRegex(ValueError, msg):
73 class P(param.Parameterized):
74 t = param.Tuple(default=None)
75
76 def test_None_default(self):
77 p = self.P()
78 assert p.g is None
79 assert p.param.g.length == 3
80 assert p.param.g.allow_None
81
82 def test_raise_if_default_is_None_and_bad_length(self):
83 msg = r"Tuple parameter 'g' is not of the correct length \(2 instead of 3\)."
84 with self.assertRaisesRegex(ValueError, msg):
85 p = self.P(g=(0, 0))
86
87 p = self.P()
88 with self.assertRaisesRegex(ValueError, msg):
89 p.g = (0, 0)
90
91 def test_bad_type(self):
92 msg = r"Tuple parameter 'e' only takes a tuple value, not <(class|type) 'str'>."
93
94 with self.assertRaisesRegex(ValueError, msg):
95 self.P.e = 'test'
96
97 with self.assertRaisesRegex(ValueError, msg):
98 self.P(e='test')
99
100 p = self.P()
101
102 with self.assertRaisesRegex(ValueError, msg):
103 p.e = 'test'
104
105 msg = r"Tuple parameter None only takes a tuple value, not <(class|type) 'str'>."
106 with self.assertRaisesRegex(ValueError, msg):
107 class P(param.Parameterized):
108 e = param.Tuple(default='test')
109
110 def test_support_allow_None(self):
111 p = self.P()
112 assert p.h == (0, 0)
113 p.h = None
114 p.h = (1, 1)
115 assert p.h == (1, 1)
116
117 class P(param.Parameterized):
118 h = param.Tuple(length=2, allow_None=True)
119
120 P.h = None
121 P.h = (1, 1)
122 assert P.h == (1, 1)
123
124
125 class TestNumericTupleParameters(API1TestCase):
126
127 def setUp(self):
128 super(TestNumericTupleParameters, self).setUp()
129 class P(param.Parameterized):
130 e = param.NumericTuple(default=(1, 1))
131 f = param.NumericTuple(default=(0, 0, 0))
132 g = param.NumericTuple(default=None, length=3)
133 h = param.NumericTuple(length=2, allow_None=True)
134
135 self.P = P
136
137 def _check_defaults(self, p):
138 assert p.default == (0, 0)
139 assert p.length == 2
140 assert p.allow_None is False
141
142 def test_defaults_class(self):
143 class P(param.Parameterized):
144 t = param.NumericTuple()
145
146 check_defaults(P.param.t, label='T')
147 self._check_defaults(P.param.t)
148
149 def test_defaults_inst(self):
150 class P(param.Parameterized):
151 t = param.NumericTuple()
152
153 p = P()
154
155 check_defaults(p.param.t, label='T')
156 self._check_defaults(p.param.t)
157
158 def test_defaults_unbound(self):
159 t = param.NumericTuple()
160
161 check_defaults(t, label=None)
162 self._check_defaults(t)
163
164 def test_set_object_constructor(self):
165 p = self.P(e=(2, 2))
166 self.assertEqual(p.e, (2, 2))
167
168 def test_length_inferred_from_default(self):
169 p = self.P()
170 assert p.param.f.length == 3
171
172 def test_raise_if_value_bad_length_constructor(self):
173 msg = r"Tuple parameter 'e' is not of the correct length \(3 instead of 2\)"
174 with self.assertRaisesRegex(ValueError, msg):
175 self.P(e=(1, 1, 1))
176
177 def test_raise_if_value_bad_length_setattr(self):
178 p = self.P()
179 msg = r"Tuple parameter 'e' is not of the correct length \(3 instead of 2\)"
180 with self.assertRaisesRegex(ValueError, msg):
181 p.e = (1, 1, 1)
182
183 def test_raise_if_default_is_None_and_no_length(self):
184 msg = "length must be specified if no default is supplied"
185 with self.assertRaisesRegex(ValueError, msg):
186 class P(param.Parameterized):
187 t = param.NumericTuple(default=None)
188
189 def test_None_default(self):
190 p = self.P()
191 assert p.g is None
192 assert p.param.g.length == 3
193 assert p.param.g.allow_None
194
195 def test_raise_if_default_is_None_and_bad_length(self):
196 msg = r"Tuple parameter 'g' is not of the correct length \(2 instead of 3\)."
197 with self.assertRaisesRegex(ValueError, msg):
198 p = self.P(g=(0, 0))
199
200 p = self.P()
201 with self.assertRaisesRegex(ValueError, msg):
202 p.g = (0, 0)
203
204 def test_bad_type(self):
205 msg = r"Tuple parameter 'e' only takes a tuple value, not <(class|type) 'str'>."
206
207 with self.assertRaisesRegex(ValueError, msg):
208 self.P.e = 'test'
209
210 with self.assertRaisesRegex(ValueError, msg):
211 self.P(e='test')
212
213 p = self.P()
214
215 with self.assertRaisesRegex(ValueError, msg):
216 p.e = 'test'
217
218 msg = r"Tuple parameter None only takes a tuple value, not <(class|type) 'str'>."
219 with self.assertRaisesRegex(ValueError, msg):
220 class P(param.Parameterized):
221 e = param.NumericTuple(default='test')
222
223 def test_support_allow_None(self):
224 p = self.P()
225 assert p.h == (0, 0)
226 p.h = None
227 p.h = (1, 1)
228 assert p.h == (1, 1)
229
230 class P(param.Parameterized):
231 h = param.NumericTuple(length=2, allow_None=True)
232
233 P.h = None
234 P.h = (1, 1)
235 assert P.h == (1, 1)
236
237 def test_raise_on_non_numeric_values(self):
238 msg = r"NumericTuple parameter 'e' only takes numeric values, not type <(class|type) 'str'>."
239
240 with self.assertRaisesRegex(ValueError, msg):
241 self.P.e = ('bad', 1)
242
243 with self.assertRaisesRegex(ValueError, msg):
244 self.P(e=('bad', 1))
245
246 p = self.P()
247
248 with self.assertRaisesRegex(ValueError, msg):
249 p.e = ('bad', 1)
250
251 msg = r"NumericTuple parameter None only takes numeric values, not type <(class|type) 'str'>."
252 with self.assertRaisesRegex(ValueError, msg):
253 class P(param.Parameterized):
254 e = param.NumericTuple(default=('bad', 1))
255
256 @pytest.mark.skipif(np is None, reason='NumPy is not available')
257 def test_support_numpy_values(self):
258 self.P(e=(np.int64(1), np.float32(2)))
259
260
261 class TestXYCoordinatesParameters(API1TestCase):
262
263 def setUp(self):
264 super(TestXYCoordinatesParameters, self).setUp()
265 class P(param.Parameterized):
266 e = param.XYCoordinates(default=(1, 1))
267 f = param.XYCoordinates(default=(0, 1), allow_None=True)
268 g = param.XYCoordinates(default=(1, 2))
269
270 self.P = P
271
272 def _check_defaults(self, p):
273 assert p.default == (0.0, 0.0)
274 assert p.length == 2
275 assert p.allow_None is False
276
277 def test_defaults_class(self):
278 class P(param.Parameterized):
279 t = param.XYCoordinates()
280
281 self._check_defaults(P.param.t)
282
283 def test_defaults_inst(self):
284 class P(param.Parameterized):
285 t = param.XYCoordinates()
286
287 p = P()
288
289 self._check_defaults(p.param.t)
290
291 def test_defaults_unbound(self):
292 t = param.XYCoordinates()
293
294 self._check_defaults(t)
295
296 def test_set_object_constructor(self):
297 p = self.P(e=(2, 2))
298 self.assertEqual(p.e, (2, 2))
299
300 def test_raise_if_value_bad_length_constructor(self):
301 msg = r"Tuple parameter 'e' is not of the correct length \(3 instead of 2\)"
302 with self.assertRaisesRegex(ValueError, msg):
303 self.P(e=(1, 1, 1))
304
305 def test_raise_if_value_bad_length_setattr(self):
306 p = self.P()
307 msg = r"Tuple parameter 'e' is not of the correct length \(3 instead of 2\)"
308 with self.assertRaisesRegex(ValueError, msg):
309 p.e = (1, 1, 1)
310
311 def test_bad_type(self):
312 msg = r"Tuple parameter 'e' only takes a tuple value, not <(class|type) 'str'>."
313
314 with self.assertRaisesRegex(ValueError, msg):
315 self.P.e = 'test'
316
317 with self.assertRaisesRegex(ValueError, msg):
318 self.P(e='test')
319
320 p = self.P()
321
322 with self.assertRaisesRegex(ValueError, msg):
323 p.e = 'test'
324
325 msg = r"Tuple parameter None only takes a tuple value, not <(class|type) 'str'>."
326 with self.assertRaisesRegex(ValueError, msg):
327 class P(param.Parameterized):
328 e = param.NumericTuple(default='test')
329
330 def test_support_allow_None_True(self):
331 p = self.P()
332 assert p.f == (0, 1)
333 p.f = None
334 assert p.f is None
335
336 class P(param.Parameterized):
337 f = param.Range(default=(0, 1), allow_None=True)
338
339 P.f = None
340 assert P.f is None
341
342 def test_support_allow_None_False(self):
343 p = self.P()
344 msg = "Tuple parameter 'g' only takes a tuple value, not <(class|type) 'NoneType'>."
345 with self.assertRaisesRegex(ValueError, msg):
346 p.g = None
347
348 msg = "Tuple parameter 'g' only takes a tuple value, not <(class|type) 'NoneType'>."
349 with self.assertRaisesRegex(ValueError, msg):
350 self.P.g = None
351
352 def test_raise_on_non_numeric_values(self):
353 msg = r"NumericTuple parameter 'e' only takes numeric values, not type <(class|type) 'str'>."
354
355 with self.assertRaisesRegex(ValueError, msg):
356 self.P.e = ('bad', 1)
357
358 with self.assertRaisesRegex(ValueError, msg):
359 self.P(e=('bad', 1))
360
361 p = self.P()
362
363 with self.assertRaisesRegex(ValueError, msg):
364 p.e = ('bad', 1)
365
366 msg = r"NumericTuple parameter None only takes numeric values, not type <(class|type) 'str'>."
367 with self.assertRaisesRegex(ValueError, msg):
368 class P(param.Parameterized):
369 e = param.NumericTuple(default=('bad', 1))
370
371 @pytest.mark.skipif(np is None, reason='NumPy is not available')
372 def test_support_numpy_values(self):
373 self.P(e=(np.int64(1), np.float32(2)))
00 import datetime as dt
1 import os
12
23 import param
34 import pytest
45
5 from param import guess_param_types
6 from param import guess_param_types, resolve_path
67
78 try:
89 import numpy as np
5556 if not type(out_param) == param.Parameter:
5657 assert out_param.default is val
5758 assert out_param.constant
59
60 @pytest.fixture
61 def reset_search_paths():
62 # The default is [os.getcwd()] which doesn't play well with the testing
63 # framework where every test creates a new temporary directory.
64 # This fixture sets it temporarily to [].
65 original = resolve_path.search_paths
66 try:
67 resolve_path.search_paths = []
68 yield
69 finally:
70 resolve_path.search_paths = original
71
72
73 def test_resolve_path_file_default():
74 assert resolve_path.path_to_file is True
75 assert resolve_path.search_paths == [os.getcwd()]
76
77
78 def test_resolve_path_file_not_found():
79 with pytest.raises(IOError, match='File surelyyoudontexist was not found in the following'):
80 resolve_path('surelyyoudontexist')
81
82
83 @pytest.mark.usefixtures('reset_search_paths')
84 def test_resolve_path_file_not_found(tmpdir):
85 cdir = os.getcwd()
86 os.chdir(str(tmpdir))
87 try:
88 with pytest.raises(IOError, match='File notthere was not found in the following'):
89 resolve_path('notthere')
90 finally:
91 os.chdir(cdir)
92
93
94 @pytest.mark.usefixtures('reset_search_paths')
95 def test_resolve_path_folder_not_found(tmpdir):
96 cdir = os.getcwd()
97 os.chdir(str(tmpdir))
98 try:
99 with pytest.raises(IOError, match='Folder notthere was not found in the following'):
100 resolve_path('notthere', path_to_file=False)
101 finally:
102 os.chdir(cdir)
103
104
105 @pytest.mark.usefixtures('reset_search_paths')
106 def test_resolve_path_either_not_found(tmpdir):
107 cdir = os.getcwd()
108 os.chdir(str(tmpdir))
109 try:
110 with pytest.raises(IOError, match='Path notthere was not found in the following'):
111 resolve_path('notthere', path_to_file=None)
112 finally:
113 os.chdir(cdir)
114
115
116 @pytest.mark.usefixtures('reset_search_paths')
117 @pytest.mark.parametrize('path_to_file', [True, False, None])
118 def test_resolve_path_abs_not_found(tmpdir, path_to_file):
119 cdir = os.getcwd()
120 fp = os.path.join(str(tmpdir), 'foo')
121 os.chdir(str(tmpdir))
122 try:
123 with pytest.raises(IOError, match='not found'):
124 resolve_path(fp, path_to_file=path_to_file)
125 finally:
126 os.chdir(cdir)
127
128
129 @pytest.mark.usefixtures('reset_search_paths')
130 def test_resolve_path_cwd_file(tmpdir):
131 cdir = os.getcwd()
132 fp = os.path.join(str(tmpdir), 'foo')
133 open(fp, 'w').close()
134 os.chdir(str(tmpdir))
135 try:
136 p = resolve_path('foo')
137 assert os.path.isfile(p)
138 assert os.path.basename(p) == 'foo'
139 assert os.path.isabs(p)
140 assert p == fp
141 finally:
142 os.chdir(cdir)
143
144
145 @pytest.mark.usefixtures('reset_search_paths')
146 def test_resolve_path_cwd_folder(tmpdir):
147 cdir = os.getcwd()
148 fp = os.path.join(str(tmpdir), 'foo')
149 os.mkdir(fp)
150 os.chdir(str(tmpdir))
151 try:
152 p = resolve_path('foo', path_to_file=False)
153 assert os.path.isdir(p)
154 assert os.path.basename(p) == 'foo'
155 assert os.path.isabs(p)
156 assert p == fp
157 finally:
158 os.chdir(cdir)
159
160
161 @pytest.mark.usefixtures('reset_search_paths')
162 def test_resolve_path_cwd_either_file(tmpdir):
163 cdir = os.getcwd()
164 fp = os.path.join(str(tmpdir), 'foo')
165 open(fp, 'w').close()
166 os.chdir(str(tmpdir))
167 try:
168 p = resolve_path('foo', path_to_file=None)
169 assert os.path.isfile(p)
170 assert os.path.basename(p) == 'foo'
171 assert os.path.isabs(p)
172 assert p == fp
173 finally:
174 os.chdir(cdir)
175
176
177 @pytest.mark.usefixtures('reset_search_paths')
178 def test_resolve_path_cwd_either_folder(tmpdir):
179 cdir = os.getcwd()
180 fp = os.path.join(str(tmpdir), 'foo')
181 os.mkdir(fp)
182 os.chdir(str(tmpdir))
183 try:
184 p = resolve_path('foo', path_to_file=None)
185 assert os.path.isdir(p)
186 assert os.path.basename(p) == 'foo'
187 assert os.path.isabs(p)
188 assert p == fp
189 finally:
190 os.chdir(cdir)
191
192
193 @pytest.mark.usefixtures('reset_search_paths')
194 def test_resolve_path_abs_file(tmpdir):
195 cdir = os.getcwd()
196 fp = os.path.join(str(tmpdir), 'foo')
197 open(fp, 'w').close()
198 os.chdir(str(tmpdir))
199 try:
200 p = resolve_path(fp)
201 assert os.path.isfile(p)
202 assert os.path.basename(p) == 'foo'
203 assert os.path.isabs(p)
204 assert p == fp
205 finally:
206 os.chdir(cdir)
207
208
209 @pytest.mark.usefixtures('reset_search_paths')
210 def test_resolve_path_abs_folder(tmpdir):
211 cdir = os.getcwd()
212 fp = os.path.join(str(tmpdir), 'foo')
213 os.mkdir(fp)
214 os.chdir(str(tmpdir))
215 try:
216 p = resolve_path(fp, path_to_file=False)
217 assert os.path.isdir(p)
218 assert os.path.basename(p) == 'foo'
219 assert os.path.isabs(p)
220 assert p == fp
221 finally:
222 os.chdir(cdir)
223
224
225 @pytest.mark.usefixtures('reset_search_paths')
226 def test_resolve_path_abs_either_file(tmpdir):
227 cdir = os.getcwd()
228 fp = os.path.join(str(tmpdir), 'foo')
229 open(fp, 'w').close()
230 os.chdir(str(tmpdir))
231 try:
232 p = resolve_path(fp, path_to_file=None)
233 assert os.path.isfile(p)
234 assert os.path.basename(p) == 'foo'
235 assert os.path.isabs(p)
236 assert p == fp
237 finally:
238 os.chdir(cdir)
239
240
241 @pytest.mark.usefixtures('reset_search_paths')
242 def test_resolve_path_abs_either_folder(tmpdir):
243 cdir = os.getcwd()
244 fp = os.path.join(str(tmpdir), 'foo')
245 os.mkdir(fp)
246 os.chdir(str(tmpdir))
247 try:
248 p = resolve_path(fp, path_to_file=None)
249 assert os.path.isdir(p)
250 assert os.path.basename(p) == 'foo'
251 assert os.path.isabs(p)
252 assert p == fp
253 finally:
254 os.chdir(cdir)
255
256
257 def test_resolve_path_search_paths_file(tmpdir):
258 fp = os.path.join(str(tmpdir), 'foo')
259 open(fp, 'w').close()
260 p = resolve_path('foo', search_paths=[str(tmpdir)])
261 assert os.path.isfile(p)
262 assert os.path.basename(p) == 'foo'
263 assert os.path.isabs(p)
264 assert p == fp
265
266
267 @pytest.mark.usefixtures('reset_search_paths')
268 def test_resolve_path_search_paths_folder(tmpdir):
269 fp = os.path.join(str(tmpdir), 'foo')
270 os.mkdir(fp)
271 p = resolve_path('foo', search_paths=[str(tmpdir)], path_to_file=False)
272 assert os.path.isdir(p)
273 assert os.path.basename(p) == 'foo'
274 assert os.path.isabs(p)
275 assert p == fp
276
277
278 @pytest.mark.usefixtures('reset_search_paths')
279 def test_resolve_path_search_paths_either_file(tmpdir):
280 fp = os.path.join(str(tmpdir), 'foo')
281 open(fp, 'w').close()
282 p = resolve_path('foo', search_paths=[str(tmpdir)], path_to_file=None)
283 assert os.path.isfile(p)
284 assert os.path.basename(p) == 'foo'
285 assert os.path.isabs(p)
286 assert p == fp
287
288
289 @pytest.mark.usefixtures('reset_search_paths')
290 def test_resolve_path_search_paths_either_folder(tmpdir):
291 fp = os.path.join(str(tmpdir), 'foo')
292 os.mkdir(fp)
293 p = resolve_path('foo', search_paths=[str(tmpdir)], path_to_file=None)
294 assert os.path.isdir(p)
295 assert os.path.basename(p) == 'foo'
296 assert os.path.isabs(p)
297 assert p == fp
298
299
300 @pytest.mark.usefixtures('reset_search_paths')
301 def test_resolve_path_search_paths_multiple_file(tmpdir):
302 d1 = os.path.join(str(tmpdir), 'd1')
303 d2 = os.path.join(str(tmpdir), 'd2')
304 os.mkdir(d1)
305 os.mkdir(d2)
306 fp1 = os.path.join(d1, 'foo1')
307 open(fp1, 'w').close()
308 fp2 = os.path.join(d2, 'foo2')
309 open(fp2, 'w').close()
310 p = resolve_path('foo1', search_paths=[d1, d2])
311 assert os.path.isfile(p)
312 assert os.path.basename(p) == 'foo1'
313 assert os.path.isabs(p)
314 assert p == fp1
315
316 p = resolve_path('foo2', search_paths=[d1, d2])
317 assert os.path.isfile(p)
318 assert os.path.basename(p) == 'foo2'
319 assert os.path.isabs(p)
320 assert p == fp2
511511 obj = SimpleWatchExample()
512512
513513 obj.param.watch(obj.method, ['a'])
514 obj.param.watch(lambda x: None, 'd', what='bounds')
514515
515516 copied = copy.deepcopy(obj)
516517
7272 raise AssertionError(msg.format(level=level,
7373 last_line=repr(last_line[0]),
7474 substring=repr(substring)))
75
76
77 def check_defaults(parameter, label, skip=[]):
78 # ! Not testing default and allow_None
79 if 'doc' not in skip:
80 assert parameter.doc is None
81 if 'precedence' not in skip:
82 assert parameter.precedence is None
83 if 'instantiate' not in skip:
84 assert parameter.instantiate is False
85 if 'constant' not in skip:
86 assert parameter.constant is False
87 if 'readonly' not in skip:
88 assert parameter.readonly is False
89 if 'pickle_default_value' not in skip:
90 assert parameter.pickle_default_value is True
91 if 'per_instance' not in skip:
92 assert parameter.per_instance is True
93 if 'label' not in skip:
94 assert parameter.label == label
1515 description = run test suite under {basepython}
1616 deps = .[tests]
1717 commands =
18 pytest tests --cov=numbergen --cov=param --cov-append --cov-report xml
18 coverage run --source=numbergen,param -m pytest tests
19 coverage report
20 coverage xml
1921
2022 [testenv:with_numpy]
2123 description = run test suite with numpy under {basepython}
99 description = run test suite under {basepython}
1010 deps = .[tests]
1111 commands =
12 pytest tests --ignore tests/API1/testparamdepends_py3.py --cov=numbergen --cov=param --cov-append --cov-report xml
12 coverage run --source=numbergen,param -m pytest tests --ignore tests/API1/testparamdepends_py3.py
13 coverage report --omit param/_async.py
14 coverage xml --omit param/_async.py
1315
1416 [testenv:with_numpy]
1517 description = run test suite with numpy under {basepython}