New upstream release.
Debian Janitor
1 year, 1 month ago
80 | 80 | python setup.py sdist bdist_wheel |
81 | 81 | - name: Publish package to PyPI |
82 | 82 | if: github.event_name == 'push' |
83 | uses: pypa/gh-action-pypi-publish@master | |
83 | uses: pypa/gh-action-pypi-publish@release/v1 | |
84 | 84 | with: |
85 | 85 | user: ${{ secrets.PPU }} |
86 | 86 | password: ${{ secrets.PPP }} |
1 | 1 | on: |
2 | 2 | push: |
3 | 3 | branches: |
4 | - master | |
4 | - main | |
5 | 5 | pull_request: |
6 | 6 | branches: |
7 | 7 | - '*' |
29 | 29 | - uses: actions/checkout@v3 |
30 | 30 | with: |
31 | 31 | fetch-depth: "100" |
32 | - name: Fetch unshallow | |
33 | run: git fetch --prune --tags --unshallow -f | |
32 | 34 | - name: Set up Python ${{ matrix.python-version }} |
33 | 35 | uses: actions/setup-python@v4 |
34 | 36 | 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> | |
1 | 1 | |
2 | 2 | | | | |
3 | 3 | | --- | --- | |
4 | 4 | | 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) || | |
6 | 6 | | 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/) | |
7 | 7 | | 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) | |
8 | 8 | | Python | [![Python support](https://img.shields.io/pypi/pyversions/param.svg)](https://pypi.org/project/param/) |
9 | 9 | | 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) | | |
11 | 11 | | Support | [![Discourse](https://img.shields.io/discourse/status?server=https%3A%2F%2Fdiscourse.holoviz.org)](https://discourse.holoviz.org/) | |
12 | 12 | |
13 | 13 | 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 | ||
0 | 6 | python-param (1.12.3-1) unstable; urgency=medium |
1 | 7 | |
2 | 8 | * Team upload. |
0 | 0 | # About |
1 | 1 | |
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. | |
3 | 3 | |
4 | 4 | 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). |
5 | 5 |
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) |⏎ |
0 | 0 | # 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)) | |
1 | 35 | |
2 | 36 | ## Version 1.12.3 |
3 | 37 |
3 | 3 | "cell_type": "markdown", |
4 | 4 | "metadata": {}, |
5 | 5 | "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\">" | |
7 | 7 | ] |
8 | 8 | }, |
9 | 9 | { |
274 | 274 | "- 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", |
275 | 275 | "- 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", |
276 | 276 | "\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", | |
278 | 278 | "\n", |
279 | 279 | "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", |
280 | 280 | "\n", |
370 | 370 | "\n", |
371 | 371 | "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", |
372 | 372 | "\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", | |
374 | 374 | "\n", |
375 | 375 | "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", |
376 | 376 | "\n", |
49 | 49 | "cell_type": "markdown", |
50 | 50 | "metadata": {}, |
51 | 51 | "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!" | |
53 | 53 | ] |
54 | 54 | }, |
55 | 55 | { |
42 | 42 | # only two required files. |
43 | 43 | try: |
44 | 44 | 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")) | |
46 | 46 | except: |
47 | 47 | __version__ = "0.0.0+unknown" |
48 | 48 | |
734 | 734 | return (l, u) |
735 | 735 | |
736 | 736 | |
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 | ||
737 | 773 | class Number(Dynamic): |
738 | 774 | """ |
739 | 775 | A numeric Dynamic Parameter, with a default value and optional bounds. |
1021 | 1057 | @classmethod |
1022 | 1058 | def serialize(cls, value): |
1023 | 1059 | if value is None: |
1024 | return 'null' | |
1060 | return None | |
1025 | 1061 | return list(value) # As JSON has no tuple representation |
1026 | 1062 | |
1027 | 1063 | @classmethod |
1028 | 1064 | def deserialize(cls, value): |
1029 | if value == 'null': | |
1065 | if value == 'null' or value is None: | |
1030 | 1066 | return None |
1031 | 1067 | return tuple(value) # As JSON has no tuple representation |
1032 | 1068 | |
1482 | 1518 | @classmethod |
1483 | 1519 | def serialize(cls, value): |
1484 | 1520 | if value is None: |
1485 | return 'null' | |
1521 | return None | |
1486 | 1522 | return value.tolist() |
1487 | 1523 | |
1488 | 1524 | @classmethod |
1489 | 1525 | def deserialize(cls, value): |
1490 | if value == 'null': | |
1526 | if value == 'null' or value is None: | |
1491 | 1527 | return None |
1492 | 1528 | from numpy import asarray |
1493 | 1529 | return asarray(value) |
1569 | 1605 | @classmethod |
1570 | 1606 | def serialize(cls, value): |
1571 | 1607 | if value is None: |
1572 | return 'null' | |
1608 | return None | |
1573 | 1609 | return value.to_dict('records') |
1574 | 1610 | |
1575 | 1611 | @classmethod |
1576 | 1612 | def deserialize(cls, value): |
1577 | if value == 'null': | |
1613 | if value == 'null' or value is None: | |
1578 | 1614 | return None |
1579 | 1615 | from pandas import DataFrame as pdDFrame |
1580 | 1616 | return pdDFrame(value) |
1877 | 1913 | def _validate(self, val): |
1878 | 1914 | if (val is None and self.allow_None): |
1879 | 1915 | return |
1916 | if not isinstance(val, list): | |
1917 | raise ValueError("ListSelector parameter %r only takes list " | |
1918 | "types, not %r." % (self.name, val)) | |
1880 | 1919 | for o in val: |
1881 | 1920 | super(ListSelector, self)._validate(o) |
1882 | 1921 | |
1941 | 1980 | @classmethod |
1942 | 1981 | def serialize(cls, value): |
1943 | 1982 | if value is None: |
1944 | return 'null' | |
1983 | return None | |
1945 | 1984 | if not isinstance(value, (dt.datetime, dt.date)): # i.e np.datetime64 |
1946 | 1985 | value = value.astype(dt.datetime) |
1947 | 1986 | return value.strftime("%Y-%m-%dT%H:%M:%S.%f") |
1948 | 1987 | |
1949 | 1988 | @classmethod |
1950 | 1989 | def deserialize(cls, value): |
1951 | if value == 'null': | |
1990 | if value == 'null' or value is None: | |
1952 | 1991 | return None |
1953 | 1992 | return dt.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f") |
1954 | 1993 | |
1979 | 2018 | @classmethod |
1980 | 2019 | def serialize(cls, value): |
1981 | 2020 | if value is None: |
1982 | return 'null' | |
2021 | return None | |
1983 | 2022 | return value.strftime("%Y-%m-%d") |
1984 | 2023 | |
1985 | 2024 | @classmethod |
1986 | 2025 | def deserialize(cls, value): |
1987 | if value == 'null': | |
2026 | if value == 'null' or value is None: | |
1988 | 2027 | return None |
1989 | 2028 | return dt.datetime.strptime(value, "%Y-%m-%d").date() |
1990 | 2029 | |
2055 | 2094 | return |
2056 | 2095 | is_hex = re.match('^#?(([0-9a-fA-F]{2}){3}|([0-9a-fA-F]){3})$', val) |
2057 | 2096 | 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: | |
2059 | 2098 | raise ValueError("Color '%s' only takes RGB hex codes " |
2060 | 2099 | "or named colors, received '%s'." % (self.name, val)) |
2061 | 2100 | elif not is_hex: |
2139 | 2178 | @classmethod |
2140 | 2179 | def serialize(cls, value): |
2141 | 2180 | if value is None: |
2142 | return 'null' | |
2181 | return None | |
2143 | 2182 | # List as JSON has no tuple representation |
2144 | 2183 | serialized = [] |
2145 | 2184 | for v in value: |
2154 | 2193 | return serialized |
2155 | 2194 | |
2156 | 2195 | def deserialize(cls, value): |
2157 | if value == 'null': | |
2196 | if value == 'null' or value is None: | |
2158 | 2197 | return None |
2159 | 2198 | deserialized = [] |
2160 | 2199 | for v in value: |
2190 | 2229 | @classmethod |
2191 | 2230 | def serialize(cls, value): |
2192 | 2231 | if value is None: |
2193 | return 'null' | |
2232 | return None | |
2194 | 2233 | # As JSON has no tuple representation |
2195 | 2234 | return [v.strftime("%Y-%m-%d") for v in value] |
2196 | 2235 | |
2197 | 2236 | @classmethod |
2198 | 2237 | def deserialize(cls, value): |
2199 | if value == 'null': | |
2238 | if value == 'null' or value is None: | |
2200 | 2239 | return None |
2201 | 2240 | # As JSON has no tuple representation |
2202 | 2241 | return tuple([dt.datetime.strptime(v, "%Y-%m-%d").date() for v in value]) |
2 | 2 | by param internal callbacks. These are defined in a separate file due |
3 | 3 | to py2 incompatibility with both `async/await` and `yield from` syntax. |
4 | 4 | """ |
5 | from functools import wraps | |
5 | 6 | |
6 | 7 | def generate_depends(func): |
8 | @wraps(func) | |
7 | 9 | async def _depends(*args, **kw): # noqa: E999 |
8 | await func(*args, **kw) # noqa: E999 | |
10 | return await func(*args, **kw) # noqa: E999 | |
9 | 11 | return _depends |
10 | 12 | |
11 | 13 | def generate_caller(function, what='value', changed=None, callback=None, skip_event=None): |
1116 | 1116 | "it has been bound to a Parameterized.") |
1117 | 1117 | |
1118 | 1118 | 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)) | |
1120 | 1120 | try: |
1121 | 1121 | old = getattr(self, attribute) if implemented else NotImplemented |
1122 | 1122 | if slot_attribute: |
399 | 399 | prefix = reponame + '-' # Prefix to match |
400 | 400 | if setup_dir.startswith(prefix): |
401 | 401 | 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): | |
404 | 404 | return tag |
405 | 405 | return None |
406 | 406 |
19 | 19 | # (https://github.com/pypa/pip/issues/1197) |
20 | 20 | 'tests': [ |
21 | 21 | 'pytest', |
22 | 'pytest-cov', | |
22 | 'coverage', | |
23 | 23 | 'flake8', |
24 | 24 | ], |
25 | 25 | 'doc': [ |
52 | 52 | p.g = [7] |
53 | 53 | try: |
54 | 54 | p.g = None |
55 | except TypeError: | |
55 | except ValueError: | |
56 | 56 | pass |
57 | 57 | else: |
58 | 58 | raise AssertionError("Object set outside range.") |
109 | 109 | ### new tests (not copied from testobjectselector) |
110 | 110 | |
111 | 111 | def test_bad_default(self): |
112 | with self.assertRaises(TypeError): | |
112 | with self.assertRaises(ValueError): | |
113 | 113 | class Q(param.Parameterized): |
114 | 114 | r = param.ListSelector(default=6,check_on_set=True) |
115 | 115 | |
116 | 116 | def test_implied_check_on_set(self): |
117 | with self.assertRaises(TypeError): | |
117 | with self.assertRaises(ValueError): | |
118 | 118 | class Q(param.Parameterized): |
119 | 119 | r = param.ListSelector(default=7,objects=[7,8]) |
120 | 120 | |
134 | 134 | class Q(param.Parameterized): |
135 | 135 | r = param.ListSelector(default=6,check_on_set=False) |
136 | 136 | |
137 | with self.assertRaises(TypeError): | |
137 | with self.assertRaises(ValueError): | |
138 | 138 | Q.r = 6 |
139 | 139 | ########################## |
140 | 140 |
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) |
6 | 6 | import pytest |
7 | 7 | import param |
8 | 8 | from . import API1TestCase |
9 | from .utils import check_defaults | |
9 | 10 | |
10 | 11 | |
11 | 12 | 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) | |
12 | 43 | |
13 | 44 | def test_initialization_out_of_bounds(self): |
14 | 45 | try: |
56 | 87 | def test_datetime_not_accepted(self): |
57 | 88 | with pytest.raises(ValueError): |
58 | 89 | 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) |
9 | 9 | # test date range. |
10 | 10 | |
11 | 11 | 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) | |
12 | 40 | |
13 | 41 | bad_range = (dt.date(2017,2,27),dt.date(2017,2,26)) |
14 | 42 |
6 | 6 | |
7 | 7 | import param |
8 | 8 | from . import API1TestCase |
9 | from .utils import check_defaults | |
9 | 10 | |
10 | 11 | class TestClassSelectorParameters(API1TestCase): |
11 | 12 | |
18 | 19 | h = param.ClassSelector(default=int,class_=(int,str), is_instance=False) |
19 | 20 | |
20 | 21 | 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 | |
21 | 53 | |
22 | 54 | def test_single_class_instance_constructor(self): |
23 | 55 | p = self.P(e=6) |
72 | 104 | |
73 | 105 | class TestDictParameters(API1TestCase): |
74 | 106 | |
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 | ||
75 | 136 | def test_valid_dict_parameter(self): |
76 | 137 | valid_dict = {1:2, 3:3} |
77 | 138 |
2 | 2 | """ |
3 | 3 | import param |
4 | 4 | from . import API1TestCase |
5 | from .utils import check_defaults | |
5 | 6 | |
6 | 7 | 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) | |
7 | 35 | |
8 | 36 | def test_initialization_invalid_string(self): |
9 | 37 | try: |
61 | 89 | q = param.Color(allow_named=True) |
62 | 90 | Q.q = 'indianred' |
63 | 91 | 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') |
6 | 6 | |
7 | 7 | import param |
8 | 8 | from . import API1TestCase |
9 | from .utils import check_defaults | |
9 | 10 | |
10 | 11 | class TestCompositeParameters(API1TestCase): |
11 | 12 | |
32 | 33 | |
33 | 34 | self.SomeSequence = SomeSequence |
34 | 35 | |
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 | ||
35 | 66 | def test_initialization(self): |
36 | 67 | "Make an instance and do default checks" |
37 | 68 | self.assertEqual(self.a.x, 0) |
38 | 69 | self.assertEqual(self.a.y, 0) |
39 | 70 | self.assertEqual(self.a.xy, [0,0]) |
40 | ||
41 | 71 | |
42 | 72 | def test_set_component(self): |
43 | 73 | self.a.x = 1 |
0 | 0 | """ |
1 | 1 | Unit test for Date parameters. |
2 | 2 | """ |
3 | ||
4 | ||
3 | import sys | |
4 | import json | |
5 | 5 | import datetime as dt |
6 | 6 | import param |
7 | 7 | from . import API1TestCase |
8 | from .utils import check_defaults | |
8 | 9 | |
9 | 10 | 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) | |
10 | 41 | |
11 | 42 | def test_initialization_out_of_bounds(self): |
12 | 43 | try: |
51 | 82 | self.assertEqual(q.get_soft_bounds(), (dt.datetime(2017,2,1), |
52 | 83 | dt.datetime(2017,2,25))) |
53 | 84 | |
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) |
7 | 7 | import pytest |
8 | 8 | |
9 | 9 | from . import API1TestCase |
10 | from .utils import check_defaults | |
10 | 11 | |
11 | 12 | try: |
12 | 13 | import numpy as np |
17 | 18 | # test date range. |
18 | 19 | |
19 | 20 | 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) | |
20 | 49 | |
21 | 50 | bad_range = (dt.datetime(2017,2,27),dt.datetime(2017,2,26)) |
22 | 51 |
1 | 1 | Do all subclasses of Parameter supply a valid default? |
2 | 2 | """ |
3 | 3 | import pytest |
4 | ||
5 | import param | |
4 | 6 | |
5 | 7 | from param.parameterized import add_metaclass |
6 | 8 | from param import concrete_descendents, Parameter |
9 | 11 | from param import * # noqa |
10 | 12 | from param import ClassSelector |
11 | 13 | from . import API1TestCase |
14 | from .utils import check_defaults | |
12 | 15 | |
13 | 16 | positional_args = { |
14 | 17 | # ClassSelector: (object,) |
49 | 52 | @add_metaclass(DefaultsMetaclassTest) |
50 | 53 | class TestDefaults(API1TestCase): |
51 | 54 | 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 |
0 | 0 | import param |
1 | 1 | from . import API1TestCase |
2 | from .utils import check_defaults | |
2 | 3 | # TODO: I copied the tests from testobjectselector, although I |
3 | 4 | # struggled to understand some of them. Both files should be reviewed |
4 | 5 | # and cleaned up together. |
15 | 16 | l = param.List(["red","green","blue"], item_type=str, bounds=(0,10)) |
16 | 17 | |
17 | 18 | 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) | |
18 | 49 | |
19 | 50 | def test_default_None(self): |
20 | 51 | class Q(param.Parameterized): |
50 | 81 | pass |
51 | 82 | else: |
52 | 83 | 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.") |
0 | 0 | import param |
1 | 1 | from . import API1TestCase |
2 | from .utils import check_defaults | |
2 | 3 | # TODO: I copied the tests from testobjectselector, although I |
3 | 4 | # struggled to understand some of them. Both files should be reviewed |
4 | 5 | # and cleaned up together. |
19 | 20 | |
20 | 21 | self.P = P |
21 | 22 | |
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 | ||
22 | 53 | def test_default_None(self): |
23 | 54 | class Q(param.Parameterized): |
24 | 55 | r = param.ListSelector(default=None) |
26 | 57 | def test_set_object_constructor(self): |
27 | 58 | p = self.P(e=[6]) |
28 | 59 | 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 | ||
29 | 69 | |
30 | 70 | def test_set_object_outside_bounds(self): |
31 | 71 | p = self.P(e=[6]) |
51 | 91 | p.g = [7] |
52 | 92 | try: |
53 | 93 | p.g = None |
54 | except TypeError: | |
94 | except ValueError: | |
55 | 95 | pass |
56 | 96 | else: |
57 | 97 | raise AssertionError("Object set outside range.") |
108 | 148 | ### new tests (not copied from testobjectselector) |
109 | 149 | |
110 | 150 | def test_bad_default(self): |
111 | with self.assertRaises(TypeError): | |
151 | with self.assertRaises(ValueError): | |
112 | 152 | class Q(param.Parameterized): |
113 | 153 | r = param.ListSelector(default=6,check_on_set=True) |
114 | 154 | |
115 | 155 | def test_implied_check_on_set(self): |
116 | with self.assertRaises(TypeError): | |
156 | with self.assertRaises(ValueError): | |
117 | 157 | class Q(param.Parameterized): |
118 | 158 | r = param.ListSelector(default=7,objects=[7,8]) |
119 | 159 | |
133 | 173 | class Q(param.Parameterized): |
134 | 174 | r = param.ListSelector(default=6,check_on_set=False) |
135 | 175 | |
136 | with self.assertRaises(TypeError): | |
176 | with self.assertRaises(ValueError): | |
137 | 177 | Q.r = 6 |
138 | 178 | ########################## |
139 | 179 | |
153 | 193 | |
154 | 194 | with self.assertRaises(TypeError): |
155 | 195 | 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] |
1 | 1 | Unit test for Number parameters and their subclasses. |
2 | 2 | """ |
3 | 3 | import param |
4 | import datetime as dt | |
5 | 4 | from . import API1TestCase |
5 | from .utils import check_defaults | |
6 | 6 | |
7 | 7 | |
8 | 8 | 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 | |
9 | 342 | |
10 | 343 | def test_initialization_without_step_class(self): |
11 | 344 | class Q(param.Parameterized): |
12 | q = param.Number(default=1) | |
345 | q = param.Integer(default=1) | |
13 | 346 | |
14 | 347 | self.assertEqual(Q.param['q'].step, None) |
15 | 348 | |
349 | ||
350 | def test_initialization_without_step_class(self): | |
351 | self.assertEqual(self.P.param['e'].step, None) | |
352 | ||
16 | 353 | 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) | |
21 | 355 | |
22 | 356 | 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) | |
28 | 359 | |
29 | 360 | 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) | |
35 | 363 | |
36 | 364 | 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') | |
40 | 368 | |
41 | 369 | def test_step_invalid_type_integer_parameter(self): |
42 | 370 | exception = "Step can only be None or an integer value" |
43 | 371 | with self.assertRaisesRegex(ValueError, exception): |
44 | 372 | param.Integer(step=3.4) |
45 | 373 | |
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) |
5 | 5 | |
6 | 6 | import param |
7 | 7 | from . import API1TestCase |
8 | from .utils import check_defaults | |
8 | 9 | |
9 | 10 | try: |
10 | 11 | import numpy |
23 | 24 | |
24 | 25 | # TODO: incomplete |
25 | 26 | 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 | ||
26 | 57 | def test_array_param(self): |
27 | 58 | class Z(param.Parameterized): |
28 | 59 | z = param.Array(default=numpy.array([1])) |
6 | 6 | |
7 | 7 | import param |
8 | 8 | from . import API1TestCase |
9 | from .utils import check_defaults | |
9 | 10 | from collections import OrderedDict |
10 | 11 | |
11 | 12 | |
27 | 28 | |
28 | 29 | self.P = P |
29 | 30 | |
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 | ||
30 | 61 | def test_set_object_constructor(self): |
31 | 62 | p = self.P(e=6) |
32 | 63 | 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 | |
33 | 74 | |
34 | 75 | def test_get_range_list(self): |
35 | 76 | r = self.P.param.params("g").get_range() |
5 | 5 | |
6 | 6 | import param |
7 | 7 | from . import API1TestCase |
8 | from .utils import check_defaults | |
8 | 9 | |
9 | 10 | try: |
10 | 11 | import pandas |
17 | 18 | |
18 | 19 | class TestDataFrame(API1TestCase): |
19 | 20 | |
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 | ||
20 | 53 | def test_dataframe_positional_argument(self): |
21 | 54 | valid_df = pandas.DataFrame({'a':[1,2], 'b':[2,3], 'c':[4,5]}, |
22 | 55 | columns=['b', 'a', 'c']) |
162 | 195 | |
163 | 196 | class TestSeries(API1TestCase): |
164 | 197 | |
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 | ||
165 | 228 | def test_series_positional_argument(self): |
166 | 229 | valid_series = pandas.Series([1,2]) |
167 | 230 | 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 |
5 | 5 | |
6 | 6 | |
7 | 7 | 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 | |
8 | 113 | |
9 | 114 | def test_initialization_out_of_bounds(self): |
10 | 115 | try: |
6 | 6 | |
7 | 7 | import param |
8 | 8 | from . import API1TestCase |
9 | from.utils import check_defaults | |
9 | 10 | from collections import OrderedDict |
10 | 11 | |
11 | 12 | |
27 | 28 | |
28 | 29 | self.P = P |
29 | 30 | |
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 | ||
30 | 61 | def test_set_object_constructor(self): |
31 | 62 | p = self.P(e=6) |
32 | 63 | 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 | |
33 | 74 | |
34 | 75 | def test_get_range_list(self): |
35 | 76 | r = self.P.param.params("g").get_range() |
3 | 3 | import sys |
4 | 4 | |
5 | 5 | from . import API1TestCase |
6 | from .utils import check_defaults | |
6 | 7 | |
7 | 8 | import param |
8 | 9 | |
10 | 11 | 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]?)$' |
11 | 12 | |
12 | 13 | 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) | |
13 | 41 | |
14 | 42 | def test_regex_ok(self): |
15 | 43 | 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))) |
0 | 0 | import datetime as dt |
1 | import os | |
1 | 2 | |
2 | 3 | import param |
3 | 4 | import pytest |
4 | 5 | |
5 | from param import guess_param_types | |
6 | from param import guess_param_types, resolve_path | |
6 | 7 | |
7 | 8 | try: |
8 | 9 | import numpy as np |
55 | 56 | if not type(out_param) == param.Parameter: |
56 | 57 | assert out_param.default is val |
57 | 58 | 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 |
511 | 511 | obj = SimpleWatchExample() |
512 | 512 | |
513 | 513 | obj.param.watch(obj.method, ['a']) |
514 | obj.param.watch(lambda x: None, 'd', what='bounds') | |
514 | 515 | |
515 | 516 | copied = copy.deepcopy(obj) |
516 | 517 |
72 | 72 | raise AssertionError(msg.format(level=level, |
73 | 73 | last_line=repr(last_line[0]), |
74 | 74 | 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 |
15 | 15 | description = run test suite under {basepython} |
16 | 16 | deps = .[tests] |
17 | 17 | 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 | |
19 | 21 | |
20 | 22 | [testenv:with_numpy] |
21 | 23 | description = run test suite with numpy under {basepython} |
9 | 9 | description = run test suite under {basepython} |
10 | 10 | deps = .[tests] |
11 | 11 | 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 | |
13 | 15 | |
14 | 16 | [testenv:with_numpy] |
15 | 17 | description = run test suite with numpy under {basepython} |