aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python
diff options
context:
space:
mode:
authordvshkurko <dvshkurko@yandex-team.ru>2022-02-10 16:45:52 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:52 +0300
commitc768a99151e47c3a4bb7b92c514d256abd301c4d (patch)
tree1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /contrib/python
parent321ee9bce31ec6e238be26dbcbe539cffa2c3309 (diff)
downloadydb-c768a99151e47c3a4bb7b92c514d256abd301c4d.tar.gz
Restoring authorship annotation for <dvshkurko@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/python')
-rw-r--r--contrib/python/Jinja2/py2/jinja2/loaders.py2
-rw-r--r--contrib/python/Jinja2/py3/jinja2/loaders.py2
-rw-r--r--contrib/python/MarkupSafe/py2/.dist-info/METADATA206
-rw-r--r--contrib/python/MarkupSafe/py2/.dist-info/top_level.txt2
-rw-r--r--contrib/python/MarkupSafe/py2/ya.make10
-rw-r--r--contrib/python/MarkupSafe/py3/.dist-info/METADATA138
-rw-r--r--contrib/python/MarkupSafe/py3/.dist-info/top_level.txt2
-rw-r--r--contrib/python/MarkupSafe/py3/ya.make10
-rw-r--r--contrib/python/setuptools/py2/pkg_resources/__init__.py10
-rw-r--r--contrib/python/setuptools/py3/pkg_resources/__init__.py8
-rw-r--r--contrib/python/traitlets/py2/tests/ya.make24
-rw-r--r--contrib/python/traitlets/py2/traitlets/tests/_warnings.py214
-rw-r--r--contrib/python/traitlets/py2/traitlets/tests/test_traitlets.py4836
-rw-r--r--contrib/python/traitlets/py2/traitlets/tests/test_traitlets_enum.py362
-rw-r--r--contrib/python/traitlets/py2/traitlets/tests/utils.py76
-rw-r--r--contrib/python/traitlets/py2/ya.make6
-rw-r--r--contrib/python/traitlets/py3/traitlets/tests/_warnings.py194
-rw-r--r--contrib/python/traitlets/py3/traitlets/tests/test_traitlets.py4608
-rw-r--r--contrib/python/traitlets/py3/traitlets/tests/test_traitlets_enum.py354
-rw-r--r--contrib/python/traitlets/py3/traitlets/tests/utils.py78
-rw-r--r--contrib/python/traitlets/py3/ya.make6
-rw-r--r--contrib/python/traitlets/ya.make4
-rw-r--r--contrib/python/ya.make48
23 files changed, 5600 insertions, 5600 deletions
diff --git a/contrib/python/Jinja2/py2/jinja2/loaders.py b/contrib/python/Jinja2/py2/jinja2/loaders.py
index 2c9798bb57..bad1774ab0 100644
--- a/contrib/python/Jinja2/py2/jinja2/loaders.py
+++ b/contrib/python/Jinja2/py2/jinja2/loaders.py
@@ -513,6 +513,6 @@ class ResourceLoader(BaseLoader):
if self.module_loader is None:
raise TemplateNotFound(template)
try:
- return self.module_loader.get_data(os.path.join(self.prefix, template)).decode('utf-8'), None, None
+ return self.module_loader.get_data(os.path.join(self.prefix, template)).decode('utf-8'), None, None
except IOError:
raise TemplateNotFound(template)
diff --git a/contrib/python/Jinja2/py3/jinja2/loaders.py b/contrib/python/Jinja2/py3/jinja2/loaders.py
index 5617839609..cc58eca221 100644
--- a/contrib/python/Jinja2/py3/jinja2/loaders.py
+++ b/contrib/python/Jinja2/py3/jinja2/loaders.py
@@ -681,6 +681,6 @@ class ResourceLoader(BaseLoader):
if self.module_loader is None:
raise TemplateNotFound(template)
try:
- return self.module_loader.get_data(os.path.join(self.prefix, template)).decode('utf-8'), None, None
+ return self.module_loader.get_data(os.path.join(self.prefix, template)).decode('utf-8'), None, None
except IOError:
raise TemplateNotFound(template)
diff --git a/contrib/python/MarkupSafe/py2/.dist-info/METADATA b/contrib/python/MarkupSafe/py2/.dist-info/METADATA
index 52da515b7e..b6d72a81d2 100644
--- a/contrib/python/MarkupSafe/py2/.dist-info/METADATA
+++ b/contrib/python/MarkupSafe/py2/.dist-info/METADATA
@@ -1,103 +1,103 @@
-Metadata-Version: 2.1
-Name: MarkupSafe
-Version: 1.1.1
-Summary: Safely add untrusted strings to HTML/XML markup.
-Home-page: https://palletsprojects.com/p/markupsafe/
-Author: Armin Ronacher
-Author-email: armin.ronacher@active-4.com
-Maintainer: The Pallets Team
-Maintainer-email: contact@palletsprojects.com
-License: BSD-3-Clause
-Project-URL: Code, https://github.com/pallets/markupsafe
-Project-URL: Issue tracker, https://github.com/pallets/markupsafe/issues
-Project-URL: Documentation, https://markupsafe.palletsprojects.com/
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Web Environment
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Topic :: Text Processing :: Markup :: HTML
-Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*
-
-MarkupSafe
-==========
-
-MarkupSafe implements a text object that escapes characters so it is
-safe to use in HTML and XML. Characters that have special meanings are
-replaced so that they display as the actual characters. This mitigates
-injection attacks, meaning untrusted user input can safely be displayed
-on a page.
-
-
-Installing
-----------
-
-Install and update using `pip`_:
-
-.. code-block:: text
-
- pip install -U MarkupSafe
-
-.. _pip: https://pip.pypa.io/en/stable/quickstart/
-
-
-Examples
---------
-
-.. code-block:: pycon
-
- >>> from markupsafe import Markup, escape
- >>> # escape replaces special characters and wraps in Markup
- >>> escape('<script>alert(document.cookie);</script>')
- Markup(u'&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
- >>> # wrap in Markup to mark text "safe" and prevent escaping
- >>> Markup('<strong>Hello</strong>')
- Markup('<strong>hello</strong>')
- >>> escape(Markup('<strong>Hello</strong>'))
- Markup('<strong>hello</strong>')
- >>> # Markup is a text subclass (str on Python 3, unicode on Python 2)
- >>> # methods and operators escape their arguments
- >>> template = Markup("Hello <em>%s</em>")
- >>> template % '"World"'
- Markup('Hello <em>&#34;World&#34;</em>')
-
-
-Donate
-------
-
-The Pallets organization develops and supports MarkupSafe and other
-libraries that use it. In order to grow the community of contributors
-and users, and allow the maintainers to devote more time to the
-projects, `please donate today`_.
-
-.. _please donate today: https://palletsprojects.com/donate
-
-
-Links
------
-
-* Website: https://palletsprojects.com/p/markupsafe/
-* Documentation: https://markupsafe.palletsprojects.com/
-* License: `BSD-3-Clause <https://github.com/pallets/markupsafe/blob/master/LICENSE.rst>`_
-* Releases: https://pypi.org/project/MarkupSafe/
-* Code: https://github.com/pallets/markupsafe
-* Issue tracker: https://github.com/pallets/markupsafe/issues
-* Test status:
-
- * Linux, Mac: https://travis-ci.org/pallets/markupsafe
- * Windows: https://ci.appveyor.com/project/pallets/markupsafe
-
-* Test coverage: https://codecov.io/gh/pallets/markupsafe
-
-
+Metadata-Version: 2.1
+Name: MarkupSafe
+Version: 1.1.1
+Summary: Safely add untrusted strings to HTML/XML markup.
+Home-page: https://palletsprojects.com/p/markupsafe/
+Author: Armin Ronacher
+Author-email: armin.ronacher@active-4.com
+Maintainer: The Pallets Team
+Maintainer-email: contact@palletsprojects.com
+License: BSD-3-Clause
+Project-URL: Code, https://github.com/pallets/markupsafe
+Project-URL: Issue tracker, https://github.com/pallets/markupsafe/issues
+Project-URL: Documentation, https://markupsafe.palletsprojects.com/
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Text Processing :: Markup :: HTML
+Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*
+
+MarkupSafe
+==========
+
+MarkupSafe implements a text object that escapes characters so it is
+safe to use in HTML and XML. Characters that have special meanings are
+replaced so that they display as the actual characters. This mitigates
+injection attacks, meaning untrusted user input can safely be displayed
+on a page.
+
+
+Installing
+----------
+
+Install and update using `pip`_:
+
+.. code-block:: text
+
+ pip install -U MarkupSafe
+
+.. _pip: https://pip.pypa.io/en/stable/quickstart/
+
+
+Examples
+--------
+
+.. code-block:: pycon
+
+ >>> from markupsafe import Markup, escape
+ >>> # escape replaces special characters and wraps in Markup
+ >>> escape('<script>alert(document.cookie);</script>')
+ Markup(u'&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
+ >>> # wrap in Markup to mark text "safe" and prevent escaping
+ >>> Markup('<strong>Hello</strong>')
+ Markup('<strong>hello</strong>')
+ >>> escape(Markup('<strong>Hello</strong>'))
+ Markup('<strong>hello</strong>')
+ >>> # Markup is a text subclass (str on Python 3, unicode on Python 2)
+ >>> # methods and operators escape their arguments
+ >>> template = Markup("Hello <em>%s</em>")
+ >>> template % '"World"'
+ Markup('Hello <em>&#34;World&#34;</em>')
+
+
+Donate
+------
+
+The Pallets organization develops and supports MarkupSafe and other
+libraries that use it. In order to grow the community of contributors
+and users, and allow the maintainers to devote more time to the
+projects, `please donate today`_.
+
+.. _please donate today: https://palletsprojects.com/donate
+
+
+Links
+-----
+
+* Website: https://palletsprojects.com/p/markupsafe/
+* Documentation: https://markupsafe.palletsprojects.com/
+* License: `BSD-3-Clause <https://github.com/pallets/markupsafe/blob/master/LICENSE.rst>`_
+* Releases: https://pypi.org/project/MarkupSafe/
+* Code: https://github.com/pallets/markupsafe
+* Issue tracker: https://github.com/pallets/markupsafe/issues
+* Test status:
+
+ * Linux, Mac: https://travis-ci.org/pallets/markupsafe
+ * Windows: https://ci.appveyor.com/project/pallets/markupsafe
+
+* Test coverage: https://codecov.io/gh/pallets/markupsafe
+
+
diff --git a/contrib/python/MarkupSafe/py2/.dist-info/top_level.txt b/contrib/python/MarkupSafe/py2/.dist-info/top_level.txt
index ecf81b4a7b..75bf729258 100644
--- a/contrib/python/MarkupSafe/py2/.dist-info/top_level.txt
+++ b/contrib/python/MarkupSafe/py2/.dist-info/top_level.txt
@@ -1 +1 @@
-markupsafe
+markupsafe
diff --git a/contrib/python/MarkupSafe/py2/ya.make b/contrib/python/MarkupSafe/py2/ya.make
index 576210225d..0e773ee33a 100644
--- a/contrib/python/MarkupSafe/py2/ya.make
+++ b/contrib/python/MarkupSafe/py2/ya.make
@@ -26,12 +26,12 @@ NO_LINT()
NO_COMPILER_WARNINGS()
-RESOURCE_FILES(
+RESOURCE_FILES(
PREFIX contrib/python/MarkupSafe/py2/
- .dist-info/METADATA
- .dist-info/top_level.txt
-)
-
+ .dist-info/METADATA
+ .dist-info/top_level.txt
+)
+
END()
RECURSE_FOR_TESTS(
diff --git a/contrib/python/MarkupSafe/py3/.dist-info/METADATA b/contrib/python/MarkupSafe/py3/.dist-info/METADATA
index fd912e0497..e87ebb99a9 100644
--- a/contrib/python/MarkupSafe/py3/.dist-info/METADATA
+++ b/contrib/python/MarkupSafe/py3/.dist-info/METADATA
@@ -1,94 +1,94 @@
-Metadata-Version: 2.1
-Name: MarkupSafe
+Metadata-Version: 2.1
+Name: MarkupSafe
Version: 2.0.1
-Summary: Safely add untrusted strings to HTML/XML markup.
-Home-page: https://palletsprojects.com/p/markupsafe/
-Author: Armin Ronacher
-Author-email: armin.ronacher@active-4.com
+Summary: Safely add untrusted strings to HTML/XML markup.
+Home-page: https://palletsprojects.com/p/markupsafe/
+Author: Armin Ronacher
+Author-email: armin.ronacher@active-4.com
Maintainer: Pallets
-Maintainer-email: contact@palletsprojects.com
-License: BSD-3-Clause
+Maintainer-email: contact@palletsprojects.com
+License: BSD-3-Clause
Project-URL: Donate, https://palletsprojects.com/donate
-Project-URL: Documentation, https://markupsafe.palletsprojects.com/
+Project-URL: Documentation, https://markupsafe.palletsprojects.com/
Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/
Project-URL: Source Code, https://github.com/pallets/markupsafe/
Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/
Project-URL: Twitter, https://twitter.com/PalletsTeam
Project-URL: Chat, https://discord.gg/pallets
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Web Environment
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
-Classifier: Topic :: Text Processing :: Markup :: HTML
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Classifier: Topic :: Text Processing :: Markup :: HTML
Requires-Python: >=3.6
Description-Content-Type: text/x-rst
License-File: LICENSE.rst
-
-MarkupSafe
-==========
-
-MarkupSafe implements a text object that escapes characters so it is
-safe to use in HTML and XML. Characters that have special meanings are
-replaced so that they display as the actual characters. This mitigates
-injection attacks, meaning untrusted user input can safely be displayed
-on a page.
-
-
-Installing
-----------
-
-Install and update using `pip`_:
-
-.. code-block:: text
-
- pip install -U MarkupSafe
-
-.. _pip: https://pip.pypa.io/en/stable/quickstart/
-
-
-Examples
---------
-
-.. code-block:: pycon
-
- >>> from markupsafe import Markup, escape
-
- >>> # escape replaces special characters and wraps in Markup
+
+MarkupSafe
+==========
+
+MarkupSafe implements a text object that escapes characters so it is
+safe to use in HTML and XML. Characters that have special meanings are
+replaced so that they display as the actual characters. This mitigates
+injection attacks, meaning untrusted user input can safely be displayed
+on a page.
+
+
+Installing
+----------
+
+Install and update using `pip`_:
+
+.. code-block:: text
+
+ pip install -U MarkupSafe
+
+.. _pip: https://pip.pypa.io/en/stable/quickstart/
+
+
+Examples
+--------
+
+.. code-block:: pycon
+
+ >>> from markupsafe import Markup, escape
+
+ >>> # escape replaces special characters and wraps in Markup
>>> escape("<script>alert(document.cookie);</script>")
Markup('&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
- >>> # wrap in Markup to mark text "safe" and prevent escaping
+ >>> # wrap in Markup to mark text "safe" and prevent escaping
>>> Markup("<strong>Hello</strong>")
- Markup('<strong>hello</strong>')
+ Markup('<strong>hello</strong>')
>>> escape(Markup("<strong>Hello</strong>"))
- Markup('<strong>hello</strong>')
+ Markup('<strong>hello</strong>')
>>> # Markup is a str subclass
- >>> # methods and operators escape their arguments
+ >>> # methods and operators escape their arguments
>>> template = Markup("Hello <em>{name}</em>")
>>> template.format(name='"World"')
- Markup('Hello <em>&#34;World&#34;</em>')
-
-
-Donate
-------
-
-The Pallets organization develops and supports MarkupSafe and other
+ Markup('Hello <em>&#34;World&#34;</em>')
+
+
+Donate
+------
+
+The Pallets organization develops and supports MarkupSafe and other
popular packages. In order to grow the community of contributors and
users, and allow the maintainers to devote more time to the projects,
`please donate today`_.
-
-.. _please donate today: https://palletsprojects.com/donate
-
-
-Links
------
-
+
+.. _please donate today: https://palletsprojects.com/donate
+
+
+Links
+-----
+
- Documentation: https://markupsafe.palletsprojects.com/
- Changes: https://markupsafe.palletsprojects.com/changes/
- PyPI Releases: https://pypi.org/project/MarkupSafe/
@@ -97,5 +97,5 @@ Links
- Website: https://palletsprojects.com/p/markupsafe/
- Twitter: https://twitter.com/PalletsTeam
- Chat: https://discord.gg/pallets
-
-
+
+
diff --git a/contrib/python/MarkupSafe/py3/.dist-info/top_level.txt b/contrib/python/MarkupSafe/py3/.dist-info/top_level.txt
index ecf81b4a7b..75bf729258 100644
--- a/contrib/python/MarkupSafe/py3/.dist-info/top_level.txt
+++ b/contrib/python/MarkupSafe/py3/.dist-info/top_level.txt
@@ -1 +1 @@
-markupsafe
+markupsafe
diff --git a/contrib/python/MarkupSafe/py3/ya.make b/contrib/python/MarkupSafe/py3/ya.make
index cf7035d171..8c750e15d8 100644
--- a/contrib/python/MarkupSafe/py3/ya.make
+++ b/contrib/python/MarkupSafe/py3/ya.make
@@ -27,13 +27,13 @@ PY_SRCS(
markupsafe/_speedups.pyi
)
-RESOURCE_FILES(
+RESOURCE_FILES(
PREFIX contrib/python/MarkupSafe/py3/
- .dist-info/METADATA
- .dist-info/top_level.txt
+ .dist-info/METADATA
+ .dist-info/top_level.txt
markupsafe/py.typed
-)
-
+)
+
END()
RECURSE_FOR_TESTS(
diff --git a/contrib/python/setuptools/py2/pkg_resources/__init__.py b/contrib/python/setuptools/py2/pkg_resources/__init__.py
index c44ac12129..649a2ce651 100644
--- a/contrib/python/setuptools/py2/pkg_resources/__init__.py
+++ b/contrib/python/setuptools/py2/pkg_resources/__init__.py
@@ -3278,19 +3278,19 @@ class ResProvider(EmptyProvider):
path = os.path.normpath(path)
return self._resource_fs.get(path)
- def _listdir(self, path):
+ def _listdir(self, path):
result = self.__lookup(path)
if result is None:
return []
if isinstance(path, six.text_type) and six.PY2:
return [key.decode('utf-8') for key in result]
- else:
+ else:
return list(result)
- def _isdir(self, path):
+ def _isdir(self, path):
return bool(self.__lookup(path))
-
-
+
+
class ResDistribution(DistInfoDistribution):
def __init__(self, prefix):
super(ResDistribution, self).__init__(
diff --git a/contrib/python/setuptools/py3/pkg_resources/__init__.py b/contrib/python/setuptools/py3/pkg_resources/__init__.py
index 43b2459c60..6b947a49a7 100644
--- a/contrib/python/setuptools/py3/pkg_resources/__init__.py
+++ b/contrib/python/setuptools/py3/pkg_resources/__init__.py
@@ -3283,16 +3283,16 @@ class ResProvider(EmptyProvider):
path = os.path.normpath(path)
return self._resource_fs.get(path)
- def _listdir(self, path):
+ def _listdir(self, path):
result = self.__lookup(path)
if result is None:
return []
return list(result)
- def _isdir(self, path):
+ def _isdir(self, path):
return bool(self.__lookup(path))
-
-
+
+
class ResDistribution(DistInfoDistribution):
def __init__(self, prefix):
super(ResDistribution, self).__init__(
diff --git a/contrib/python/traitlets/py2/tests/ya.make b/contrib/python/traitlets/py2/tests/ya.make
index 050f5d1cc0..d2d3e3b9bf 100644
--- a/contrib/python/traitlets/py2/tests/ya.make
+++ b/contrib/python/traitlets/py2/tests/ya.make
@@ -1,15 +1,15 @@
PY2TEST()
-
-OWNER(g:python-contrib borman nslus)
-
-PEERDIR(
+
+OWNER(g:python-contrib borman nslus)
+
+PEERDIR(
contrib/python/traitlets
-)
-
+)
+
ENV(
YA_PYTEST_DISABLE_DOCTEST=yes
)
-
+
SRCDIR(contrib/python/traitlets/py2/traitlets)
TEST_SRCS(
@@ -18,8 +18,8 @@ TEST_SRCS(
tests/test_traitlets.py
tests/test_traitlets_enum.py
tests/utils.py
-)
-
-NO_LINT()
-
-END()
+)
+
+NO_LINT()
+
+END()
diff --git a/contrib/python/traitlets/py2/traitlets/tests/_warnings.py b/contrib/python/traitlets/py2/traitlets/tests/_warnings.py
index beb3bf6ad5..f135d1f67e 100644
--- a/contrib/python/traitlets/py2/traitlets/tests/_warnings.py
+++ b/contrib/python/traitlets/py2/traitlets/tests/_warnings.py
@@ -1,107 +1,107 @@
-# From scikit-image: https://github.com/scikit-image/scikit-image/blob/c2f8c4ab123ebe5f7b827bc495625a32bb225c10/skimage/_shared/_warnings.py
-# Licensed under modified BSD license
-
-__all__ = ['all_warnings', 'expected_warnings']
-
-from contextlib import contextmanager
-import sys
-import warnings
-import inspect
-import re
-
-
-@contextmanager
-def all_warnings():
- """
- Context for use in testing to ensure that all warnings are raised.
- Examples
- --------
- >>> import warnings
- >>> def foo():
- ... warnings.warn(RuntimeWarning("bar"))
- We raise the warning once, while the warning filter is set to "once".
- Hereafter, the warning is invisible, even with custom filters:
- >>> with warnings.catch_warnings():
- ... warnings.simplefilter('once')
- ... foo()
- We can now run ``foo()`` without a warning being raised:
- >>> from numpy.testing import assert_warns
- >>> foo()
- To catch the warning, we call in the help of ``all_warnings``:
- >>> with all_warnings():
- ... assert_warns(RuntimeWarning, foo)
- """
-
- # Whenever a warning is triggered, Python adds a __warningregistry__
- # member to the *calling* module. The exercize here is to find
- # and eradicate all those breadcrumbs that were left lying around.
- #
- # We proceed by first searching all parent calling frames and explicitly
- # clearing their warning registries (necessary for the doctests above to
- # pass). Then, we search for all submodules of skimage and clear theirs
- # as well (necessary for the skimage test suite to pass).
-
- frame = inspect.currentframe()
- if frame:
- for f in inspect.getouterframes(frame):
- f[0].f_locals['__warningregistry__'] = {}
- del frame
-
- for mod_name, mod in list(sys.modules.items()):
- if 'six.moves' in mod_name:
- continue
- try:
- mod.__warningregistry__.clear()
- except AttributeError:
- pass
-
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always")
- yield w
-
-
-@contextmanager
-def expected_warnings(matching):
- """Context for use in testing to catch known warnings matching regexes
-
- Parameters
- ----------
- matching : list of strings or compiled regexes
- Regexes for the desired warning to catch
- Examples
- --------
- >>> from skimage import data, img_as_ubyte, img_as_float
- >>> with expected_warnings(['precision loss']):
- ... d = img_as_ubyte(img_as_float(data.coins()))
- Notes
- -----
- Uses `all_warnings` to ensure all warnings are raised.
- Upon exiting, it checks the recorded warnings for the desired matching
- pattern(s).
- Raises a ValueError if any match was not found or an unexpected
- warning was raised.
- Allows for three types of behaviors: "and", "or", and "optional" matches.
- This is done to accomodate different build enviroments or loop conditions
- that may produce different warnings. The behaviors can be combined.
- If you pass multiple patterns, you get an orderless "and", where all of the
- warnings must be raised.
- If you use the "|" operator in a pattern, you can catch one of several warnings.
- Finally, you can use "|\A\Z" in a pattern to signify it as optional.
- """
- with all_warnings() as w:
- # enter context
- yield w
- # exited user context, check the recorded warnings
- remaining = [m for m in matching if not '\A\Z' in m.split('|')]
- for warn in w:
- found = False
- for match in matching:
- if re.search(match, str(warn.message)) is not None:
- found = True
- if match in remaining:
- remaining.remove(match)
- if not found:
- raise ValueError('Unexpected warning: %s' % str(warn.message))
- if len(remaining) > 0:
- msg = 'No warning raised matching:\n%s' % '\n'.join(remaining)
- raise ValueError(msg)
+# From scikit-image: https://github.com/scikit-image/scikit-image/blob/c2f8c4ab123ebe5f7b827bc495625a32bb225c10/skimage/_shared/_warnings.py
+# Licensed under modified BSD license
+
+__all__ = ['all_warnings', 'expected_warnings']
+
+from contextlib import contextmanager
+import sys
+import warnings
+import inspect
+import re
+
+
+@contextmanager
+def all_warnings():
+ """
+ Context for use in testing to ensure that all warnings are raised.
+ Examples
+ --------
+ >>> import warnings
+ >>> def foo():
+ ... warnings.warn(RuntimeWarning("bar"))
+ We raise the warning once, while the warning filter is set to "once".
+ Hereafter, the warning is invisible, even with custom filters:
+ >>> with warnings.catch_warnings():
+ ... warnings.simplefilter('once')
+ ... foo()
+ We can now run ``foo()`` without a warning being raised:
+ >>> from numpy.testing import assert_warns
+ >>> foo()
+ To catch the warning, we call in the help of ``all_warnings``:
+ >>> with all_warnings():
+ ... assert_warns(RuntimeWarning, foo)
+ """
+
+ # Whenever a warning is triggered, Python adds a __warningregistry__
+ # member to the *calling* module. The exercize here is to find
+ # and eradicate all those breadcrumbs that were left lying around.
+ #
+ # We proceed by first searching all parent calling frames and explicitly
+ # clearing their warning registries (necessary for the doctests above to
+ # pass). Then, we search for all submodules of skimage and clear theirs
+ # as well (necessary for the skimage test suite to pass).
+
+ frame = inspect.currentframe()
+ if frame:
+ for f in inspect.getouterframes(frame):
+ f[0].f_locals['__warningregistry__'] = {}
+ del frame
+
+ for mod_name, mod in list(sys.modules.items()):
+ if 'six.moves' in mod_name:
+ continue
+ try:
+ mod.__warningregistry__.clear()
+ except AttributeError:
+ pass
+
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter("always")
+ yield w
+
+
+@contextmanager
+def expected_warnings(matching):
+ """Context for use in testing to catch known warnings matching regexes
+
+ Parameters
+ ----------
+ matching : list of strings or compiled regexes
+ Regexes for the desired warning to catch
+ Examples
+ --------
+ >>> from skimage import data, img_as_ubyte, img_as_float
+ >>> with expected_warnings(['precision loss']):
+ ... d = img_as_ubyte(img_as_float(data.coins()))
+ Notes
+ -----
+ Uses `all_warnings` to ensure all warnings are raised.
+ Upon exiting, it checks the recorded warnings for the desired matching
+ pattern(s).
+ Raises a ValueError if any match was not found or an unexpected
+ warning was raised.
+ Allows for three types of behaviors: "and", "or", and "optional" matches.
+ This is done to accomodate different build enviroments or loop conditions
+ that may produce different warnings. The behaviors can be combined.
+ If you pass multiple patterns, you get an orderless "and", where all of the
+ warnings must be raised.
+ If you use the "|" operator in a pattern, you can catch one of several warnings.
+ Finally, you can use "|\A\Z" in a pattern to signify it as optional.
+ """
+ with all_warnings() as w:
+ # enter context
+ yield w
+ # exited user context, check the recorded warnings
+ remaining = [m for m in matching if not '\A\Z' in m.split('|')]
+ for warn in w:
+ found = False
+ for match in matching:
+ if re.search(match, str(warn.message)) is not None:
+ found = True
+ if match in remaining:
+ remaining.remove(match)
+ if not found:
+ raise ValueError('Unexpected warning: %s' % str(warn.message))
+ if len(remaining) > 0:
+ msg = 'No warning raised matching:\n%s' % '\n'.join(remaining)
+ raise ValueError(msg)
diff --git a/contrib/python/traitlets/py2/traitlets/tests/test_traitlets.py b/contrib/python/traitlets/py2/traitlets/tests/test_traitlets.py
index 5c0440f9ba..11b334cb60 100644
--- a/contrib/python/traitlets/py2/traitlets/tests/test_traitlets.py
+++ b/contrib/python/traitlets/py2/traitlets/tests/test_traitlets.py
@@ -1,2419 +1,2419 @@
-# encoding: utf-8
-"""Tests for traitlets.traitlets."""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-#
-# Adapted from enthought.traits, Copyright (c) Enthought, Inc.,
-# also under the terms of the Modified BSD License.
-
-import pickle
-import re
-import sys
+# encoding: utf-8
+"""Tests for traitlets.traitlets."""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+#
+# Adapted from enthought.traits, Copyright (c) Enthought, Inc.,
+# also under the terms of the Modified BSD License.
+
+import pickle
+import re
+import sys
from ._warnings import expected_warnings
-
-from unittest import TestCase
-import pytest
-from pytest import mark
-
-from traitlets import (
- HasTraits, MetaHasTraits, TraitType, Any, Bool, CBytes, Dict, Enum,
- Int, CInt, Long, CLong, Integer, Float, CFloat, Complex, Bytes, Unicode,
- TraitError, Union, All, Undefined, Type, This, Instance, TCPAddress,
- List, Tuple, ObjectName, DottedObjectName, CRegExp, link, directional_link,
- ForwardDeclaredType, ForwardDeclaredInstance, validate, observe, default,
- observe_compat, BaseDescriptor, HasDescriptors,
-)
-
-import six
-
-def change_dict(*ordered_values):
- change_names = ('name', 'old', 'new', 'owner', 'type')
- return dict(zip(change_names, ordered_values))
-
-#-----------------------------------------------------------------------------
-# Helper classes for testing
-#-----------------------------------------------------------------------------
-
-
-class HasTraitsStub(HasTraits):
-
- def notify_change(self, change):
- self._notify_name = change['name']
- self._notify_old = change['old']
- self._notify_new = change['new']
- self._notify_type = change['type']
-
-
-#-----------------------------------------------------------------------------
-# Test classes
-#-----------------------------------------------------------------------------
-
-
-class TestTraitType(TestCase):
-
- def test_get_undefined(self):
- class A(HasTraits):
- a = TraitType
- a = A()
- with self.assertRaises(TraitError):
- a.a
-
- def test_set(self):
- class A(HasTraitsStub):
- a = TraitType
-
- a = A()
- a.a = 10
- self.assertEqual(a.a, 10)
- self.assertEqual(a._notify_name, 'a')
- self.assertEqual(a._notify_old, Undefined)
- self.assertEqual(a._notify_new, 10)
-
- def test_validate(self):
- class MyTT(TraitType):
- def validate(self, inst, value):
- return -1
- class A(HasTraitsStub):
- tt = MyTT
-
- a = A()
- a.tt = 10
- self.assertEqual(a.tt, -1)
-
- def test_default_validate(self):
- class MyIntTT(TraitType):
- def validate(self, obj, value):
- if isinstance(value, int):
- return value
- self.error(obj, value)
- class A(HasTraits):
- tt = MyIntTT(10)
- a = A()
- self.assertEqual(a.tt, 10)
-
- # Defaults are validated when the HasTraits is instantiated
- class B(HasTraits):
- tt = MyIntTT('bad default')
- self.assertRaises(TraitError, B)
-
- def test_info(self):
- class A(HasTraits):
- tt = TraitType
- a = A()
- self.assertEqual(A.tt.info(), 'any value')
-
- def test_error(self):
- class A(HasTraits):
- tt = TraitType
- a = A()
- self.assertRaises(TraitError, A.tt.error, a, 10)
-
- def test_deprecated_dynamic_initializer(self):
- class A(HasTraits):
- x = Int(10)
- def _x_default(self):
- return 11
- class B(A):
- x = Int(20)
- class C(A):
- def _x_default(self):
- return 21
-
- a = A()
- self.assertEqual(a._trait_values, {})
- self.assertEqual(a.x, 11)
- self.assertEqual(a._trait_values, {'x': 11})
- b = B()
- self.assertEqual(b.x, 20)
- self.assertEqual(b._trait_values, {'x': 20})
- c = C()
- self.assertEqual(c._trait_values, {})
- self.assertEqual(c.x, 21)
- self.assertEqual(c._trait_values, {'x': 21})
- # Ensure that the base class remains unmolested when the _default
- # initializer gets overridden in a subclass.
- a = A()
- c = C()
- self.assertEqual(a._trait_values, {})
- self.assertEqual(a.x, 11)
- self.assertEqual(a._trait_values, {'x': 11})
-
- def test_dynamic_initializer(self):
-
- class A(HasTraits):
- x = Int(10)
-
- @default('x')
- def _default_x(self):
- return 11
-
- class B(A):
- x = Int(20)
-
- class C(A):
-
- @default('x')
- def _default_x(self):
- return 21
-
- a = A()
- self.assertEqual(a._trait_values, {})
- self.assertEqual(a.x, 11)
- self.assertEqual(a._trait_values, {'x': 11})
- b = B()
- self.assertEqual(b.x, 20)
- self.assertEqual(b._trait_values, {'x': 20})
- c = C()
- self.assertEqual(c._trait_values, {})
- self.assertEqual(c.x, 21)
- self.assertEqual(c._trait_values, {'x': 21})
- # Ensure that the base class remains unmolested when the _default
- # initializer gets overridden in a subclass.
- a = A()
- c = C()
- self.assertEqual(a._trait_values, {})
- self.assertEqual(a.x, 11)
- self.assertEqual(a._trait_values, {'x': 11})
-
- def test_tag_metadata(self):
- class MyIntTT(TraitType):
- metadata = {'a': 1, 'b': 2}
- a = MyIntTT(10).tag(b=3, c=4)
- self.assertEqual(a.metadata, {'a': 1, 'b': 3, 'c': 4})
-
- def test_metadata_localized_instance(self):
- class MyIntTT(TraitType):
- metadata = {'a': 1, 'b': 2}
- a = MyIntTT(10)
- b = MyIntTT(10)
- a.metadata['c'] = 3
- # make sure that changing a's metadata didn't change b's metadata
- self.assertNotIn('c', b.metadata)
-
- def test_union_metadata(self):
- class Foo(HasTraits):
- bar = (Int().tag(ta=1) | Dict().tag(ta=2, ti='b')).tag(ti='a')
- foo = Foo()
- # At this point, no value has been set for bar, so value-specific
- # is not set.
- self.assertEqual(foo.trait_metadata('bar', 'ta'), None)
- self.assertEqual(foo.trait_metadata('bar', 'ti'), 'a')
- foo.bar = {}
- self.assertEqual(foo.trait_metadata('bar', 'ta'), 2)
- self.assertEqual(foo.trait_metadata('bar', 'ti'), 'b')
- foo.bar = 1
- self.assertEqual(foo.trait_metadata('bar', 'ta'), 1)
- self.assertEqual(foo.trait_metadata('bar', 'ti'), 'a')
-
- def test_union_default_value(self):
- class Foo(HasTraits):
- bar = Union([Dict(), Int()], default_value=1)
- foo = Foo()
- self.assertEqual(foo.bar, 1)
-
- def test_deprecated_metadata_access(self):
- class MyIntTT(TraitType):
- metadata = {'a': 1, 'b': 2}
- a = MyIntTT(10)
- with expected_warnings(["use the instance .metadata dictionary directly"]*2):
- a.set_metadata('key', 'value')
- v = a.get_metadata('key')
- self.assertEqual(v, 'value')
- with expected_warnings(["use the instance .help string directly"]*2):
- a.set_metadata('help', 'some help')
- v = a.get_metadata('help')
- self.assertEqual(v, 'some help')
-
- def test_trait_types_deprecated(self):
- with expected_warnings(["Traits should be given as instances"]):
- class C(HasTraits):
- t = Int
-
- def test_trait_types_list_deprecated(self):
- with expected_warnings(["Traits should be given as instances"]):
- class C(HasTraits):
- t = List(Int)
-
- def test_trait_types_tuple_deprecated(self):
- with expected_warnings(["Traits should be given as instances"]):
- class C(HasTraits):
- t = Tuple(Int)
-
- def test_trait_types_dict_deprecated(self):
- with expected_warnings(["Traits should be given as instances"]):
- class C(HasTraits):
- t = Dict(Int)
-
-class TestHasDescriptorsMeta(TestCase):
-
- def test_metaclass(self):
- self.assertEqual(type(HasTraits), MetaHasTraits)
-
- class A(HasTraits):
- a = Int()
-
- a = A()
- self.assertEqual(type(a.__class__), MetaHasTraits)
- self.assertEqual(a.a,0)
- a.a = 10
- self.assertEqual(a.a,10)
-
- class B(HasTraits):
- b = Int()
-
- b = B()
- self.assertEqual(b.b,0)
- b.b = 10
- self.assertEqual(b.b,10)
-
- class C(HasTraits):
- c = Int(30)
-
- c = C()
- self.assertEqual(c.c,30)
- c.c = 10
- self.assertEqual(c.c,10)
-
- def test_this_class(self):
- class A(HasTraits):
- t = This()
- tt = This()
- class B(A):
- tt = This()
- ttt = This()
- self.assertEqual(A.t.this_class, A)
- self.assertEqual(B.t.this_class, A)
- self.assertEqual(B.tt.this_class, B)
- self.assertEqual(B.ttt.this_class, B)
-
-class TestHasDescriptors(TestCase):
-
- def test_setup_instance(self):
-
- class FooDescriptor(BaseDescriptor):
-
- def instance_init(self, inst):
- foo = inst.foo # instance should have the attr
-
- class HasFooDescriptors(HasDescriptors):
-
- fd = FooDescriptor()
-
- def setup_instance(self, *args, **kwargs):
- self.foo = kwargs.get('foo', None)
- super(HasFooDescriptors, self).setup_instance(*args, **kwargs)
-
- hfd = HasFooDescriptors(foo='bar')
-
-class TestHasTraitsNotify(TestCase):
-
- def setUp(self):
- self._notify1 = []
- self._notify2 = []
-
- def notify1(self, name, old, new):
- self._notify1.append((name, old, new))
-
- def notify2(self, name, old, new):
- self._notify2.append((name, old, new))
-
- def test_notify_all(self):
-
- class A(HasTraits):
- a = Int()
- b = Float()
-
- a = A()
- a.on_trait_change(self.notify1)
- a.a = 0
- self.assertEqual(len(self._notify1),0)
- a.b = 0.0
- self.assertEqual(len(self._notify1),0)
- a.a = 10
- self.assertTrue(('a',0,10) in self._notify1)
- a.b = 10.0
- self.assertTrue(('b',0.0,10.0) in self._notify1)
- self.assertRaises(TraitError,setattr,a,'a','bad string')
- self.assertRaises(TraitError,setattr,a,'b','bad string')
- self._notify1 = []
- a.on_trait_change(self.notify1,remove=True)
- a.a = 20
- a.b = 20.0
- self.assertEqual(len(self._notify1),0)
-
- def test_notify_one(self):
-
- class A(HasTraits):
- a = Int()
- b = Float()
-
- a = A()
- a.on_trait_change(self.notify1, 'a')
- a.a = 0
- self.assertEqual(len(self._notify1),0)
- a.a = 10
- self.assertTrue(('a',0,10) in self._notify1)
- self.assertRaises(TraitError,setattr,a,'a','bad string')
-
- def test_subclass(self):
-
- class A(HasTraits):
- a = Int()
-
- class B(A):
- b = Float()
-
- b = B()
- self.assertEqual(b.a,0)
- self.assertEqual(b.b,0.0)
- b.a = 100
- b.b = 100.0
- self.assertEqual(b.a,100)
- self.assertEqual(b.b,100.0)
-
- def test_notify_subclass(self):
-
- class A(HasTraits):
- a = Int()
-
- class B(A):
- b = Float()
-
- b = B()
- b.on_trait_change(self.notify1, 'a')
- b.on_trait_change(self.notify2, 'b')
- b.a = 0
- b.b = 0.0
- self.assertEqual(len(self._notify1),0)
- self.assertEqual(len(self._notify2),0)
- b.a = 10
- b.b = 10.0
- self.assertTrue(('a',0,10) in self._notify1)
- self.assertTrue(('b',0.0,10.0) in self._notify2)
-
- def test_static_notify(self):
-
- class A(HasTraits):
- a = Int()
- _notify1 = []
- def _a_changed(self, name, old, new):
- self._notify1.append((name, old, new))
-
- a = A()
- a.a = 0
- # This is broken!!!
- self.assertEqual(len(a._notify1),0)
- a.a = 10
- self.assertTrue(('a',0,10) in a._notify1)
-
- class B(A):
- b = Float()
- _notify2 = []
- def _b_changed(self, name, old, new):
- self._notify2.append((name, old, new))
-
- b = B()
- b.a = 10
- b.b = 10.0
- self.assertTrue(('a',0,10) in b._notify1)
- self.assertTrue(('b',0.0,10.0) in b._notify2)
-
- def test_notify_args(self):
-
- def callback0():
- self.cb = ()
- def callback1(name):
- self.cb = (name,)
- def callback2(name, new):
- self.cb = (name, new)
- def callback3(name, old, new):
- self.cb = (name, old, new)
- def callback4(name, old, new, obj):
- self.cb = (name, old, new, obj)
-
- class A(HasTraits):
- a = Int()
-
- a = A()
- a.on_trait_change(callback0, 'a')
- a.a = 10
- self.assertEqual(self.cb,())
- a.on_trait_change(callback0, 'a', remove=True)
-
- a.on_trait_change(callback1, 'a')
- a.a = 100
- self.assertEqual(self.cb,('a',))
- a.on_trait_change(callback1, 'a', remove=True)
-
- a.on_trait_change(callback2, 'a')
- a.a = 1000
- self.assertEqual(self.cb,('a',1000))
- a.on_trait_change(callback2, 'a', remove=True)
-
- a.on_trait_change(callback3, 'a')
- a.a = 10000
- self.assertEqual(self.cb,('a',1000,10000))
- a.on_trait_change(callback3, 'a', remove=True)
-
- a.on_trait_change(callback4, 'a')
- a.a = 100000
- self.assertEqual(self.cb,('a',10000,100000,a))
- self.assertEqual(len(a._trait_notifiers['a']['change']), 1)
- a.on_trait_change(callback4, 'a', remove=True)
-
- self.assertEqual(len(a._trait_notifiers['a']['change']), 0)
-
- def test_notify_only_once(self):
-
- class A(HasTraits):
- listen_to = ['a']
-
- a = Int(0)
- b = 0
-
- def __init__(self, **kwargs):
- super(A, self).__init__(**kwargs)
- self.on_trait_change(self.listener1, ['a'])
-
- def listener1(self, name, old, new):
- self.b += 1
-
- class B(A):
-
- c = 0
- d = 0
-
- def __init__(self, **kwargs):
- super(B, self).__init__(**kwargs)
- self.on_trait_change(self.listener2)
-
- def listener2(self, name, old, new):
- self.c += 1
-
- def _a_changed(self, name, old, new):
- self.d += 1
-
- b = B()
- b.a += 1
- self.assertEqual(b.b, b.c)
- self.assertEqual(b.b, b.d)
- b.a += 1
- self.assertEqual(b.b, b.c)
- self.assertEqual(b.b, b.d)
-
-class TestObserveDecorator(TestCase):
-
- def setUp(self):
- self._notify1 = []
- self._notify2 = []
-
- def notify1(self, change):
- self._notify1.append(change)
-
- def notify2(self, change):
- self._notify2.append(change)
-
- def test_notify_all(self):
-
- class A(HasTraits):
- a = Int()
- b = Float()
-
- a = A()
- a.observe(self.notify1)
- a.a = 0
- self.assertEqual(len(self._notify1),0)
- a.b = 0.0
- self.assertEqual(len(self._notify1),0)
- a.a = 10
- change = change_dict('a', 0, 10, a, 'change')
- self.assertTrue(change in self._notify1)
- a.b = 10.0
- change = change_dict('b', 0.0, 10.0, a, 'change')
- self.assertTrue(change in self._notify1)
- self.assertRaises(TraitError,setattr,a,'a','bad string')
- self.assertRaises(TraitError,setattr,a,'b','bad string')
- self._notify1 = []
- a.unobserve(self.notify1)
- a.a = 20
- a.b = 20.0
- self.assertEqual(len(self._notify1),0)
-
- def test_notify_one(self):
-
- class A(HasTraits):
- a = Int()
- b = Float()
-
- a = A()
- a.observe(self.notify1, 'a')
- a.a = 0
- self.assertEqual(len(self._notify1),0)
- a.a = 10
- change = change_dict('a', 0, 10, a, 'change')
- self.assertTrue(change in self._notify1)
- self.assertRaises(TraitError,setattr,a,'a','bad string')
-
- def test_subclass(self):
-
- class A(HasTraits):
- a = Int()
-
- class B(A):
- b = Float()
-
- b = B()
- self.assertEqual(b.a,0)
- self.assertEqual(b.b,0.0)
- b.a = 100
- b.b = 100.0
- self.assertEqual(b.a,100)
- self.assertEqual(b.b,100.0)
-
- def test_notify_subclass(self):
-
- class A(HasTraits):
- a = Int()
-
- class B(A):
- b = Float()
-
- b = B()
- b.observe(self.notify1, 'a')
- b.observe(self.notify2, 'b')
- b.a = 0
- b.b = 0.0
- self.assertEqual(len(self._notify1),0)
- self.assertEqual(len(self._notify2),0)
- b.a = 10
- b.b = 10.0
- change = change_dict('a', 0, 10, b, 'change')
- self.assertTrue(change in self._notify1)
- change = change_dict('b', 0.0, 10.0, b, 'change')
- self.assertTrue(change in self._notify2)
-
- def test_static_notify(self):
-
- class A(HasTraits):
- a = Int()
- b = Int()
- _notify1 = []
- _notify_any = []
-
- @observe('a')
- def _a_changed(self, change):
- self._notify1.append(change)
-
- @observe(All)
- def _any_changed(self, change):
- self._notify_any.append(change)
-
- a = A()
- a.a = 0
- self.assertEqual(len(a._notify1),0)
- a.a = 10
- change = change_dict('a', 0, 10, a, 'change')
- self.assertTrue(change in a._notify1)
- a.b = 1
- self.assertEqual(len(a._notify_any), 2)
- change = change_dict('b', 0, 1, a, 'change')
- self.assertTrue(change in a._notify_any)
-
- class B(A):
- b = Float()
- _notify2 = []
- @observe('b')
- def _b_changed(self, change):
- self._notify2.append(change)
-
- b = B()
- b.a = 10
- b.b = 10.0
- change = change_dict('a', 0, 10, b, 'change')
- self.assertTrue(change in b._notify1)
- change = change_dict('b', 0.0, 10.0, b, 'change')
- self.assertTrue(change in b._notify2)
-
- def test_notify_args(self):
-
- def callback0():
- self.cb = ()
- def callback1(change):
- self.cb = change
-
- class A(HasTraits):
- a = Int()
-
- a = A()
- a.on_trait_change(callback0, 'a')
- a.a = 10
- self.assertEqual(self.cb,())
- a.unobserve(callback0, 'a')
-
- a.observe(callback1, 'a')
- a.a = 100
- change = change_dict('a', 10, 100, a, 'change')
- self.assertEqual(self.cb, change)
- self.assertEqual(len(a._trait_notifiers['a']['change']), 1)
- a.unobserve(callback1, 'a')
-
- self.assertEqual(len(a._trait_notifiers['a']['change']), 0)
-
- def test_notify_only_once(self):
-
- class A(HasTraits):
- listen_to = ['a']
-
- a = Int(0)
- b = 0
-
- def __init__(self, **kwargs):
- super(A, self).__init__(**kwargs)
- self.observe(self.listener1, ['a'])
-
- def listener1(self, change):
- self.b += 1
-
- class B(A):
-
- c = 0
- d = 0
-
- def __init__(self, **kwargs):
- super(B, self).__init__(**kwargs)
- self.observe(self.listener2)
-
- def listener2(self, change):
- self.c += 1
-
- @observe('a')
- def _a_changed(self, change):
- self.d += 1
-
- b = B()
- b.a += 1
- self.assertEqual(b.b, b.c)
- self.assertEqual(b.b, b.d)
- b.a += 1
- self.assertEqual(b.b, b.c)
- self.assertEqual(b.b, b.d)
-
-
-class TestHasTraits(TestCase):
-
- def test_trait_names(self):
- class A(HasTraits):
- i = Int()
- f = Float()
- a = A()
- self.assertEqual(sorted(a.trait_names()),['f','i'])
- self.assertEqual(sorted(A.class_trait_names()),['f','i'])
- self.assertTrue(a.has_trait('f'))
- self.assertFalse(a.has_trait('g'))
-
- def test_trait_metadata_deprecated(self):
- with expected_warnings(['metadata should be set using the \.tag\(\) method']):
- class A(HasTraits):
- i = Int(config_key='MY_VALUE')
- a = A()
- self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE')
-
- def test_trait_metadata(self):
- class A(HasTraits):
- i = Int().tag(config_key='MY_VALUE')
- a = A()
- self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE')
-
- def test_trait_metadata_default(self):
- class A(HasTraits):
- i = Int()
- a = A()
- self.assertEqual(a.trait_metadata('i', 'config_key'), None)
- self.assertEqual(a.trait_metadata('i', 'config_key', 'default'), 'default')
-
- def test_traits(self):
- class A(HasTraits):
- i = Int()
- f = Float()
- a = A()
- self.assertEqual(a.traits(), dict(i=A.i, f=A.f))
- self.assertEqual(A.class_traits(), dict(i=A.i, f=A.f))
-
- def test_traits_metadata(self):
- class A(HasTraits):
- i = Int().tag(config_key='VALUE1', other_thing='VALUE2')
- f = Float().tag(config_key='VALUE3', other_thing='VALUE2')
- j = Int(0)
- a = A()
- self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j))
- traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
- self.assertEqual(traits, dict(i=A.i))
-
- # This passes, but it shouldn't because I am replicating a bug in
- # traits.
- traits = a.traits(config_key=lambda v: True)
- self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j))
-
- def test_traits_metadata_deprecated(self):
- with expected_warnings(['metadata should be set using the \.tag\(\) method']*2):
- class A(HasTraits):
- i = Int(config_key='VALUE1', other_thing='VALUE2')
- f = Float(config_key='VALUE3', other_thing='VALUE2')
- j = Int(0)
- a = A()
- self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j))
- traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
- self.assertEqual(traits, dict(i=A.i))
-
- # This passes, but it shouldn't because I am replicating a bug in
- # traits.
- traits = a.traits(config_key=lambda v: True)
- self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j))
-
-
- def test_init(self):
- class A(HasTraits):
- i = Int()
- x = Float()
- a = A(i=1, x=10.0)
- self.assertEqual(a.i, 1)
- self.assertEqual(a.x, 10.0)
-
- def test_positional_args(self):
- class A(HasTraits):
- i = Int(0)
- def __init__(self, i):
- super(A, self).__init__()
- self.i = i
-
- a = A(5)
- self.assertEqual(a.i, 5)
- # should raise TypeError if no positional arg given
- self.assertRaises(TypeError, A)
-
-#-----------------------------------------------------------------------------
-# Tests for specific trait types
-#-----------------------------------------------------------------------------
-
-
-class TestType(TestCase):
-
- def test_default(self):
-
- class B(object): pass
- class A(HasTraits):
- klass = Type(allow_none=True)
-
- a = A()
- self.assertEqual(a.klass, object)
-
- a.klass = B
- self.assertEqual(a.klass, B)
- self.assertRaises(TraitError, setattr, a, 'klass', 10)
-
- def test_default_options(self):
-
- class B(object): pass
- class C(B): pass
- class A(HasTraits):
- # Different possible combinations of options for default_value
- # and klass. default_value=None is only valid with allow_none=True.
- k1 = Type()
- k2 = Type(None, allow_none=True)
- k3 = Type(B)
- k4 = Type(klass=B)
- k5 = Type(default_value=None, klass=B, allow_none=True)
- k6 = Type(default_value=C, klass=B)
-
- self.assertIs(A.k1.default_value, object)
- self.assertIs(A.k1.klass, object)
- self.assertIs(A.k2.default_value, None)
- self.assertIs(A.k2.klass, object)
- self.assertIs(A.k3.default_value, B)
- self.assertIs(A.k3.klass, B)
- self.assertIs(A.k4.default_value, B)
- self.assertIs(A.k4.klass, B)
- self.assertIs(A.k5.default_value, None)
- self.assertIs(A.k5.klass, B)
- self.assertIs(A.k6.default_value, C)
- self.assertIs(A.k6.klass, B)
-
- a = A()
- self.assertIs(a.k1, object)
- self.assertIs(a.k2, None)
- self.assertIs(a.k3, B)
- self.assertIs(a.k4, B)
- self.assertIs(a.k5, None)
- self.assertIs(a.k6, C)
-
- def test_value(self):
-
- class B(object): pass
- class C(object): pass
- class A(HasTraits):
- klass = Type(B)
-
- a = A()
- self.assertEqual(a.klass, B)
- self.assertRaises(TraitError, setattr, a, 'klass', C)
- self.assertRaises(TraitError, setattr, a, 'klass', object)
- a.klass = B
-
- def test_allow_none(self):
-
- class B(object): pass
- class C(B): pass
- class A(HasTraits):
- klass = Type(B)
-
- a = A()
- self.assertEqual(a.klass, B)
- self.assertRaises(TraitError, setattr, a, 'klass', None)
- a.klass = C
- self.assertEqual(a.klass, C)
-
- def test_validate_klass(self):
-
- class A(HasTraits):
- klass = Type('no strings allowed')
-
- self.assertRaises(ImportError, A)
-
- class A(HasTraits):
- klass = Type('rub.adub.Duck')
-
- self.assertRaises(ImportError, A)
-
- def test_validate_default(self):
-
- class B(object): pass
- class A(HasTraits):
- klass = Type('bad default', B)
-
- self.assertRaises(ImportError, A)
-
- class C(HasTraits):
- klass = Type(None, B)
-
- self.assertRaises(TraitError, C)
-
- def test_str_klass(self):
-
- class A(HasTraits):
- klass = Type('ipython_genutils.ipstruct.Struct')
-
- from ipython_genutils.ipstruct import Struct
- a = A()
- a.klass = Struct
- self.assertEqual(a.klass, Struct)
-
- self.assertRaises(TraitError, setattr, a, 'klass', 10)
-
- def test_set_str_klass(self):
-
- class A(HasTraits):
- klass = Type()
-
- a = A(klass='ipython_genutils.ipstruct.Struct')
- from ipython_genutils.ipstruct import Struct
- self.assertEqual(a.klass, Struct)
-
-class TestInstance(TestCase):
-
- def test_basic(self):
- class Foo(object): pass
- class Bar(Foo): pass
- class Bah(object): pass
-
- class A(HasTraits):
- inst = Instance(Foo, allow_none=True)
-
- a = A()
- self.assertTrue(a.inst is None)
- a.inst = Foo()
- self.assertTrue(isinstance(a.inst, Foo))
- a.inst = Bar()
- self.assertTrue(isinstance(a.inst, Foo))
- self.assertRaises(TraitError, setattr, a, 'inst', Foo)
- self.assertRaises(TraitError, setattr, a, 'inst', Bar)
- self.assertRaises(TraitError, setattr, a, 'inst', Bah())
-
- def test_default_klass(self):
- class Foo(object): pass
- class Bar(Foo): pass
- class Bah(object): pass
-
- class FooInstance(Instance):
- klass = Foo
-
- class A(HasTraits):
- inst = FooInstance(allow_none=True)
-
- a = A()
- self.assertTrue(a.inst is None)
- a.inst = Foo()
- self.assertTrue(isinstance(a.inst, Foo))
- a.inst = Bar()
- self.assertTrue(isinstance(a.inst, Foo))
- self.assertRaises(TraitError, setattr, a, 'inst', Foo)
- self.assertRaises(TraitError, setattr, a, 'inst', Bar)
- self.assertRaises(TraitError, setattr, a, 'inst', Bah())
-
- def test_unique_default_value(self):
- class Foo(object): pass
- class A(HasTraits):
- inst = Instance(Foo,(),{})
-
- a = A()
- b = A()
- self.assertTrue(a.inst is not b.inst)
-
- def test_args_kw(self):
- class Foo(object):
- def __init__(self, c): self.c = c
- class Bar(object): pass
- class Bah(object):
- def __init__(self, c, d):
- self.c = c; self.d = d
-
- class A(HasTraits):
- inst = Instance(Foo, (10,))
- a = A()
- self.assertEqual(a.inst.c, 10)
-
- class B(HasTraits):
- inst = Instance(Bah, args=(10,), kw=dict(d=20))
- b = B()
- self.assertEqual(b.inst.c, 10)
- self.assertEqual(b.inst.d, 20)
-
- class C(HasTraits):
- inst = Instance(Foo, allow_none=True)
- c = C()
- self.assertTrue(c.inst is None)
-
- def test_bad_default(self):
- class Foo(object): pass
-
- class A(HasTraits):
- inst = Instance(Foo)
-
- a = A()
- with self.assertRaises(TraitError):
- a.inst
-
- def test_instance(self):
- class Foo(object): pass
-
- def inner():
- class A(HasTraits):
- inst = Instance(Foo())
-
- self.assertRaises(TraitError, inner)
-
-
-class TestThis(TestCase):
-
- def test_this_class(self):
- class Foo(HasTraits):
- this = This()
-
- f = Foo()
- self.assertEqual(f.this, None)
- g = Foo()
- f.this = g
- self.assertEqual(f.this, g)
- self.assertRaises(TraitError, setattr, f, 'this', 10)
-
- def test_this_inst(self):
- class Foo(HasTraits):
- this = This()
-
- f = Foo()
- f.this = Foo()
- self.assertTrue(isinstance(f.this, Foo))
-
- def test_subclass(self):
- class Foo(HasTraits):
- t = This()
- class Bar(Foo):
- pass
- f = Foo()
- b = Bar()
- f.t = b
- b.t = f
- self.assertEqual(f.t, b)
- self.assertEqual(b.t, f)
-
- def test_subclass_override(self):
- class Foo(HasTraits):
- t = This()
- class Bar(Foo):
- t = This()
- f = Foo()
- b = Bar()
- f.t = b
- self.assertEqual(f.t, b)
- self.assertRaises(TraitError, setattr, b, 't', f)
-
- def test_this_in_container(self):
-
- class Tree(HasTraits):
- value = Unicode()
- leaves = List(This())
-
- tree = Tree(
- value='foo',
- leaves=[Tree(value='bar'), Tree(value='buzz')]
- )
-
- with self.assertRaises(TraitError):
- tree.leaves = [1, 2]
-
-class TraitTestBase(TestCase):
- """A best testing class for basic trait types."""
-
- def assign(self, value):
- self.obj.value = value
-
- def coerce(self, value):
- return value
-
- def test_good_values(self):
- if hasattr(self, '_good_values'):
- for value in self._good_values:
- self.assign(value)
- self.assertEqual(self.obj.value, self.coerce(value))
-
- def test_bad_values(self):
- if hasattr(self, '_bad_values'):
- for value in self._bad_values:
- try:
- self.assertRaises(TraitError, self.assign, value)
- except AssertionError:
- assert False, value
-
- def test_default_value(self):
- if hasattr(self, '_default_value'):
- self.assertEqual(self._default_value, self.obj.value)
-
- def test_allow_none(self):
- if (hasattr(self, '_bad_values') and hasattr(self, '_good_values') and
- None in self._bad_values):
- trait=self.obj.traits()['value']
- try:
- trait.allow_none = True
- self._bad_values.remove(None)
- #skip coerce. Allow None casts None to None.
- self.assign(None)
- self.assertEqual(self.obj.value,None)
- self.test_good_values()
- self.test_bad_values()
- finally:
- #tear down
- trait.allow_none = False
- self._bad_values.append(None)
-
- def tearDown(self):
- # restore default value after tests, if set
- if hasattr(self, '_default_value'):
- self.obj.value = self._default_value
-
-
-class AnyTrait(HasTraits):
-
- value = Any()
-
-class AnyTraitTest(TraitTestBase):
-
- obj = AnyTrait()
-
- _default_value = None
- _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
- _bad_values = []
-
-class UnionTrait(HasTraits):
-
- value = Union([Type(), Bool()])
-
-class UnionTraitTest(TraitTestBase):
-
- obj = UnionTrait(value='ipython_genutils.ipstruct.Struct')
- _good_values = [int, float, True]
- _bad_values = [[], (0,), 1j]
-
-class OrTrait(HasTraits):
-
- value = Bool() | Unicode()
-
-class OrTraitTest(TraitTestBase):
-
- obj = OrTrait()
- _good_values = [True, False, 'ten']
- _bad_values = [[], (0,), 1j]
-
-class IntTrait(HasTraits):
-
- value = Int(99, min=-100)
-
-class TestInt(TraitTestBase):
-
- obj = IntTrait()
- _default_value = 99
- _good_values = [10, -10]
- _bad_values = ['ten', u'ten', [10], {'ten': 10}, (10,), None, 1j,
- 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L',
- u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', -200]
- if not six.PY3:
- _bad_values.extend([long(10), long(-10), 10*sys.maxint, -10*sys.maxint])
-
-
-class CIntTrait(HasTraits):
- value = CInt('5')
-
-class TestCInt(TraitTestBase):
- obj = CIntTrait()
-
- _default_value = 5
- _good_values = ['10', '-10', u'10', u'-10', 10, 10.0, -10.0, 10.1]
- _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,),
- None, 1j, '10.1', u'10.1']
-
- def coerce(self, n):
- return int(n)
-
-
-class MinBoundCIntTrait(HasTraits):
- value = CInt('5', min=3)
-
-class TestMinBoundCInt(TestCInt):
- obj = MinBoundCIntTrait()
-
- _default_value = 5
- _good_values = [3, 3.0, '3']
- _bad_values = [2.6, 2, -3, -3.0]
-
-
-class LongTrait(HasTraits):
-
- value = Long(99 if six.PY3 else long(99))
-
-class TestLong(TraitTestBase):
-
- obj = LongTrait()
-
- _default_value = 99 if six.PY3 else long(99)
- _good_values = [10, -10]
- _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,),
- None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
- '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1',
- u'-10.1']
- if not six.PY3:
- # maxint undefined on py3, because int == long
- _good_values.extend([long(10), long(-10), 10*sys.maxint, -10*sys.maxint])
- _bad_values.extend([[long(10)], (long(10),)])
-
- @mark.skipif(six.PY3, reason="not relevant on py3")
- def test_cast_small(self):
- """Long casts ints to long"""
- self.obj.value = 10
- self.assertEqual(type(self.obj.value), long)
-
-
-class MinBoundLongTrait(HasTraits):
- value = Long(99 if six.PY3 else long(99), min=5)
-
-class TestMinBoundLong(TraitTestBase):
- obj = MinBoundLongTrait()
-
- _default_value = 99 if six.PY3 else long(99)
- _good_values = [5, 10]
- _bad_values = [4, -10]
-
-
-class MaxBoundLongTrait(HasTraits):
- value = Long(5 if six.PY3 else long(5), max=10)
-
-class TestMaxBoundLong(TraitTestBase):
- obj = MaxBoundLongTrait()
-
- _default_value = 5 if six.PY3 else long(5)
- _good_values = [10, -2]
- _bad_values = [11, 20]
-
-
-class CLongTrait(HasTraits):
- value = CLong('5')
-
-class TestCLong(TraitTestBase):
- obj = CLongTrait()
-
- _default_value = 5 if six.PY3 else long(5)
- _good_values = ['10', '-10', u'10', u'-10', 10, 10.0, -10.0, 10.1]
- _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,),
- None, 1j, '10.1', u'10.1']
-
- def coerce(self, n):
- return int(n) if six.PY3 else long(n)
-
-
-class MaxBoundCLongTrait(HasTraits):
- value = CLong('5', max=10)
-
-class TestMaxBoundCLong(TestCLong):
- obj = MaxBoundCLongTrait()
-
- _default_value = 5 if six.PY3 else long(5)
- _good_values = [10, '10', 10.3]
- _bad_values = [11.0, '11']
-
-
-class IntegerTrait(HasTraits):
- value = Integer(1)
-
-class TestInteger(TestLong):
- obj = IntegerTrait()
- _default_value = 1
-
- def coerce(self, n):
- return int(n)
-
- @mark.skipif(six.PY3, reason="not relevant on py3")
- def test_cast_small(self):
- """Integer casts small longs to int"""
-
- self.obj.value = long(100)
- self.assertEqual(type(self.obj.value), int)
-
-
-class MinBoundIntegerTrait(HasTraits):
- value = Integer(5, min=3)
-
-class TestMinBoundInteger(TraitTestBase):
- obj = MinBoundIntegerTrait()
-
- _default_value = 5
- _good_values = 3, 20
- _bad_values = [2, -10]
-
-
-class MaxBoundIntegerTrait(HasTraits):
- value = Integer(1, max=3)
-
-class TestMaxBoundInteger(TraitTestBase):
- obj = MaxBoundIntegerTrait()
-
- _default_value = 1
- _good_values = 3, -2
- _bad_values = [4, 10]
-
-
-class FloatTrait(HasTraits):
-
- value = Float(99.0, max=200.0)
-
-class TestFloat(TraitTestBase):
-
- obj = FloatTrait()
-
- _default_value = 99.0
- _good_values = [10, -10, 10.1, -10.1]
- _bad_values = ['ten', u'ten', [10], {'ten': 10}, (10,), None,
- 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10',
- u'-10', u'10L', u'-10L', u'10.1', u'-10.1', 201.0]
- if not six.PY3:
- _bad_values.extend([long(10), long(-10)])
-
-
-class CFloatTrait(HasTraits):
-
- value = CFloat('99.0', max=200.0)
-
-class TestCFloat(TraitTestBase):
-
- obj = CFloatTrait()
-
- _default_value = 99.0
- _good_values = [10, 10.0, 10.5, '10.0', '10', '-10', '10.0', u'10']
- _bad_values = ['ten', u'ten', [10], {'ten': 10}, (10,), None, 1j,
- 200.1, '200.1']
-
- def coerce(self, v):
- return float(v)
-
-
-class ComplexTrait(HasTraits):
-
- value = Complex(99.0-99.0j)
-
-class TestComplex(TraitTestBase):
-
- obj = ComplexTrait()
-
- _default_value = 99.0-99.0j
- _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
- 10.1j, 10.1+10.1j, 10.1-10.1j]
- _bad_values = [u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
- if not six.PY3:
- _bad_values.extend([long(10), long(-10)])
-
-
-class BytesTrait(HasTraits):
-
- value = Bytes(b'string')
-
-class TestBytes(TraitTestBase):
-
- obj = BytesTrait()
-
- _default_value = b'string'
- _good_values = [b'10', b'-10', b'10L',
- b'-10L', b'10.1', b'-10.1', b'string']
- _bad_values = [10, -10, 10.1, -10.1, 1j, [10],
- ['ten'],{'ten': 10},(10,), None, u'string']
- if not six.PY3:
- _bad_values.extend([long(10), long(-10)])
-
-
-class UnicodeTrait(HasTraits):
-
- value = Unicode(u'unicode')
-
-class TestUnicode(TraitTestBase):
-
- obj = UnicodeTrait()
-
- _default_value = u'unicode'
- _good_values = ['10', '-10', '10L', '-10L', '10.1',
- '-10.1', '', u'', 'string', u'string', u"€"]
- _bad_values = [10, -10, 10.1, -10.1, 1j,
- [10], ['ten'], [u'ten'], {'ten': 10},(10,), None]
- if not six.PY3:
- _bad_values.extend([long(10), long(-10)])
-
-
-class ObjectNameTrait(HasTraits):
- value = ObjectName("abc")
-
-class TestObjectName(TraitTestBase):
- obj = ObjectNameTrait()
-
- _default_value = "abc"
- _good_values = ["a", "gh", "g9", "g_", "_G", u"a345_"]
- _bad_values = [1, "", u"€", "9g", "!", "#abc", "aj@", "a.b", "a()", "a[0]",
- None, object(), object]
- if sys.version_info[0] < 3:
- _bad_values.append(u"þ")
- else:
- _good_values.append(u"þ") # þ=1 is valid in Python 3 (PEP 3131).
-
-
-class DottedObjectNameTrait(HasTraits):
- value = DottedObjectName("a.b")
-
-class TestDottedObjectName(TraitTestBase):
- obj = DottedObjectNameTrait()
-
- _default_value = "a.b"
- _good_values = ["A", "y.t", "y765.__repr__", "os.path.join", u"os.path.join"]
- _bad_values = [1, u"abc.€", "_.@", ".", ".abc", "abc.", ".abc.", None]
- if sys.version_info[0] < 3:
- _bad_values.append(u"t.þ")
- else:
- _good_values.append(u"t.þ")
-
-
-class TCPAddressTrait(HasTraits):
- value = TCPAddress()
-
-class TestTCPAddress(TraitTestBase):
-
- obj = TCPAddressTrait()
-
- _default_value = ('127.0.0.1',0)
- _good_values = [('localhost',0),('192.168.0.1',1000),('www.google.com',80)]
- _bad_values = [(0,0),('localhost',10.0),('localhost',-1), None]
-
-class ListTrait(HasTraits):
-
- value = List(Int())
-
-class TestList(TraitTestBase):
-
- obj = ListTrait()
-
- _default_value = []
- _good_values = [[], [1], list(range(10)), (1,2)]
- _bad_values = [10, [1,'a'], 'a']
-
- def coerce(self, value):
- if value is not None:
- value = list(value)
- return value
-
-class Foo(object):
- pass
-
-class NoneInstanceListTrait(HasTraits):
-
- value = List(Instance(Foo))
-
-class TestNoneInstanceList(TraitTestBase):
-
- obj = NoneInstanceListTrait()
-
- _default_value = []
- _good_values = [[Foo(), Foo()], []]
- _bad_values = [[None], [Foo(), None]]
-
-
-class InstanceListTrait(HasTraits):
-
- value = List(Instance(__name__+'.Foo'))
-
-class TestInstanceList(TraitTestBase):
-
- obj = InstanceListTrait()
-
- def test_klass(self):
- """Test that the instance klass is properly assigned."""
- self.assertIs(self.obj.traits()['value']._trait.klass, Foo)
-
- _default_value = []
- _good_values = [[Foo(), Foo()], []]
- _bad_values = [['1', 2,], '1', [Foo], None]
-
-class UnionListTrait(HasTraits):
-
- value = List(Int() | Bool())
-
-class TestUnionListTrait(HasTraits):
-
- obj = UnionListTrait()
-
- _default_value = []
- _good_values = [[True, 1], [False, True]]
- _bad_values = [[1, 'True'], False]
-
-
-class LenListTrait(HasTraits):
-
- value = List(Int(), [0], minlen=1, maxlen=2)
-
-class TestLenList(TraitTestBase):
-
- obj = LenListTrait()
-
- _default_value = [0]
- _good_values = [[1], [1,2], (1,2)]
- _bad_values = [10, [1,'a'], 'a', [], list(range(3))]
-
- def coerce(self, value):
- if value is not None:
- value = list(value)
- return value
-
-class TupleTrait(HasTraits):
-
- value = Tuple(Int(allow_none=True), default_value=(1,))
-
-class TestTupleTrait(TraitTestBase):
-
- obj = TupleTrait()
-
- _default_value = (1,)
- _good_values = [(1,), (0,), [1]]
- _bad_values = [10, (1, 2), ('a'), (), None]
-
- def coerce(self, value):
- if value is not None:
- value = tuple(value)
- return value
-
- def test_invalid_args(self):
- self.assertRaises(TypeError, Tuple, 5)
- self.assertRaises(TypeError, Tuple, default_value='hello')
- t = Tuple(Int(), CBytes(), default_value=(1,5))
-
-class LooseTupleTrait(HasTraits):
-
- value = Tuple((1,2,3))
-
-class TestLooseTupleTrait(TraitTestBase):
-
- obj = LooseTupleTrait()
-
- _default_value = (1,2,3)
- _good_values = [(1,), [1], (0,), tuple(range(5)), tuple('hello'), ('a',5), ()]
- _bad_values = [10, 'hello', {}, None]
-
- def coerce(self, value):
- if value is not None:
- value = tuple(value)
- return value
-
- def test_invalid_args(self):
- self.assertRaises(TypeError, Tuple, 5)
- self.assertRaises(TypeError, Tuple, default_value='hello')
- t = Tuple(Int(), CBytes(), default_value=(1,5))
-
-
-class MultiTupleTrait(HasTraits):
-
- value = Tuple(Int(), Bytes(), default_value=[99,b'bottles'])
-
-class TestMultiTuple(TraitTestBase):
-
- obj = MultiTupleTrait()
-
- _default_value = (99,b'bottles')
- _good_values = [(1,b'a'), (2,b'b')]
- _bad_values = ((),10, b'a', (1,b'a',3), (b'a',1), (1, u'a'))
-
-class CRegExpTrait(HasTraits):
-
- value = CRegExp(r'')
-
-class TestCRegExp(TraitTestBase):
-
- def coerce(self, value):
- return re.compile(value)
-
- obj = CRegExpTrait()
-
- _default_value = re.compile(r'')
- _good_values = [r'\d+', re.compile(r'\d+')]
- _bad_values = ['(', None, ()]
-
-class DictTrait(HasTraits):
- value = Dict()
-
-def test_dict_assignment():
- d = dict()
- c = DictTrait()
- c.value = d
- d['a'] = 5
- assert d == c.value
- assert c.value is d
-
-
-class UniformlyValidatedDictTrait(HasTraits):
-
- value = Dict(trait=Unicode(),
- default_value={'foo': '1'})
-
-
-class TestInstanceUniformlyValidatedDict(TraitTestBase):
-
- obj = UniformlyValidatedDictTrait()
-
- _default_value = {'foo': '1'}
- _good_values = [{'foo': '0', 'bar': '1'}]
- _bad_values = [{'foo': 0, 'bar': '1'}]
-
-
-class KeyValidatedDictTrait(HasTraits):
-
- value = Dict(traits={'foo': Int()},
- default_value={'foo': 1})
-
-
-class TestInstanceKeyValidatedDict(TraitTestBase):
-
- obj = KeyValidatedDictTrait()
-
- _default_value = {'foo': 1}
- _good_values = [{'foo': 0, 'bar': '1'}, {'foo': 0, 'bar': 1}]
- _bad_values = [{'foo': '0', 'bar': '1'}]
-
-
-class FullyValidatedDictTrait(HasTraits):
-
- value = Dict(trait=Unicode(),
- traits={'foo': Int()},
- default_value={'foo': 1})
-
-
-class TestInstanceFullyValidatedDict(TraitTestBase):
-
- obj = FullyValidatedDictTrait()
-
- _default_value = {'foo': 1}
- _good_values = [{'foo': 0, 'bar': '1'}, {'foo': 1, 'bar': '2'}]
- _bad_values = [{'foo': 0, 'bar': 1}, {'foo': '0', 'bar': '1'}]
-
-
-def test_dict_default_value():
- """Check that the `{}` default value of the Dict traitlet constructor is
- actually copied."""
-
- class Foo(HasTraits):
- d1 = Dict()
- d2 = Dict()
-
- foo = Foo()
- assert foo.d1 == {}
- assert foo.d2 == {}
- assert foo.d1 is not foo.d2
-
-
-class TestValidationHook(TestCase):
-
- def test_parity_trait(self):
- """Verify that the early validation hook is effective"""
-
- class Parity(HasTraits):
-
- value = Int(0)
- parity = Enum(['odd', 'even'], default_value='even')
-
- @validate('value')
- def _value_validate(self, proposal):
- value = proposal['value']
- if self.parity == 'even' and value % 2:
- raise TraitError('Expected an even number')
- if self.parity == 'odd' and (value % 2 == 0):
- raise TraitError('Expected an odd number')
- return value
-
- u = Parity()
- u.parity = 'odd'
- u.value = 1 # OK
- with self.assertRaises(TraitError):
- u.value = 2 # Trait Error
-
- u.parity = 'even'
- u.value = 2 # OK
-
- def test_multiple_validate(self):
- """Verify that we can register the same validator to multiple names"""
-
- class OddEven(HasTraits):
-
- odd = Int(1)
- even = Int(0)
-
- @validate('odd', 'even')
- def check_valid(self, proposal):
- if proposal['trait'].name == 'odd' and not proposal['value'] % 2:
- raise TraitError('odd should be odd')
- if proposal['trait'].name == 'even' and proposal['value'] % 2:
- raise TraitError('even should be even')
-
- u = OddEven()
- u.odd = 3 # OK
- with self.assertRaises(TraitError):
- u.odd = 2 # Trait Error
-
- u.even = 2 # OK
- with self.assertRaises(TraitError):
- u.even = 3 # Trait Error
-
-
-
-class TestLink(TestCase):
-
- def test_connect_same(self):
- """Verify two traitlets of the same type can be linked together using link."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- a = A(value=9)
- b = A(value=8)
-
- # Conenct the two classes.
- c = link((a, 'value'), (b, 'value'))
-
- # Make sure the values are the same at the point of linking.
- self.assertEqual(a.value, b.value)
-
- # Change one of the values to make sure they stay in sync.
- a.value = 5
- self.assertEqual(a.value, b.value)
- b.value = 6
- self.assertEqual(a.value, b.value)
-
- def test_link_different(self):
- """Verify two traitlets of different types can be linked together using link."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- class B(HasTraits):
- count = Int()
- a = A(value=9)
- b = B(count=8)
-
- # Conenct the two classes.
- c = link((a, 'value'), (b, 'count'))
-
- # Make sure the values are the same at the point of linking.
- self.assertEqual(a.value, b.count)
-
- # Change one of the values to make sure they stay in sync.
- a.value = 5
- self.assertEqual(a.value, b.count)
- b.count = 4
- self.assertEqual(a.value, b.count)
-
- def test_unlink(self):
- """Verify two linked traitlets can be unlinked."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- a = A(value=9)
- b = A(value=8)
-
- # Connect the two classes.
- c = link((a, 'value'), (b, 'value'))
- a.value = 4
- c.unlink()
-
- # Change one of the values to make sure they don't stay in sync.
- a.value = 5
- self.assertNotEqual(a.value, b.value)
-
- def test_callbacks(self):
- """Verify two linked traitlets have their callbacks called once."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- class B(HasTraits):
- count = Int()
- a = A(value=9)
- b = B(count=8)
-
- # Register callbacks that count.
- callback_count = []
- def a_callback(name, old, new):
- callback_count.append('a')
- a.on_trait_change(a_callback, 'value')
- def b_callback(name, old, new):
- callback_count.append('b')
- b.on_trait_change(b_callback, 'count')
-
- # Connect the two classes.
- c = link((a, 'value'), (b, 'count'))
-
- # Make sure b's count was set to a's value once.
- self.assertEqual(''.join(callback_count), 'b')
- del callback_count[:]
-
- # Make sure a's value was set to b's count once.
- b.count = 5
- self.assertEqual(''.join(callback_count), 'ba')
- del callback_count[:]
-
- # Make sure b's count was set to a's value once.
- a.value = 4
- self.assertEqual(''.join(callback_count), 'ab')
- del callback_count[:]
-
-class TestDirectionalLink(TestCase):
- def test_connect_same(self):
- """Verify two traitlets of the same type can be linked together using directional_link."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- a = A(value=9)
- b = A(value=8)
-
- # Conenct the two classes.
- c = directional_link((a, 'value'), (b, 'value'))
-
- # Make sure the values are the same at the point of linking.
- self.assertEqual(a.value, b.value)
-
- # Change one the value of the source and check that it synchronizes the target.
- a.value = 5
- self.assertEqual(b.value, 5)
- # Change one the value of the target and check that it has no impact on the source
- b.value = 6
- self.assertEqual(a.value, 5)
-
- def test_tranform(self):
- """Test transform link."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- a = A(value=9)
- b = A(value=8)
-
- # Conenct the two classes.
- c = directional_link((a, 'value'), (b, 'value'), lambda x: 2 * x)
-
- # Make sure the values are correct at the point of linking.
- self.assertEqual(b.value, 2 * a.value)
-
- # Change one the value of the source and check that it modifies the target.
- a.value = 5
- self.assertEqual(b.value, 10)
- # Change one the value of the target and check that it has no impact on the source
- b.value = 6
- self.assertEqual(a.value, 5)
-
- def test_link_different(self):
- """Verify two traitlets of different types can be linked together using link."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- class B(HasTraits):
- count = Int()
- a = A(value=9)
- b = B(count=8)
-
- # Conenct the two classes.
- c = directional_link((a, 'value'), (b, 'count'))
-
- # Make sure the values are the same at the point of linking.
- self.assertEqual(a.value, b.count)
-
- # Change one the value of the source and check that it synchronizes the target.
- a.value = 5
- self.assertEqual(b.count, 5)
- # Change one the value of the target and check that it has no impact on the source
- b.value = 6
- self.assertEqual(a.value, 5)
-
- def test_unlink(self):
- """Verify two linked traitlets can be unlinked."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- a = A(value=9)
- b = A(value=8)
-
- # Connect the two classes.
- c = directional_link((a, 'value'), (b, 'value'))
- a.value = 4
- c.unlink()
-
- # Change one of the values to make sure they don't stay in sync.
- a.value = 5
- self.assertNotEqual(a.value, b.value)
-
-class Pickleable(HasTraits):
-
- i = Int()
- @observe('i')
- def _i_changed(self, change): pass
- @validate('i')
- def _i_validate(self, commit):
- return commit['value']
-
- j = Int()
-
- def __init__(self):
- with self.hold_trait_notifications():
- self.i = 1
- self.on_trait_change(self._i_changed, 'i')
-
-def test_pickle_hastraits():
- c = Pickleable()
- for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
- p = pickle.dumps(c, protocol)
- c2 = pickle.loads(p)
- assert c2.i == c.i
- assert c2.j == c.j
-
- c.i = 5
- for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
- p = pickle.dumps(c, protocol)
- c2 = pickle.loads(p)
- assert c2.i == c.i
- assert c2.j == c.j
-
-
-def test_hold_trait_notifications():
- changes = []
-
- class Test(HasTraits):
- a = Integer(0)
- b = Integer(0)
-
- def _a_changed(self, name, old, new):
- changes.append((old, new))
-
- def _b_validate(self, value, trait):
- if value != 0:
- raise TraitError('Only 0 is a valid value')
- return value
-
- # Test context manager and nesting
- t = Test()
- with t.hold_trait_notifications():
- with t.hold_trait_notifications():
- t.a = 1
- assert t.a == 1
- assert changes == []
- t.a = 2
- assert t.a == 2
- with t.hold_trait_notifications():
- t.a = 3
- assert t.a == 3
- assert changes == []
- t.a = 4
- assert t.a == 4
- assert changes == []
- t.a = 4
- assert t.a == 4
- assert changes == []
-
- assert changes == [(0, 4)]
- # Test roll-back
- try:
- with t.hold_trait_notifications():
- t.b = 1 # raises a Trait error
- except:
- pass
- assert t.b == 0
-
-
-class RollBack(HasTraits):
- bar = Int()
- def _bar_validate(self, value, trait):
- if value:
- raise TraitError('foobar')
- return value
-
-
-class TestRollback(TestCase):
-
- def test_roll_back(self):
-
- def assign_rollback():
- RollBack(bar=1)
-
- self.assertRaises(TraitError, assign_rollback)
-
-
-class CacheModification(HasTraits):
- foo = Int()
- bar = Int()
-
- def _bar_validate(self, value, trait):
- self.foo = value
- return value
-
- def _foo_validate(self, value, trait):
- self.bar = value
- return value
-
-
-def test_cache_modification():
- CacheModification(foo=1)
- CacheModification(bar=1)
-
-
-class OrderTraits(HasTraits):
- notified = Dict()
-
- a = Unicode()
- b = Unicode()
- c = Unicode()
- d = Unicode()
- e = Unicode()
- f = Unicode()
- g = Unicode()
- h = Unicode()
- i = Unicode()
- j = Unicode()
- k = Unicode()
- l = Unicode()
-
- def _notify(self, name, old, new):
- """check the value of all traits when each trait change is triggered
-
- This verifies that the values are not sensitive
- to dict ordering when loaded from kwargs
- """
- # check the value of the other traits
- # when a given trait change notification fires
- self.notified[name] = {
- c: getattr(self, c) for c in 'abcdefghijkl'
- }
-
- def __init__(self, **kwargs):
- self.on_trait_change(self._notify)
- super(OrderTraits, self).__init__(**kwargs)
-
-def test_notification_order():
- d = {c:c for c in 'abcdefghijkl'}
- obj = OrderTraits()
- assert obj.notified == {}
- obj = OrderTraits(**d)
- notifications = {
- c: d for c in 'abcdefghijkl'
- }
- assert obj.notified == notifications
-
-
-
-###
-# Traits for Forward Declaration Tests
-###
-class ForwardDeclaredInstanceTrait(HasTraits):
-
- value = ForwardDeclaredInstance('ForwardDeclaredBar', allow_none=True)
-
-class ForwardDeclaredTypeTrait(HasTraits):
-
- value = ForwardDeclaredType('ForwardDeclaredBar', allow_none=True)
-
-class ForwardDeclaredInstanceListTrait(HasTraits):
-
- value = List(ForwardDeclaredInstance('ForwardDeclaredBar'))
-
-class ForwardDeclaredTypeListTrait(HasTraits):
-
- value = List(ForwardDeclaredType('ForwardDeclaredBar'))
-###
-# End Traits for Forward Declaration Tests
-###
-
-###
-# Classes for Forward Declaration Tests
-###
-class ForwardDeclaredBar(object):
- pass
-
-class ForwardDeclaredBarSub(ForwardDeclaredBar):
- pass
-###
-# End Classes for Forward Declaration Tests
-###
-
-###
-# Forward Declaration Tests
-###
-class TestForwardDeclaredInstanceTrait(TraitTestBase):
-
- obj = ForwardDeclaredInstanceTrait()
- _default_value = None
- _good_values = [None, ForwardDeclaredBar(), ForwardDeclaredBarSub()]
- _bad_values = ['foo', 3, ForwardDeclaredBar, ForwardDeclaredBarSub]
-
-class TestForwardDeclaredTypeTrait(TraitTestBase):
-
- obj = ForwardDeclaredTypeTrait()
- _default_value = None
- _good_values = [None, ForwardDeclaredBar, ForwardDeclaredBarSub]
- _bad_values = ['foo', 3, ForwardDeclaredBar(), ForwardDeclaredBarSub()]
-
-class TestForwardDeclaredInstanceList(TraitTestBase):
-
- obj = ForwardDeclaredInstanceListTrait()
-
- def test_klass(self):
- """Test that the instance klass is properly assigned."""
- self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar)
-
- _default_value = []
- _good_values = [
- [ForwardDeclaredBar(), ForwardDeclaredBarSub()],
- [],
- ]
- _bad_values = [
- ForwardDeclaredBar(),
- [ForwardDeclaredBar(), 3, None],
- '1',
- # Note that this is the type, not an instance.
- [ForwardDeclaredBar],
- [None],
- None,
- ]
-
-class TestForwardDeclaredTypeList(TraitTestBase):
-
- obj = ForwardDeclaredTypeListTrait()
-
- def test_klass(self):
- """Test that the instance klass is properly assigned."""
- self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar)
-
- _default_value = []
- _good_values = [
- [ForwardDeclaredBar, ForwardDeclaredBarSub],
- [],
- ]
- _bad_values = [
- ForwardDeclaredBar,
- [ForwardDeclaredBar, 3],
- '1',
- # Note that this is an instance, not the type.
- [ForwardDeclaredBar()],
- [None],
- None,
- ]
-###
-# End Forward Declaration Tests
-###
-
-class TestDynamicTraits(TestCase):
-
- def setUp(self):
- self._notify1 = []
-
- def notify1(self, name, old, new):
- self._notify1.append((name, old, new))
-
- def test_notify_all(self):
-
- class A(HasTraits):
- pass
-
- a = A()
- self.assertTrue(not hasattr(a, 'x'))
- self.assertTrue(not hasattr(a, 'y'))
-
- # Dynamically add trait x.
- a.add_traits(x=Int())
- self.assertTrue(hasattr(a, 'x'))
- self.assertTrue(isinstance(a, (A, )))
-
- # Dynamically add trait y.
- a.add_traits(y=Float())
- self.assertTrue(hasattr(a, 'y'))
- self.assertTrue(isinstance(a, (A, )))
- self.assertEqual(a.__class__.__name__, A.__name__)
-
- # Create a new instance and verify that x and y
- # aren't defined.
- b = A()
- self.assertTrue(not hasattr(b, 'x'))
- self.assertTrue(not hasattr(b, 'y'))
-
- # Verify that notification works like normal.
- a.on_trait_change(self.notify1)
- a.x = 0
- self.assertEqual(len(self._notify1), 0)
- a.y = 0.0
- self.assertEqual(len(self._notify1), 0)
- a.x = 10
- self.assertTrue(('x', 0, 10) in self._notify1)
- a.y = 10.0
- self.assertTrue(('y', 0.0, 10.0) in self._notify1)
- self.assertRaises(TraitError, setattr, a, 'x', 'bad string')
- self.assertRaises(TraitError, setattr, a, 'y', 'bad string')
- self._notify1 = []
- a.on_trait_change(self.notify1, remove=True)
- a.x = 20
- a.y = 20.0
- self.assertEqual(len(self._notify1), 0)
-
-
-def test_enum_no_default():
- class C(HasTraits):
- t = Enum(['a', 'b'])
-
- c = C()
- c.t = 'a'
- assert c.t == 'a'
-
- c = C()
-
- with pytest.raises(TraitError):
- t = c.t
-
- c = C(t='b')
- assert c.t == 'b'
-
-
-def test_default_value_repr():
- class C(HasTraits):
- t = Type('traitlets.HasTraits')
- t2 = Type(HasTraits)
- n = Integer(0)
- lis = List()
- d = Dict()
-
- assert C.t.default_value_repr() == "'traitlets.HasTraits'"
- assert C.t2.default_value_repr() == "'traitlets.traitlets.HasTraits'"
- assert C.n.default_value_repr() == '0'
- assert C.lis.default_value_repr() == '[]'
- assert C.d.default_value_repr() == '{}'
-
-
-class TransitionalClass(HasTraits):
-
- d = Any()
- @default('d')
- def _d_default(self):
- return TransitionalClass
-
- parent_super = False
- calls_super = Integer(0)
-
- @default('calls_super')
- def _calls_super_default(self):
- return -1
-
- @observe('calls_super')
- @observe_compat
- def _calls_super_changed(self, change):
- self.parent_super = change
-
- parent_override = False
- overrides = Integer(0)
-
- @observe('overrides')
- @observe_compat
- def _overrides_changed(self, change):
- self.parent_override = change
-
-
-class SubClass(TransitionalClass):
- def _d_default(self):
- return SubClass
-
- subclass_super = False
- def _calls_super_changed(self, name, old, new):
- self.subclass_super = True
- super(SubClass, self)._calls_super_changed(name, old, new)
-
- subclass_override = False
- def _overrides_changed(self, name, old, new):
- self.subclass_override = True
-
-
-def test_subclass_compat():
- obj = SubClass()
- obj.calls_super = 5
- assert obj.parent_super
- assert obj.subclass_super
- obj.overrides = 5
- assert obj.subclass_override
- assert not obj.parent_override
- assert obj.d is SubClass
-
-
-class DefinesHandler(HasTraits):
- parent_called = False
-
- trait = Integer()
- @observe('trait')
- def handler(self, change):
- self.parent_called = True
-
-
-class OverridesHandler(DefinesHandler):
- child_called = False
-
- @observe('trait')
- def handler(self, change):
- self.child_called = True
-
-
-def test_subclass_override_observer():
- obj = OverridesHandler()
- obj.trait = 5
- assert obj.child_called
- assert not obj.parent_called
-
-
-class DoesntRegisterHandler(DefinesHandler):
- child_called = False
-
- def handler(self, change):
- self.child_called = True
-
-
-def test_subclass_override_not_registered():
- """Subclass that overrides observer and doesn't re-register unregisters both"""
- obj = DoesntRegisterHandler()
- obj.trait = 5
- assert not obj.child_called
- assert not obj.parent_called
-
-
-class AddsHandler(DefinesHandler):
- child_called = False
-
- @observe('trait')
- def child_handler(self, change):
- self.child_called = True
-
-def test_subclass_add_observer():
- obj = AddsHandler()
- obj.trait = 5
- assert obj.child_called
- assert obj.parent_called
-
-
-def test_observe_iterables():
-
- class C(HasTraits):
- i = Integer()
- s = Unicode()
-
- c = C()
- recorded = {}
- def record(change):
- recorded['change'] = change
-
- # observe with names=set
- c.observe(record, names={'i', 's'})
- c.i = 5
- assert recorded['change'].name == 'i'
- assert recorded['change'].new == 5
- c.s = 'hi'
- assert recorded['change'].name == 's'
- assert recorded['change'].new == 'hi'
-
- # observe with names=custom container with iter, contains
- class MyContainer(object):
- def __init__(self, container):
- self.container = container
-
- def __iter__(self):
- return iter(self.container)
-
- def __contains__(self, key):
- return key in self.container
-
- c.observe(record, names=MyContainer({'i', 's'}))
- c.i = 10
- assert recorded['change'].name == 'i'
- assert recorded['change'].new == 10
- c.s = 'ok'
- assert recorded['change'].name == 's'
- assert recorded['change'].new == 'ok'
-
-
-def test_super_args():
- class SuperRecorder(object):
- def __init__(self, *args, **kwargs):
- self.super_args = args
- self.super_kwargs = kwargs
-
- class SuperHasTraits(HasTraits, SuperRecorder):
- i = Integer()
-
- obj = SuperHasTraits('a1', 'a2', b=10, i=5, c='x')
- assert obj.i == 5
- assert not hasattr(obj, 'b')
- assert not hasattr(obj, 'c')
- assert obj.super_args == ('a1' , 'a2')
- assert obj.super_kwargs == {'b': 10 , 'c': 'x'}
-
-def test_super_bad_args():
- class SuperHasTraits(HasTraits):
- a = Integer()
-
- if sys.version_info < (3,):
- # Legacy Python, object.__init__ warns itself, instead of raising
- w = ['object.__init__']
- else:
- w = ["Passing unrecoginized arguments"]
- with expected_warnings(w):
- obj = SuperHasTraits(a=1, b=2)
- assert obj.a == 1
- assert not hasattr(obj, 'b')
+
+from unittest import TestCase
+import pytest
+from pytest import mark
+
+from traitlets import (
+ HasTraits, MetaHasTraits, TraitType, Any, Bool, CBytes, Dict, Enum,
+ Int, CInt, Long, CLong, Integer, Float, CFloat, Complex, Bytes, Unicode,
+ TraitError, Union, All, Undefined, Type, This, Instance, TCPAddress,
+ List, Tuple, ObjectName, DottedObjectName, CRegExp, link, directional_link,
+ ForwardDeclaredType, ForwardDeclaredInstance, validate, observe, default,
+ observe_compat, BaseDescriptor, HasDescriptors,
+)
+
+import six
+
+def change_dict(*ordered_values):
+ change_names = ('name', 'old', 'new', 'owner', 'type')
+ return dict(zip(change_names, ordered_values))
+
+#-----------------------------------------------------------------------------
+# Helper classes for testing
+#-----------------------------------------------------------------------------
+
+
+class HasTraitsStub(HasTraits):
+
+ def notify_change(self, change):
+ self._notify_name = change['name']
+ self._notify_old = change['old']
+ self._notify_new = change['new']
+ self._notify_type = change['type']
+
+
+#-----------------------------------------------------------------------------
+# Test classes
+#-----------------------------------------------------------------------------
+
+
+class TestTraitType(TestCase):
+
+ def test_get_undefined(self):
+ class A(HasTraits):
+ a = TraitType
+ a = A()
+ with self.assertRaises(TraitError):
+ a.a
+
+ def test_set(self):
+ class A(HasTraitsStub):
+ a = TraitType
+
+ a = A()
+ a.a = 10
+ self.assertEqual(a.a, 10)
+ self.assertEqual(a._notify_name, 'a')
+ self.assertEqual(a._notify_old, Undefined)
+ self.assertEqual(a._notify_new, 10)
+
+ def test_validate(self):
+ class MyTT(TraitType):
+ def validate(self, inst, value):
+ return -1
+ class A(HasTraitsStub):
+ tt = MyTT
+
+ a = A()
+ a.tt = 10
+ self.assertEqual(a.tt, -1)
+
+ def test_default_validate(self):
+ class MyIntTT(TraitType):
+ def validate(self, obj, value):
+ if isinstance(value, int):
+ return value
+ self.error(obj, value)
+ class A(HasTraits):
+ tt = MyIntTT(10)
+ a = A()
+ self.assertEqual(a.tt, 10)
+
+ # Defaults are validated when the HasTraits is instantiated
+ class B(HasTraits):
+ tt = MyIntTT('bad default')
+ self.assertRaises(TraitError, B)
+
+ def test_info(self):
+ class A(HasTraits):
+ tt = TraitType
+ a = A()
+ self.assertEqual(A.tt.info(), 'any value')
+
+ def test_error(self):
+ class A(HasTraits):
+ tt = TraitType
+ a = A()
+ self.assertRaises(TraitError, A.tt.error, a, 10)
+
+ def test_deprecated_dynamic_initializer(self):
+ class A(HasTraits):
+ x = Int(10)
+ def _x_default(self):
+ return 11
+ class B(A):
+ x = Int(20)
+ class C(A):
+ def _x_default(self):
+ return 21
+
+ a = A()
+ self.assertEqual(a._trait_values, {})
+ self.assertEqual(a.x, 11)
+ self.assertEqual(a._trait_values, {'x': 11})
+ b = B()
+ self.assertEqual(b.x, 20)
+ self.assertEqual(b._trait_values, {'x': 20})
+ c = C()
+ self.assertEqual(c._trait_values, {})
+ self.assertEqual(c.x, 21)
+ self.assertEqual(c._trait_values, {'x': 21})
+ # Ensure that the base class remains unmolested when the _default
+ # initializer gets overridden in a subclass.
+ a = A()
+ c = C()
+ self.assertEqual(a._trait_values, {})
+ self.assertEqual(a.x, 11)
+ self.assertEqual(a._trait_values, {'x': 11})
+
+ def test_dynamic_initializer(self):
+
+ class A(HasTraits):
+ x = Int(10)
+
+ @default('x')
+ def _default_x(self):
+ return 11
+
+ class B(A):
+ x = Int(20)
+
+ class C(A):
+
+ @default('x')
+ def _default_x(self):
+ return 21
+
+ a = A()
+ self.assertEqual(a._trait_values, {})
+ self.assertEqual(a.x, 11)
+ self.assertEqual(a._trait_values, {'x': 11})
+ b = B()
+ self.assertEqual(b.x, 20)
+ self.assertEqual(b._trait_values, {'x': 20})
+ c = C()
+ self.assertEqual(c._trait_values, {})
+ self.assertEqual(c.x, 21)
+ self.assertEqual(c._trait_values, {'x': 21})
+ # Ensure that the base class remains unmolested when the _default
+ # initializer gets overridden in a subclass.
+ a = A()
+ c = C()
+ self.assertEqual(a._trait_values, {})
+ self.assertEqual(a.x, 11)
+ self.assertEqual(a._trait_values, {'x': 11})
+
+ def test_tag_metadata(self):
+ class MyIntTT(TraitType):
+ metadata = {'a': 1, 'b': 2}
+ a = MyIntTT(10).tag(b=3, c=4)
+ self.assertEqual(a.metadata, {'a': 1, 'b': 3, 'c': 4})
+
+ def test_metadata_localized_instance(self):
+ class MyIntTT(TraitType):
+ metadata = {'a': 1, 'b': 2}
+ a = MyIntTT(10)
+ b = MyIntTT(10)
+ a.metadata['c'] = 3
+ # make sure that changing a's metadata didn't change b's metadata
+ self.assertNotIn('c', b.metadata)
+
+ def test_union_metadata(self):
+ class Foo(HasTraits):
+ bar = (Int().tag(ta=1) | Dict().tag(ta=2, ti='b')).tag(ti='a')
+ foo = Foo()
+ # At this point, no value has been set for bar, so value-specific
+ # is not set.
+ self.assertEqual(foo.trait_metadata('bar', 'ta'), None)
+ self.assertEqual(foo.trait_metadata('bar', 'ti'), 'a')
+ foo.bar = {}
+ self.assertEqual(foo.trait_metadata('bar', 'ta'), 2)
+ self.assertEqual(foo.trait_metadata('bar', 'ti'), 'b')
+ foo.bar = 1
+ self.assertEqual(foo.trait_metadata('bar', 'ta'), 1)
+ self.assertEqual(foo.trait_metadata('bar', 'ti'), 'a')
+
+ def test_union_default_value(self):
+ class Foo(HasTraits):
+ bar = Union([Dict(), Int()], default_value=1)
+ foo = Foo()
+ self.assertEqual(foo.bar, 1)
+
+ def test_deprecated_metadata_access(self):
+ class MyIntTT(TraitType):
+ metadata = {'a': 1, 'b': 2}
+ a = MyIntTT(10)
+ with expected_warnings(["use the instance .metadata dictionary directly"]*2):
+ a.set_metadata('key', 'value')
+ v = a.get_metadata('key')
+ self.assertEqual(v, 'value')
+ with expected_warnings(["use the instance .help string directly"]*2):
+ a.set_metadata('help', 'some help')
+ v = a.get_metadata('help')
+ self.assertEqual(v, 'some help')
+
+ def test_trait_types_deprecated(self):
+ with expected_warnings(["Traits should be given as instances"]):
+ class C(HasTraits):
+ t = Int
+
+ def test_trait_types_list_deprecated(self):
+ with expected_warnings(["Traits should be given as instances"]):
+ class C(HasTraits):
+ t = List(Int)
+
+ def test_trait_types_tuple_deprecated(self):
+ with expected_warnings(["Traits should be given as instances"]):
+ class C(HasTraits):
+ t = Tuple(Int)
+
+ def test_trait_types_dict_deprecated(self):
+ with expected_warnings(["Traits should be given as instances"]):
+ class C(HasTraits):
+ t = Dict(Int)
+
+class TestHasDescriptorsMeta(TestCase):
+
+ def test_metaclass(self):
+ self.assertEqual(type(HasTraits), MetaHasTraits)
+
+ class A(HasTraits):
+ a = Int()
+
+ a = A()
+ self.assertEqual(type(a.__class__), MetaHasTraits)
+ self.assertEqual(a.a,0)
+ a.a = 10
+ self.assertEqual(a.a,10)
+
+ class B(HasTraits):
+ b = Int()
+
+ b = B()
+ self.assertEqual(b.b,0)
+ b.b = 10
+ self.assertEqual(b.b,10)
+
+ class C(HasTraits):
+ c = Int(30)
+
+ c = C()
+ self.assertEqual(c.c,30)
+ c.c = 10
+ self.assertEqual(c.c,10)
+
+ def test_this_class(self):
+ class A(HasTraits):
+ t = This()
+ tt = This()
+ class B(A):
+ tt = This()
+ ttt = This()
+ self.assertEqual(A.t.this_class, A)
+ self.assertEqual(B.t.this_class, A)
+ self.assertEqual(B.tt.this_class, B)
+ self.assertEqual(B.ttt.this_class, B)
+
+class TestHasDescriptors(TestCase):
+
+ def test_setup_instance(self):
+
+ class FooDescriptor(BaseDescriptor):
+
+ def instance_init(self, inst):
+ foo = inst.foo # instance should have the attr
+
+ class HasFooDescriptors(HasDescriptors):
+
+ fd = FooDescriptor()
+
+ def setup_instance(self, *args, **kwargs):
+ self.foo = kwargs.get('foo', None)
+ super(HasFooDescriptors, self).setup_instance(*args, **kwargs)
+
+ hfd = HasFooDescriptors(foo='bar')
+
+class TestHasTraitsNotify(TestCase):
+
+ def setUp(self):
+ self._notify1 = []
+ self._notify2 = []
+
+ def notify1(self, name, old, new):
+ self._notify1.append((name, old, new))
+
+ def notify2(self, name, old, new):
+ self._notify2.append((name, old, new))
+
+ def test_notify_all(self):
+
+ class A(HasTraits):
+ a = Int()
+ b = Float()
+
+ a = A()
+ a.on_trait_change(self.notify1)
+ a.a = 0
+ self.assertEqual(len(self._notify1),0)
+ a.b = 0.0
+ self.assertEqual(len(self._notify1),0)
+ a.a = 10
+ self.assertTrue(('a',0,10) in self._notify1)
+ a.b = 10.0
+ self.assertTrue(('b',0.0,10.0) in self._notify1)
+ self.assertRaises(TraitError,setattr,a,'a','bad string')
+ self.assertRaises(TraitError,setattr,a,'b','bad string')
+ self._notify1 = []
+ a.on_trait_change(self.notify1,remove=True)
+ a.a = 20
+ a.b = 20.0
+ self.assertEqual(len(self._notify1),0)
+
+ def test_notify_one(self):
+
+ class A(HasTraits):
+ a = Int()
+ b = Float()
+
+ a = A()
+ a.on_trait_change(self.notify1, 'a')
+ a.a = 0
+ self.assertEqual(len(self._notify1),0)
+ a.a = 10
+ self.assertTrue(('a',0,10) in self._notify1)
+ self.assertRaises(TraitError,setattr,a,'a','bad string')
+
+ def test_subclass(self):
+
+ class A(HasTraits):
+ a = Int()
+
+ class B(A):
+ b = Float()
+
+ b = B()
+ self.assertEqual(b.a,0)
+ self.assertEqual(b.b,0.0)
+ b.a = 100
+ b.b = 100.0
+ self.assertEqual(b.a,100)
+ self.assertEqual(b.b,100.0)
+
+ def test_notify_subclass(self):
+
+ class A(HasTraits):
+ a = Int()
+
+ class B(A):
+ b = Float()
+
+ b = B()
+ b.on_trait_change(self.notify1, 'a')
+ b.on_trait_change(self.notify2, 'b')
+ b.a = 0
+ b.b = 0.0
+ self.assertEqual(len(self._notify1),0)
+ self.assertEqual(len(self._notify2),0)
+ b.a = 10
+ b.b = 10.0
+ self.assertTrue(('a',0,10) in self._notify1)
+ self.assertTrue(('b',0.0,10.0) in self._notify2)
+
+ def test_static_notify(self):
+
+ class A(HasTraits):
+ a = Int()
+ _notify1 = []
+ def _a_changed(self, name, old, new):
+ self._notify1.append((name, old, new))
+
+ a = A()
+ a.a = 0
+ # This is broken!!!
+ self.assertEqual(len(a._notify1),0)
+ a.a = 10
+ self.assertTrue(('a',0,10) in a._notify1)
+
+ class B(A):
+ b = Float()
+ _notify2 = []
+ def _b_changed(self, name, old, new):
+ self._notify2.append((name, old, new))
+
+ b = B()
+ b.a = 10
+ b.b = 10.0
+ self.assertTrue(('a',0,10) in b._notify1)
+ self.assertTrue(('b',0.0,10.0) in b._notify2)
+
+ def test_notify_args(self):
+
+ def callback0():
+ self.cb = ()
+ def callback1(name):
+ self.cb = (name,)
+ def callback2(name, new):
+ self.cb = (name, new)
+ def callback3(name, old, new):
+ self.cb = (name, old, new)
+ def callback4(name, old, new, obj):
+ self.cb = (name, old, new, obj)
+
+ class A(HasTraits):
+ a = Int()
+
+ a = A()
+ a.on_trait_change(callback0, 'a')
+ a.a = 10
+ self.assertEqual(self.cb,())
+ a.on_trait_change(callback0, 'a', remove=True)
+
+ a.on_trait_change(callback1, 'a')
+ a.a = 100
+ self.assertEqual(self.cb,('a',))
+ a.on_trait_change(callback1, 'a', remove=True)
+
+ a.on_trait_change(callback2, 'a')
+ a.a = 1000
+ self.assertEqual(self.cb,('a',1000))
+ a.on_trait_change(callback2, 'a', remove=True)
+
+ a.on_trait_change(callback3, 'a')
+ a.a = 10000
+ self.assertEqual(self.cb,('a',1000,10000))
+ a.on_trait_change(callback3, 'a', remove=True)
+
+ a.on_trait_change(callback4, 'a')
+ a.a = 100000
+ self.assertEqual(self.cb,('a',10000,100000,a))
+ self.assertEqual(len(a._trait_notifiers['a']['change']), 1)
+ a.on_trait_change(callback4, 'a', remove=True)
+
+ self.assertEqual(len(a._trait_notifiers['a']['change']), 0)
+
+ def test_notify_only_once(self):
+
+ class A(HasTraits):
+ listen_to = ['a']
+
+ a = Int(0)
+ b = 0
+
+ def __init__(self, **kwargs):
+ super(A, self).__init__(**kwargs)
+ self.on_trait_change(self.listener1, ['a'])
+
+ def listener1(self, name, old, new):
+ self.b += 1
+
+ class B(A):
+
+ c = 0
+ d = 0
+
+ def __init__(self, **kwargs):
+ super(B, self).__init__(**kwargs)
+ self.on_trait_change(self.listener2)
+
+ def listener2(self, name, old, new):
+ self.c += 1
+
+ def _a_changed(self, name, old, new):
+ self.d += 1
+
+ b = B()
+ b.a += 1
+ self.assertEqual(b.b, b.c)
+ self.assertEqual(b.b, b.d)
+ b.a += 1
+ self.assertEqual(b.b, b.c)
+ self.assertEqual(b.b, b.d)
+
+class TestObserveDecorator(TestCase):
+
+ def setUp(self):
+ self._notify1 = []
+ self._notify2 = []
+
+ def notify1(self, change):
+ self._notify1.append(change)
+
+ def notify2(self, change):
+ self._notify2.append(change)
+
+ def test_notify_all(self):
+
+ class A(HasTraits):
+ a = Int()
+ b = Float()
+
+ a = A()
+ a.observe(self.notify1)
+ a.a = 0
+ self.assertEqual(len(self._notify1),0)
+ a.b = 0.0
+ self.assertEqual(len(self._notify1),0)
+ a.a = 10
+ change = change_dict('a', 0, 10, a, 'change')
+ self.assertTrue(change in self._notify1)
+ a.b = 10.0
+ change = change_dict('b', 0.0, 10.0, a, 'change')
+ self.assertTrue(change in self._notify1)
+ self.assertRaises(TraitError,setattr,a,'a','bad string')
+ self.assertRaises(TraitError,setattr,a,'b','bad string')
+ self._notify1 = []
+ a.unobserve(self.notify1)
+ a.a = 20
+ a.b = 20.0
+ self.assertEqual(len(self._notify1),0)
+
+ def test_notify_one(self):
+
+ class A(HasTraits):
+ a = Int()
+ b = Float()
+
+ a = A()
+ a.observe(self.notify1, 'a')
+ a.a = 0
+ self.assertEqual(len(self._notify1),0)
+ a.a = 10
+ change = change_dict('a', 0, 10, a, 'change')
+ self.assertTrue(change in self._notify1)
+ self.assertRaises(TraitError,setattr,a,'a','bad string')
+
+ def test_subclass(self):
+
+ class A(HasTraits):
+ a = Int()
+
+ class B(A):
+ b = Float()
+
+ b = B()
+ self.assertEqual(b.a,0)
+ self.assertEqual(b.b,0.0)
+ b.a = 100
+ b.b = 100.0
+ self.assertEqual(b.a,100)
+ self.assertEqual(b.b,100.0)
+
+ def test_notify_subclass(self):
+
+ class A(HasTraits):
+ a = Int()
+
+ class B(A):
+ b = Float()
+
+ b = B()
+ b.observe(self.notify1, 'a')
+ b.observe(self.notify2, 'b')
+ b.a = 0
+ b.b = 0.0
+ self.assertEqual(len(self._notify1),0)
+ self.assertEqual(len(self._notify2),0)
+ b.a = 10
+ b.b = 10.0
+ change = change_dict('a', 0, 10, b, 'change')
+ self.assertTrue(change in self._notify1)
+ change = change_dict('b', 0.0, 10.0, b, 'change')
+ self.assertTrue(change in self._notify2)
+
+ def test_static_notify(self):
+
+ class A(HasTraits):
+ a = Int()
+ b = Int()
+ _notify1 = []
+ _notify_any = []
+
+ @observe('a')
+ def _a_changed(self, change):
+ self._notify1.append(change)
+
+ @observe(All)
+ def _any_changed(self, change):
+ self._notify_any.append(change)
+
+ a = A()
+ a.a = 0
+ self.assertEqual(len(a._notify1),0)
+ a.a = 10
+ change = change_dict('a', 0, 10, a, 'change')
+ self.assertTrue(change in a._notify1)
+ a.b = 1
+ self.assertEqual(len(a._notify_any), 2)
+ change = change_dict('b', 0, 1, a, 'change')
+ self.assertTrue(change in a._notify_any)
+
+ class B(A):
+ b = Float()
+ _notify2 = []
+ @observe('b')
+ def _b_changed(self, change):
+ self._notify2.append(change)
+
+ b = B()
+ b.a = 10
+ b.b = 10.0
+ change = change_dict('a', 0, 10, b, 'change')
+ self.assertTrue(change in b._notify1)
+ change = change_dict('b', 0.0, 10.0, b, 'change')
+ self.assertTrue(change in b._notify2)
+
+ def test_notify_args(self):
+
+ def callback0():
+ self.cb = ()
+ def callback1(change):
+ self.cb = change
+
+ class A(HasTraits):
+ a = Int()
+
+ a = A()
+ a.on_trait_change(callback0, 'a')
+ a.a = 10
+ self.assertEqual(self.cb,())
+ a.unobserve(callback0, 'a')
+
+ a.observe(callback1, 'a')
+ a.a = 100
+ change = change_dict('a', 10, 100, a, 'change')
+ self.assertEqual(self.cb, change)
+ self.assertEqual(len(a._trait_notifiers['a']['change']), 1)
+ a.unobserve(callback1, 'a')
+
+ self.assertEqual(len(a._trait_notifiers['a']['change']), 0)
+
+ def test_notify_only_once(self):
+
+ class A(HasTraits):
+ listen_to = ['a']
+
+ a = Int(0)
+ b = 0
+
+ def __init__(self, **kwargs):
+ super(A, self).__init__(**kwargs)
+ self.observe(self.listener1, ['a'])
+
+ def listener1(self, change):
+ self.b += 1
+
+ class B(A):
+
+ c = 0
+ d = 0
+
+ def __init__(self, **kwargs):
+ super(B, self).__init__(**kwargs)
+ self.observe(self.listener2)
+
+ def listener2(self, change):
+ self.c += 1
+
+ @observe('a')
+ def _a_changed(self, change):
+ self.d += 1
+
+ b = B()
+ b.a += 1
+ self.assertEqual(b.b, b.c)
+ self.assertEqual(b.b, b.d)
+ b.a += 1
+ self.assertEqual(b.b, b.c)
+ self.assertEqual(b.b, b.d)
+
+
+class TestHasTraits(TestCase):
+
+ def test_trait_names(self):
+ class A(HasTraits):
+ i = Int()
+ f = Float()
+ a = A()
+ self.assertEqual(sorted(a.trait_names()),['f','i'])
+ self.assertEqual(sorted(A.class_trait_names()),['f','i'])
+ self.assertTrue(a.has_trait('f'))
+ self.assertFalse(a.has_trait('g'))
+
+ def test_trait_metadata_deprecated(self):
+ with expected_warnings(['metadata should be set using the \.tag\(\) method']):
+ class A(HasTraits):
+ i = Int(config_key='MY_VALUE')
+ a = A()
+ self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE')
+
+ def test_trait_metadata(self):
+ class A(HasTraits):
+ i = Int().tag(config_key='MY_VALUE')
+ a = A()
+ self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE')
+
+ def test_trait_metadata_default(self):
+ class A(HasTraits):
+ i = Int()
+ a = A()
+ self.assertEqual(a.trait_metadata('i', 'config_key'), None)
+ self.assertEqual(a.trait_metadata('i', 'config_key', 'default'), 'default')
+
+ def test_traits(self):
+ class A(HasTraits):
+ i = Int()
+ f = Float()
+ a = A()
+ self.assertEqual(a.traits(), dict(i=A.i, f=A.f))
+ self.assertEqual(A.class_traits(), dict(i=A.i, f=A.f))
+
+ def test_traits_metadata(self):
+ class A(HasTraits):
+ i = Int().tag(config_key='VALUE1', other_thing='VALUE2')
+ f = Float().tag(config_key='VALUE3', other_thing='VALUE2')
+ j = Int(0)
+ a = A()
+ self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j))
+ traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
+ self.assertEqual(traits, dict(i=A.i))
+
+ # This passes, but it shouldn't because I am replicating a bug in
+ # traits.
+ traits = a.traits(config_key=lambda v: True)
+ self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j))
+
+ def test_traits_metadata_deprecated(self):
+ with expected_warnings(['metadata should be set using the \.tag\(\) method']*2):
+ class A(HasTraits):
+ i = Int(config_key='VALUE1', other_thing='VALUE2')
+ f = Float(config_key='VALUE3', other_thing='VALUE2')
+ j = Int(0)
+ a = A()
+ self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j))
+ traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
+ self.assertEqual(traits, dict(i=A.i))
+
+ # This passes, but it shouldn't because I am replicating a bug in
+ # traits.
+ traits = a.traits(config_key=lambda v: True)
+ self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j))
+
+
+ def test_init(self):
+ class A(HasTraits):
+ i = Int()
+ x = Float()
+ a = A(i=1, x=10.0)
+ self.assertEqual(a.i, 1)
+ self.assertEqual(a.x, 10.0)
+
+ def test_positional_args(self):
+ class A(HasTraits):
+ i = Int(0)
+ def __init__(self, i):
+ super(A, self).__init__()
+ self.i = i
+
+ a = A(5)
+ self.assertEqual(a.i, 5)
+ # should raise TypeError if no positional arg given
+ self.assertRaises(TypeError, A)
+
+#-----------------------------------------------------------------------------
+# Tests for specific trait types
+#-----------------------------------------------------------------------------
+
+
+class TestType(TestCase):
+
+ def test_default(self):
+
+ class B(object): pass
+ class A(HasTraits):
+ klass = Type(allow_none=True)
+
+ a = A()
+ self.assertEqual(a.klass, object)
+
+ a.klass = B
+ self.assertEqual(a.klass, B)
+ self.assertRaises(TraitError, setattr, a, 'klass', 10)
+
+ def test_default_options(self):
+
+ class B(object): pass
+ class C(B): pass
+ class A(HasTraits):
+ # Different possible combinations of options for default_value
+ # and klass. default_value=None is only valid with allow_none=True.
+ k1 = Type()
+ k2 = Type(None, allow_none=True)
+ k3 = Type(B)
+ k4 = Type(klass=B)
+ k5 = Type(default_value=None, klass=B, allow_none=True)
+ k6 = Type(default_value=C, klass=B)
+
+ self.assertIs(A.k1.default_value, object)
+ self.assertIs(A.k1.klass, object)
+ self.assertIs(A.k2.default_value, None)
+ self.assertIs(A.k2.klass, object)
+ self.assertIs(A.k3.default_value, B)
+ self.assertIs(A.k3.klass, B)
+ self.assertIs(A.k4.default_value, B)
+ self.assertIs(A.k4.klass, B)
+ self.assertIs(A.k5.default_value, None)
+ self.assertIs(A.k5.klass, B)
+ self.assertIs(A.k6.default_value, C)
+ self.assertIs(A.k6.klass, B)
+
+ a = A()
+ self.assertIs(a.k1, object)
+ self.assertIs(a.k2, None)
+ self.assertIs(a.k3, B)
+ self.assertIs(a.k4, B)
+ self.assertIs(a.k5, None)
+ self.assertIs(a.k6, C)
+
+ def test_value(self):
+
+ class B(object): pass
+ class C(object): pass
+ class A(HasTraits):
+ klass = Type(B)
+
+ a = A()
+ self.assertEqual(a.klass, B)
+ self.assertRaises(TraitError, setattr, a, 'klass', C)
+ self.assertRaises(TraitError, setattr, a, 'klass', object)
+ a.klass = B
+
+ def test_allow_none(self):
+
+ class B(object): pass
+ class C(B): pass
+ class A(HasTraits):
+ klass = Type(B)
+
+ a = A()
+ self.assertEqual(a.klass, B)
+ self.assertRaises(TraitError, setattr, a, 'klass', None)
+ a.klass = C
+ self.assertEqual(a.klass, C)
+
+ def test_validate_klass(self):
+
+ class A(HasTraits):
+ klass = Type('no strings allowed')
+
+ self.assertRaises(ImportError, A)
+
+ class A(HasTraits):
+ klass = Type('rub.adub.Duck')
+
+ self.assertRaises(ImportError, A)
+
+ def test_validate_default(self):
+
+ class B(object): pass
+ class A(HasTraits):
+ klass = Type('bad default', B)
+
+ self.assertRaises(ImportError, A)
+
+ class C(HasTraits):
+ klass = Type(None, B)
+
+ self.assertRaises(TraitError, C)
+
+ def test_str_klass(self):
+
+ class A(HasTraits):
+ klass = Type('ipython_genutils.ipstruct.Struct')
+
+ from ipython_genutils.ipstruct import Struct
+ a = A()
+ a.klass = Struct
+ self.assertEqual(a.klass, Struct)
+
+ self.assertRaises(TraitError, setattr, a, 'klass', 10)
+
+ def test_set_str_klass(self):
+
+ class A(HasTraits):
+ klass = Type()
+
+ a = A(klass='ipython_genutils.ipstruct.Struct')
+ from ipython_genutils.ipstruct import Struct
+ self.assertEqual(a.klass, Struct)
+
+class TestInstance(TestCase):
+
+ def test_basic(self):
+ class Foo(object): pass
+ class Bar(Foo): pass
+ class Bah(object): pass
+
+ class A(HasTraits):
+ inst = Instance(Foo, allow_none=True)
+
+ a = A()
+ self.assertTrue(a.inst is None)
+ a.inst = Foo()
+ self.assertTrue(isinstance(a.inst, Foo))
+ a.inst = Bar()
+ self.assertTrue(isinstance(a.inst, Foo))
+ self.assertRaises(TraitError, setattr, a, 'inst', Foo)
+ self.assertRaises(TraitError, setattr, a, 'inst', Bar)
+ self.assertRaises(TraitError, setattr, a, 'inst', Bah())
+
+ def test_default_klass(self):
+ class Foo(object): pass
+ class Bar(Foo): pass
+ class Bah(object): pass
+
+ class FooInstance(Instance):
+ klass = Foo
+
+ class A(HasTraits):
+ inst = FooInstance(allow_none=True)
+
+ a = A()
+ self.assertTrue(a.inst is None)
+ a.inst = Foo()
+ self.assertTrue(isinstance(a.inst, Foo))
+ a.inst = Bar()
+ self.assertTrue(isinstance(a.inst, Foo))
+ self.assertRaises(TraitError, setattr, a, 'inst', Foo)
+ self.assertRaises(TraitError, setattr, a, 'inst', Bar)
+ self.assertRaises(TraitError, setattr, a, 'inst', Bah())
+
+ def test_unique_default_value(self):
+ class Foo(object): pass
+ class A(HasTraits):
+ inst = Instance(Foo,(),{})
+
+ a = A()
+ b = A()
+ self.assertTrue(a.inst is not b.inst)
+
+ def test_args_kw(self):
+ class Foo(object):
+ def __init__(self, c): self.c = c
+ class Bar(object): pass
+ class Bah(object):
+ def __init__(self, c, d):
+ self.c = c; self.d = d
+
+ class A(HasTraits):
+ inst = Instance(Foo, (10,))
+ a = A()
+ self.assertEqual(a.inst.c, 10)
+
+ class B(HasTraits):
+ inst = Instance(Bah, args=(10,), kw=dict(d=20))
+ b = B()
+ self.assertEqual(b.inst.c, 10)
+ self.assertEqual(b.inst.d, 20)
+
+ class C(HasTraits):
+ inst = Instance(Foo, allow_none=True)
+ c = C()
+ self.assertTrue(c.inst is None)
+
+ def test_bad_default(self):
+ class Foo(object): pass
+
+ class A(HasTraits):
+ inst = Instance(Foo)
+
+ a = A()
+ with self.assertRaises(TraitError):
+ a.inst
+
+ def test_instance(self):
+ class Foo(object): pass
+
+ def inner():
+ class A(HasTraits):
+ inst = Instance(Foo())
+
+ self.assertRaises(TraitError, inner)
+
+
+class TestThis(TestCase):
+
+ def test_this_class(self):
+ class Foo(HasTraits):
+ this = This()
+
+ f = Foo()
+ self.assertEqual(f.this, None)
+ g = Foo()
+ f.this = g
+ self.assertEqual(f.this, g)
+ self.assertRaises(TraitError, setattr, f, 'this', 10)
+
+ def test_this_inst(self):
+ class Foo(HasTraits):
+ this = This()
+
+ f = Foo()
+ f.this = Foo()
+ self.assertTrue(isinstance(f.this, Foo))
+
+ def test_subclass(self):
+ class Foo(HasTraits):
+ t = This()
+ class Bar(Foo):
+ pass
+ f = Foo()
+ b = Bar()
+ f.t = b
+ b.t = f
+ self.assertEqual(f.t, b)
+ self.assertEqual(b.t, f)
+
+ def test_subclass_override(self):
+ class Foo(HasTraits):
+ t = This()
+ class Bar(Foo):
+ t = This()
+ f = Foo()
+ b = Bar()
+ f.t = b
+ self.assertEqual(f.t, b)
+ self.assertRaises(TraitError, setattr, b, 't', f)
+
+ def test_this_in_container(self):
+
+ class Tree(HasTraits):
+ value = Unicode()
+ leaves = List(This())
+
+ tree = Tree(
+ value='foo',
+ leaves=[Tree(value='bar'), Tree(value='buzz')]
+ )
+
+ with self.assertRaises(TraitError):
+ tree.leaves = [1, 2]
+
+class TraitTestBase(TestCase):
+ """A best testing class for basic trait types."""
+
+ def assign(self, value):
+ self.obj.value = value
+
+ def coerce(self, value):
+ return value
+
+ def test_good_values(self):
+ if hasattr(self, '_good_values'):
+ for value in self._good_values:
+ self.assign(value)
+ self.assertEqual(self.obj.value, self.coerce(value))
+
+ def test_bad_values(self):
+ if hasattr(self, '_bad_values'):
+ for value in self._bad_values:
+ try:
+ self.assertRaises(TraitError, self.assign, value)
+ except AssertionError:
+ assert False, value
+
+ def test_default_value(self):
+ if hasattr(self, '_default_value'):
+ self.assertEqual(self._default_value, self.obj.value)
+
+ def test_allow_none(self):
+ if (hasattr(self, '_bad_values') and hasattr(self, '_good_values') and
+ None in self._bad_values):
+ trait=self.obj.traits()['value']
+ try:
+ trait.allow_none = True
+ self._bad_values.remove(None)
+ #skip coerce. Allow None casts None to None.
+ self.assign(None)
+ self.assertEqual(self.obj.value,None)
+ self.test_good_values()
+ self.test_bad_values()
+ finally:
+ #tear down
+ trait.allow_none = False
+ self._bad_values.append(None)
+
+ def tearDown(self):
+ # restore default value after tests, if set
+ if hasattr(self, '_default_value'):
+ self.obj.value = self._default_value
+
+
+class AnyTrait(HasTraits):
+
+ value = Any()
+
+class AnyTraitTest(TraitTestBase):
+
+ obj = AnyTrait()
+
+ _default_value = None
+ _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
+ _bad_values = []
+
+class UnionTrait(HasTraits):
+
+ value = Union([Type(), Bool()])
+
+class UnionTraitTest(TraitTestBase):
+
+ obj = UnionTrait(value='ipython_genutils.ipstruct.Struct')
+ _good_values = [int, float, True]
+ _bad_values = [[], (0,), 1j]
+
+class OrTrait(HasTraits):
+
+ value = Bool() | Unicode()
+
+class OrTraitTest(TraitTestBase):
+
+ obj = OrTrait()
+ _good_values = [True, False, 'ten']
+ _bad_values = [[], (0,), 1j]
+
+class IntTrait(HasTraits):
+
+ value = Int(99, min=-100)
+
+class TestInt(TraitTestBase):
+
+ obj = IntTrait()
+ _default_value = 99
+ _good_values = [10, -10]
+ _bad_values = ['ten', u'ten', [10], {'ten': 10}, (10,), None, 1j,
+ 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L',
+ u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', -200]
+ if not six.PY3:
+ _bad_values.extend([long(10), long(-10), 10*sys.maxint, -10*sys.maxint])
+
+
+class CIntTrait(HasTraits):
+ value = CInt('5')
+
+class TestCInt(TraitTestBase):
+ obj = CIntTrait()
+
+ _default_value = 5
+ _good_values = ['10', '-10', u'10', u'-10', 10, 10.0, -10.0, 10.1]
+ _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,),
+ None, 1j, '10.1', u'10.1']
+
+ def coerce(self, n):
+ return int(n)
+
+
+class MinBoundCIntTrait(HasTraits):
+ value = CInt('5', min=3)
+
+class TestMinBoundCInt(TestCInt):
+ obj = MinBoundCIntTrait()
+
+ _default_value = 5
+ _good_values = [3, 3.0, '3']
+ _bad_values = [2.6, 2, -3, -3.0]
+
+
+class LongTrait(HasTraits):
+
+ value = Long(99 if six.PY3 else long(99))
+
+class TestLong(TraitTestBase):
+
+ obj = LongTrait()
+
+ _default_value = 99 if six.PY3 else long(99)
+ _good_values = [10, -10]
+ _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,),
+ None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
+ '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1',
+ u'-10.1']
+ if not six.PY3:
+ # maxint undefined on py3, because int == long
+ _good_values.extend([long(10), long(-10), 10*sys.maxint, -10*sys.maxint])
+ _bad_values.extend([[long(10)], (long(10),)])
+
+ @mark.skipif(six.PY3, reason="not relevant on py3")
+ def test_cast_small(self):
+ """Long casts ints to long"""
+ self.obj.value = 10
+ self.assertEqual(type(self.obj.value), long)
+
+
+class MinBoundLongTrait(HasTraits):
+ value = Long(99 if six.PY3 else long(99), min=5)
+
+class TestMinBoundLong(TraitTestBase):
+ obj = MinBoundLongTrait()
+
+ _default_value = 99 if six.PY3 else long(99)
+ _good_values = [5, 10]
+ _bad_values = [4, -10]
+
+
+class MaxBoundLongTrait(HasTraits):
+ value = Long(5 if six.PY3 else long(5), max=10)
+
+class TestMaxBoundLong(TraitTestBase):
+ obj = MaxBoundLongTrait()
+
+ _default_value = 5 if six.PY3 else long(5)
+ _good_values = [10, -2]
+ _bad_values = [11, 20]
+
+
+class CLongTrait(HasTraits):
+ value = CLong('5')
+
+class TestCLong(TraitTestBase):
+ obj = CLongTrait()
+
+ _default_value = 5 if six.PY3 else long(5)
+ _good_values = ['10', '-10', u'10', u'-10', 10, 10.0, -10.0, 10.1]
+ _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,),
+ None, 1j, '10.1', u'10.1']
+
+ def coerce(self, n):
+ return int(n) if six.PY3 else long(n)
+
+
+class MaxBoundCLongTrait(HasTraits):
+ value = CLong('5', max=10)
+
+class TestMaxBoundCLong(TestCLong):
+ obj = MaxBoundCLongTrait()
+
+ _default_value = 5 if six.PY3 else long(5)
+ _good_values = [10, '10', 10.3]
+ _bad_values = [11.0, '11']
+
+
+class IntegerTrait(HasTraits):
+ value = Integer(1)
+
+class TestInteger(TestLong):
+ obj = IntegerTrait()
+ _default_value = 1
+
+ def coerce(self, n):
+ return int(n)
+
+ @mark.skipif(six.PY3, reason="not relevant on py3")
+ def test_cast_small(self):
+ """Integer casts small longs to int"""
+
+ self.obj.value = long(100)
+ self.assertEqual(type(self.obj.value), int)
+
+
+class MinBoundIntegerTrait(HasTraits):
+ value = Integer(5, min=3)
+
+class TestMinBoundInteger(TraitTestBase):
+ obj = MinBoundIntegerTrait()
+
+ _default_value = 5
+ _good_values = 3, 20
+ _bad_values = [2, -10]
+
+
+class MaxBoundIntegerTrait(HasTraits):
+ value = Integer(1, max=3)
+
+class TestMaxBoundInteger(TraitTestBase):
+ obj = MaxBoundIntegerTrait()
+
+ _default_value = 1
+ _good_values = 3, -2
+ _bad_values = [4, 10]
+
+
+class FloatTrait(HasTraits):
+
+ value = Float(99.0, max=200.0)
+
+class TestFloat(TraitTestBase):
+
+ obj = FloatTrait()
+
+ _default_value = 99.0
+ _good_values = [10, -10, 10.1, -10.1]
+ _bad_values = ['ten', u'ten', [10], {'ten': 10}, (10,), None,
+ 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10',
+ u'-10', u'10L', u'-10L', u'10.1', u'-10.1', 201.0]
+ if not six.PY3:
+ _bad_values.extend([long(10), long(-10)])
+
+
+class CFloatTrait(HasTraits):
+
+ value = CFloat('99.0', max=200.0)
+
+class TestCFloat(TraitTestBase):
+
+ obj = CFloatTrait()
+
+ _default_value = 99.0
+ _good_values = [10, 10.0, 10.5, '10.0', '10', '-10', '10.0', u'10']
+ _bad_values = ['ten', u'ten', [10], {'ten': 10}, (10,), None, 1j,
+ 200.1, '200.1']
+
+ def coerce(self, v):
+ return float(v)
+
+
+class ComplexTrait(HasTraits):
+
+ value = Complex(99.0-99.0j)
+
+class TestComplex(TraitTestBase):
+
+ obj = ComplexTrait()
+
+ _default_value = 99.0-99.0j
+ _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
+ 10.1j, 10.1+10.1j, 10.1-10.1j]
+ _bad_values = [u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
+ if not six.PY3:
+ _bad_values.extend([long(10), long(-10)])
+
+
+class BytesTrait(HasTraits):
+
+ value = Bytes(b'string')
+
+class TestBytes(TraitTestBase):
+
+ obj = BytesTrait()
+
+ _default_value = b'string'
+ _good_values = [b'10', b'-10', b'10L',
+ b'-10L', b'10.1', b'-10.1', b'string']
+ _bad_values = [10, -10, 10.1, -10.1, 1j, [10],
+ ['ten'],{'ten': 10},(10,), None, u'string']
+ if not six.PY3:
+ _bad_values.extend([long(10), long(-10)])
+
+
+class UnicodeTrait(HasTraits):
+
+ value = Unicode(u'unicode')
+
+class TestUnicode(TraitTestBase):
+
+ obj = UnicodeTrait()
+
+ _default_value = u'unicode'
+ _good_values = ['10', '-10', '10L', '-10L', '10.1',
+ '-10.1', '', u'', 'string', u'string', u"€"]
+ _bad_values = [10, -10, 10.1, -10.1, 1j,
+ [10], ['ten'], [u'ten'], {'ten': 10},(10,), None]
+ if not six.PY3:
+ _bad_values.extend([long(10), long(-10)])
+
+
+class ObjectNameTrait(HasTraits):
+ value = ObjectName("abc")
+
+class TestObjectName(TraitTestBase):
+ obj = ObjectNameTrait()
+
+ _default_value = "abc"
+ _good_values = ["a", "gh", "g9", "g_", "_G", u"a345_"]
+ _bad_values = [1, "", u"€", "9g", "!", "#abc", "aj@", "a.b", "a()", "a[0]",
+ None, object(), object]
+ if sys.version_info[0] < 3:
+ _bad_values.append(u"þ")
+ else:
+ _good_values.append(u"þ") # þ=1 is valid in Python 3 (PEP 3131).
+
+
+class DottedObjectNameTrait(HasTraits):
+ value = DottedObjectName("a.b")
+
+class TestDottedObjectName(TraitTestBase):
+ obj = DottedObjectNameTrait()
+
+ _default_value = "a.b"
+ _good_values = ["A", "y.t", "y765.__repr__", "os.path.join", u"os.path.join"]
+ _bad_values = [1, u"abc.€", "_.@", ".", ".abc", "abc.", ".abc.", None]
+ if sys.version_info[0] < 3:
+ _bad_values.append(u"t.þ")
+ else:
+ _good_values.append(u"t.þ")
+
+
+class TCPAddressTrait(HasTraits):
+ value = TCPAddress()
+
+class TestTCPAddress(TraitTestBase):
+
+ obj = TCPAddressTrait()
+
+ _default_value = ('127.0.0.1',0)
+ _good_values = [('localhost',0),('192.168.0.1',1000),('www.google.com',80)]
+ _bad_values = [(0,0),('localhost',10.0),('localhost',-1), None]
+
+class ListTrait(HasTraits):
+
+ value = List(Int())
+
+class TestList(TraitTestBase):
+
+ obj = ListTrait()
+
+ _default_value = []
+ _good_values = [[], [1], list(range(10)), (1,2)]
+ _bad_values = [10, [1,'a'], 'a']
+
+ def coerce(self, value):
+ if value is not None:
+ value = list(value)
+ return value
+
+class Foo(object):
+ pass
+
+class NoneInstanceListTrait(HasTraits):
+
+ value = List(Instance(Foo))
+
+class TestNoneInstanceList(TraitTestBase):
+
+ obj = NoneInstanceListTrait()
+
+ _default_value = []
+ _good_values = [[Foo(), Foo()], []]
+ _bad_values = [[None], [Foo(), None]]
+
+
+class InstanceListTrait(HasTraits):
+
+ value = List(Instance(__name__+'.Foo'))
+
+class TestInstanceList(TraitTestBase):
+
+ obj = InstanceListTrait()
+
+ def test_klass(self):
+ """Test that the instance klass is properly assigned."""
+ self.assertIs(self.obj.traits()['value']._trait.klass, Foo)
+
+ _default_value = []
+ _good_values = [[Foo(), Foo()], []]
+ _bad_values = [['1', 2,], '1', [Foo], None]
+
+class UnionListTrait(HasTraits):
+
+ value = List(Int() | Bool())
+
+class TestUnionListTrait(HasTraits):
+
+ obj = UnionListTrait()
+
+ _default_value = []
+ _good_values = [[True, 1], [False, True]]
+ _bad_values = [[1, 'True'], False]
+
+
+class LenListTrait(HasTraits):
+
+ value = List(Int(), [0], minlen=1, maxlen=2)
+
+class TestLenList(TraitTestBase):
+
+ obj = LenListTrait()
+
+ _default_value = [0]
+ _good_values = [[1], [1,2], (1,2)]
+ _bad_values = [10, [1,'a'], 'a', [], list(range(3))]
+
+ def coerce(self, value):
+ if value is not None:
+ value = list(value)
+ return value
+
+class TupleTrait(HasTraits):
+
+ value = Tuple(Int(allow_none=True), default_value=(1,))
+
+class TestTupleTrait(TraitTestBase):
+
+ obj = TupleTrait()
+
+ _default_value = (1,)
+ _good_values = [(1,), (0,), [1]]
+ _bad_values = [10, (1, 2), ('a'), (), None]
+
+ def coerce(self, value):
+ if value is not None:
+ value = tuple(value)
+ return value
+
+ def test_invalid_args(self):
+ self.assertRaises(TypeError, Tuple, 5)
+ self.assertRaises(TypeError, Tuple, default_value='hello')
+ t = Tuple(Int(), CBytes(), default_value=(1,5))
+
+class LooseTupleTrait(HasTraits):
+
+ value = Tuple((1,2,3))
+
+class TestLooseTupleTrait(TraitTestBase):
+
+ obj = LooseTupleTrait()
+
+ _default_value = (1,2,3)
+ _good_values = [(1,), [1], (0,), tuple(range(5)), tuple('hello'), ('a',5), ()]
+ _bad_values = [10, 'hello', {}, None]
+
+ def coerce(self, value):
+ if value is not None:
+ value = tuple(value)
+ return value
+
+ def test_invalid_args(self):
+ self.assertRaises(TypeError, Tuple, 5)
+ self.assertRaises(TypeError, Tuple, default_value='hello')
+ t = Tuple(Int(), CBytes(), default_value=(1,5))
+
+
+class MultiTupleTrait(HasTraits):
+
+ value = Tuple(Int(), Bytes(), default_value=[99,b'bottles'])
+
+class TestMultiTuple(TraitTestBase):
+
+ obj = MultiTupleTrait()
+
+ _default_value = (99,b'bottles')
+ _good_values = [(1,b'a'), (2,b'b')]
+ _bad_values = ((),10, b'a', (1,b'a',3), (b'a',1), (1, u'a'))
+
+class CRegExpTrait(HasTraits):
+
+ value = CRegExp(r'')
+
+class TestCRegExp(TraitTestBase):
+
+ def coerce(self, value):
+ return re.compile(value)
+
+ obj = CRegExpTrait()
+
+ _default_value = re.compile(r'')
+ _good_values = [r'\d+', re.compile(r'\d+')]
+ _bad_values = ['(', None, ()]
+
+class DictTrait(HasTraits):
+ value = Dict()
+
+def test_dict_assignment():
+ d = dict()
+ c = DictTrait()
+ c.value = d
+ d['a'] = 5
+ assert d == c.value
+ assert c.value is d
+
+
+class UniformlyValidatedDictTrait(HasTraits):
+
+ value = Dict(trait=Unicode(),
+ default_value={'foo': '1'})
+
+
+class TestInstanceUniformlyValidatedDict(TraitTestBase):
+
+ obj = UniformlyValidatedDictTrait()
+
+ _default_value = {'foo': '1'}
+ _good_values = [{'foo': '0', 'bar': '1'}]
+ _bad_values = [{'foo': 0, 'bar': '1'}]
+
+
+class KeyValidatedDictTrait(HasTraits):
+
+ value = Dict(traits={'foo': Int()},
+ default_value={'foo': 1})
+
+
+class TestInstanceKeyValidatedDict(TraitTestBase):
+
+ obj = KeyValidatedDictTrait()
+
+ _default_value = {'foo': 1}
+ _good_values = [{'foo': 0, 'bar': '1'}, {'foo': 0, 'bar': 1}]
+ _bad_values = [{'foo': '0', 'bar': '1'}]
+
+
+class FullyValidatedDictTrait(HasTraits):
+
+ value = Dict(trait=Unicode(),
+ traits={'foo': Int()},
+ default_value={'foo': 1})
+
+
+class TestInstanceFullyValidatedDict(TraitTestBase):
+
+ obj = FullyValidatedDictTrait()
+
+ _default_value = {'foo': 1}
+ _good_values = [{'foo': 0, 'bar': '1'}, {'foo': 1, 'bar': '2'}]
+ _bad_values = [{'foo': 0, 'bar': 1}, {'foo': '0', 'bar': '1'}]
+
+
+def test_dict_default_value():
+ """Check that the `{}` default value of the Dict traitlet constructor is
+ actually copied."""
+
+ class Foo(HasTraits):
+ d1 = Dict()
+ d2 = Dict()
+
+ foo = Foo()
+ assert foo.d1 == {}
+ assert foo.d2 == {}
+ assert foo.d1 is not foo.d2
+
+
+class TestValidationHook(TestCase):
+
+ def test_parity_trait(self):
+ """Verify that the early validation hook is effective"""
+
+ class Parity(HasTraits):
+
+ value = Int(0)
+ parity = Enum(['odd', 'even'], default_value='even')
+
+ @validate('value')
+ def _value_validate(self, proposal):
+ value = proposal['value']
+ if self.parity == 'even' and value % 2:
+ raise TraitError('Expected an even number')
+ if self.parity == 'odd' and (value % 2 == 0):
+ raise TraitError('Expected an odd number')
+ return value
+
+ u = Parity()
+ u.parity = 'odd'
+ u.value = 1 # OK
+ with self.assertRaises(TraitError):
+ u.value = 2 # Trait Error
+
+ u.parity = 'even'
+ u.value = 2 # OK
+
+ def test_multiple_validate(self):
+ """Verify that we can register the same validator to multiple names"""
+
+ class OddEven(HasTraits):
+
+ odd = Int(1)
+ even = Int(0)
+
+ @validate('odd', 'even')
+ def check_valid(self, proposal):
+ if proposal['trait'].name == 'odd' and not proposal['value'] % 2:
+ raise TraitError('odd should be odd')
+ if proposal['trait'].name == 'even' and proposal['value'] % 2:
+ raise TraitError('even should be even')
+
+ u = OddEven()
+ u.odd = 3 # OK
+ with self.assertRaises(TraitError):
+ u.odd = 2 # Trait Error
+
+ u.even = 2 # OK
+ with self.assertRaises(TraitError):
+ u.even = 3 # Trait Error
+
+
+
+class TestLink(TestCase):
+
+ def test_connect_same(self):
+ """Verify two traitlets of the same type can be linked together using link."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ a = A(value=9)
+ b = A(value=8)
+
+ # Conenct the two classes.
+ c = link((a, 'value'), (b, 'value'))
+
+ # Make sure the values are the same at the point of linking.
+ self.assertEqual(a.value, b.value)
+
+ # Change one of the values to make sure they stay in sync.
+ a.value = 5
+ self.assertEqual(a.value, b.value)
+ b.value = 6
+ self.assertEqual(a.value, b.value)
+
+ def test_link_different(self):
+ """Verify two traitlets of different types can be linked together using link."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ class B(HasTraits):
+ count = Int()
+ a = A(value=9)
+ b = B(count=8)
+
+ # Conenct the two classes.
+ c = link((a, 'value'), (b, 'count'))
+
+ # Make sure the values are the same at the point of linking.
+ self.assertEqual(a.value, b.count)
+
+ # Change one of the values to make sure they stay in sync.
+ a.value = 5
+ self.assertEqual(a.value, b.count)
+ b.count = 4
+ self.assertEqual(a.value, b.count)
+
+ def test_unlink(self):
+ """Verify two linked traitlets can be unlinked."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ a = A(value=9)
+ b = A(value=8)
+
+ # Connect the two classes.
+ c = link((a, 'value'), (b, 'value'))
+ a.value = 4
+ c.unlink()
+
+ # Change one of the values to make sure they don't stay in sync.
+ a.value = 5
+ self.assertNotEqual(a.value, b.value)
+
+ def test_callbacks(self):
+ """Verify two linked traitlets have their callbacks called once."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ class B(HasTraits):
+ count = Int()
+ a = A(value=9)
+ b = B(count=8)
+
+ # Register callbacks that count.
+ callback_count = []
+ def a_callback(name, old, new):
+ callback_count.append('a')
+ a.on_trait_change(a_callback, 'value')
+ def b_callback(name, old, new):
+ callback_count.append('b')
+ b.on_trait_change(b_callback, 'count')
+
+ # Connect the two classes.
+ c = link((a, 'value'), (b, 'count'))
+
+ # Make sure b's count was set to a's value once.
+ self.assertEqual(''.join(callback_count), 'b')
+ del callback_count[:]
+
+ # Make sure a's value was set to b's count once.
+ b.count = 5
+ self.assertEqual(''.join(callback_count), 'ba')
+ del callback_count[:]
+
+ # Make sure b's count was set to a's value once.
+ a.value = 4
+ self.assertEqual(''.join(callback_count), 'ab')
+ del callback_count[:]
+
+class TestDirectionalLink(TestCase):
+ def test_connect_same(self):
+ """Verify two traitlets of the same type can be linked together using directional_link."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ a = A(value=9)
+ b = A(value=8)
+
+ # Conenct the two classes.
+ c = directional_link((a, 'value'), (b, 'value'))
+
+ # Make sure the values are the same at the point of linking.
+ self.assertEqual(a.value, b.value)
+
+ # Change one the value of the source and check that it synchronizes the target.
+ a.value = 5
+ self.assertEqual(b.value, 5)
+ # Change one the value of the target and check that it has no impact on the source
+ b.value = 6
+ self.assertEqual(a.value, 5)
+
+ def test_tranform(self):
+ """Test transform link."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ a = A(value=9)
+ b = A(value=8)
+
+ # Conenct the two classes.
+ c = directional_link((a, 'value'), (b, 'value'), lambda x: 2 * x)
+
+ # Make sure the values are correct at the point of linking.
+ self.assertEqual(b.value, 2 * a.value)
+
+ # Change one the value of the source and check that it modifies the target.
+ a.value = 5
+ self.assertEqual(b.value, 10)
+ # Change one the value of the target and check that it has no impact on the source
+ b.value = 6
+ self.assertEqual(a.value, 5)
+
+ def test_link_different(self):
+ """Verify two traitlets of different types can be linked together using link."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ class B(HasTraits):
+ count = Int()
+ a = A(value=9)
+ b = B(count=8)
+
+ # Conenct the two classes.
+ c = directional_link((a, 'value'), (b, 'count'))
+
+ # Make sure the values are the same at the point of linking.
+ self.assertEqual(a.value, b.count)
+
+ # Change one the value of the source and check that it synchronizes the target.
+ a.value = 5
+ self.assertEqual(b.count, 5)
+ # Change one the value of the target and check that it has no impact on the source
+ b.value = 6
+ self.assertEqual(a.value, 5)
+
+ def test_unlink(self):
+ """Verify two linked traitlets can be unlinked."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ a = A(value=9)
+ b = A(value=8)
+
+ # Connect the two classes.
+ c = directional_link((a, 'value'), (b, 'value'))
+ a.value = 4
+ c.unlink()
+
+ # Change one of the values to make sure they don't stay in sync.
+ a.value = 5
+ self.assertNotEqual(a.value, b.value)
+
+class Pickleable(HasTraits):
+
+ i = Int()
+ @observe('i')
+ def _i_changed(self, change): pass
+ @validate('i')
+ def _i_validate(self, commit):
+ return commit['value']
+
+ j = Int()
+
+ def __init__(self):
+ with self.hold_trait_notifications():
+ self.i = 1
+ self.on_trait_change(self._i_changed, 'i')
+
+def test_pickle_hastraits():
+ c = Pickleable()
+ for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
+ p = pickle.dumps(c, protocol)
+ c2 = pickle.loads(p)
+ assert c2.i == c.i
+ assert c2.j == c.j
+
+ c.i = 5
+ for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
+ p = pickle.dumps(c, protocol)
+ c2 = pickle.loads(p)
+ assert c2.i == c.i
+ assert c2.j == c.j
+
+
+def test_hold_trait_notifications():
+ changes = []
+
+ class Test(HasTraits):
+ a = Integer(0)
+ b = Integer(0)
+
+ def _a_changed(self, name, old, new):
+ changes.append((old, new))
+
+ def _b_validate(self, value, trait):
+ if value != 0:
+ raise TraitError('Only 0 is a valid value')
+ return value
+
+ # Test context manager and nesting
+ t = Test()
+ with t.hold_trait_notifications():
+ with t.hold_trait_notifications():
+ t.a = 1
+ assert t.a == 1
+ assert changes == []
+ t.a = 2
+ assert t.a == 2
+ with t.hold_trait_notifications():
+ t.a = 3
+ assert t.a == 3
+ assert changes == []
+ t.a = 4
+ assert t.a == 4
+ assert changes == []
+ t.a = 4
+ assert t.a == 4
+ assert changes == []
+
+ assert changes == [(0, 4)]
+ # Test roll-back
+ try:
+ with t.hold_trait_notifications():
+ t.b = 1 # raises a Trait error
+ except:
+ pass
+ assert t.b == 0
+
+
+class RollBack(HasTraits):
+ bar = Int()
+ def _bar_validate(self, value, trait):
+ if value:
+ raise TraitError('foobar')
+ return value
+
+
+class TestRollback(TestCase):
+
+ def test_roll_back(self):
+
+ def assign_rollback():
+ RollBack(bar=1)
+
+ self.assertRaises(TraitError, assign_rollback)
+
+
+class CacheModification(HasTraits):
+ foo = Int()
+ bar = Int()
+
+ def _bar_validate(self, value, trait):
+ self.foo = value
+ return value
+
+ def _foo_validate(self, value, trait):
+ self.bar = value
+ return value
+
+
+def test_cache_modification():
+ CacheModification(foo=1)
+ CacheModification(bar=1)
+
+
+class OrderTraits(HasTraits):
+ notified = Dict()
+
+ a = Unicode()
+ b = Unicode()
+ c = Unicode()
+ d = Unicode()
+ e = Unicode()
+ f = Unicode()
+ g = Unicode()
+ h = Unicode()
+ i = Unicode()
+ j = Unicode()
+ k = Unicode()
+ l = Unicode()
+
+ def _notify(self, name, old, new):
+ """check the value of all traits when each trait change is triggered
+
+ This verifies that the values are not sensitive
+ to dict ordering when loaded from kwargs
+ """
+ # check the value of the other traits
+ # when a given trait change notification fires
+ self.notified[name] = {
+ c: getattr(self, c) for c in 'abcdefghijkl'
+ }
+
+ def __init__(self, **kwargs):
+ self.on_trait_change(self._notify)
+ super(OrderTraits, self).__init__(**kwargs)
+
+def test_notification_order():
+ d = {c:c for c in 'abcdefghijkl'}
+ obj = OrderTraits()
+ assert obj.notified == {}
+ obj = OrderTraits(**d)
+ notifications = {
+ c: d for c in 'abcdefghijkl'
+ }
+ assert obj.notified == notifications
+
+
+
+###
+# Traits for Forward Declaration Tests
+###
+class ForwardDeclaredInstanceTrait(HasTraits):
+
+ value = ForwardDeclaredInstance('ForwardDeclaredBar', allow_none=True)
+
+class ForwardDeclaredTypeTrait(HasTraits):
+
+ value = ForwardDeclaredType('ForwardDeclaredBar', allow_none=True)
+
+class ForwardDeclaredInstanceListTrait(HasTraits):
+
+ value = List(ForwardDeclaredInstance('ForwardDeclaredBar'))
+
+class ForwardDeclaredTypeListTrait(HasTraits):
+
+ value = List(ForwardDeclaredType('ForwardDeclaredBar'))
+###
+# End Traits for Forward Declaration Tests
+###
+
+###
+# Classes for Forward Declaration Tests
+###
+class ForwardDeclaredBar(object):
+ pass
+
+class ForwardDeclaredBarSub(ForwardDeclaredBar):
+ pass
+###
+# End Classes for Forward Declaration Tests
+###
+
+###
+# Forward Declaration Tests
+###
+class TestForwardDeclaredInstanceTrait(TraitTestBase):
+
+ obj = ForwardDeclaredInstanceTrait()
+ _default_value = None
+ _good_values = [None, ForwardDeclaredBar(), ForwardDeclaredBarSub()]
+ _bad_values = ['foo', 3, ForwardDeclaredBar, ForwardDeclaredBarSub]
+
+class TestForwardDeclaredTypeTrait(TraitTestBase):
+
+ obj = ForwardDeclaredTypeTrait()
+ _default_value = None
+ _good_values = [None, ForwardDeclaredBar, ForwardDeclaredBarSub]
+ _bad_values = ['foo', 3, ForwardDeclaredBar(), ForwardDeclaredBarSub()]
+
+class TestForwardDeclaredInstanceList(TraitTestBase):
+
+ obj = ForwardDeclaredInstanceListTrait()
+
+ def test_klass(self):
+ """Test that the instance klass is properly assigned."""
+ self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar)
+
+ _default_value = []
+ _good_values = [
+ [ForwardDeclaredBar(), ForwardDeclaredBarSub()],
+ [],
+ ]
+ _bad_values = [
+ ForwardDeclaredBar(),
+ [ForwardDeclaredBar(), 3, None],
+ '1',
+ # Note that this is the type, not an instance.
+ [ForwardDeclaredBar],
+ [None],
+ None,
+ ]
+
+class TestForwardDeclaredTypeList(TraitTestBase):
+
+ obj = ForwardDeclaredTypeListTrait()
+
+ def test_klass(self):
+ """Test that the instance klass is properly assigned."""
+ self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar)
+
+ _default_value = []
+ _good_values = [
+ [ForwardDeclaredBar, ForwardDeclaredBarSub],
+ [],
+ ]
+ _bad_values = [
+ ForwardDeclaredBar,
+ [ForwardDeclaredBar, 3],
+ '1',
+ # Note that this is an instance, not the type.
+ [ForwardDeclaredBar()],
+ [None],
+ None,
+ ]
+###
+# End Forward Declaration Tests
+###
+
+class TestDynamicTraits(TestCase):
+
+ def setUp(self):
+ self._notify1 = []
+
+ def notify1(self, name, old, new):
+ self._notify1.append((name, old, new))
+
+ def test_notify_all(self):
+
+ class A(HasTraits):
+ pass
+
+ a = A()
+ self.assertTrue(not hasattr(a, 'x'))
+ self.assertTrue(not hasattr(a, 'y'))
+
+ # Dynamically add trait x.
+ a.add_traits(x=Int())
+ self.assertTrue(hasattr(a, 'x'))
+ self.assertTrue(isinstance(a, (A, )))
+
+ # Dynamically add trait y.
+ a.add_traits(y=Float())
+ self.assertTrue(hasattr(a, 'y'))
+ self.assertTrue(isinstance(a, (A, )))
+ self.assertEqual(a.__class__.__name__, A.__name__)
+
+ # Create a new instance and verify that x and y
+ # aren't defined.
+ b = A()
+ self.assertTrue(not hasattr(b, 'x'))
+ self.assertTrue(not hasattr(b, 'y'))
+
+ # Verify that notification works like normal.
+ a.on_trait_change(self.notify1)
+ a.x = 0
+ self.assertEqual(len(self._notify1), 0)
+ a.y = 0.0
+ self.assertEqual(len(self._notify1), 0)
+ a.x = 10
+ self.assertTrue(('x', 0, 10) in self._notify1)
+ a.y = 10.0
+ self.assertTrue(('y', 0.0, 10.0) in self._notify1)
+ self.assertRaises(TraitError, setattr, a, 'x', 'bad string')
+ self.assertRaises(TraitError, setattr, a, 'y', 'bad string')
+ self._notify1 = []
+ a.on_trait_change(self.notify1, remove=True)
+ a.x = 20
+ a.y = 20.0
+ self.assertEqual(len(self._notify1), 0)
+
+
+def test_enum_no_default():
+ class C(HasTraits):
+ t = Enum(['a', 'b'])
+
+ c = C()
+ c.t = 'a'
+ assert c.t == 'a'
+
+ c = C()
+
+ with pytest.raises(TraitError):
+ t = c.t
+
+ c = C(t='b')
+ assert c.t == 'b'
+
+
+def test_default_value_repr():
+ class C(HasTraits):
+ t = Type('traitlets.HasTraits')
+ t2 = Type(HasTraits)
+ n = Integer(0)
+ lis = List()
+ d = Dict()
+
+ assert C.t.default_value_repr() == "'traitlets.HasTraits'"
+ assert C.t2.default_value_repr() == "'traitlets.traitlets.HasTraits'"
+ assert C.n.default_value_repr() == '0'
+ assert C.lis.default_value_repr() == '[]'
+ assert C.d.default_value_repr() == '{}'
+
+
+class TransitionalClass(HasTraits):
+
+ d = Any()
+ @default('d')
+ def _d_default(self):
+ return TransitionalClass
+
+ parent_super = False
+ calls_super = Integer(0)
+
+ @default('calls_super')
+ def _calls_super_default(self):
+ return -1
+
+ @observe('calls_super')
+ @observe_compat
+ def _calls_super_changed(self, change):
+ self.parent_super = change
+
+ parent_override = False
+ overrides = Integer(0)
+
+ @observe('overrides')
+ @observe_compat
+ def _overrides_changed(self, change):
+ self.parent_override = change
+
+
+class SubClass(TransitionalClass):
+ def _d_default(self):
+ return SubClass
+
+ subclass_super = False
+ def _calls_super_changed(self, name, old, new):
+ self.subclass_super = True
+ super(SubClass, self)._calls_super_changed(name, old, new)
+
+ subclass_override = False
+ def _overrides_changed(self, name, old, new):
+ self.subclass_override = True
+
+
+def test_subclass_compat():
+ obj = SubClass()
+ obj.calls_super = 5
+ assert obj.parent_super
+ assert obj.subclass_super
+ obj.overrides = 5
+ assert obj.subclass_override
+ assert not obj.parent_override
+ assert obj.d is SubClass
+
+
+class DefinesHandler(HasTraits):
+ parent_called = False
+
+ trait = Integer()
+ @observe('trait')
+ def handler(self, change):
+ self.parent_called = True
+
+
+class OverridesHandler(DefinesHandler):
+ child_called = False
+
+ @observe('trait')
+ def handler(self, change):
+ self.child_called = True
+
+
+def test_subclass_override_observer():
+ obj = OverridesHandler()
+ obj.trait = 5
+ assert obj.child_called
+ assert not obj.parent_called
+
+
+class DoesntRegisterHandler(DefinesHandler):
+ child_called = False
+
+ def handler(self, change):
+ self.child_called = True
+
+
+def test_subclass_override_not_registered():
+ """Subclass that overrides observer and doesn't re-register unregisters both"""
+ obj = DoesntRegisterHandler()
+ obj.trait = 5
+ assert not obj.child_called
+ assert not obj.parent_called
+
+
+class AddsHandler(DefinesHandler):
+ child_called = False
+
+ @observe('trait')
+ def child_handler(self, change):
+ self.child_called = True
+
+def test_subclass_add_observer():
+ obj = AddsHandler()
+ obj.trait = 5
+ assert obj.child_called
+ assert obj.parent_called
+
+
+def test_observe_iterables():
+
+ class C(HasTraits):
+ i = Integer()
+ s = Unicode()
+
+ c = C()
+ recorded = {}
+ def record(change):
+ recorded['change'] = change
+
+ # observe with names=set
+ c.observe(record, names={'i', 's'})
+ c.i = 5
+ assert recorded['change'].name == 'i'
+ assert recorded['change'].new == 5
+ c.s = 'hi'
+ assert recorded['change'].name == 's'
+ assert recorded['change'].new == 'hi'
+
+ # observe with names=custom container with iter, contains
+ class MyContainer(object):
+ def __init__(self, container):
+ self.container = container
+
+ def __iter__(self):
+ return iter(self.container)
+
+ def __contains__(self, key):
+ return key in self.container
+
+ c.observe(record, names=MyContainer({'i', 's'}))
+ c.i = 10
+ assert recorded['change'].name == 'i'
+ assert recorded['change'].new == 10
+ c.s = 'ok'
+ assert recorded['change'].name == 's'
+ assert recorded['change'].new == 'ok'
+
+
+def test_super_args():
+ class SuperRecorder(object):
+ def __init__(self, *args, **kwargs):
+ self.super_args = args
+ self.super_kwargs = kwargs
+
+ class SuperHasTraits(HasTraits, SuperRecorder):
+ i = Integer()
+
+ obj = SuperHasTraits('a1', 'a2', b=10, i=5, c='x')
+ assert obj.i == 5
+ assert not hasattr(obj, 'b')
+ assert not hasattr(obj, 'c')
+ assert obj.super_args == ('a1' , 'a2')
+ assert obj.super_kwargs == {'b': 10 , 'c': 'x'}
+
+def test_super_bad_args():
+ class SuperHasTraits(HasTraits):
+ a = Integer()
+
+ if sys.version_info < (3,):
+ # Legacy Python, object.__init__ warns itself, instead of raising
+ w = ['object.__init__']
+ else:
+ w = ["Passing unrecoginized arguments"]
+ with expected_warnings(w):
+ obj = SuperHasTraits(a=1, b=2)
+ assert obj.a == 1
+ assert not hasattr(obj, 'b')
diff --git a/contrib/python/traitlets/py2/traitlets/tests/test_traitlets_enum.py b/contrib/python/traitlets/py2/traitlets/tests/test_traitlets_enum.py
index 234466ac99..82259ae6c5 100644
--- a/contrib/python/traitlets/py2/traitlets/tests/test_traitlets_enum.py
+++ b/contrib/python/traitlets/py2/traitlets/tests/test_traitlets_enum.py
@@ -1,181 +1,181 @@
-# -*- coding: UTF-8 -*-
-# pylint: disable=missing-docstring, too-few-public-methods
-"""
-Test the trait-type ``UseEnum``.
-"""
-
-import unittest
-import enum
-from ipython_genutils.py3compat import string_types
-from traitlets import HasTraits, TraitError, UseEnum
-
-
-# -----------------------------------------------------------------------------
-# TEST SUPPORT:
-# -----------------------------------------------------------------------------
-class Color(enum.Enum):
- red = 1
- green = 2
- blue = 3
- yellow = 4
-
-class OtherColor(enum.Enum):
- red = 0
- green = 1
-
-
-# -----------------------------------------------------------------------------
-# TESTSUITE:
-# -----------------------------------------------------------------------------
-class TestUseEnum(unittest.TestCase):
- # pylint: disable=invalid-name
-
- class Example(HasTraits):
- color = UseEnum(Color, help="Color enum")
-
- def test_assign_enum_value(self):
- example = self.Example()
- example.color = Color.green
- self.assertEqual(example.color, Color.green)
-
- def test_assign_all_enum_values(self):
- # pylint: disable=no-member
- enum_values = [value for value in Color.__members__.values()]
- for value in enum_values:
- self.assertIsInstance(value, Color)
- example = self.Example()
- example.color = value
- self.assertEqual(example.color, value)
- self.assertIsInstance(value, Color)
-
- def test_assign_enum_value__with_other_enum_raises_error(self):
- example = self.Example()
- with self.assertRaises(TraitError):
- example.color = OtherColor.green
-
- def test_assign_enum_name_1(self):
- # -- CONVERT: string => Enum value (item)
- example = self.Example()
- example.color = "red"
- self.assertEqual(example.color, Color.red)
-
- def test_assign_enum_value_name(self):
- # -- CONVERT: string => Enum value (item)
- # pylint: disable=no-member
- enum_names = [enum_val.name for enum_val in Color.__members__.values()]
- for value in enum_names:
- self.assertIsInstance(value, string_types)
- example = self.Example()
- enum_value = Color.__members__.get(value)
- example.color = value
- self.assertIs(example.color, enum_value)
- self.assertEqual(example.color.name, value)
-
- def test_assign_scoped_enum_value_name(self):
- # -- CONVERT: string => Enum value (item)
- scoped_names = ["Color.red", "Color.green", "Color.blue", "Color.yellow"]
- for value in scoped_names:
- example = self.Example()
- example.color = value
- self.assertIsInstance(example.color, Color)
- self.assertEqual(str(example.color), value)
-
- def test_assign_bad_enum_value_name__raises_error(self):
- # -- CONVERT: string => Enum value (item)
- bad_enum_names = ["UNKNOWN_COLOR", "RED", "Green", "blue2"]
- for value in bad_enum_names:
- example = self.Example()
- with self.assertRaises(TraitError):
- example.color = value
-
- def test_assign_enum_value_number_1(self):
- # -- CONVERT: number => Enum value (item)
- example = self.Example()
- example.color = 1 # == Color.red.value
- example.color = Color.red.value
- self.assertEqual(example.color, Color.red)
-
- def test_assign_enum_value_number(self):
- # -- CONVERT: number => Enum value (item)
- # pylint: disable=no-member
- enum_numbers = [enum_val.value
- for enum_val in Color.__members__.values()]
- for value in enum_numbers:
- self.assertIsInstance(value, int)
- example = self.Example()
- example.color = value
- self.assertIsInstance(example.color, Color)
- self.assertEqual(example.color.value, value)
-
- def test_assign_bad_enum_value_number__raises_error(self):
- # -- CONVERT: number => Enum value (item)
- bad_numbers = [-1, 0, 5]
- for value in bad_numbers:
- self.assertIsInstance(value, int)
- assert UseEnum(Color).select_by_number(value, None) is None
- example = self.Example()
- with self.assertRaises(TraitError):
- example.color = value
-
- def test_ctor_without_default_value(self):
- # -- IMPLICIT: default_value = Color.red (first enum-value)
- class Example2(HasTraits):
- color = UseEnum(Color)
-
- example = Example2()
- self.assertEqual(example.color, Color.red)
-
- def test_ctor_with_default_value_as_enum_value(self):
- # -- CONVERT: number => Enum value (item)
- class Example2(HasTraits):
- color = UseEnum(Color, default_value=Color.green)
-
- example = Example2()
- self.assertEqual(example.color, Color.green)
-
-
- def test_ctor_with_default_value_none_and_not_allow_none(self):
- # -- IMPLICIT: default_value = Color.red (first enum-value)
- class Example2(HasTraits):
- color1 = UseEnum(Color, default_value=None, allow_none=False)
- color2 = UseEnum(Color, default_value=None)
- example = Example2()
- self.assertEqual(example.color1, Color.red)
- self.assertEqual(example.color2, Color.red)
-
- def test_ctor_with_default_value_none_and_allow_none(self):
- class Example2(HasTraits):
- color1 = UseEnum(Color, default_value=None, allow_none=True)
- color2 = UseEnum(Color, allow_none=True)
-
- example = Example2()
- self.assertIs(example.color1, None)
- self.assertIs(example.color2, None)
-
- def test_assign_none_without_allow_none_resets_to_default_value(self):
- class Example2(HasTraits):
- color1 = UseEnum(Color, allow_none=False)
- color2 = UseEnum(Color)
-
- example = Example2()
- example.color1 = None
- example.color2 = None
- self.assertIs(example.color1, Color.red)
- self.assertIs(example.color2, Color.red)
-
- def test_assign_none_to_enum_or_none(self):
- class Example2(HasTraits):
- color = UseEnum(Color, allow_none=True)
-
- example = Example2()
- example.color = None
- self.assertIs(example.color, None)
-
- def test_assign_bad_value_with_to_enum_or_none(self):
- class Example2(HasTraits):
- color = UseEnum(Color, allow_none=True)
-
- example = Example2()
- with self.assertRaises(TraitError):
- example.color = "BAD_VALUE"
-
+# -*- coding: UTF-8 -*-
+# pylint: disable=missing-docstring, too-few-public-methods
+"""
+Test the trait-type ``UseEnum``.
+"""
+
+import unittest
+import enum
+from ipython_genutils.py3compat import string_types
+from traitlets import HasTraits, TraitError, UseEnum
+
+
+# -----------------------------------------------------------------------------
+# TEST SUPPORT:
+# -----------------------------------------------------------------------------
+class Color(enum.Enum):
+ red = 1
+ green = 2
+ blue = 3
+ yellow = 4
+
+class OtherColor(enum.Enum):
+ red = 0
+ green = 1
+
+
+# -----------------------------------------------------------------------------
+# TESTSUITE:
+# -----------------------------------------------------------------------------
+class TestUseEnum(unittest.TestCase):
+ # pylint: disable=invalid-name
+
+ class Example(HasTraits):
+ color = UseEnum(Color, help="Color enum")
+
+ def test_assign_enum_value(self):
+ example = self.Example()
+ example.color = Color.green
+ self.assertEqual(example.color, Color.green)
+
+ def test_assign_all_enum_values(self):
+ # pylint: disable=no-member
+ enum_values = [value for value in Color.__members__.values()]
+ for value in enum_values:
+ self.assertIsInstance(value, Color)
+ example = self.Example()
+ example.color = value
+ self.assertEqual(example.color, value)
+ self.assertIsInstance(value, Color)
+
+ def test_assign_enum_value__with_other_enum_raises_error(self):
+ example = self.Example()
+ with self.assertRaises(TraitError):
+ example.color = OtherColor.green
+
+ def test_assign_enum_name_1(self):
+ # -- CONVERT: string => Enum value (item)
+ example = self.Example()
+ example.color = "red"
+ self.assertEqual(example.color, Color.red)
+
+ def test_assign_enum_value_name(self):
+ # -- CONVERT: string => Enum value (item)
+ # pylint: disable=no-member
+ enum_names = [enum_val.name for enum_val in Color.__members__.values()]
+ for value in enum_names:
+ self.assertIsInstance(value, string_types)
+ example = self.Example()
+ enum_value = Color.__members__.get(value)
+ example.color = value
+ self.assertIs(example.color, enum_value)
+ self.assertEqual(example.color.name, value)
+
+ def test_assign_scoped_enum_value_name(self):
+ # -- CONVERT: string => Enum value (item)
+ scoped_names = ["Color.red", "Color.green", "Color.blue", "Color.yellow"]
+ for value in scoped_names:
+ example = self.Example()
+ example.color = value
+ self.assertIsInstance(example.color, Color)
+ self.assertEqual(str(example.color), value)
+
+ def test_assign_bad_enum_value_name__raises_error(self):
+ # -- CONVERT: string => Enum value (item)
+ bad_enum_names = ["UNKNOWN_COLOR", "RED", "Green", "blue2"]
+ for value in bad_enum_names:
+ example = self.Example()
+ with self.assertRaises(TraitError):
+ example.color = value
+
+ def test_assign_enum_value_number_1(self):
+ # -- CONVERT: number => Enum value (item)
+ example = self.Example()
+ example.color = 1 # == Color.red.value
+ example.color = Color.red.value
+ self.assertEqual(example.color, Color.red)
+
+ def test_assign_enum_value_number(self):
+ # -- CONVERT: number => Enum value (item)
+ # pylint: disable=no-member
+ enum_numbers = [enum_val.value
+ for enum_val in Color.__members__.values()]
+ for value in enum_numbers:
+ self.assertIsInstance(value, int)
+ example = self.Example()
+ example.color = value
+ self.assertIsInstance(example.color, Color)
+ self.assertEqual(example.color.value, value)
+
+ def test_assign_bad_enum_value_number__raises_error(self):
+ # -- CONVERT: number => Enum value (item)
+ bad_numbers = [-1, 0, 5]
+ for value in bad_numbers:
+ self.assertIsInstance(value, int)
+ assert UseEnum(Color).select_by_number(value, None) is None
+ example = self.Example()
+ with self.assertRaises(TraitError):
+ example.color = value
+
+ def test_ctor_without_default_value(self):
+ # -- IMPLICIT: default_value = Color.red (first enum-value)
+ class Example2(HasTraits):
+ color = UseEnum(Color)
+
+ example = Example2()
+ self.assertEqual(example.color, Color.red)
+
+ def test_ctor_with_default_value_as_enum_value(self):
+ # -- CONVERT: number => Enum value (item)
+ class Example2(HasTraits):
+ color = UseEnum(Color, default_value=Color.green)
+
+ example = Example2()
+ self.assertEqual(example.color, Color.green)
+
+
+ def test_ctor_with_default_value_none_and_not_allow_none(self):
+ # -- IMPLICIT: default_value = Color.red (first enum-value)
+ class Example2(HasTraits):
+ color1 = UseEnum(Color, default_value=None, allow_none=False)
+ color2 = UseEnum(Color, default_value=None)
+ example = Example2()
+ self.assertEqual(example.color1, Color.red)
+ self.assertEqual(example.color2, Color.red)
+
+ def test_ctor_with_default_value_none_and_allow_none(self):
+ class Example2(HasTraits):
+ color1 = UseEnum(Color, default_value=None, allow_none=True)
+ color2 = UseEnum(Color, allow_none=True)
+
+ example = Example2()
+ self.assertIs(example.color1, None)
+ self.assertIs(example.color2, None)
+
+ def test_assign_none_without_allow_none_resets_to_default_value(self):
+ class Example2(HasTraits):
+ color1 = UseEnum(Color, allow_none=False)
+ color2 = UseEnum(Color)
+
+ example = Example2()
+ example.color1 = None
+ example.color2 = None
+ self.assertIs(example.color1, Color.red)
+ self.assertIs(example.color2, Color.red)
+
+ def test_assign_none_to_enum_or_none(self):
+ class Example2(HasTraits):
+ color = UseEnum(Color, allow_none=True)
+
+ example = Example2()
+ example.color = None
+ self.assertIs(example.color, None)
+
+ def test_assign_bad_value_with_to_enum_or_none(self):
+ class Example2(HasTraits):
+ color = UseEnum(Color, allow_none=True)
+
+ example = Example2()
+ with self.assertRaises(TraitError):
+ example.color = "BAD_VALUE"
+
diff --git a/contrib/python/traitlets/py2/traitlets/tests/utils.py b/contrib/python/traitlets/py2/traitlets/tests/utils.py
index 4efe85358a..88845d8519 100644
--- a/contrib/python/traitlets/py2/traitlets/tests/utils.py
+++ b/contrib/python/traitlets/py2/traitlets/tests/utils.py
@@ -1,39 +1,39 @@
-import sys
-
-from subprocess import Popen, PIPE
-
-def get_output_error_code(cmd):
- """Get stdout, stderr, and exit code from running a command"""
+import sys
+
+from subprocess import Popen, PIPE
+
+def get_output_error_code(cmd):
+ """Get stdout, stderr, and exit code from running a command"""
p = Popen(cmd, stdout=PIPE, stderr=PIPE)
- out, err = p.communicate()
- out = out.decode('utf8', 'replace')
- err = err.decode('utf8', 'replace')
- return out, err, p.returncode
-
-
-def check_help_output(pkg, subcommand=None):
- """test that `python -m PKG [subcommand] -h` works"""
- cmd = [sys.executable, '-m', pkg]
- if subcommand:
- cmd.extend(subcommand)
- cmd.append('-h')
- out, err, rc = get_output_error_code(cmd)
- assert rc == 0, err
- assert "Traceback" not in err
- assert "Options" in out
- assert "--help-all" in out
- return out, err
-
-
-def check_help_all_output(pkg, subcommand=None):
- """test that `python -m PKG --help-all` works"""
- cmd = [sys.executable, '-m', pkg]
- if subcommand:
- cmd.extend(subcommand)
- cmd.append('--help-all')
- out, err, rc = get_output_error_code(cmd)
- assert rc == 0, err
- assert "Traceback" not in err
- assert "Options" in out
- assert "Class parameters" in out
- return out, err
+ out, err = p.communicate()
+ out = out.decode('utf8', 'replace')
+ err = err.decode('utf8', 'replace')
+ return out, err, p.returncode
+
+
+def check_help_output(pkg, subcommand=None):
+ """test that `python -m PKG [subcommand] -h` works"""
+ cmd = [sys.executable, '-m', pkg]
+ if subcommand:
+ cmd.extend(subcommand)
+ cmd.append('-h')
+ out, err, rc = get_output_error_code(cmd)
+ assert rc == 0, err
+ assert "Traceback" not in err
+ assert "Options" in out
+ assert "--help-all" in out
+ return out, err
+
+
+def check_help_all_output(pkg, subcommand=None):
+ """test that `python -m PKG --help-all` works"""
+ cmd = [sys.executable, '-m', pkg]
+ if subcommand:
+ cmd.extend(subcommand)
+ cmd.append('--help-all')
+ out, err, rc = get_output_error_code(cmd)
+ assert rc == 0, err
+ assert "Traceback" not in err
+ assert "Options" in out
+ assert "Class parameters" in out
+ return out, err
diff --git a/contrib/python/traitlets/py2/ya.make b/contrib/python/traitlets/py2/ya.make
index ed668b5d34..4a60107101 100644
--- a/contrib/python/traitlets/py2/ya.make
+++ b/contrib/python/traitlets/py2/ya.make
@@ -44,7 +44,7 @@ RESOURCE_FILES(
)
END()
-
-RECURSE_FOR_TESTS(
+
+RECURSE_FOR_TESTS(
tests
-)
+)
diff --git a/contrib/python/traitlets/py3/traitlets/tests/_warnings.py b/contrib/python/traitlets/py3/traitlets/tests/_warnings.py
index eb80d0a936..05e916806f 100644
--- a/contrib/python/traitlets/py3/traitlets/tests/_warnings.py
+++ b/contrib/python/traitlets/py3/traitlets/tests/_warnings.py
@@ -1,110 +1,110 @@
-# From scikit-image: https://github.com/scikit-image/scikit-image/blob/c2f8c4ab123ebe5f7b827bc495625a32bb225c10/skimage/_shared/_warnings.py
-# Licensed under modified BSD license
-
-__all__ = ['all_warnings', 'expected_warnings']
-
+# From scikit-image: https://github.com/scikit-image/scikit-image/blob/c2f8c4ab123ebe5f7b827bc495625a32bb225c10/skimage/_shared/_warnings.py
+# Licensed under modified BSD license
+
+__all__ = ['all_warnings', 'expected_warnings']
+
import inspect
import os
import re
-import sys
-import warnings
+import sys
+import warnings
from contextlib import contextmanager
from unittest import mock
-
-
-@contextmanager
-def all_warnings():
- """
- Context for use in testing to ensure that all warnings are raised.
- Examples
- --------
- >>> import warnings
- >>> def foo():
- ... warnings.warn(RuntimeWarning("bar"))
- We raise the warning once, while the warning filter is set to "once".
- Hereafter, the warning is invisible, even with custom filters:
- >>> with warnings.catch_warnings():
- ... warnings.simplefilter('once')
- ... foo()
- We can now run ``foo()`` without a warning being raised:
- >>> from numpy.testing import assert_warns
- >>> foo()
- To catch the warning, we call in the help of ``all_warnings``:
- >>> with all_warnings():
- ... assert_warns(RuntimeWarning, foo)
- """
-
- # Whenever a warning is triggered, Python adds a __warningregistry__
- # member to the *calling* module. The exercize here is to find
- # and eradicate all those breadcrumbs that were left lying around.
- #
- # We proceed by first searching all parent calling frames and explicitly
- # clearing their warning registries (necessary for the doctests above to
- # pass). Then, we search for all submodules of skimage and clear theirs
- # as well (necessary for the skimage test suite to pass).
-
- frame = inspect.currentframe()
- if frame:
- for f in inspect.getouterframes(frame):
- f[0].f_locals['__warningregistry__'] = {}
- del frame
-
- for mod_name, mod in list(sys.modules.items()):
- try:
- mod.__warningregistry__.clear()
- except AttributeError:
- pass
-
+
+
+@contextmanager
+def all_warnings():
+ """
+ Context for use in testing to ensure that all warnings are raised.
+ Examples
+ --------
+ >>> import warnings
+ >>> def foo():
+ ... warnings.warn(RuntimeWarning("bar"))
+ We raise the warning once, while the warning filter is set to "once".
+ Hereafter, the warning is invisible, even with custom filters:
+ >>> with warnings.catch_warnings():
+ ... warnings.simplefilter('once')
+ ... foo()
+ We can now run ``foo()`` without a warning being raised:
+ >>> from numpy.testing import assert_warns
+ >>> foo()
+ To catch the warning, we call in the help of ``all_warnings``:
+ >>> with all_warnings():
+ ... assert_warns(RuntimeWarning, foo)
+ """
+
+ # Whenever a warning is triggered, Python adds a __warningregistry__
+ # member to the *calling* module. The exercize here is to find
+ # and eradicate all those breadcrumbs that were left lying around.
+ #
+ # We proceed by first searching all parent calling frames and explicitly
+ # clearing their warning registries (necessary for the doctests above to
+ # pass). Then, we search for all submodules of skimage and clear theirs
+ # as well (necessary for the skimage test suite to pass).
+
+ frame = inspect.currentframe()
+ if frame:
+ for f in inspect.getouterframes(frame):
+ f[0].f_locals['__warningregistry__'] = {}
+ del frame
+
+ for mod_name, mod in list(sys.modules.items()):
+ try:
+ mod.__warningregistry__.clear()
+ except AttributeError:
+ pass
+
with warnings.catch_warnings(record=True) as w, \
mock.patch.dict(os.environ, {'TRAITLETS_ALL_DEPRECATIONS': '1'}):
- warnings.simplefilter("always")
- yield w
-
-
-@contextmanager
-def expected_warnings(matching):
+ warnings.simplefilter("always")
+ yield w
+
+
+@contextmanager
+def expected_warnings(matching):
r"""Context for use in testing to catch known warnings matching regexes
- Parameters
- ----------
- matching : list of strings or compiled regexes
- Regexes for the desired warning to catch
+ Parameters
+ ----------
+ matching : list of strings or compiled regexes
+ Regexes for the desired warning to catch
- Examples
- --------
- >>> from skimage import data, img_as_ubyte, img_as_float
+ Examples
+ --------
+ >>> from skimage import data, img_as_ubyte, img_as_float
>>> with expected_warnings(["precision loss"]):
- ... d = img_as_ubyte(img_as_float(data.coins()))
+ ... d = img_as_ubyte(img_as_float(data.coins()))
- Notes
- -----
- Uses `all_warnings` to ensure all warnings are raised.
- Upon exiting, it checks the recorded warnings for the desired matching
- pattern(s).
- Raises a ValueError if any match was not found or an unexpected
- warning was raised.
- Allows for three types of behaviors: "and", "or", and "optional" matches.
- This is done to accomodate different build enviroments or loop conditions
- that may produce different warnings. The behaviors can be combined.
- If you pass multiple patterns, you get an orderless "and", where all of the
- warnings must be raised.
- If you use the "|" operator in a pattern, you can catch one of several warnings.
- Finally, you can use "|\A\Z" in a pattern to signify it as optional.
- """
- with all_warnings() as w:
- # enter context
- yield w
- # exited user context, check the recorded warnings
+ Notes
+ -----
+ Uses `all_warnings` to ensure all warnings are raised.
+ Upon exiting, it checks the recorded warnings for the desired matching
+ pattern(s).
+ Raises a ValueError if any match was not found or an unexpected
+ warning was raised.
+ Allows for three types of behaviors: "and", "or", and "optional" matches.
+ This is done to accomodate different build enviroments or loop conditions
+ that may produce different warnings. The behaviors can be combined.
+ If you pass multiple patterns, you get an orderless "and", where all of the
+ warnings must be raised.
+ If you use the "|" operator in a pattern, you can catch one of several warnings.
+ Finally, you can use "|\A\Z" in a pattern to signify it as optional.
+ """
+ with all_warnings() as w:
+ # enter context
+ yield w
+ # exited user context, check the recorded warnings
remaining = [m for m in matching if not r'\A\Z' in m.split('|')]
- for warn in w:
- found = False
- for match in matching:
- if re.search(match, str(warn.message)) is not None:
- found = True
- if match in remaining:
- remaining.remove(match)
- if not found:
- raise ValueError('Unexpected warning: %s' % str(warn.message))
- if len(remaining) > 0:
- msg = 'No warning raised matching:\n%s' % '\n'.join(remaining)
- raise ValueError(msg)
+ for warn in w:
+ found = False
+ for match in matching:
+ if re.search(match, str(warn.message)) is not None:
+ found = True
+ if match in remaining:
+ remaining.remove(match)
+ if not found:
+ raise ValueError('Unexpected warning: %s' % str(warn.message))
+ if len(remaining) > 0:
+ msg = 'No warning raised matching:\n%s' % '\n'.join(remaining)
+ raise ValueError(msg)
diff --git a/contrib/python/traitlets/py3/traitlets/tests/test_traitlets.py b/contrib/python/traitlets/py3/traitlets/tests/test_traitlets.py
index ece95f6108..e42dbc01d0 100644
--- a/contrib/python/traitlets/py3/traitlets/tests/test_traitlets.py
+++ b/contrib/python/traitlets/py3/traitlets/tests/test_traitlets.py
@@ -1,20 +1,20 @@
-# encoding: utf-8
-"""Tests for traitlets.traitlets."""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
+# encoding: utf-8
+"""Tests for traitlets.traitlets."""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
#
-# Adapted from enthought.traits, Copyright (c) Enthought, Inc.,
-# also under the terms of the Modified BSD License.
-
-import pickle
-import re
+# Adapted from enthought.traits, Copyright (c) Enthought, Inc.,
+# also under the terms of the Modified BSD License.
+
+import pickle
+import re
from unittest import TestCase
-
-import pytest
-
+
+import pytest
+
from traitlets.tests._warnings import expected_warnings
-from traitlets import (
+from traitlets import (
HasTraits,
MetaHasTraits,
TraitType,
@@ -60,121 +60,121 @@ from traitlets import (
BaseDescriptor,
HasDescriptors,
CUnicode,
-)
+)
from traitlets.utils import cast_unicode
-
-
-def change_dict(*ordered_values):
- change_names = ('name', 'old', 'new', 'owner', 'type')
- return dict(zip(change_names, ordered_values))
-
-#-----------------------------------------------------------------------------
-# Helper classes for testing
-#-----------------------------------------------------------------------------
-
-
-class HasTraitsStub(HasTraits):
-
- def notify_change(self, change):
- self._notify_name = change['name']
- self._notify_old = change['old']
- self._notify_new = change['new']
- self._notify_type = change['type']
-
-
-#-----------------------------------------------------------------------------
-# Test classes
-#-----------------------------------------------------------------------------
-
-
-class TestTraitType(TestCase):
-
- def test_get_undefined(self):
- class A(HasTraits):
- a = TraitType
- a = A()
+
+
+def change_dict(*ordered_values):
+ change_names = ('name', 'old', 'new', 'owner', 'type')
+ return dict(zip(change_names, ordered_values))
+
+#-----------------------------------------------------------------------------
+# Helper classes for testing
+#-----------------------------------------------------------------------------
+
+
+class HasTraitsStub(HasTraits):
+
+ def notify_change(self, change):
+ self._notify_name = change['name']
+ self._notify_old = change['old']
+ self._notify_new = change['new']
+ self._notify_type = change['type']
+
+
+#-----------------------------------------------------------------------------
+# Test classes
+#-----------------------------------------------------------------------------
+
+
+class TestTraitType(TestCase):
+
+ def test_get_undefined(self):
+ class A(HasTraits):
+ a = TraitType
+ a = A()
assert a.a is Undefined
-
- def test_set(self):
- class A(HasTraitsStub):
- a = TraitType
-
- a = A()
- a.a = 10
- self.assertEqual(a.a, 10)
- self.assertEqual(a._notify_name, 'a')
- self.assertEqual(a._notify_old, Undefined)
- self.assertEqual(a._notify_new, 10)
-
- def test_validate(self):
- class MyTT(TraitType):
- def validate(self, inst, value):
- return -1
- class A(HasTraitsStub):
- tt = MyTT
-
- a = A()
- a.tt = 10
- self.assertEqual(a.tt, -1)
-
- def test_default_validate(self):
- class MyIntTT(TraitType):
- def validate(self, obj, value):
- if isinstance(value, int):
- return value
- self.error(obj, value)
- class A(HasTraits):
- tt = MyIntTT(10)
- a = A()
- self.assertEqual(a.tt, 10)
-
- # Defaults are validated when the HasTraits is instantiated
- class B(HasTraits):
- tt = MyIntTT('bad default')
+
+ def test_set(self):
+ class A(HasTraitsStub):
+ a = TraitType
+
+ a = A()
+ a.a = 10
+ self.assertEqual(a.a, 10)
+ self.assertEqual(a._notify_name, 'a')
+ self.assertEqual(a._notify_old, Undefined)
+ self.assertEqual(a._notify_new, 10)
+
+ def test_validate(self):
+ class MyTT(TraitType):
+ def validate(self, inst, value):
+ return -1
+ class A(HasTraitsStub):
+ tt = MyTT
+
+ a = A()
+ a.tt = 10
+ self.assertEqual(a.tt, -1)
+
+ def test_default_validate(self):
+ class MyIntTT(TraitType):
+ def validate(self, obj, value):
+ if isinstance(value, int):
+ return value
+ self.error(obj, value)
+ class A(HasTraits):
+ tt = MyIntTT(10)
+ a = A()
+ self.assertEqual(a.tt, 10)
+
+ # Defaults are validated when the HasTraits is instantiated
+ class B(HasTraits):
+ tt = MyIntTT('bad default')
self.assertRaises(TraitError, getattr, B(), 'tt')
-
- def test_info(self):
- class A(HasTraits):
- tt = TraitType
- a = A()
- self.assertEqual(A.tt.info(), 'any value')
-
- def test_error(self):
- class A(HasTraits):
+
+ def test_info(self):
+ class A(HasTraits):
+ tt = TraitType
+ a = A()
+ self.assertEqual(A.tt.info(), 'any value')
+
+ def test_error(self):
+ class A(HasTraits):
tt = TraitType()
- a = A()
- self.assertRaises(TraitError, A.tt.error, a, 10)
-
- def test_deprecated_dynamic_initializer(self):
- class A(HasTraits):
- x = Int(10)
- def _x_default(self):
- return 11
- class B(A):
- x = Int(20)
- class C(A):
- def _x_default(self):
- return 21
-
- a = A()
- self.assertEqual(a._trait_values, {})
- self.assertEqual(a.x, 11)
- self.assertEqual(a._trait_values, {'x': 11})
- b = B()
- self.assertEqual(b.x, 20)
- self.assertEqual(b._trait_values, {'x': 20})
- c = C()
- self.assertEqual(c._trait_values, {})
- self.assertEqual(c.x, 21)
- self.assertEqual(c._trait_values, {'x': 21})
- # Ensure that the base class remains unmolested when the _default
- # initializer gets overridden in a subclass.
- a = A()
- c = C()
- self.assertEqual(a._trait_values, {})
- self.assertEqual(a.x, 11)
- self.assertEqual(a._trait_values, {'x': 11})
-
+ a = A()
+ self.assertRaises(TraitError, A.tt.error, a, 10)
+
+ def test_deprecated_dynamic_initializer(self):
+ class A(HasTraits):
+ x = Int(10)
+ def _x_default(self):
+ return 11
+ class B(A):
+ x = Int(20)
+ class C(A):
+ def _x_default(self):
+ return 21
+
+ a = A()
+ self.assertEqual(a._trait_values, {})
+ self.assertEqual(a.x, 11)
+ self.assertEqual(a._trait_values, {'x': 11})
+ b = B()
+ self.assertEqual(b.x, 20)
+ self.assertEqual(b._trait_values, {'x': 20})
+ c = C()
+ self.assertEqual(c._trait_values, {})
+ self.assertEqual(c.x, 21)
+ self.assertEqual(c._trait_values, {'x': 21})
+ # Ensure that the base class remains unmolested when the _default
+ # initializer gets overridden in a subclass.
+ a = A()
+ c = C()
+ self.assertEqual(a._trait_values, {})
+ self.assertEqual(a.x, 11)
+ self.assertEqual(a._trait_values, {'x': 11})
+
def test_deprecated_method_warnings(self):
with expected_warnings([]):
@@ -215,79 +215,79 @@ class TestTraitType(TestCase):
assert obj.x == 5
- def test_dynamic_initializer(self):
-
- class A(HasTraits):
- x = Int(10)
-
- @default('x')
- def _default_x(self):
- return 11
-
- class B(A):
- x = Int(20)
-
- class C(A):
-
- @default('x')
- def _default_x(self):
- return 21
-
- a = A()
- self.assertEqual(a._trait_values, {})
- self.assertEqual(a.x, 11)
- self.assertEqual(a._trait_values, {'x': 11})
- b = B()
- self.assertEqual(b.x, 20)
- self.assertEqual(b._trait_values, {'x': 20})
- c = C()
- self.assertEqual(c._trait_values, {})
- self.assertEqual(c.x, 21)
- self.assertEqual(c._trait_values, {'x': 21})
- # Ensure that the base class remains unmolested when the _default
- # initializer gets overridden in a subclass.
- a = A()
- c = C()
- self.assertEqual(a._trait_values, {})
- self.assertEqual(a.x, 11)
- self.assertEqual(a._trait_values, {'x': 11})
-
- def test_tag_metadata(self):
- class MyIntTT(TraitType):
- metadata = {'a': 1, 'b': 2}
- a = MyIntTT(10).tag(b=3, c=4)
- self.assertEqual(a.metadata, {'a': 1, 'b': 3, 'c': 4})
-
- def test_metadata_localized_instance(self):
- class MyIntTT(TraitType):
- metadata = {'a': 1, 'b': 2}
- a = MyIntTT(10)
- b = MyIntTT(10)
- a.metadata['c'] = 3
- # make sure that changing a's metadata didn't change b's metadata
- self.assertNotIn('c', b.metadata)
-
- def test_union_metadata(self):
- class Foo(HasTraits):
- bar = (Int().tag(ta=1) | Dict().tag(ta=2, ti='b')).tag(ti='a')
- foo = Foo()
- # At this point, no value has been set for bar, so value-specific
- # is not set.
- self.assertEqual(foo.trait_metadata('bar', 'ta'), None)
- self.assertEqual(foo.trait_metadata('bar', 'ti'), 'a')
- foo.bar = {}
- self.assertEqual(foo.trait_metadata('bar', 'ta'), 2)
- self.assertEqual(foo.trait_metadata('bar', 'ti'), 'b')
- foo.bar = 1
- self.assertEqual(foo.trait_metadata('bar', 'ta'), 1)
- self.assertEqual(foo.trait_metadata('bar', 'ti'), 'a')
-
- def test_union_default_value(self):
- class Foo(HasTraits):
- bar = Union([Dict(), Int()], default_value=1)
- foo = Foo()
- self.assertEqual(foo.bar, 1)
-
+ def test_dynamic_initializer(self):
+
+ class A(HasTraits):
+ x = Int(10)
+
+ @default('x')
+ def _default_x(self):
+ return 11
+
+ class B(A):
+ x = Int(20)
+
+ class C(A):
+
+ @default('x')
+ def _default_x(self):
+ return 21
+
+ a = A()
+ self.assertEqual(a._trait_values, {})
+ self.assertEqual(a.x, 11)
+ self.assertEqual(a._trait_values, {'x': 11})
+ b = B()
+ self.assertEqual(b.x, 20)
+ self.assertEqual(b._trait_values, {'x': 20})
+ c = C()
+ self.assertEqual(c._trait_values, {})
+ self.assertEqual(c.x, 21)
+ self.assertEqual(c._trait_values, {'x': 21})
+ # Ensure that the base class remains unmolested when the _default
+ # initializer gets overridden in a subclass.
+ a = A()
+ c = C()
+ self.assertEqual(a._trait_values, {})
+ self.assertEqual(a.x, 11)
+ self.assertEqual(a._trait_values, {'x': 11})
+
+ def test_tag_metadata(self):
+ class MyIntTT(TraitType):
+ metadata = {'a': 1, 'b': 2}
+ a = MyIntTT(10).tag(b=3, c=4)
+ self.assertEqual(a.metadata, {'a': 1, 'b': 3, 'c': 4})
+
+ def test_metadata_localized_instance(self):
+ class MyIntTT(TraitType):
+ metadata = {'a': 1, 'b': 2}
+ a = MyIntTT(10)
+ b = MyIntTT(10)
+ a.metadata['c'] = 3
+ # make sure that changing a's metadata didn't change b's metadata
+ self.assertNotIn('c', b.metadata)
+
+ def test_union_metadata(self):
+ class Foo(HasTraits):
+ bar = (Int().tag(ta=1) | Dict().tag(ta=2, ti='b')).tag(ti='a')
+ foo = Foo()
+ # At this point, no value has been set for bar, so value-specific
+ # is not set.
+ self.assertEqual(foo.trait_metadata('bar', 'ta'), None)
+ self.assertEqual(foo.trait_metadata('bar', 'ti'), 'a')
+ foo.bar = {}
+ self.assertEqual(foo.trait_metadata('bar', 'ta'), 2)
+ self.assertEqual(foo.trait_metadata('bar', 'ti'), 'b')
+ foo.bar = 1
+ self.assertEqual(foo.trait_metadata('bar', 'ta'), 1)
+ self.assertEqual(foo.trait_metadata('bar', 'ti'), 'a')
+
+ def test_union_default_value(self):
+ class Foo(HasTraits):
+ bar = Union([Dict(), Int()], default_value=1)
+ foo = Foo()
+ self.assertEqual(foo.bar, 1)
+
def test_union_validation_priority(self):
class Foo(HasTraits):
bar = Union([CInt(), Unicode()])
@@ -301,506 +301,506 @@ class TestTraitType(TestCase):
bar = Union([Dict(), Int()])
self.assertEqual(Foo().bar, {})
- def test_deprecated_metadata_access(self):
- class MyIntTT(TraitType):
- metadata = {'a': 1, 'b': 2}
- a = MyIntTT(10)
- with expected_warnings(["use the instance .metadata dictionary directly"]*2):
- a.set_metadata('key', 'value')
- v = a.get_metadata('key')
- self.assertEqual(v, 'value')
- with expected_warnings(["use the instance .help string directly"]*2):
- a.set_metadata('help', 'some help')
- v = a.get_metadata('help')
- self.assertEqual(v, 'some help')
-
- def test_trait_types_deprecated(self):
- with expected_warnings(["Traits should be given as instances"]):
- class C(HasTraits):
- t = Int
-
- def test_trait_types_list_deprecated(self):
- with expected_warnings(["Traits should be given as instances"]):
- class C(HasTraits):
- t = List(Int)
-
- def test_trait_types_tuple_deprecated(self):
- with expected_warnings(["Traits should be given as instances"]):
- class C(HasTraits):
- t = Tuple(Int)
-
- def test_trait_types_dict_deprecated(self):
- with expected_warnings(["Traits should be given as instances"]):
- class C(HasTraits):
- t = Dict(Int)
-
-class TestHasDescriptorsMeta(TestCase):
-
- def test_metaclass(self):
- self.assertEqual(type(HasTraits), MetaHasTraits)
-
- class A(HasTraits):
- a = Int()
-
- a = A()
- self.assertEqual(type(a.__class__), MetaHasTraits)
- self.assertEqual(a.a,0)
- a.a = 10
- self.assertEqual(a.a,10)
-
- class B(HasTraits):
- b = Int()
-
- b = B()
- self.assertEqual(b.b,0)
- b.b = 10
- self.assertEqual(b.b,10)
-
- class C(HasTraits):
- c = Int(30)
-
- c = C()
- self.assertEqual(c.c,30)
- c.c = 10
- self.assertEqual(c.c,10)
-
- def test_this_class(self):
- class A(HasTraits):
- t = This()
- tt = This()
- class B(A):
- tt = This()
- ttt = This()
- self.assertEqual(A.t.this_class, A)
- self.assertEqual(B.t.this_class, A)
- self.assertEqual(B.tt.this_class, B)
- self.assertEqual(B.ttt.this_class, B)
-
-class TestHasDescriptors(TestCase):
-
- def test_setup_instance(self):
-
- class FooDescriptor(BaseDescriptor):
-
- def instance_init(self, inst):
- foo = inst.foo # instance should have the attr
-
- class HasFooDescriptors(HasDescriptors):
-
- fd = FooDescriptor()
-
- def setup_instance(self, *args, **kwargs):
- self.foo = kwargs.get('foo', None)
- super(HasFooDescriptors, self).setup_instance(*args, **kwargs)
-
- hfd = HasFooDescriptors(foo='bar')
-
-class TestHasTraitsNotify(TestCase):
-
- def setUp(self):
- self._notify1 = []
- self._notify2 = []
-
- def notify1(self, name, old, new):
- self._notify1.append((name, old, new))
-
- def notify2(self, name, old, new):
- self._notify2.append((name, old, new))
-
- def test_notify_all(self):
-
- class A(HasTraits):
- a = Int()
- b = Float()
-
- a = A()
- a.on_trait_change(self.notify1)
- a.a = 0
- self.assertEqual(len(self._notify1),0)
- a.b = 0.0
- self.assertEqual(len(self._notify1),0)
- a.a = 10
- self.assertTrue(('a',0,10) in self._notify1)
- a.b = 10.0
- self.assertTrue(('b',0.0,10.0) in self._notify1)
- self.assertRaises(TraitError,setattr,a,'a','bad string')
- self.assertRaises(TraitError,setattr,a,'b','bad string')
- self._notify1 = []
- a.on_trait_change(self.notify1,remove=True)
- a.a = 20
- a.b = 20.0
- self.assertEqual(len(self._notify1),0)
-
- def test_notify_one(self):
-
- class A(HasTraits):
- a = Int()
- b = Float()
-
- a = A()
- a.on_trait_change(self.notify1, 'a')
- a.a = 0
- self.assertEqual(len(self._notify1),0)
- a.a = 10
- self.assertTrue(('a',0,10) in self._notify1)
- self.assertRaises(TraitError,setattr,a,'a','bad string')
-
- def test_subclass(self):
-
- class A(HasTraits):
- a = Int()
-
- class B(A):
- b = Float()
-
- b = B()
- self.assertEqual(b.a,0)
- self.assertEqual(b.b,0.0)
- b.a = 100
- b.b = 100.0
- self.assertEqual(b.a,100)
- self.assertEqual(b.b,100.0)
-
- def test_notify_subclass(self):
-
- class A(HasTraits):
- a = Int()
-
- class B(A):
- b = Float()
-
- b = B()
- b.on_trait_change(self.notify1, 'a')
- b.on_trait_change(self.notify2, 'b')
- b.a = 0
- b.b = 0.0
- self.assertEqual(len(self._notify1),0)
- self.assertEqual(len(self._notify2),0)
- b.a = 10
- b.b = 10.0
- self.assertTrue(('a',0,10) in self._notify1)
- self.assertTrue(('b',0.0,10.0) in self._notify2)
-
- def test_static_notify(self):
-
- class A(HasTraits):
- a = Int()
- _notify1 = []
- def _a_changed(self, name, old, new):
- self._notify1.append((name, old, new))
-
- a = A()
- a.a = 0
- # This is broken!!!
- self.assertEqual(len(a._notify1),0)
- a.a = 10
- self.assertTrue(('a',0,10) in a._notify1)
-
- class B(A):
- b = Float()
- _notify2 = []
- def _b_changed(self, name, old, new):
- self._notify2.append((name, old, new))
-
- b = B()
- b.a = 10
- b.b = 10.0
- self.assertTrue(('a',0,10) in b._notify1)
- self.assertTrue(('b',0.0,10.0) in b._notify2)
-
- def test_notify_args(self):
-
- def callback0():
- self.cb = ()
- def callback1(name):
- self.cb = (name,)
- def callback2(name, new):
- self.cb = (name, new)
- def callback3(name, old, new):
- self.cb = (name, old, new)
- def callback4(name, old, new, obj):
- self.cb = (name, old, new, obj)
-
- class A(HasTraits):
- a = Int()
-
- a = A()
- a.on_trait_change(callback0, 'a')
- a.a = 10
- self.assertEqual(self.cb,())
- a.on_trait_change(callback0, 'a', remove=True)
-
- a.on_trait_change(callback1, 'a')
- a.a = 100
- self.assertEqual(self.cb,('a',))
- a.on_trait_change(callback1, 'a', remove=True)
-
- a.on_trait_change(callback2, 'a')
- a.a = 1000
- self.assertEqual(self.cb,('a',1000))
- a.on_trait_change(callback2, 'a', remove=True)
-
- a.on_trait_change(callback3, 'a')
- a.a = 10000
- self.assertEqual(self.cb,('a',1000,10000))
- a.on_trait_change(callback3, 'a', remove=True)
-
- a.on_trait_change(callback4, 'a')
- a.a = 100000
- self.assertEqual(self.cb,('a',10000,100000,a))
- self.assertEqual(len(a._trait_notifiers['a']['change']), 1)
- a.on_trait_change(callback4, 'a', remove=True)
-
- self.assertEqual(len(a._trait_notifiers['a']['change']), 0)
-
- def test_notify_only_once(self):
-
- class A(HasTraits):
- listen_to = ['a']
-
- a = Int(0)
- b = 0
-
- def __init__(self, **kwargs):
- super(A, self).__init__(**kwargs)
- self.on_trait_change(self.listener1, ['a'])
-
- def listener1(self, name, old, new):
- self.b += 1
-
- class B(A):
-
- c = 0
- d = 0
-
- def __init__(self, **kwargs):
- super(B, self).__init__(**kwargs)
- self.on_trait_change(self.listener2)
-
- def listener2(self, name, old, new):
- self.c += 1
-
- def _a_changed(self, name, old, new):
- self.d += 1
-
- b = B()
- b.a += 1
- self.assertEqual(b.b, b.c)
- self.assertEqual(b.b, b.d)
- b.a += 1
- self.assertEqual(b.b, b.c)
- self.assertEqual(b.b, b.d)
-
-class TestObserveDecorator(TestCase):
-
- def setUp(self):
- self._notify1 = []
- self._notify2 = []
-
- def notify1(self, change):
- self._notify1.append(change)
-
- def notify2(self, change):
- self._notify2.append(change)
-
- def test_notify_all(self):
-
- class A(HasTraits):
- a = Int()
- b = Float()
-
- a = A()
- a.observe(self.notify1)
- a.a = 0
- self.assertEqual(len(self._notify1),0)
- a.b = 0.0
- self.assertEqual(len(self._notify1),0)
- a.a = 10
- change = change_dict('a', 0, 10, a, 'change')
- self.assertTrue(change in self._notify1)
- a.b = 10.0
- change = change_dict('b', 0.0, 10.0, a, 'change')
- self.assertTrue(change in self._notify1)
- self.assertRaises(TraitError,setattr,a,'a','bad string')
- self.assertRaises(TraitError,setattr,a,'b','bad string')
- self._notify1 = []
- a.unobserve(self.notify1)
- a.a = 20
- a.b = 20.0
- self.assertEqual(len(self._notify1),0)
-
- def test_notify_one(self):
-
- class A(HasTraits):
- a = Int()
- b = Float()
-
- a = A()
- a.observe(self.notify1, 'a')
- a.a = 0
- self.assertEqual(len(self._notify1),0)
- a.a = 10
- change = change_dict('a', 0, 10, a, 'change')
- self.assertTrue(change in self._notify1)
- self.assertRaises(TraitError,setattr,a,'a','bad string')
-
- def test_subclass(self):
-
- class A(HasTraits):
- a = Int()
-
- class B(A):
- b = Float()
-
- b = B()
- self.assertEqual(b.a,0)
- self.assertEqual(b.b,0.0)
- b.a = 100
- b.b = 100.0
- self.assertEqual(b.a,100)
- self.assertEqual(b.b,100.0)
-
- def test_notify_subclass(self):
-
- class A(HasTraits):
- a = Int()
-
- class B(A):
- b = Float()
-
- b = B()
- b.observe(self.notify1, 'a')
- b.observe(self.notify2, 'b')
- b.a = 0
- b.b = 0.0
- self.assertEqual(len(self._notify1),0)
- self.assertEqual(len(self._notify2),0)
- b.a = 10
- b.b = 10.0
- change = change_dict('a', 0, 10, b, 'change')
- self.assertTrue(change in self._notify1)
- change = change_dict('b', 0.0, 10.0, b, 'change')
- self.assertTrue(change in self._notify2)
-
- def test_static_notify(self):
-
- class A(HasTraits):
- a = Int()
- b = Int()
- _notify1 = []
- _notify_any = []
-
- @observe('a')
- def _a_changed(self, change):
- self._notify1.append(change)
-
- @observe(All)
- def _any_changed(self, change):
- self._notify_any.append(change)
-
- a = A()
- a.a = 0
- self.assertEqual(len(a._notify1),0)
- a.a = 10
- change = change_dict('a', 0, 10, a, 'change')
- self.assertTrue(change in a._notify1)
- a.b = 1
- self.assertEqual(len(a._notify_any), 2)
- change = change_dict('b', 0, 1, a, 'change')
- self.assertTrue(change in a._notify_any)
-
- class B(A):
- b = Float()
- _notify2 = []
- @observe('b')
- def _b_changed(self, change):
- self._notify2.append(change)
-
- b = B()
- b.a = 10
- b.b = 10.0
- change = change_dict('a', 0, 10, b, 'change')
- self.assertTrue(change in b._notify1)
- change = change_dict('b', 0.0, 10.0, b, 'change')
- self.assertTrue(change in b._notify2)
-
- def test_notify_args(self):
-
- def callback0():
- self.cb = ()
- def callback1(change):
- self.cb = change
-
- class A(HasTraits):
- a = Int()
-
- a = A()
- a.on_trait_change(callback0, 'a')
- a.a = 10
- self.assertEqual(self.cb,())
- a.unobserve(callback0, 'a')
-
- a.observe(callback1, 'a')
- a.a = 100
- change = change_dict('a', 10, 100, a, 'change')
- self.assertEqual(self.cb, change)
- self.assertEqual(len(a._trait_notifiers['a']['change']), 1)
- a.unobserve(callback1, 'a')
-
- self.assertEqual(len(a._trait_notifiers['a']['change']), 0)
-
- def test_notify_only_once(self):
-
- class A(HasTraits):
- listen_to = ['a']
-
- a = Int(0)
- b = 0
-
- def __init__(self, **kwargs):
- super(A, self).__init__(**kwargs)
- self.observe(self.listener1, ['a'])
-
- def listener1(self, change):
- self.b += 1
-
- class B(A):
-
- c = 0
- d = 0
-
- def __init__(self, **kwargs):
- super(B, self).__init__(**kwargs)
- self.observe(self.listener2)
-
- def listener2(self, change):
- self.c += 1
-
- @observe('a')
- def _a_changed(self, change):
- self.d += 1
-
- b = B()
- b.a += 1
- self.assertEqual(b.b, b.c)
- self.assertEqual(b.b, b.d)
- b.a += 1
- self.assertEqual(b.b, b.c)
- self.assertEqual(b.b, b.d)
-
-
-class TestHasTraits(TestCase):
-
- def test_trait_names(self):
- class A(HasTraits):
- i = Int()
- f = Float()
- a = A()
- self.assertEqual(sorted(a.trait_names()),['f','i'])
- self.assertEqual(sorted(A.class_trait_names()),['f','i'])
- self.assertTrue(a.has_trait('f'))
- self.assertFalse(a.has_trait('g'))
-
+ def test_deprecated_metadata_access(self):
+ class MyIntTT(TraitType):
+ metadata = {'a': 1, 'b': 2}
+ a = MyIntTT(10)
+ with expected_warnings(["use the instance .metadata dictionary directly"]*2):
+ a.set_metadata('key', 'value')
+ v = a.get_metadata('key')
+ self.assertEqual(v, 'value')
+ with expected_warnings(["use the instance .help string directly"]*2):
+ a.set_metadata('help', 'some help')
+ v = a.get_metadata('help')
+ self.assertEqual(v, 'some help')
+
+ def test_trait_types_deprecated(self):
+ with expected_warnings(["Traits should be given as instances"]):
+ class C(HasTraits):
+ t = Int
+
+ def test_trait_types_list_deprecated(self):
+ with expected_warnings(["Traits should be given as instances"]):
+ class C(HasTraits):
+ t = List(Int)
+
+ def test_trait_types_tuple_deprecated(self):
+ with expected_warnings(["Traits should be given as instances"]):
+ class C(HasTraits):
+ t = Tuple(Int)
+
+ def test_trait_types_dict_deprecated(self):
+ with expected_warnings(["Traits should be given as instances"]):
+ class C(HasTraits):
+ t = Dict(Int)
+
+class TestHasDescriptorsMeta(TestCase):
+
+ def test_metaclass(self):
+ self.assertEqual(type(HasTraits), MetaHasTraits)
+
+ class A(HasTraits):
+ a = Int()
+
+ a = A()
+ self.assertEqual(type(a.__class__), MetaHasTraits)
+ self.assertEqual(a.a,0)
+ a.a = 10
+ self.assertEqual(a.a,10)
+
+ class B(HasTraits):
+ b = Int()
+
+ b = B()
+ self.assertEqual(b.b,0)
+ b.b = 10
+ self.assertEqual(b.b,10)
+
+ class C(HasTraits):
+ c = Int(30)
+
+ c = C()
+ self.assertEqual(c.c,30)
+ c.c = 10
+ self.assertEqual(c.c,10)
+
+ def test_this_class(self):
+ class A(HasTraits):
+ t = This()
+ tt = This()
+ class B(A):
+ tt = This()
+ ttt = This()
+ self.assertEqual(A.t.this_class, A)
+ self.assertEqual(B.t.this_class, A)
+ self.assertEqual(B.tt.this_class, B)
+ self.assertEqual(B.ttt.this_class, B)
+
+class TestHasDescriptors(TestCase):
+
+ def test_setup_instance(self):
+
+ class FooDescriptor(BaseDescriptor):
+
+ def instance_init(self, inst):
+ foo = inst.foo # instance should have the attr
+
+ class HasFooDescriptors(HasDescriptors):
+
+ fd = FooDescriptor()
+
+ def setup_instance(self, *args, **kwargs):
+ self.foo = kwargs.get('foo', None)
+ super(HasFooDescriptors, self).setup_instance(*args, **kwargs)
+
+ hfd = HasFooDescriptors(foo='bar')
+
+class TestHasTraitsNotify(TestCase):
+
+ def setUp(self):
+ self._notify1 = []
+ self._notify2 = []
+
+ def notify1(self, name, old, new):
+ self._notify1.append((name, old, new))
+
+ def notify2(self, name, old, new):
+ self._notify2.append((name, old, new))
+
+ def test_notify_all(self):
+
+ class A(HasTraits):
+ a = Int()
+ b = Float()
+
+ a = A()
+ a.on_trait_change(self.notify1)
+ a.a = 0
+ self.assertEqual(len(self._notify1),0)
+ a.b = 0.0
+ self.assertEqual(len(self._notify1),0)
+ a.a = 10
+ self.assertTrue(('a',0,10) in self._notify1)
+ a.b = 10.0
+ self.assertTrue(('b',0.0,10.0) in self._notify1)
+ self.assertRaises(TraitError,setattr,a,'a','bad string')
+ self.assertRaises(TraitError,setattr,a,'b','bad string')
+ self._notify1 = []
+ a.on_trait_change(self.notify1,remove=True)
+ a.a = 20
+ a.b = 20.0
+ self.assertEqual(len(self._notify1),0)
+
+ def test_notify_one(self):
+
+ class A(HasTraits):
+ a = Int()
+ b = Float()
+
+ a = A()
+ a.on_trait_change(self.notify1, 'a')
+ a.a = 0
+ self.assertEqual(len(self._notify1),0)
+ a.a = 10
+ self.assertTrue(('a',0,10) in self._notify1)
+ self.assertRaises(TraitError,setattr,a,'a','bad string')
+
+ def test_subclass(self):
+
+ class A(HasTraits):
+ a = Int()
+
+ class B(A):
+ b = Float()
+
+ b = B()
+ self.assertEqual(b.a,0)
+ self.assertEqual(b.b,0.0)
+ b.a = 100
+ b.b = 100.0
+ self.assertEqual(b.a,100)
+ self.assertEqual(b.b,100.0)
+
+ def test_notify_subclass(self):
+
+ class A(HasTraits):
+ a = Int()
+
+ class B(A):
+ b = Float()
+
+ b = B()
+ b.on_trait_change(self.notify1, 'a')
+ b.on_trait_change(self.notify2, 'b')
+ b.a = 0
+ b.b = 0.0
+ self.assertEqual(len(self._notify1),0)
+ self.assertEqual(len(self._notify2),0)
+ b.a = 10
+ b.b = 10.0
+ self.assertTrue(('a',0,10) in self._notify1)
+ self.assertTrue(('b',0.0,10.0) in self._notify2)
+
+ def test_static_notify(self):
+
+ class A(HasTraits):
+ a = Int()
+ _notify1 = []
+ def _a_changed(self, name, old, new):
+ self._notify1.append((name, old, new))
+
+ a = A()
+ a.a = 0
+ # This is broken!!!
+ self.assertEqual(len(a._notify1),0)
+ a.a = 10
+ self.assertTrue(('a',0,10) in a._notify1)
+
+ class B(A):
+ b = Float()
+ _notify2 = []
+ def _b_changed(self, name, old, new):
+ self._notify2.append((name, old, new))
+
+ b = B()
+ b.a = 10
+ b.b = 10.0
+ self.assertTrue(('a',0,10) in b._notify1)
+ self.assertTrue(('b',0.0,10.0) in b._notify2)
+
+ def test_notify_args(self):
+
+ def callback0():
+ self.cb = ()
+ def callback1(name):
+ self.cb = (name,)
+ def callback2(name, new):
+ self.cb = (name, new)
+ def callback3(name, old, new):
+ self.cb = (name, old, new)
+ def callback4(name, old, new, obj):
+ self.cb = (name, old, new, obj)
+
+ class A(HasTraits):
+ a = Int()
+
+ a = A()
+ a.on_trait_change(callback0, 'a')
+ a.a = 10
+ self.assertEqual(self.cb,())
+ a.on_trait_change(callback0, 'a', remove=True)
+
+ a.on_trait_change(callback1, 'a')
+ a.a = 100
+ self.assertEqual(self.cb,('a',))
+ a.on_trait_change(callback1, 'a', remove=True)
+
+ a.on_trait_change(callback2, 'a')
+ a.a = 1000
+ self.assertEqual(self.cb,('a',1000))
+ a.on_trait_change(callback2, 'a', remove=True)
+
+ a.on_trait_change(callback3, 'a')
+ a.a = 10000
+ self.assertEqual(self.cb,('a',1000,10000))
+ a.on_trait_change(callback3, 'a', remove=True)
+
+ a.on_trait_change(callback4, 'a')
+ a.a = 100000
+ self.assertEqual(self.cb,('a',10000,100000,a))
+ self.assertEqual(len(a._trait_notifiers['a']['change']), 1)
+ a.on_trait_change(callback4, 'a', remove=True)
+
+ self.assertEqual(len(a._trait_notifiers['a']['change']), 0)
+
+ def test_notify_only_once(self):
+
+ class A(HasTraits):
+ listen_to = ['a']
+
+ a = Int(0)
+ b = 0
+
+ def __init__(self, **kwargs):
+ super(A, self).__init__(**kwargs)
+ self.on_trait_change(self.listener1, ['a'])
+
+ def listener1(self, name, old, new):
+ self.b += 1
+
+ class B(A):
+
+ c = 0
+ d = 0
+
+ def __init__(self, **kwargs):
+ super(B, self).__init__(**kwargs)
+ self.on_trait_change(self.listener2)
+
+ def listener2(self, name, old, new):
+ self.c += 1
+
+ def _a_changed(self, name, old, new):
+ self.d += 1
+
+ b = B()
+ b.a += 1
+ self.assertEqual(b.b, b.c)
+ self.assertEqual(b.b, b.d)
+ b.a += 1
+ self.assertEqual(b.b, b.c)
+ self.assertEqual(b.b, b.d)
+
+class TestObserveDecorator(TestCase):
+
+ def setUp(self):
+ self._notify1 = []
+ self._notify2 = []
+
+ def notify1(self, change):
+ self._notify1.append(change)
+
+ def notify2(self, change):
+ self._notify2.append(change)
+
+ def test_notify_all(self):
+
+ class A(HasTraits):
+ a = Int()
+ b = Float()
+
+ a = A()
+ a.observe(self.notify1)
+ a.a = 0
+ self.assertEqual(len(self._notify1),0)
+ a.b = 0.0
+ self.assertEqual(len(self._notify1),0)
+ a.a = 10
+ change = change_dict('a', 0, 10, a, 'change')
+ self.assertTrue(change in self._notify1)
+ a.b = 10.0
+ change = change_dict('b', 0.0, 10.0, a, 'change')
+ self.assertTrue(change in self._notify1)
+ self.assertRaises(TraitError,setattr,a,'a','bad string')
+ self.assertRaises(TraitError,setattr,a,'b','bad string')
+ self._notify1 = []
+ a.unobserve(self.notify1)
+ a.a = 20
+ a.b = 20.0
+ self.assertEqual(len(self._notify1),0)
+
+ def test_notify_one(self):
+
+ class A(HasTraits):
+ a = Int()
+ b = Float()
+
+ a = A()
+ a.observe(self.notify1, 'a')
+ a.a = 0
+ self.assertEqual(len(self._notify1),0)
+ a.a = 10
+ change = change_dict('a', 0, 10, a, 'change')
+ self.assertTrue(change in self._notify1)
+ self.assertRaises(TraitError,setattr,a,'a','bad string')
+
+ def test_subclass(self):
+
+ class A(HasTraits):
+ a = Int()
+
+ class B(A):
+ b = Float()
+
+ b = B()
+ self.assertEqual(b.a,0)
+ self.assertEqual(b.b,0.0)
+ b.a = 100
+ b.b = 100.0
+ self.assertEqual(b.a,100)
+ self.assertEqual(b.b,100.0)
+
+ def test_notify_subclass(self):
+
+ class A(HasTraits):
+ a = Int()
+
+ class B(A):
+ b = Float()
+
+ b = B()
+ b.observe(self.notify1, 'a')
+ b.observe(self.notify2, 'b')
+ b.a = 0
+ b.b = 0.0
+ self.assertEqual(len(self._notify1),0)
+ self.assertEqual(len(self._notify2),0)
+ b.a = 10
+ b.b = 10.0
+ change = change_dict('a', 0, 10, b, 'change')
+ self.assertTrue(change in self._notify1)
+ change = change_dict('b', 0.0, 10.0, b, 'change')
+ self.assertTrue(change in self._notify2)
+
+ def test_static_notify(self):
+
+ class A(HasTraits):
+ a = Int()
+ b = Int()
+ _notify1 = []
+ _notify_any = []
+
+ @observe('a')
+ def _a_changed(self, change):
+ self._notify1.append(change)
+
+ @observe(All)
+ def _any_changed(self, change):
+ self._notify_any.append(change)
+
+ a = A()
+ a.a = 0
+ self.assertEqual(len(a._notify1),0)
+ a.a = 10
+ change = change_dict('a', 0, 10, a, 'change')
+ self.assertTrue(change in a._notify1)
+ a.b = 1
+ self.assertEqual(len(a._notify_any), 2)
+ change = change_dict('b', 0, 1, a, 'change')
+ self.assertTrue(change in a._notify_any)
+
+ class B(A):
+ b = Float()
+ _notify2 = []
+ @observe('b')
+ def _b_changed(self, change):
+ self._notify2.append(change)
+
+ b = B()
+ b.a = 10
+ b.b = 10.0
+ change = change_dict('a', 0, 10, b, 'change')
+ self.assertTrue(change in b._notify1)
+ change = change_dict('b', 0.0, 10.0, b, 'change')
+ self.assertTrue(change in b._notify2)
+
+ def test_notify_args(self):
+
+ def callback0():
+ self.cb = ()
+ def callback1(change):
+ self.cb = change
+
+ class A(HasTraits):
+ a = Int()
+
+ a = A()
+ a.on_trait_change(callback0, 'a')
+ a.a = 10
+ self.assertEqual(self.cb,())
+ a.unobserve(callback0, 'a')
+
+ a.observe(callback1, 'a')
+ a.a = 100
+ change = change_dict('a', 10, 100, a, 'change')
+ self.assertEqual(self.cb, change)
+ self.assertEqual(len(a._trait_notifiers['a']['change']), 1)
+ a.unobserve(callback1, 'a')
+
+ self.assertEqual(len(a._trait_notifiers['a']['change']), 0)
+
+ def test_notify_only_once(self):
+
+ class A(HasTraits):
+ listen_to = ['a']
+
+ a = Int(0)
+ b = 0
+
+ def __init__(self, **kwargs):
+ super(A, self).__init__(**kwargs)
+ self.observe(self.listener1, ['a'])
+
+ def listener1(self, change):
+ self.b += 1
+
+ class B(A):
+
+ c = 0
+ d = 0
+
+ def __init__(self, **kwargs):
+ super(B, self).__init__(**kwargs)
+ self.observe(self.listener2)
+
+ def listener2(self, change):
+ self.c += 1
+
+ @observe('a')
+ def _a_changed(self, change):
+ self.d += 1
+
+ b = B()
+ b.a += 1
+ self.assertEqual(b.b, b.c)
+ self.assertEqual(b.b, b.d)
+ b.a += 1
+ self.assertEqual(b.b, b.c)
+ self.assertEqual(b.b, b.d)
+
+
+class TestHasTraits(TestCase):
+
+ def test_trait_names(self):
+ class A(HasTraits):
+ i = Int()
+ f = Float()
+ a = A()
+ self.assertEqual(sorted(a.trait_names()),['f','i'])
+ self.assertEqual(sorted(A.class_trait_names()),['f','i'])
+ self.assertTrue(a.has_trait('f'))
+ self.assertFalse(a.has_trait('g'))
+
def test_trait_has_value(self):
class A(HasTraits):
i = Int()
@@ -813,438 +813,438 @@ class TestHasTraits(TestCase):
self.assertTrue(a.trait_has_value('i'))
self.assertTrue(a.trait_has_value('f'))
- def test_trait_metadata_deprecated(self):
+ def test_trait_metadata_deprecated(self):
with expected_warnings([r'metadata should be set using the \.tag\(\) method']):
- class A(HasTraits):
- i = Int(config_key='MY_VALUE')
- a = A()
- self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE')
-
- def test_trait_metadata(self):
- class A(HasTraits):
- i = Int().tag(config_key='MY_VALUE')
- a = A()
- self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE')
-
- def test_trait_metadata_default(self):
- class A(HasTraits):
- i = Int()
- a = A()
- self.assertEqual(a.trait_metadata('i', 'config_key'), None)
- self.assertEqual(a.trait_metadata('i', 'config_key', 'default'), 'default')
-
- def test_traits(self):
- class A(HasTraits):
- i = Int()
- f = Float()
- a = A()
- self.assertEqual(a.traits(), dict(i=A.i, f=A.f))
- self.assertEqual(A.class_traits(), dict(i=A.i, f=A.f))
-
- def test_traits_metadata(self):
- class A(HasTraits):
- i = Int().tag(config_key='VALUE1', other_thing='VALUE2')
- f = Float().tag(config_key='VALUE3', other_thing='VALUE2')
- j = Int(0)
- a = A()
- self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j))
- traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
- self.assertEqual(traits, dict(i=A.i))
-
- # This passes, but it shouldn't because I am replicating a bug in
- # traits.
- traits = a.traits(config_key=lambda v: True)
- self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j))
-
- def test_traits_metadata_deprecated(self):
+ class A(HasTraits):
+ i = Int(config_key='MY_VALUE')
+ a = A()
+ self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE')
+
+ def test_trait_metadata(self):
+ class A(HasTraits):
+ i = Int().tag(config_key='MY_VALUE')
+ a = A()
+ self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE')
+
+ def test_trait_metadata_default(self):
+ class A(HasTraits):
+ i = Int()
+ a = A()
+ self.assertEqual(a.trait_metadata('i', 'config_key'), None)
+ self.assertEqual(a.trait_metadata('i', 'config_key', 'default'), 'default')
+
+ def test_traits(self):
+ class A(HasTraits):
+ i = Int()
+ f = Float()
+ a = A()
+ self.assertEqual(a.traits(), dict(i=A.i, f=A.f))
+ self.assertEqual(A.class_traits(), dict(i=A.i, f=A.f))
+
+ def test_traits_metadata(self):
+ class A(HasTraits):
+ i = Int().tag(config_key='VALUE1', other_thing='VALUE2')
+ f = Float().tag(config_key='VALUE3', other_thing='VALUE2')
+ j = Int(0)
+ a = A()
+ self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j))
+ traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
+ self.assertEqual(traits, dict(i=A.i))
+
+ # This passes, but it shouldn't because I am replicating a bug in
+ # traits.
+ traits = a.traits(config_key=lambda v: True)
+ self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j))
+
+ def test_traits_metadata_deprecated(self):
with expected_warnings([r'metadata should be set using the \.tag\(\) method']*2):
- class A(HasTraits):
- i = Int(config_key='VALUE1', other_thing='VALUE2')
- f = Float(config_key='VALUE3', other_thing='VALUE2')
- j = Int(0)
- a = A()
- self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j))
- traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
- self.assertEqual(traits, dict(i=A.i))
-
- # This passes, but it shouldn't because I am replicating a bug in
- # traits.
- traits = a.traits(config_key=lambda v: True)
- self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j))
-
-
- def test_init(self):
- class A(HasTraits):
- i = Int()
- x = Float()
- a = A(i=1, x=10.0)
- self.assertEqual(a.i, 1)
- self.assertEqual(a.x, 10.0)
-
- def test_positional_args(self):
- class A(HasTraits):
- i = Int(0)
- def __init__(self, i):
- super(A, self).__init__()
- self.i = i
-
- a = A(5)
- self.assertEqual(a.i, 5)
- # should raise TypeError if no positional arg given
- self.assertRaises(TypeError, A)
-
-#-----------------------------------------------------------------------------
-# Tests for specific trait types
-#-----------------------------------------------------------------------------
-
-
-class TestType(TestCase):
-
- def test_default(self):
-
- class B(object): pass
- class A(HasTraits):
- klass = Type(allow_none=True)
-
- a = A()
- self.assertEqual(a.klass, object)
-
- a.klass = B
- self.assertEqual(a.klass, B)
- self.assertRaises(TraitError, setattr, a, 'klass', 10)
-
- def test_default_options(self):
-
- class B(object): pass
- class C(B): pass
- class A(HasTraits):
- # Different possible combinations of options for default_value
- # and klass. default_value=None is only valid with allow_none=True.
- k1 = Type()
- k2 = Type(None, allow_none=True)
- k3 = Type(B)
- k4 = Type(klass=B)
- k5 = Type(default_value=None, klass=B, allow_none=True)
- k6 = Type(default_value=C, klass=B)
-
- self.assertIs(A.k1.default_value, object)
- self.assertIs(A.k1.klass, object)
- self.assertIs(A.k2.default_value, None)
- self.assertIs(A.k2.klass, object)
- self.assertIs(A.k3.default_value, B)
- self.assertIs(A.k3.klass, B)
- self.assertIs(A.k4.default_value, B)
- self.assertIs(A.k4.klass, B)
- self.assertIs(A.k5.default_value, None)
- self.assertIs(A.k5.klass, B)
- self.assertIs(A.k6.default_value, C)
- self.assertIs(A.k6.klass, B)
-
- a = A()
- self.assertIs(a.k1, object)
- self.assertIs(a.k2, None)
- self.assertIs(a.k3, B)
- self.assertIs(a.k4, B)
- self.assertIs(a.k5, None)
- self.assertIs(a.k6, C)
-
- def test_value(self):
-
- class B(object): pass
- class C(object): pass
- class A(HasTraits):
- klass = Type(B)
-
- a = A()
- self.assertEqual(a.klass, B)
- self.assertRaises(TraitError, setattr, a, 'klass', C)
- self.assertRaises(TraitError, setattr, a, 'klass', object)
- a.klass = B
-
- def test_allow_none(self):
-
- class B(object): pass
- class C(B): pass
- class A(HasTraits):
- klass = Type(B)
-
- a = A()
- self.assertEqual(a.klass, B)
- self.assertRaises(TraitError, setattr, a, 'klass', None)
- a.klass = C
- self.assertEqual(a.klass, C)
-
- def test_validate_klass(self):
-
- class A(HasTraits):
- klass = Type('no strings allowed')
-
- self.assertRaises(ImportError, A)
-
- class A(HasTraits):
- klass = Type('rub.adub.Duck')
-
- self.assertRaises(ImportError, A)
-
- def test_validate_default(self):
-
- class B(object): pass
- class A(HasTraits):
- klass = Type('bad default', B)
-
- self.assertRaises(ImportError, A)
-
- class C(HasTraits):
- klass = Type(None, B)
-
+ class A(HasTraits):
+ i = Int(config_key='VALUE1', other_thing='VALUE2')
+ f = Float(config_key='VALUE3', other_thing='VALUE2')
+ j = Int(0)
+ a = A()
+ self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j))
+ traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
+ self.assertEqual(traits, dict(i=A.i))
+
+ # This passes, but it shouldn't because I am replicating a bug in
+ # traits.
+ traits = a.traits(config_key=lambda v: True)
+ self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j))
+
+
+ def test_init(self):
+ class A(HasTraits):
+ i = Int()
+ x = Float()
+ a = A(i=1, x=10.0)
+ self.assertEqual(a.i, 1)
+ self.assertEqual(a.x, 10.0)
+
+ def test_positional_args(self):
+ class A(HasTraits):
+ i = Int(0)
+ def __init__(self, i):
+ super(A, self).__init__()
+ self.i = i
+
+ a = A(5)
+ self.assertEqual(a.i, 5)
+ # should raise TypeError if no positional arg given
+ self.assertRaises(TypeError, A)
+
+#-----------------------------------------------------------------------------
+# Tests for specific trait types
+#-----------------------------------------------------------------------------
+
+
+class TestType(TestCase):
+
+ def test_default(self):
+
+ class B(object): pass
+ class A(HasTraits):
+ klass = Type(allow_none=True)
+
+ a = A()
+ self.assertEqual(a.klass, object)
+
+ a.klass = B
+ self.assertEqual(a.klass, B)
+ self.assertRaises(TraitError, setattr, a, 'klass', 10)
+
+ def test_default_options(self):
+
+ class B(object): pass
+ class C(B): pass
+ class A(HasTraits):
+ # Different possible combinations of options for default_value
+ # and klass. default_value=None is only valid with allow_none=True.
+ k1 = Type()
+ k2 = Type(None, allow_none=True)
+ k3 = Type(B)
+ k4 = Type(klass=B)
+ k5 = Type(default_value=None, klass=B, allow_none=True)
+ k6 = Type(default_value=C, klass=B)
+
+ self.assertIs(A.k1.default_value, object)
+ self.assertIs(A.k1.klass, object)
+ self.assertIs(A.k2.default_value, None)
+ self.assertIs(A.k2.klass, object)
+ self.assertIs(A.k3.default_value, B)
+ self.assertIs(A.k3.klass, B)
+ self.assertIs(A.k4.default_value, B)
+ self.assertIs(A.k4.klass, B)
+ self.assertIs(A.k5.default_value, None)
+ self.assertIs(A.k5.klass, B)
+ self.assertIs(A.k6.default_value, C)
+ self.assertIs(A.k6.klass, B)
+
+ a = A()
+ self.assertIs(a.k1, object)
+ self.assertIs(a.k2, None)
+ self.assertIs(a.k3, B)
+ self.assertIs(a.k4, B)
+ self.assertIs(a.k5, None)
+ self.assertIs(a.k6, C)
+
+ def test_value(self):
+
+ class B(object): pass
+ class C(object): pass
+ class A(HasTraits):
+ klass = Type(B)
+
+ a = A()
+ self.assertEqual(a.klass, B)
+ self.assertRaises(TraitError, setattr, a, 'klass', C)
+ self.assertRaises(TraitError, setattr, a, 'klass', object)
+ a.klass = B
+
+ def test_allow_none(self):
+
+ class B(object): pass
+ class C(B): pass
+ class A(HasTraits):
+ klass = Type(B)
+
+ a = A()
+ self.assertEqual(a.klass, B)
+ self.assertRaises(TraitError, setattr, a, 'klass', None)
+ a.klass = C
+ self.assertEqual(a.klass, C)
+
+ def test_validate_klass(self):
+
+ class A(HasTraits):
+ klass = Type('no strings allowed')
+
+ self.assertRaises(ImportError, A)
+
+ class A(HasTraits):
+ klass = Type('rub.adub.Duck')
+
+ self.assertRaises(ImportError, A)
+
+ def test_validate_default(self):
+
+ class B(object): pass
+ class A(HasTraits):
+ klass = Type('bad default', B)
+
+ self.assertRaises(ImportError, A)
+
+ class C(HasTraits):
+ klass = Type(None, B)
+
self.assertRaises(TraitError, getattr, C(), 'klass')
-
- def test_str_klass(self):
-
- class A(HasTraits):
+
+ def test_str_klass(self):
+
+ class A(HasTraits):
klass = Type("traitlets.config.Config")
-
+
from traitlets.config import Config
- a = A()
+ a = A()
a.klass = Config
self.assertEqual(a.klass, Config)
-
- self.assertRaises(TraitError, setattr, a, 'klass', 10)
-
- def test_set_str_klass(self):
-
- class A(HasTraits):
- klass = Type()
-
+
+ self.assertRaises(TraitError, setattr, a, 'klass', 10)
+
+ def test_set_str_klass(self):
+
+ class A(HasTraits):
+ klass = Type()
+
a = A(klass="traitlets.config.Config")
from traitlets.config import Config
-
+
self.assertEqual(a.klass, Config)
-class TestInstance(TestCase):
-
- def test_basic(self):
- class Foo(object): pass
- class Bar(Foo): pass
- class Bah(object): pass
-
- class A(HasTraits):
- inst = Instance(Foo, allow_none=True)
-
- a = A()
- self.assertTrue(a.inst is None)
- a.inst = Foo()
- self.assertTrue(isinstance(a.inst, Foo))
- a.inst = Bar()
- self.assertTrue(isinstance(a.inst, Foo))
- self.assertRaises(TraitError, setattr, a, 'inst', Foo)
- self.assertRaises(TraitError, setattr, a, 'inst', Bar)
- self.assertRaises(TraitError, setattr, a, 'inst', Bah())
-
- def test_default_klass(self):
- class Foo(object): pass
- class Bar(Foo): pass
- class Bah(object): pass
-
- class FooInstance(Instance):
- klass = Foo
-
- class A(HasTraits):
- inst = FooInstance(allow_none=True)
-
- a = A()
- self.assertTrue(a.inst is None)
- a.inst = Foo()
- self.assertTrue(isinstance(a.inst, Foo))
- a.inst = Bar()
- self.assertTrue(isinstance(a.inst, Foo))
- self.assertRaises(TraitError, setattr, a, 'inst', Foo)
- self.assertRaises(TraitError, setattr, a, 'inst', Bar)
- self.assertRaises(TraitError, setattr, a, 'inst', Bah())
-
- def test_unique_default_value(self):
- class Foo(object): pass
- class A(HasTraits):
- inst = Instance(Foo,(),{})
-
- a = A()
- b = A()
- self.assertTrue(a.inst is not b.inst)
-
- def test_args_kw(self):
- class Foo(object):
- def __init__(self, c): self.c = c
- class Bar(object): pass
- class Bah(object):
- def __init__(self, c, d):
- self.c = c; self.d = d
-
- class A(HasTraits):
- inst = Instance(Foo, (10,))
- a = A()
- self.assertEqual(a.inst.c, 10)
-
- class B(HasTraits):
- inst = Instance(Bah, args=(10,), kw=dict(d=20))
- b = B()
- self.assertEqual(b.inst.c, 10)
- self.assertEqual(b.inst.d, 20)
-
- class C(HasTraits):
- inst = Instance(Foo, allow_none=True)
- c = C()
- self.assertTrue(c.inst is None)
-
- def test_bad_default(self):
- class Foo(object): pass
-
- class A(HasTraits):
- inst = Instance(Foo)
-
- a = A()
- with self.assertRaises(TraitError):
- a.inst
-
- def test_instance(self):
- class Foo(object): pass
-
- def inner():
- class A(HasTraits):
- inst = Instance(Foo())
-
- self.assertRaises(TraitError, inner)
-
-
-class TestThis(TestCase):
-
- def test_this_class(self):
- class Foo(HasTraits):
- this = This()
-
- f = Foo()
- self.assertEqual(f.this, None)
- g = Foo()
- f.this = g
- self.assertEqual(f.this, g)
- self.assertRaises(TraitError, setattr, f, 'this', 10)
-
- def test_this_inst(self):
- class Foo(HasTraits):
- this = This()
-
- f = Foo()
- f.this = Foo()
- self.assertTrue(isinstance(f.this, Foo))
-
- def test_subclass(self):
- class Foo(HasTraits):
- t = This()
- class Bar(Foo):
- pass
- f = Foo()
- b = Bar()
- f.t = b
- b.t = f
- self.assertEqual(f.t, b)
- self.assertEqual(b.t, f)
-
- def test_subclass_override(self):
- class Foo(HasTraits):
- t = This()
- class Bar(Foo):
- t = This()
- f = Foo()
- b = Bar()
- f.t = b
- self.assertEqual(f.t, b)
- self.assertRaises(TraitError, setattr, b, 't', f)
-
- def test_this_in_container(self):
-
- class Tree(HasTraits):
- value = Unicode()
- leaves = List(This())
-
- tree = Tree(
- value='foo',
- leaves=[Tree(value='bar'), Tree(value='buzz')]
- )
-
- with self.assertRaises(TraitError):
- tree.leaves = [1, 2]
-
-class TraitTestBase(TestCase):
- """A best testing class for basic trait types."""
-
- def assign(self, value):
- self.obj.value = value
-
- def coerce(self, value):
- return value
-
- def test_good_values(self):
- if hasattr(self, '_good_values'):
- for value in self._good_values:
- self.assign(value)
- self.assertEqual(self.obj.value, self.coerce(value))
-
- def test_bad_values(self):
- if hasattr(self, '_bad_values'):
- for value in self._bad_values:
- try:
- self.assertRaises(TraitError, self.assign, value)
- except AssertionError:
- assert False, value
-
- def test_default_value(self):
- if hasattr(self, '_default_value'):
- self.assertEqual(self._default_value, self.obj.value)
-
- def test_allow_none(self):
- if (hasattr(self, '_bad_values') and hasattr(self, '_good_values') and
- None in self._bad_values):
- trait=self.obj.traits()['value']
- try:
- trait.allow_none = True
- self._bad_values.remove(None)
- #skip coerce. Allow None casts None to None.
- self.assign(None)
- self.assertEqual(self.obj.value,None)
- self.test_good_values()
- self.test_bad_values()
- finally:
- #tear down
- trait.allow_none = False
- self._bad_values.append(None)
-
- def tearDown(self):
- # restore default value after tests, if set
- if hasattr(self, '_default_value'):
- self.obj.value = self._default_value
-
-
-class AnyTrait(HasTraits):
-
- value = Any()
-
-class AnyTraitTest(TraitTestBase):
-
- obj = AnyTrait()
-
- _default_value = None
+class TestInstance(TestCase):
+
+ def test_basic(self):
+ class Foo(object): pass
+ class Bar(Foo): pass
+ class Bah(object): pass
+
+ class A(HasTraits):
+ inst = Instance(Foo, allow_none=True)
+
+ a = A()
+ self.assertTrue(a.inst is None)
+ a.inst = Foo()
+ self.assertTrue(isinstance(a.inst, Foo))
+ a.inst = Bar()
+ self.assertTrue(isinstance(a.inst, Foo))
+ self.assertRaises(TraitError, setattr, a, 'inst', Foo)
+ self.assertRaises(TraitError, setattr, a, 'inst', Bar)
+ self.assertRaises(TraitError, setattr, a, 'inst', Bah())
+
+ def test_default_klass(self):
+ class Foo(object): pass
+ class Bar(Foo): pass
+ class Bah(object): pass
+
+ class FooInstance(Instance):
+ klass = Foo
+
+ class A(HasTraits):
+ inst = FooInstance(allow_none=True)
+
+ a = A()
+ self.assertTrue(a.inst is None)
+ a.inst = Foo()
+ self.assertTrue(isinstance(a.inst, Foo))
+ a.inst = Bar()
+ self.assertTrue(isinstance(a.inst, Foo))
+ self.assertRaises(TraitError, setattr, a, 'inst', Foo)
+ self.assertRaises(TraitError, setattr, a, 'inst', Bar)
+ self.assertRaises(TraitError, setattr, a, 'inst', Bah())
+
+ def test_unique_default_value(self):
+ class Foo(object): pass
+ class A(HasTraits):
+ inst = Instance(Foo,(),{})
+
+ a = A()
+ b = A()
+ self.assertTrue(a.inst is not b.inst)
+
+ def test_args_kw(self):
+ class Foo(object):
+ def __init__(self, c): self.c = c
+ class Bar(object): pass
+ class Bah(object):
+ def __init__(self, c, d):
+ self.c = c; self.d = d
+
+ class A(HasTraits):
+ inst = Instance(Foo, (10,))
+ a = A()
+ self.assertEqual(a.inst.c, 10)
+
+ class B(HasTraits):
+ inst = Instance(Bah, args=(10,), kw=dict(d=20))
+ b = B()
+ self.assertEqual(b.inst.c, 10)
+ self.assertEqual(b.inst.d, 20)
+
+ class C(HasTraits):
+ inst = Instance(Foo, allow_none=True)
+ c = C()
+ self.assertTrue(c.inst is None)
+
+ def test_bad_default(self):
+ class Foo(object): pass
+
+ class A(HasTraits):
+ inst = Instance(Foo)
+
+ a = A()
+ with self.assertRaises(TraitError):
+ a.inst
+
+ def test_instance(self):
+ class Foo(object): pass
+
+ def inner():
+ class A(HasTraits):
+ inst = Instance(Foo())
+
+ self.assertRaises(TraitError, inner)
+
+
+class TestThis(TestCase):
+
+ def test_this_class(self):
+ class Foo(HasTraits):
+ this = This()
+
+ f = Foo()
+ self.assertEqual(f.this, None)
+ g = Foo()
+ f.this = g
+ self.assertEqual(f.this, g)
+ self.assertRaises(TraitError, setattr, f, 'this', 10)
+
+ def test_this_inst(self):
+ class Foo(HasTraits):
+ this = This()
+
+ f = Foo()
+ f.this = Foo()
+ self.assertTrue(isinstance(f.this, Foo))
+
+ def test_subclass(self):
+ class Foo(HasTraits):
+ t = This()
+ class Bar(Foo):
+ pass
+ f = Foo()
+ b = Bar()
+ f.t = b
+ b.t = f
+ self.assertEqual(f.t, b)
+ self.assertEqual(b.t, f)
+
+ def test_subclass_override(self):
+ class Foo(HasTraits):
+ t = This()
+ class Bar(Foo):
+ t = This()
+ f = Foo()
+ b = Bar()
+ f.t = b
+ self.assertEqual(f.t, b)
+ self.assertRaises(TraitError, setattr, b, 't', f)
+
+ def test_this_in_container(self):
+
+ class Tree(HasTraits):
+ value = Unicode()
+ leaves = List(This())
+
+ tree = Tree(
+ value='foo',
+ leaves=[Tree(value='bar'), Tree(value='buzz')]
+ )
+
+ with self.assertRaises(TraitError):
+ tree.leaves = [1, 2]
+
+class TraitTestBase(TestCase):
+ """A best testing class for basic trait types."""
+
+ def assign(self, value):
+ self.obj.value = value
+
+ def coerce(self, value):
+ return value
+
+ def test_good_values(self):
+ if hasattr(self, '_good_values'):
+ for value in self._good_values:
+ self.assign(value)
+ self.assertEqual(self.obj.value, self.coerce(value))
+
+ def test_bad_values(self):
+ if hasattr(self, '_bad_values'):
+ for value in self._bad_values:
+ try:
+ self.assertRaises(TraitError, self.assign, value)
+ except AssertionError:
+ assert False, value
+
+ def test_default_value(self):
+ if hasattr(self, '_default_value'):
+ self.assertEqual(self._default_value, self.obj.value)
+
+ def test_allow_none(self):
+ if (hasattr(self, '_bad_values') and hasattr(self, '_good_values') and
+ None in self._bad_values):
+ trait=self.obj.traits()['value']
+ try:
+ trait.allow_none = True
+ self._bad_values.remove(None)
+ #skip coerce. Allow None casts None to None.
+ self.assign(None)
+ self.assertEqual(self.obj.value,None)
+ self.test_good_values()
+ self.test_bad_values()
+ finally:
+ #tear down
+ trait.allow_none = False
+ self._bad_values.append(None)
+
+ def tearDown(self):
+ # restore default value after tests, if set
+ if hasattr(self, '_default_value'):
+ self.obj.value = self._default_value
+
+
+class AnyTrait(HasTraits):
+
+ value = Any()
+
+class AnyTraitTest(TraitTestBase):
+
+ obj = AnyTrait()
+
+ _default_value = None
_good_values = [10.0, 'ten', [10], {'ten': 10},(10,), None, 1j]
- _bad_values = []
-
-class UnionTrait(HasTraits):
-
- value = Union([Type(), Bool()])
-
-class UnionTraitTest(TraitTestBase):
-
+ _bad_values = []
+
+class UnionTrait(HasTraits):
+
+ value = Union([Type(), Bool()])
+
+class UnionTraitTest(TraitTestBase):
+
obj = UnionTrait(value="traitlets.config.Config")
- _good_values = [int, float, True]
- _bad_values = [[], (0,), 1j]
-
+ _good_values = [int, float, True]
+ _bad_values = [[], (0,), 1j]
+
class CallableTrait(HasTraits):
value = Callable()
@@ -1255,407 +1255,407 @@ class CallableTraitTest(TraitTestBase):
_good_values = [int, sorted, lambda x: print(x)]
_bad_values = [[], 1, '']
-class OrTrait(HasTraits):
-
- value = Bool() | Unicode()
-
-class OrTraitTest(TraitTestBase):
-
- obj = OrTrait()
- _good_values = [True, False, 'ten']
- _bad_values = [[], (0,), 1j]
-
-class IntTrait(HasTraits):
-
- value = Int(99, min=-100)
-
-class TestInt(TraitTestBase):
-
- obj = IntTrait()
- _default_value = 99
- _good_values = [10, -10]
+class OrTrait(HasTraits):
+
+ value = Bool() | Unicode()
+
+class OrTraitTest(TraitTestBase):
+
+ obj = OrTrait()
+ _good_values = [True, False, 'ten']
+ _bad_values = [[], (0,), 1j]
+
+class IntTrait(HasTraits):
+
+ value = Int(99, min=-100)
+
+class TestInt(TraitTestBase):
+
+ obj = IntTrait()
+ _default_value = 99
+ _good_values = [10, -10]
_bad_values = ['ten', [10], {'ten': 10}, (10,), None, 1j,
10.1, -10.1, '10L', '-10L', '10.1', '-10.1',
'10', '-10', -200]
-
-
-class CIntTrait(HasTraits):
- value = CInt('5')
-
-class TestCInt(TraitTestBase):
- obj = CIntTrait()
-
- _default_value = 5
+
+
+class CIntTrait(HasTraits):
+ value = CInt('5')
+
+class TestCInt(TraitTestBase):
+ obj = CIntTrait()
+
+ _default_value = 5
_good_values = ['10', '-10', 10, 10.0, -10.0, 10.1]
_bad_values = ['ten', [10], {'ten': 10},(10,),
None, 1j, '10.1']
-
- def coerce(self, n):
- return int(n)
-
-
-class MinBoundCIntTrait(HasTraits):
- value = CInt('5', min=3)
-
-class TestMinBoundCInt(TestCInt):
- obj = MinBoundCIntTrait()
-
- _default_value = 5
- _good_values = [3, 3.0, '3']
- _bad_values = [2.6, 2, -3, -3.0]
-
-
-class LongTrait(HasTraits):
-
+
+ def coerce(self, n):
+ return int(n)
+
+
+class MinBoundCIntTrait(HasTraits):
+ value = CInt('5', min=3)
+
+class TestMinBoundCInt(TestCInt):
+ obj = MinBoundCIntTrait()
+
+ _default_value = 5
+ _good_values = [3, 3.0, '3']
+ _bad_values = [2.6, 2, -3, -3.0]
+
+
+class LongTrait(HasTraits):
+
value = Long(99)
-
-class TestLong(TraitTestBase):
-
- obj = LongTrait()
-
+
+class TestLong(TraitTestBase):
+
+ obj = LongTrait()
+
_default_value = 99
- _good_values = [10, -10]
+ _good_values = [10, -10]
_bad_values = ['ten', [10], {'ten': 10},(10,),
- None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
+ None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
'-10.1']
-
-
-class MinBoundLongTrait(HasTraits):
+
+
+class MinBoundLongTrait(HasTraits):
value = Long(99, min=5)
-
-class TestMinBoundLong(TraitTestBase):
- obj = MinBoundLongTrait()
-
+
+class TestMinBoundLong(TraitTestBase):
+ obj = MinBoundLongTrait()
+
_default_value = 99
- _good_values = [5, 10]
- _bad_values = [4, -10]
-
-
-class MaxBoundLongTrait(HasTraits):
+ _good_values = [5, 10]
+ _bad_values = [4, -10]
+
+
+class MaxBoundLongTrait(HasTraits):
value = Long(5, max=10)
-
-class TestMaxBoundLong(TraitTestBase):
- obj = MaxBoundLongTrait()
-
+
+class TestMaxBoundLong(TraitTestBase):
+ obj = MaxBoundLongTrait()
+
_default_value = 5
- _good_values = [10, -2]
- _bad_values = [11, 20]
-
-
-class CLongTrait(HasTraits):
- value = CLong('5')
-
-class TestCLong(TraitTestBase):
- obj = CLongTrait()
-
+ _good_values = [10, -2]
+ _bad_values = [11, 20]
+
+
+class CLongTrait(HasTraits):
+ value = CLong('5')
+
+class TestCLong(TraitTestBase):
+ obj = CLongTrait()
+
_default_value = 5
_good_values = ['10', '-10', 10, 10.0, -10.0, 10.1]
_bad_values = ['ten', [10], {'ten': 10},(10,),
None, 1j, '10.1']
-
- def coerce(self, n):
+
+ def coerce(self, n):
return int(n)
-
-
-class MaxBoundCLongTrait(HasTraits):
- value = CLong('5', max=10)
-
-class TestMaxBoundCLong(TestCLong):
- obj = MaxBoundCLongTrait()
-
+
+
+class MaxBoundCLongTrait(HasTraits):
+ value = CLong('5', max=10)
+
+class TestMaxBoundCLong(TestCLong):
+ obj = MaxBoundCLongTrait()
+
+ _default_value = 5
+ _good_values = [10, '10', 10.3]
+ _bad_values = [11.0, '11']
+
+
+class IntegerTrait(HasTraits):
+ value = Integer(1)
+
+class TestInteger(TestLong):
+ obj = IntegerTrait()
+ _default_value = 1
+
+ def coerce(self, n):
+ return int(n)
+
+
+class MinBoundIntegerTrait(HasTraits):
+ value = Integer(5, min=3)
+
+class TestMinBoundInteger(TraitTestBase):
+ obj = MinBoundIntegerTrait()
+
_default_value = 5
- _good_values = [10, '10', 10.3]
- _bad_values = [11.0, '11']
-
-
-class IntegerTrait(HasTraits):
- value = Integer(1)
-
-class TestInteger(TestLong):
- obj = IntegerTrait()
- _default_value = 1
-
- def coerce(self, n):
- return int(n)
-
-
-class MinBoundIntegerTrait(HasTraits):
- value = Integer(5, min=3)
-
-class TestMinBoundInteger(TraitTestBase):
- obj = MinBoundIntegerTrait()
-
- _default_value = 5
- _good_values = 3, 20
- _bad_values = [2, -10]
-
-
-class MaxBoundIntegerTrait(HasTraits):
- value = Integer(1, max=3)
-
-class TestMaxBoundInteger(TraitTestBase):
- obj = MaxBoundIntegerTrait()
-
- _default_value = 1
- _good_values = 3, -2
- _bad_values = [4, 10]
-
-
-class FloatTrait(HasTraits):
-
- value = Float(99.0, max=200.0)
-
-class TestFloat(TraitTestBase):
-
- obj = FloatTrait()
-
- _default_value = 99.0
- _good_values = [10, -10, 10.1, -10.1]
+ _good_values = 3, 20
+ _bad_values = [2, -10]
+
+
+class MaxBoundIntegerTrait(HasTraits):
+ value = Integer(1, max=3)
+
+class TestMaxBoundInteger(TraitTestBase):
+ obj = MaxBoundIntegerTrait()
+
+ _default_value = 1
+ _good_values = 3, -2
+ _bad_values = [4, 10]
+
+
+class FloatTrait(HasTraits):
+
+ value = Float(99.0, max=200.0)
+
+class TestFloat(TraitTestBase):
+
+ obj = FloatTrait()
+
+ _default_value = 99.0
+ _good_values = [10, -10, 10.1, -10.1]
_bad_values = ['ten', [10], {'ten': 10}, (10,), None,
1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', 201.0]
-
-
-class CFloatTrait(HasTraits):
-
- value = CFloat('99.0', max=200.0)
-
-class TestCFloat(TraitTestBase):
-
- obj = CFloatTrait()
-
- _default_value = 99.0
+
+
+class CFloatTrait(HasTraits):
+
+ value = CFloat('99.0', max=200.0)
+
+class TestCFloat(TraitTestBase):
+
+ obj = CFloatTrait()
+
+ _default_value = 99.0
_good_values = [10, 10.0, 10.5, '10.0', '10', '-10']
_bad_values = ['ten', [10], {'ten': 10}, (10,), None, 1j,
- 200.1, '200.1']
-
- def coerce(self, v):
- return float(v)
-
-
-class ComplexTrait(HasTraits):
-
- value = Complex(99.0-99.0j)
-
-class TestComplex(TraitTestBase):
-
- obj = ComplexTrait()
-
- _default_value = 99.0-99.0j
- _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
- 10.1j, 10.1+10.1j, 10.1-10.1j]
+ 200.1, '200.1']
+
+ def coerce(self, v):
+ return float(v)
+
+
+class ComplexTrait(HasTraits):
+
+ value = Complex(99.0-99.0j)
+
+class TestComplex(TraitTestBase):
+
+ obj = ComplexTrait()
+
+ _default_value = 99.0-99.0j
+ _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
+ 10.1j, 10.1+10.1j, 10.1-10.1j]
_bad_values = ['10L', '-10L', 'ten', [10], {'ten': 10},(10,), None]
-
-
-class BytesTrait(HasTraits):
-
- value = Bytes(b'string')
-
-class TestBytes(TraitTestBase):
-
- obj = BytesTrait()
-
- _default_value = b'string'
- _good_values = [b'10', b'-10', b'10L',
- b'-10L', b'10.1', b'-10.1', b'string']
- _bad_values = [10, -10, 10.1, -10.1, 1j, [10],
+
+
+class BytesTrait(HasTraits):
+
+ value = Bytes(b'string')
+
+class TestBytes(TraitTestBase):
+
+ obj = BytesTrait()
+
+ _default_value = b'string'
+ _good_values = [b'10', b'-10', b'10L',
+ b'-10L', b'10.1', b'-10.1', b'string']
+ _bad_values = [10, -10, 10.1, -10.1, 1j, [10],
['ten'],{'ten': 10},(10,), None, 'string']
-
-
-class UnicodeTrait(HasTraits):
-
+
+
+class UnicodeTrait(HasTraits):
+
value = Unicode('unicode')
-
-class TestUnicode(TraitTestBase):
-
- obj = UnicodeTrait()
-
+
+class TestUnicode(TraitTestBase):
+
+ obj = UnicodeTrait()
+
_default_value = 'unicode'
- _good_values = ['10', '-10', '10L', '-10L', '10.1',
+ _good_values = ['10', '-10', '10L', '-10L', '10.1',
'-10.1', '', 'string', "€", b"bytestring"]
- _bad_values = [10, -10, 10.1, -10.1, 1j,
+ _bad_values = [10, -10, 10.1, -10.1, 1j,
[10], ['ten'], {'ten': 10},(10,), None]
-
+
def coerce(self, v):
return cast_unicode(v)
-
-
-class ObjectNameTrait(HasTraits):
- value = ObjectName("abc")
-
-class TestObjectName(TraitTestBase):
- obj = ObjectNameTrait()
-
- _default_value = "abc"
+
+
+class ObjectNameTrait(HasTraits):
+ value = ObjectName("abc")
+
+class TestObjectName(TraitTestBase):
+ obj = ObjectNameTrait()
+
+ _default_value = "abc"
_good_values = ["a", "gh", "g9", "g_", "_G", "a345_"]
_bad_values = [1, "", "€", "9g", "!", "#abc", "aj@", "a.b", "a()", "a[0]",
- None, object(), object]
+ None, object(), object]
_good_values.append("þ") # þ=1 is valid in Python 3 (PEP 3131).
-
-
-class DottedObjectNameTrait(HasTraits):
- value = DottedObjectName("a.b")
-
-class TestDottedObjectName(TraitTestBase):
- obj = DottedObjectNameTrait()
-
- _default_value = "a.b"
+
+
+class DottedObjectNameTrait(HasTraits):
+ value = DottedObjectName("a.b")
+
+class TestDottedObjectName(TraitTestBase):
+ obj = DottedObjectNameTrait()
+
+ _default_value = "a.b"
_good_values = ["A", "y.t", "y765.__repr__", "os.path.join"]
_bad_values = [1, "abc.€", "_.@", ".", ".abc", "abc.", ".abc.", None]
-
+
_good_values.append("t.þ")
-
-
-class TCPAddressTrait(HasTraits):
- value = TCPAddress()
-
-class TestTCPAddress(TraitTestBase):
-
- obj = TCPAddressTrait()
-
- _default_value = ('127.0.0.1',0)
- _good_values = [('localhost',0),('192.168.0.1',1000),('www.google.com',80)]
- _bad_values = [(0,0),('localhost',10.0),('localhost',-1), None]
-
-
-class ListTrait(HasTraits):
-
- value = List(Int())
-
-
-class TestList(TraitTestBase):
-
- obj = ListTrait()
-
- _default_value = []
- _good_values = [[], [1], list(range(10)), (1,2)]
- _bad_values = [10, [1,'a'], 'a']
-
- def coerce(self, value):
- if value is not None:
- value = list(value)
- return value
-
-
-class Foo(object):
- pass
-
-class NoneInstanceListTrait(HasTraits):
-
- value = List(Instance(Foo))
-
-class TestNoneInstanceList(TraitTestBase):
-
- obj = NoneInstanceListTrait()
-
- _default_value = []
- _good_values = [[Foo(), Foo()], []]
- _bad_values = [[None], [Foo(), None]]
-
-
-class InstanceListTrait(HasTraits):
-
- value = List(Instance(__name__+'.Foo'))
-
-class TestInstanceList(TraitTestBase):
-
- obj = InstanceListTrait()
-
- def test_klass(self):
- """Test that the instance klass is properly assigned."""
- self.assertIs(self.obj.traits()['value']._trait.klass, Foo)
-
- _default_value = []
- _good_values = [[Foo(), Foo()], []]
- _bad_values = [['1', 2,], '1', [Foo], None]
-
-class UnionListTrait(HasTraits):
-
- value = List(Int() | Bool())
-
+
+
+class TCPAddressTrait(HasTraits):
+ value = TCPAddress()
+
+class TestTCPAddress(TraitTestBase):
+
+ obj = TCPAddressTrait()
+
+ _default_value = ('127.0.0.1',0)
+ _good_values = [('localhost',0),('192.168.0.1',1000),('www.google.com',80)]
+ _bad_values = [(0,0),('localhost',10.0),('localhost',-1), None]
+
+
+class ListTrait(HasTraits):
+
+ value = List(Int())
+
+
+class TestList(TraitTestBase):
+
+ obj = ListTrait()
+
+ _default_value = []
+ _good_values = [[], [1], list(range(10)), (1,2)]
+ _bad_values = [10, [1,'a'], 'a']
+
+ def coerce(self, value):
+ if value is not None:
+ value = list(value)
+ return value
+
+
+class Foo(object):
+ pass
+
+class NoneInstanceListTrait(HasTraits):
+
+ value = List(Instance(Foo))
+
+class TestNoneInstanceList(TraitTestBase):
+
+ obj = NoneInstanceListTrait()
+
+ _default_value = []
+ _good_values = [[Foo(), Foo()], []]
+ _bad_values = [[None], [Foo(), None]]
+
+
+class InstanceListTrait(HasTraits):
+
+ value = List(Instance(__name__+'.Foo'))
+
+class TestInstanceList(TraitTestBase):
+
+ obj = InstanceListTrait()
+
+ def test_klass(self):
+ """Test that the instance klass is properly assigned."""
+ self.assertIs(self.obj.traits()['value']._trait.klass, Foo)
+
+ _default_value = []
+ _good_values = [[Foo(), Foo()], []]
+ _bad_values = [['1', 2,], '1', [Foo], None]
+
+class UnionListTrait(HasTraits):
+
+ value = List(Int() | Bool())
+
class TestUnionListTrait(TraitTestBase):
-
- obj = UnionListTrait()
-
- _default_value = []
- _good_values = [[True, 1], [False, True]]
- _bad_values = [[1, 'True'], False]
-
-
-class LenListTrait(HasTraits):
-
- value = List(Int(), [0], minlen=1, maxlen=2)
-
-class TestLenList(TraitTestBase):
-
- obj = LenListTrait()
-
- _default_value = [0]
- _good_values = [[1], [1,2], (1,2)]
- _bad_values = [10, [1,'a'], 'a', [], list(range(3))]
-
- def coerce(self, value):
- if value is not None:
- value = list(value)
- return value
-
-class TupleTrait(HasTraits):
-
- value = Tuple(Int(allow_none=True), default_value=(1,))
-
-class TestTupleTrait(TraitTestBase):
-
- obj = TupleTrait()
-
+
+ obj = UnionListTrait()
+
+ _default_value = []
+ _good_values = [[True, 1], [False, True]]
+ _bad_values = [[1, 'True'], False]
+
+
+class LenListTrait(HasTraits):
+
+ value = List(Int(), [0], minlen=1, maxlen=2)
+
+class TestLenList(TraitTestBase):
+
+ obj = LenListTrait()
+
+ _default_value = [0]
+ _good_values = [[1], [1,2], (1,2)]
+ _bad_values = [10, [1,'a'], 'a', [], list(range(3))]
+
+ def coerce(self, value):
+ if value is not None:
+ value = list(value)
+ return value
+
+class TupleTrait(HasTraits):
+
+ value = Tuple(Int(allow_none=True), default_value=(1,))
+
+class TestTupleTrait(TraitTestBase):
+
+ obj = TupleTrait()
+
_default_value = (1,)
- _good_values = [(1,), (0,), [1]]
- _bad_values = [10, (1, 2), ('a'), (), None]
-
- def coerce(self, value):
- if value is not None:
- value = tuple(value)
- return value
-
- def test_invalid_args(self):
- self.assertRaises(TypeError, Tuple, 5)
- self.assertRaises(TypeError, Tuple, default_value='hello')
- t = Tuple(Int(), CBytes(), default_value=(1,5))
-
-class LooseTupleTrait(HasTraits):
-
- value = Tuple((1,2,3))
-
-class TestLooseTupleTrait(TraitTestBase):
-
- obj = LooseTupleTrait()
-
- _default_value = (1,2,3)
- _good_values = [(1,), [1], (0,), tuple(range(5)), tuple('hello'), ('a',5), ()]
- _bad_values = [10, 'hello', {}, None]
-
- def coerce(self, value):
- if value is not None:
- value = tuple(value)
- return value
-
- def test_invalid_args(self):
- self.assertRaises(TypeError, Tuple, 5)
- self.assertRaises(TypeError, Tuple, default_value='hello')
- t = Tuple(Int(), CBytes(), default_value=(1,5))
-
-
-class MultiTupleTrait(HasTraits):
-
- value = Tuple(Int(), Bytes(), default_value=[99,b'bottles'])
-
-class TestMultiTuple(TraitTestBase):
-
- obj = MultiTupleTrait()
-
- _default_value = (99,b'bottles')
- _good_values = [(1,b'a'), (2,b'b')]
+ _good_values = [(1,), (0,), [1]]
+ _bad_values = [10, (1, 2), ('a'), (), None]
+
+ def coerce(self, value):
+ if value is not None:
+ value = tuple(value)
+ return value
+
+ def test_invalid_args(self):
+ self.assertRaises(TypeError, Tuple, 5)
+ self.assertRaises(TypeError, Tuple, default_value='hello')
+ t = Tuple(Int(), CBytes(), default_value=(1,5))
+
+class LooseTupleTrait(HasTraits):
+
+ value = Tuple((1,2,3))
+
+class TestLooseTupleTrait(TraitTestBase):
+
+ obj = LooseTupleTrait()
+
+ _default_value = (1,2,3)
+ _good_values = [(1,), [1], (0,), tuple(range(5)), tuple('hello'), ('a',5), ()]
+ _bad_values = [10, 'hello', {}, None]
+
+ def coerce(self, value):
+ if value is not None:
+ value = tuple(value)
+ return value
+
+ def test_invalid_args(self):
+ self.assertRaises(TypeError, Tuple, 5)
+ self.assertRaises(TypeError, Tuple, default_value='hello')
+ t = Tuple(Int(), CBytes(), default_value=(1,5))
+
+
+class MultiTupleTrait(HasTraits):
+
+ value = Tuple(Int(), Bytes(), default_value=[99,b'bottles'])
+
+class TestMultiTuple(TraitTestBase):
+
+ obj = MultiTupleTrait()
+
+ _default_value = (99,b'bottles')
+ _good_values = [(1,b'a'), (2,b'b')]
_bad_values = ((),10, b'a', (1,b'a',3), (b'a',1), (1, 'a'))
-
+
@pytest.mark.parametrize(
"Trait", (List, Tuple, Set, Dict, Integer, Unicode,),
@@ -1707,64 +1707,64 @@ def test_subclass_default_value(Trait, default_value):
assert c.t == default_value
-class CRegExpTrait(HasTraits):
-
- value = CRegExp(r'')
-
-
-class TestCRegExp(TraitTestBase):
-
- def coerce(self, value):
- return re.compile(value)
-
- obj = CRegExpTrait()
-
- _default_value = re.compile(r'')
- _good_values = [r'\d+', re.compile(r'\d+')]
- _bad_values = ['(', None, ()]
-
-class DictTrait(HasTraits):
- value = Dict()
-
-def test_dict_assignment():
- d = dict()
- c = DictTrait()
- c.value = d
- d['a'] = 5
+class CRegExpTrait(HasTraits):
+
+ value = CRegExp(r'')
+
+
+class TestCRegExp(TraitTestBase):
+
+ def coerce(self, value):
+ return re.compile(value)
+
+ obj = CRegExpTrait()
+
+ _default_value = re.compile(r'')
+ _good_values = [r'\d+', re.compile(r'\d+')]
+ _bad_values = ['(', None, ()]
+
+class DictTrait(HasTraits):
+ value = Dict()
+
+def test_dict_assignment():
+ d = dict()
+ c = DictTrait()
+ c.value = d
+ d['a'] = 5
assert d == c.value
- assert c.value is d
-
-
+ assert c.value is d
+
+
class UniformlyValueValidatedDictTrait(HasTraits):
-
- value = Dict(trait=Unicode(),
- default_value={'foo': '1'})
-
-
+
+ value = Dict(trait=Unicode(),
+ default_value={'foo': '1'})
+
+
class TestInstanceUniformlyValueValidatedDict(TraitTestBase):
-
+
obj = UniformlyValueValidatedDictTrait()
-
- _default_value = {'foo': '1'}
- _good_values = [{'foo': '0', 'bar': '1'}]
- _bad_values = [{'foo': 0, 'bar': '1'}]
-
-
+
+ _default_value = {'foo': '1'}
+ _good_values = [{'foo': '0', 'bar': '1'}]
+ _bad_values = [{'foo': 0, 'bar': '1'}]
+
+
class NonuniformlyValueValidatedDictTrait(HasTraits):
-
- value = Dict(traits={'foo': Int()},
- default_value={'foo': 1})
-
-
+
+ value = Dict(traits={'foo': Int()},
+ default_value={'foo': 1})
+
+
class TestInstanceNonuniformlyValueValidatedDict(TraitTestBase):
-
+
obj = NonuniformlyValueValidatedDictTrait()
-
- _default_value = {'foo': 1}
- _good_values = [{'foo': 0, 'bar': '1'}, {'foo': 0, 'bar': 1}]
- _bad_values = [{'foo': '0', 'bar': '1'}]
-
-
+
+ _default_value = {'foo': 1}
+ _good_values = [{'foo': 0, 'bar': '1'}, {'foo': 0, 'bar': 1}]
+ _bad_values = [{'foo': '0', 'bar': '1'}]
+
+
class KeyValidatedDictTrait(HasTraits):
value = Dict(key_trait=Unicode(),
@@ -1780,196 +1780,196 @@ class TestInstanceKeyValidatedDict(TraitTestBase):
_bad_values = [{'foo': '0', 0: '1'}]
-class FullyValidatedDictTrait(HasTraits):
-
- value = Dict(trait=Unicode(),
+class FullyValidatedDictTrait(HasTraits):
+
+ value = Dict(trait=Unicode(),
key_trait=Unicode(),
- traits={'foo': Int()},
- default_value={'foo': 1})
-
-
-class TestInstanceFullyValidatedDict(TraitTestBase):
-
- obj = FullyValidatedDictTrait()
-
- _default_value = {'foo': 1}
- _good_values = [{'foo': 0, 'bar': '1'}, {'foo': 1, 'bar': '2'}]
+ traits={'foo': Int()},
+ default_value={'foo': 1})
+
+
+class TestInstanceFullyValidatedDict(TraitTestBase):
+
+ obj = FullyValidatedDictTrait()
+
+ _default_value = {'foo': 1}
+ _good_values = [{'foo': 0, 'bar': '1'}, {'foo': 1, 'bar': '2'}]
_bad_values = [{'foo': 0, 'bar': 1}, {'foo': '0', 'bar': '1'}, {'foo': 0, 0: '1'}]
-
-
-def test_dict_default_value():
- """Check that the `{}` default value of the Dict traitlet constructor is
- actually copied."""
-
- class Foo(HasTraits):
- d1 = Dict()
- d2 = Dict()
-
- foo = Foo()
- assert foo.d1 == {}
- assert foo.d2 == {}
- assert foo.d1 is not foo.d2
-
-
-class TestValidationHook(TestCase):
-
- def test_parity_trait(self):
- """Verify that the early validation hook is effective"""
-
- class Parity(HasTraits):
-
- value = Int(0)
- parity = Enum(['odd', 'even'], default_value='even')
-
- @validate('value')
- def _value_validate(self, proposal):
- value = proposal['value']
- if self.parity == 'even' and value % 2:
- raise TraitError('Expected an even number')
- if self.parity == 'odd' and (value % 2 == 0):
- raise TraitError('Expected an odd number')
- return value
-
- u = Parity()
- u.parity = 'odd'
- u.value = 1 # OK
- with self.assertRaises(TraitError):
- u.value = 2 # Trait Error
-
- u.parity = 'even'
- u.value = 2 # OK
-
- def test_multiple_validate(self):
- """Verify that we can register the same validator to multiple names"""
-
- class OddEven(HasTraits):
-
- odd = Int(1)
- even = Int(0)
-
- @validate('odd', 'even')
- def check_valid(self, proposal):
- if proposal['trait'].name == 'odd' and not proposal['value'] % 2:
- raise TraitError('odd should be odd')
- if proposal['trait'].name == 'even' and proposal['value'] % 2:
- raise TraitError('even should be even')
-
- u = OddEven()
- u.odd = 3 # OK
- with self.assertRaises(TraitError):
- u.odd = 2 # Trait Error
-
- u.even = 2 # OK
- with self.assertRaises(TraitError):
- u.even = 3 # Trait Error
-
-
-
-class TestLink(TestCase):
-
- def test_connect_same(self):
- """Verify two traitlets of the same type can be linked together using link."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- a = A(value=9)
- b = A(value=8)
-
- # Conenct the two classes.
- c = link((a, 'value'), (b, 'value'))
-
- # Make sure the values are the same at the point of linking.
- self.assertEqual(a.value, b.value)
-
- # Change one of the values to make sure they stay in sync.
- a.value = 5
- self.assertEqual(a.value, b.value)
- b.value = 6
- self.assertEqual(a.value, b.value)
-
- def test_link_different(self):
- """Verify two traitlets of different types can be linked together using link."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- class B(HasTraits):
- count = Int()
- a = A(value=9)
- b = B(count=8)
-
- # Conenct the two classes.
- c = link((a, 'value'), (b, 'count'))
-
- # Make sure the values are the same at the point of linking.
- self.assertEqual(a.value, b.count)
-
- # Change one of the values to make sure they stay in sync.
- a.value = 5
- self.assertEqual(a.value, b.count)
- b.count = 4
- self.assertEqual(a.value, b.count)
-
+
+
+def test_dict_default_value():
+ """Check that the `{}` default value of the Dict traitlet constructor is
+ actually copied."""
+
+ class Foo(HasTraits):
+ d1 = Dict()
+ d2 = Dict()
+
+ foo = Foo()
+ assert foo.d1 == {}
+ assert foo.d2 == {}
+ assert foo.d1 is not foo.d2
+
+
+class TestValidationHook(TestCase):
+
+ def test_parity_trait(self):
+ """Verify that the early validation hook is effective"""
+
+ class Parity(HasTraits):
+
+ value = Int(0)
+ parity = Enum(['odd', 'even'], default_value='even')
+
+ @validate('value')
+ def _value_validate(self, proposal):
+ value = proposal['value']
+ if self.parity == 'even' and value % 2:
+ raise TraitError('Expected an even number')
+ if self.parity == 'odd' and (value % 2 == 0):
+ raise TraitError('Expected an odd number')
+ return value
+
+ u = Parity()
+ u.parity = 'odd'
+ u.value = 1 # OK
+ with self.assertRaises(TraitError):
+ u.value = 2 # Trait Error
+
+ u.parity = 'even'
+ u.value = 2 # OK
+
+ def test_multiple_validate(self):
+ """Verify that we can register the same validator to multiple names"""
+
+ class OddEven(HasTraits):
+
+ odd = Int(1)
+ even = Int(0)
+
+ @validate('odd', 'even')
+ def check_valid(self, proposal):
+ if proposal['trait'].name == 'odd' and not proposal['value'] % 2:
+ raise TraitError('odd should be odd')
+ if proposal['trait'].name == 'even' and proposal['value'] % 2:
+ raise TraitError('even should be even')
+
+ u = OddEven()
+ u.odd = 3 # OK
+ with self.assertRaises(TraitError):
+ u.odd = 2 # Trait Error
+
+ u.even = 2 # OK
+ with self.assertRaises(TraitError):
+ u.even = 3 # Trait Error
+
+
+
+class TestLink(TestCase):
+
+ def test_connect_same(self):
+ """Verify two traitlets of the same type can be linked together using link."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ a = A(value=9)
+ b = A(value=8)
+
+ # Conenct the two classes.
+ c = link((a, 'value'), (b, 'value'))
+
+ # Make sure the values are the same at the point of linking.
+ self.assertEqual(a.value, b.value)
+
+ # Change one of the values to make sure they stay in sync.
+ a.value = 5
+ self.assertEqual(a.value, b.value)
+ b.value = 6
+ self.assertEqual(a.value, b.value)
+
+ def test_link_different(self):
+ """Verify two traitlets of different types can be linked together using link."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ class B(HasTraits):
+ count = Int()
+ a = A(value=9)
+ b = B(count=8)
+
+ # Conenct the two classes.
+ c = link((a, 'value'), (b, 'count'))
+
+ # Make sure the values are the same at the point of linking.
+ self.assertEqual(a.value, b.count)
+
+ # Change one of the values to make sure they stay in sync.
+ a.value = 5
+ self.assertEqual(a.value, b.count)
+ b.count = 4
+ self.assertEqual(a.value, b.count)
+
def test_unlink_link(self):
"""Verify two linked traitlets can be unlinked and relinked."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- a = A(value=9)
- b = A(value=8)
-
- # Connect the two classes.
- c = link((a, 'value'), (b, 'value'))
- a.value = 4
- c.unlink()
-
- # Change one of the values to make sure they don't stay in sync.
- a.value = 5
- self.assertNotEqual(a.value, b.value)
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ a = A(value=9)
+ b = A(value=8)
+
+ # Connect the two classes.
+ c = link((a, 'value'), (b, 'value'))
+ a.value = 4
+ c.unlink()
+
+ # Change one of the values to make sure they don't stay in sync.
+ a.value = 5
+ self.assertNotEqual(a.value, b.value)
c.link()
self.assertEqual(a.value, b.value)
a.value += 1
self.assertEqual(a.value, b.value)
-
- def test_callbacks(self):
- """Verify two linked traitlets have their callbacks called once."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- class B(HasTraits):
- count = Int()
- a = A(value=9)
- b = B(count=8)
-
- # Register callbacks that count.
- callback_count = []
- def a_callback(name, old, new):
- callback_count.append('a')
- a.on_trait_change(a_callback, 'value')
- def b_callback(name, old, new):
- callback_count.append('b')
- b.on_trait_change(b_callback, 'count')
-
- # Connect the two classes.
- c = link((a, 'value'), (b, 'count'))
-
- # Make sure b's count was set to a's value once.
- self.assertEqual(''.join(callback_count), 'b')
- del callback_count[:]
-
- # Make sure a's value was set to b's count once.
- b.count = 5
- self.assertEqual(''.join(callback_count), 'ba')
- del callback_count[:]
-
- # Make sure b's count was set to a's value once.
- a.value = 4
- self.assertEqual(''.join(callback_count), 'ab')
- del callback_count[:]
-
+
+ def test_callbacks(self):
+ """Verify two linked traitlets have their callbacks called once."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ class B(HasTraits):
+ count = Int()
+ a = A(value=9)
+ b = B(count=8)
+
+ # Register callbacks that count.
+ callback_count = []
+ def a_callback(name, old, new):
+ callback_count.append('a')
+ a.on_trait_change(a_callback, 'value')
+ def b_callback(name, old, new):
+ callback_count.append('b')
+ b.on_trait_change(b_callback, 'count')
+
+ # Connect the two classes.
+ c = link((a, 'value'), (b, 'count'))
+
+ # Make sure b's count was set to a's value once.
+ self.assertEqual(''.join(callback_count), 'b')
+ del callback_count[:]
+
+ # Make sure a's value was set to b's count once.
+ b.count = 5
+ self.assertEqual(''.join(callback_count), 'ba')
+ del callback_count[:]
+
+ # Make sure b's count was set to a's value once.
+ a.value = 4
+ self.assertEqual(''.join(callback_count), 'ab')
+ del callback_count[:]
+
def test_tranform(self):
"""Test transform link."""
@@ -2020,610 +2020,610 @@ class TestLink(TestCase):
l = link((mc, "i"), (mc, "j"))
self.assertRaises(TraitError, setattr, mc, 'j', 2)
-class TestDirectionalLink(TestCase):
- def test_connect_same(self):
- """Verify two traitlets of the same type can be linked together using directional_link."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- a = A(value=9)
- b = A(value=8)
-
- # Conenct the two classes.
- c = directional_link((a, 'value'), (b, 'value'))
-
- # Make sure the values are the same at the point of linking.
- self.assertEqual(a.value, b.value)
-
- # Change one the value of the source and check that it synchronizes the target.
- a.value = 5
- self.assertEqual(b.value, 5)
- # Change one the value of the target and check that it has no impact on the source
- b.value = 6
- self.assertEqual(a.value, 5)
-
- def test_tranform(self):
- """Test transform link."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- a = A(value=9)
- b = A(value=8)
-
- # Conenct the two classes.
- c = directional_link((a, 'value'), (b, 'value'), lambda x: 2 * x)
-
- # Make sure the values are correct at the point of linking.
- self.assertEqual(b.value, 2 * a.value)
-
- # Change one the value of the source and check that it modifies the target.
- a.value = 5
- self.assertEqual(b.value, 10)
- # Change one the value of the target and check that it has no impact on the source
- b.value = 6
- self.assertEqual(a.value, 5)
-
- def test_link_different(self):
- """Verify two traitlets of different types can be linked together using link."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- class B(HasTraits):
- count = Int()
- a = A(value=9)
- b = B(count=8)
-
- # Conenct the two classes.
- c = directional_link((a, 'value'), (b, 'count'))
-
- # Make sure the values are the same at the point of linking.
- self.assertEqual(a.value, b.count)
-
- # Change one the value of the source and check that it synchronizes the target.
- a.value = 5
- self.assertEqual(b.count, 5)
- # Change one the value of the target and check that it has no impact on the source
- b.value = 6
- self.assertEqual(a.value, 5)
-
+class TestDirectionalLink(TestCase):
+ def test_connect_same(self):
+ """Verify two traitlets of the same type can be linked together using directional_link."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ a = A(value=9)
+ b = A(value=8)
+
+ # Conenct the two classes.
+ c = directional_link((a, 'value'), (b, 'value'))
+
+ # Make sure the values are the same at the point of linking.
+ self.assertEqual(a.value, b.value)
+
+ # Change one the value of the source and check that it synchronizes the target.
+ a.value = 5
+ self.assertEqual(b.value, 5)
+ # Change one the value of the target and check that it has no impact on the source
+ b.value = 6
+ self.assertEqual(a.value, 5)
+
+ def test_tranform(self):
+ """Test transform link."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ a = A(value=9)
+ b = A(value=8)
+
+ # Conenct the two classes.
+ c = directional_link((a, 'value'), (b, 'value'), lambda x: 2 * x)
+
+ # Make sure the values are correct at the point of linking.
+ self.assertEqual(b.value, 2 * a.value)
+
+ # Change one the value of the source and check that it modifies the target.
+ a.value = 5
+ self.assertEqual(b.value, 10)
+ # Change one the value of the target and check that it has no impact on the source
+ b.value = 6
+ self.assertEqual(a.value, 5)
+
+ def test_link_different(self):
+ """Verify two traitlets of different types can be linked together using link."""
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ class B(HasTraits):
+ count = Int()
+ a = A(value=9)
+ b = B(count=8)
+
+ # Conenct the two classes.
+ c = directional_link((a, 'value'), (b, 'count'))
+
+ # Make sure the values are the same at the point of linking.
+ self.assertEqual(a.value, b.count)
+
+ # Change one the value of the source and check that it synchronizes the target.
+ a.value = 5
+ self.assertEqual(b.count, 5)
+ # Change one the value of the target and check that it has no impact on the source
+ b.value = 6
+ self.assertEqual(a.value, 5)
+
def test_unlink_link(self):
"""Verify two linked traitlets can be unlinked and relinked."""
-
- # Create two simple classes with Int traitlets.
- class A(HasTraits):
- value = Int()
- a = A(value=9)
- b = A(value=8)
-
- # Connect the two classes.
- c = directional_link((a, 'value'), (b, 'value'))
- a.value = 4
- c.unlink()
-
- # Change one of the values to make sure they don't stay in sync.
- a.value = 5
- self.assertNotEqual(a.value, b.value)
+
+ # Create two simple classes with Int traitlets.
+ class A(HasTraits):
+ value = Int()
+ a = A(value=9)
+ b = A(value=8)
+
+ # Connect the two classes.
+ c = directional_link((a, 'value'), (b, 'value'))
+ a.value = 4
+ c.unlink()
+
+ # Change one of the values to make sure they don't stay in sync.
+ a.value = 5
+ self.assertNotEqual(a.value, b.value)
c.link()
self.assertEqual(a.value, b.value)
a.value += 1
self.assertEqual(a.value, b.value)
-
-class Pickleable(HasTraits):
-
- i = Int()
- @observe('i')
- def _i_changed(self, change): pass
- @validate('i')
- def _i_validate(self, commit):
- return commit['value']
-
- j = Int()
-
- def __init__(self):
- with self.hold_trait_notifications():
- self.i = 1
- self.on_trait_change(self._i_changed, 'i')
-
-def test_pickle_hastraits():
- c = Pickleable()
- for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
- p = pickle.dumps(c, protocol)
- c2 = pickle.loads(p)
- assert c2.i == c.i
- assert c2.j == c.j
-
- c.i = 5
- for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
- p = pickle.dumps(c, protocol)
- c2 = pickle.loads(p)
- assert c2.i == c.i
- assert c2.j == c.j
-
-
-def test_hold_trait_notifications():
- changes = []
-
- class Test(HasTraits):
- a = Integer(0)
- b = Integer(0)
-
- def _a_changed(self, name, old, new):
- changes.append((old, new))
-
- def _b_validate(self, value, trait):
- if value != 0:
- raise TraitError('Only 0 is a valid value')
- return value
-
- # Test context manager and nesting
- t = Test()
- with t.hold_trait_notifications():
- with t.hold_trait_notifications():
- t.a = 1
- assert t.a == 1
- assert changes == []
- t.a = 2
- assert t.a == 2
- with t.hold_trait_notifications():
- t.a = 3
- assert t.a == 3
- assert changes == []
- t.a = 4
- assert t.a == 4
- assert changes == []
- t.a = 4
- assert t.a == 4
- assert changes == []
-
- assert changes == [(0, 4)]
- # Test roll-back
- try:
- with t.hold_trait_notifications():
- t.b = 1 # raises a Trait error
- except:
- pass
- assert t.b == 0
-
-
-class RollBack(HasTraits):
- bar = Int()
- def _bar_validate(self, value, trait):
- if value:
- raise TraitError('foobar')
- return value
-
-
-class TestRollback(TestCase):
-
- def test_roll_back(self):
-
- def assign_rollback():
- RollBack(bar=1)
-
- self.assertRaises(TraitError, assign_rollback)
-
-
-class CacheModification(HasTraits):
- foo = Int()
- bar = Int()
-
- def _bar_validate(self, value, trait):
- self.foo = value
- return value
-
- def _foo_validate(self, value, trait):
- self.bar = value
- return value
-
-
-def test_cache_modification():
- CacheModification(foo=1)
- CacheModification(bar=1)
-
-
-class OrderTraits(HasTraits):
- notified = Dict()
-
- a = Unicode()
- b = Unicode()
- c = Unicode()
- d = Unicode()
- e = Unicode()
- f = Unicode()
- g = Unicode()
- h = Unicode()
- i = Unicode()
- j = Unicode()
- k = Unicode()
- l = Unicode()
-
- def _notify(self, name, old, new):
- """check the value of all traits when each trait change is triggered
-
- This verifies that the values are not sensitive
- to dict ordering when loaded from kwargs
- """
- # check the value of the other traits
- # when a given trait change notification fires
- self.notified[name] = {
- c: getattr(self, c) for c in 'abcdefghijkl'
- }
-
- def __init__(self, **kwargs):
- self.on_trait_change(self._notify)
- super(OrderTraits, self).__init__(**kwargs)
-
-def test_notification_order():
- d = {c:c for c in 'abcdefghijkl'}
- obj = OrderTraits()
- assert obj.notified == {}
- obj = OrderTraits(**d)
- notifications = {
- c: d for c in 'abcdefghijkl'
- }
- assert obj.notified == notifications
-
-
-
-###
-# Traits for Forward Declaration Tests
-###
-class ForwardDeclaredInstanceTrait(HasTraits):
-
- value = ForwardDeclaredInstance('ForwardDeclaredBar', allow_none=True)
-
-class ForwardDeclaredTypeTrait(HasTraits):
-
- value = ForwardDeclaredType('ForwardDeclaredBar', allow_none=True)
-
-class ForwardDeclaredInstanceListTrait(HasTraits):
-
- value = List(ForwardDeclaredInstance('ForwardDeclaredBar'))
-
-class ForwardDeclaredTypeListTrait(HasTraits):
-
- value = List(ForwardDeclaredType('ForwardDeclaredBar'))
-###
-# End Traits for Forward Declaration Tests
-###
-
-###
-# Classes for Forward Declaration Tests
-###
-class ForwardDeclaredBar(object):
- pass
-
-class ForwardDeclaredBarSub(ForwardDeclaredBar):
- pass
-###
-# End Classes for Forward Declaration Tests
-###
-
-###
-# Forward Declaration Tests
-###
-class TestForwardDeclaredInstanceTrait(TraitTestBase):
-
- obj = ForwardDeclaredInstanceTrait()
- _default_value = None
- _good_values = [None, ForwardDeclaredBar(), ForwardDeclaredBarSub()]
- _bad_values = ['foo', 3, ForwardDeclaredBar, ForwardDeclaredBarSub]
-
-class TestForwardDeclaredTypeTrait(TraitTestBase):
-
- obj = ForwardDeclaredTypeTrait()
- _default_value = None
- _good_values = [None, ForwardDeclaredBar, ForwardDeclaredBarSub]
- _bad_values = ['foo', 3, ForwardDeclaredBar(), ForwardDeclaredBarSub()]
-
-class TestForwardDeclaredInstanceList(TraitTestBase):
-
- obj = ForwardDeclaredInstanceListTrait()
-
- def test_klass(self):
- """Test that the instance klass is properly assigned."""
- self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar)
-
- _default_value = []
- _good_values = [
- [ForwardDeclaredBar(), ForwardDeclaredBarSub()],
- [],
- ]
- _bad_values = [
- ForwardDeclaredBar(),
- [ForwardDeclaredBar(), 3, None],
- '1',
- # Note that this is the type, not an instance.
- [ForwardDeclaredBar],
- [None],
- None,
- ]
-
-class TestForwardDeclaredTypeList(TraitTestBase):
-
- obj = ForwardDeclaredTypeListTrait()
-
- def test_klass(self):
- """Test that the instance klass is properly assigned."""
- self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar)
-
- _default_value = []
- _good_values = [
- [ForwardDeclaredBar, ForwardDeclaredBarSub],
- [],
- ]
- _bad_values = [
- ForwardDeclaredBar,
- [ForwardDeclaredBar, 3],
- '1',
- # Note that this is an instance, not the type.
- [ForwardDeclaredBar()],
- [None],
- None,
- ]
-###
-# End Forward Declaration Tests
-###
-
-class TestDynamicTraits(TestCase):
-
- def setUp(self):
- self._notify1 = []
-
- def notify1(self, name, old, new):
- self._notify1.append((name, old, new))
-
- def test_notify_all(self):
-
- class A(HasTraits):
- pass
-
- a = A()
- self.assertTrue(not hasattr(a, 'x'))
- self.assertTrue(not hasattr(a, 'y'))
-
- # Dynamically add trait x.
- a.add_traits(x=Int())
- self.assertTrue(hasattr(a, 'x'))
- self.assertTrue(isinstance(a, (A, )))
-
- # Dynamically add trait y.
- a.add_traits(y=Float())
- self.assertTrue(hasattr(a, 'y'))
- self.assertTrue(isinstance(a, (A, )))
- self.assertEqual(a.__class__.__name__, A.__name__)
-
- # Create a new instance and verify that x and y
- # aren't defined.
- b = A()
- self.assertTrue(not hasattr(b, 'x'))
- self.assertTrue(not hasattr(b, 'y'))
-
- # Verify that notification works like normal.
- a.on_trait_change(self.notify1)
- a.x = 0
- self.assertEqual(len(self._notify1), 0)
- a.y = 0.0
- self.assertEqual(len(self._notify1), 0)
- a.x = 10
- self.assertTrue(('x', 0, 10) in self._notify1)
- a.y = 10.0
- self.assertTrue(('y', 0.0, 10.0) in self._notify1)
- self.assertRaises(TraitError, setattr, a, 'x', 'bad string')
- self.assertRaises(TraitError, setattr, a, 'y', 'bad string')
- self._notify1 = []
- a.on_trait_change(self.notify1, remove=True)
- a.x = 20
- a.y = 20.0
- self.assertEqual(len(self._notify1), 0)
-
-
-def test_enum_no_default():
- class C(HasTraits):
- t = Enum(['a', 'b'])
-
- c = C()
- c.t = 'a'
- assert c.t == 'a'
-
- c = C()
-
- with pytest.raises(TraitError):
- t = c.t
-
- c = C(t='b')
- assert c.t == 'b'
-
-
-def test_default_value_repr():
- class C(HasTraits):
- t = Type('traitlets.HasTraits')
- t2 = Type(HasTraits)
- n = Integer(0)
- lis = List()
- d = Dict()
-
- assert C.t.default_value_repr() == "'traitlets.HasTraits'"
- assert C.t2.default_value_repr() == "'traitlets.traitlets.HasTraits'"
- assert C.n.default_value_repr() == '0'
- assert C.lis.default_value_repr() == '[]'
- assert C.d.default_value_repr() == '{}'
-
-
-class TransitionalClass(HasTraits):
-
- d = Any()
- @default('d')
- def _d_default(self):
- return TransitionalClass
-
- parent_super = False
- calls_super = Integer(0)
-
- @default('calls_super')
- def _calls_super_default(self):
- return -1
-
- @observe('calls_super')
- @observe_compat
- def _calls_super_changed(self, change):
- self.parent_super = change
-
- parent_override = False
- overrides = Integer(0)
-
- @observe('overrides')
- @observe_compat
- def _overrides_changed(self, change):
- self.parent_override = change
-
-
-class SubClass(TransitionalClass):
- def _d_default(self):
- return SubClass
-
- subclass_super = False
- def _calls_super_changed(self, name, old, new):
- self.subclass_super = True
- super(SubClass, self)._calls_super_changed(name, old, new)
-
- subclass_override = False
- def _overrides_changed(self, name, old, new):
- self.subclass_override = True
-
-
-def test_subclass_compat():
- obj = SubClass()
- obj.calls_super = 5
- assert obj.parent_super
- assert obj.subclass_super
- obj.overrides = 5
- assert obj.subclass_override
- assert not obj.parent_override
- assert obj.d is SubClass
-
-
-class DefinesHandler(HasTraits):
- parent_called = False
-
- trait = Integer()
- @observe('trait')
- def handler(self, change):
- self.parent_called = True
-
-
-class OverridesHandler(DefinesHandler):
- child_called = False
-
- @observe('trait')
- def handler(self, change):
- self.child_called = True
-
-
-def test_subclass_override_observer():
- obj = OverridesHandler()
- obj.trait = 5
- assert obj.child_called
- assert not obj.parent_called
-
-
-class DoesntRegisterHandler(DefinesHandler):
- child_called = False
-
- def handler(self, change):
- self.child_called = True
-
-
-def test_subclass_override_not_registered():
- """Subclass that overrides observer and doesn't re-register unregisters both"""
- obj = DoesntRegisterHandler()
- obj.trait = 5
- assert not obj.child_called
- assert not obj.parent_called
-
-
-class AddsHandler(DefinesHandler):
- child_called = False
-
- @observe('trait')
- def child_handler(self, change):
- self.child_called = True
-
-def test_subclass_add_observer():
- obj = AddsHandler()
- obj.trait = 5
- assert obj.child_called
- assert obj.parent_called
-
-
-def test_observe_iterables():
-
- class C(HasTraits):
- i = Integer()
- s = Unicode()
-
- c = C()
- recorded = {}
- def record(change):
- recorded['change'] = change
-
- # observe with names=set
- c.observe(record, names={'i', 's'})
- c.i = 5
- assert recorded['change'].name == 'i'
- assert recorded['change'].new == 5
- c.s = 'hi'
- assert recorded['change'].name == 's'
- assert recorded['change'].new == 'hi'
-
- # observe with names=custom container with iter, contains
- class MyContainer(object):
- def __init__(self, container):
- self.container = container
-
- def __iter__(self):
- return iter(self.container)
-
- def __contains__(self, key):
- return key in self.container
-
- c.observe(record, names=MyContainer({'i', 's'}))
- c.i = 10
- assert recorded['change'].name == 'i'
- assert recorded['change'].new == 10
- c.s = 'ok'
- assert recorded['change'].name == 's'
- assert recorded['change'].new == 'ok'
-
-
-def test_super_args():
- class SuperRecorder(object):
- def __init__(self, *args, **kwargs):
- self.super_args = args
- self.super_kwargs = kwargs
-
- class SuperHasTraits(HasTraits, SuperRecorder):
- i = Integer()
-
- obj = SuperHasTraits('a1', 'a2', b=10, i=5, c='x')
- assert obj.i == 5
- assert not hasattr(obj, 'b')
- assert not hasattr(obj, 'c')
- assert obj.super_args == ('a1' , 'a2')
- assert obj.super_kwargs == {'b': 10 , 'c': 'x'}
-
-def test_super_bad_args():
- class SuperHasTraits(HasTraits):
- a = Integer()
+
+class Pickleable(HasTraits):
+
+ i = Int()
+ @observe('i')
+ def _i_changed(self, change): pass
+ @validate('i')
+ def _i_validate(self, commit):
+ return commit['value']
+
+ j = Int()
+
+ def __init__(self):
+ with self.hold_trait_notifications():
+ self.i = 1
+ self.on_trait_change(self._i_changed, 'i')
+
+def test_pickle_hastraits():
+ c = Pickleable()
+ for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
+ p = pickle.dumps(c, protocol)
+ c2 = pickle.loads(p)
+ assert c2.i == c.i
+ assert c2.j == c.j
+
+ c.i = 5
+ for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
+ p = pickle.dumps(c, protocol)
+ c2 = pickle.loads(p)
+ assert c2.i == c.i
+ assert c2.j == c.j
+
+
+def test_hold_trait_notifications():
+ changes = []
+
+ class Test(HasTraits):
+ a = Integer(0)
+ b = Integer(0)
+
+ def _a_changed(self, name, old, new):
+ changes.append((old, new))
+
+ def _b_validate(self, value, trait):
+ if value != 0:
+ raise TraitError('Only 0 is a valid value')
+ return value
+
+ # Test context manager and nesting
+ t = Test()
+ with t.hold_trait_notifications():
+ with t.hold_trait_notifications():
+ t.a = 1
+ assert t.a == 1
+ assert changes == []
+ t.a = 2
+ assert t.a == 2
+ with t.hold_trait_notifications():
+ t.a = 3
+ assert t.a == 3
+ assert changes == []
+ t.a = 4
+ assert t.a == 4
+ assert changes == []
+ t.a = 4
+ assert t.a == 4
+ assert changes == []
+
+ assert changes == [(0, 4)]
+ # Test roll-back
+ try:
+ with t.hold_trait_notifications():
+ t.b = 1 # raises a Trait error
+ except:
+ pass
+ assert t.b == 0
+
+
+class RollBack(HasTraits):
+ bar = Int()
+ def _bar_validate(self, value, trait):
+ if value:
+ raise TraitError('foobar')
+ return value
+
+
+class TestRollback(TestCase):
+
+ def test_roll_back(self):
+
+ def assign_rollback():
+ RollBack(bar=1)
+
+ self.assertRaises(TraitError, assign_rollback)
+
+
+class CacheModification(HasTraits):
+ foo = Int()
+ bar = Int()
+
+ def _bar_validate(self, value, trait):
+ self.foo = value
+ return value
+
+ def _foo_validate(self, value, trait):
+ self.bar = value
+ return value
+
+
+def test_cache_modification():
+ CacheModification(foo=1)
+ CacheModification(bar=1)
+
+
+class OrderTraits(HasTraits):
+ notified = Dict()
+
+ a = Unicode()
+ b = Unicode()
+ c = Unicode()
+ d = Unicode()
+ e = Unicode()
+ f = Unicode()
+ g = Unicode()
+ h = Unicode()
+ i = Unicode()
+ j = Unicode()
+ k = Unicode()
+ l = Unicode()
+
+ def _notify(self, name, old, new):
+ """check the value of all traits when each trait change is triggered
+
+ This verifies that the values are not sensitive
+ to dict ordering when loaded from kwargs
+ """
+ # check the value of the other traits
+ # when a given trait change notification fires
+ self.notified[name] = {
+ c: getattr(self, c) for c in 'abcdefghijkl'
+ }
+
+ def __init__(self, **kwargs):
+ self.on_trait_change(self._notify)
+ super(OrderTraits, self).__init__(**kwargs)
+
+def test_notification_order():
+ d = {c:c for c in 'abcdefghijkl'}
+ obj = OrderTraits()
+ assert obj.notified == {}
+ obj = OrderTraits(**d)
+ notifications = {
+ c: d for c in 'abcdefghijkl'
+ }
+ assert obj.notified == notifications
+
+
+
+###
+# Traits for Forward Declaration Tests
+###
+class ForwardDeclaredInstanceTrait(HasTraits):
+
+ value = ForwardDeclaredInstance('ForwardDeclaredBar', allow_none=True)
+
+class ForwardDeclaredTypeTrait(HasTraits):
+
+ value = ForwardDeclaredType('ForwardDeclaredBar', allow_none=True)
+
+class ForwardDeclaredInstanceListTrait(HasTraits):
+
+ value = List(ForwardDeclaredInstance('ForwardDeclaredBar'))
+
+class ForwardDeclaredTypeListTrait(HasTraits):
+
+ value = List(ForwardDeclaredType('ForwardDeclaredBar'))
+###
+# End Traits for Forward Declaration Tests
+###
+
+###
+# Classes for Forward Declaration Tests
+###
+class ForwardDeclaredBar(object):
+ pass
+
+class ForwardDeclaredBarSub(ForwardDeclaredBar):
+ pass
+###
+# End Classes for Forward Declaration Tests
+###
+
+###
+# Forward Declaration Tests
+###
+class TestForwardDeclaredInstanceTrait(TraitTestBase):
+
+ obj = ForwardDeclaredInstanceTrait()
+ _default_value = None
+ _good_values = [None, ForwardDeclaredBar(), ForwardDeclaredBarSub()]
+ _bad_values = ['foo', 3, ForwardDeclaredBar, ForwardDeclaredBarSub]
+
+class TestForwardDeclaredTypeTrait(TraitTestBase):
+
+ obj = ForwardDeclaredTypeTrait()
+ _default_value = None
+ _good_values = [None, ForwardDeclaredBar, ForwardDeclaredBarSub]
+ _bad_values = ['foo', 3, ForwardDeclaredBar(), ForwardDeclaredBarSub()]
+
+class TestForwardDeclaredInstanceList(TraitTestBase):
+
+ obj = ForwardDeclaredInstanceListTrait()
+
+ def test_klass(self):
+ """Test that the instance klass is properly assigned."""
+ self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar)
+
+ _default_value = []
+ _good_values = [
+ [ForwardDeclaredBar(), ForwardDeclaredBarSub()],
+ [],
+ ]
+ _bad_values = [
+ ForwardDeclaredBar(),
+ [ForwardDeclaredBar(), 3, None],
+ '1',
+ # Note that this is the type, not an instance.
+ [ForwardDeclaredBar],
+ [None],
+ None,
+ ]
+
+class TestForwardDeclaredTypeList(TraitTestBase):
+
+ obj = ForwardDeclaredTypeListTrait()
+
+ def test_klass(self):
+ """Test that the instance klass is properly assigned."""
+ self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar)
+
+ _default_value = []
+ _good_values = [
+ [ForwardDeclaredBar, ForwardDeclaredBarSub],
+ [],
+ ]
+ _bad_values = [
+ ForwardDeclaredBar,
+ [ForwardDeclaredBar, 3],
+ '1',
+ # Note that this is an instance, not the type.
+ [ForwardDeclaredBar()],
+ [None],
+ None,
+ ]
+###
+# End Forward Declaration Tests
+###
+
+class TestDynamicTraits(TestCase):
+
+ def setUp(self):
+ self._notify1 = []
+
+ def notify1(self, name, old, new):
+ self._notify1.append((name, old, new))
+
+ def test_notify_all(self):
+
+ class A(HasTraits):
+ pass
+
+ a = A()
+ self.assertTrue(not hasattr(a, 'x'))
+ self.assertTrue(not hasattr(a, 'y'))
+
+ # Dynamically add trait x.
+ a.add_traits(x=Int())
+ self.assertTrue(hasattr(a, 'x'))
+ self.assertTrue(isinstance(a, (A, )))
+
+ # Dynamically add trait y.
+ a.add_traits(y=Float())
+ self.assertTrue(hasattr(a, 'y'))
+ self.assertTrue(isinstance(a, (A, )))
+ self.assertEqual(a.__class__.__name__, A.__name__)
+
+ # Create a new instance and verify that x and y
+ # aren't defined.
+ b = A()
+ self.assertTrue(not hasattr(b, 'x'))
+ self.assertTrue(not hasattr(b, 'y'))
+
+ # Verify that notification works like normal.
+ a.on_trait_change(self.notify1)
+ a.x = 0
+ self.assertEqual(len(self._notify1), 0)
+ a.y = 0.0
+ self.assertEqual(len(self._notify1), 0)
+ a.x = 10
+ self.assertTrue(('x', 0, 10) in self._notify1)
+ a.y = 10.0
+ self.assertTrue(('y', 0.0, 10.0) in self._notify1)
+ self.assertRaises(TraitError, setattr, a, 'x', 'bad string')
+ self.assertRaises(TraitError, setattr, a, 'y', 'bad string')
+ self._notify1 = []
+ a.on_trait_change(self.notify1, remove=True)
+ a.x = 20
+ a.y = 20.0
+ self.assertEqual(len(self._notify1), 0)
+
+
+def test_enum_no_default():
+ class C(HasTraits):
+ t = Enum(['a', 'b'])
+
+ c = C()
+ c.t = 'a'
+ assert c.t == 'a'
+
+ c = C()
+
+ with pytest.raises(TraitError):
+ t = c.t
+
+ c = C(t='b')
+ assert c.t == 'b'
+
+
+def test_default_value_repr():
+ class C(HasTraits):
+ t = Type('traitlets.HasTraits')
+ t2 = Type(HasTraits)
+ n = Integer(0)
+ lis = List()
+ d = Dict()
+
+ assert C.t.default_value_repr() == "'traitlets.HasTraits'"
+ assert C.t2.default_value_repr() == "'traitlets.traitlets.HasTraits'"
+ assert C.n.default_value_repr() == '0'
+ assert C.lis.default_value_repr() == '[]'
+ assert C.d.default_value_repr() == '{}'
+
+
+class TransitionalClass(HasTraits):
+
+ d = Any()
+ @default('d')
+ def _d_default(self):
+ return TransitionalClass
+
+ parent_super = False
+ calls_super = Integer(0)
+
+ @default('calls_super')
+ def _calls_super_default(self):
+ return -1
+
+ @observe('calls_super')
+ @observe_compat
+ def _calls_super_changed(self, change):
+ self.parent_super = change
+
+ parent_override = False
+ overrides = Integer(0)
+
+ @observe('overrides')
+ @observe_compat
+ def _overrides_changed(self, change):
+ self.parent_override = change
+
+
+class SubClass(TransitionalClass):
+ def _d_default(self):
+ return SubClass
+
+ subclass_super = False
+ def _calls_super_changed(self, name, old, new):
+ self.subclass_super = True
+ super(SubClass, self)._calls_super_changed(name, old, new)
+
+ subclass_override = False
+ def _overrides_changed(self, name, old, new):
+ self.subclass_override = True
+
+
+def test_subclass_compat():
+ obj = SubClass()
+ obj.calls_super = 5
+ assert obj.parent_super
+ assert obj.subclass_super
+ obj.overrides = 5
+ assert obj.subclass_override
+ assert not obj.parent_override
+ assert obj.d is SubClass
+
+
+class DefinesHandler(HasTraits):
+ parent_called = False
+
+ trait = Integer()
+ @observe('trait')
+ def handler(self, change):
+ self.parent_called = True
+
+
+class OverridesHandler(DefinesHandler):
+ child_called = False
+
+ @observe('trait')
+ def handler(self, change):
+ self.child_called = True
+
+
+def test_subclass_override_observer():
+ obj = OverridesHandler()
+ obj.trait = 5
+ assert obj.child_called
+ assert not obj.parent_called
+
+
+class DoesntRegisterHandler(DefinesHandler):
+ child_called = False
+
+ def handler(self, change):
+ self.child_called = True
+
+
+def test_subclass_override_not_registered():
+ """Subclass that overrides observer and doesn't re-register unregisters both"""
+ obj = DoesntRegisterHandler()
+ obj.trait = 5
+ assert not obj.child_called
+ assert not obj.parent_called
+
+
+class AddsHandler(DefinesHandler):
+ child_called = False
+
+ @observe('trait')
+ def child_handler(self, change):
+ self.child_called = True
+
+def test_subclass_add_observer():
+ obj = AddsHandler()
+ obj.trait = 5
+ assert obj.child_called
+ assert obj.parent_called
+
+
+def test_observe_iterables():
+
+ class C(HasTraits):
+ i = Integer()
+ s = Unicode()
+
+ c = C()
+ recorded = {}
+ def record(change):
+ recorded['change'] = change
+
+ # observe with names=set
+ c.observe(record, names={'i', 's'})
+ c.i = 5
+ assert recorded['change'].name == 'i'
+ assert recorded['change'].new == 5
+ c.s = 'hi'
+ assert recorded['change'].name == 's'
+ assert recorded['change'].new == 'hi'
+
+ # observe with names=custom container with iter, contains
+ class MyContainer(object):
+ def __init__(self, container):
+ self.container = container
+
+ def __iter__(self):
+ return iter(self.container)
+
+ def __contains__(self, key):
+ return key in self.container
+
+ c.observe(record, names=MyContainer({'i', 's'}))
+ c.i = 10
+ assert recorded['change'].name == 'i'
+ assert recorded['change'].new == 10
+ c.s = 'ok'
+ assert recorded['change'].name == 's'
+ assert recorded['change'].new == 'ok'
+
+
+def test_super_args():
+ class SuperRecorder(object):
+ def __init__(self, *args, **kwargs):
+ self.super_args = args
+ self.super_kwargs = kwargs
+
+ class SuperHasTraits(HasTraits, SuperRecorder):
+ i = Integer()
+
+ obj = SuperHasTraits('a1', 'a2', b=10, i=5, c='x')
+ assert obj.i == 5
+ assert not hasattr(obj, 'b')
+ assert not hasattr(obj, 'c')
+ assert obj.super_args == ('a1' , 'a2')
+ assert obj.super_kwargs == {'b': 10 , 'c': 'x'}
+
+def test_super_bad_args():
+ class SuperHasTraits(HasTraits):
+ a = Integer()
w = ["Passing unrecognized arguments"]
- with expected_warnings(w):
- obj = SuperHasTraits(a=1, b=2)
+ with expected_warnings(w):
+ obj = SuperHasTraits(a=1, b=2)
assert obj.a == 1
- assert not hasattr(obj, 'b')
+ assert not hasattr(obj, 'b')
def test_default_mro():
diff --git a/contrib/python/traitlets/py3/traitlets/tests/test_traitlets_enum.py b/contrib/python/traitlets/py3/traitlets/tests/test_traitlets_enum.py
index 6a074aadfb..769e830b33 100644
--- a/contrib/python/traitlets/py3/traitlets/tests/test_traitlets_enum.py
+++ b/contrib/python/traitlets/py3/traitlets/tests/test_traitlets_enum.py
@@ -1,28 +1,28 @@
-# pylint: disable=missing-docstring, too-few-public-methods
-"""
-Test the trait-type ``UseEnum``.
-"""
-
-import unittest
-import enum
+# pylint: disable=missing-docstring, too-few-public-methods
+"""
+Test the trait-type ``UseEnum``.
+"""
+
+import unittest
+import enum
from traitlets import HasTraits, TraitError, Enum, UseEnum, CaselessStrEnum, FuzzyEnum
-
-
-# -----------------------------------------------------------------------------
-# TEST SUPPORT:
-# -----------------------------------------------------------------------------
-
-class Color(enum.Enum):
- red = 1
- green = 2
- blue = 3
- yellow = 4
-
-class OtherColor(enum.Enum):
- red = 0
- green = 1
-
-
+
+
+# -----------------------------------------------------------------------------
+# TEST SUPPORT:
+# -----------------------------------------------------------------------------
+
+class Color(enum.Enum):
+ red = 1
+ green = 2
+ blue = 3
+ yellow = 4
+
+class OtherColor(enum.Enum):
+ red = 0
+ green = 1
+
+
class CSColor(enum.Enum):
red = 1
Green = 2
@@ -33,161 +33,161 @@ class CSColor(enum.Enum):
color_choices = 'red Green BLUE YeLLoW'.split()
-# -----------------------------------------------------------------------------
-# TESTSUITE:
-# -----------------------------------------------------------------------------
-class TestUseEnum(unittest.TestCase):
- # pylint: disable=invalid-name
-
- class Example(HasTraits):
- color = UseEnum(Color, help="Color enum")
-
- def test_assign_enum_value(self):
- example = self.Example()
- example.color = Color.green
- self.assertEqual(example.color, Color.green)
-
- def test_assign_all_enum_values(self):
- # pylint: disable=no-member
- enum_values = [value for value in Color.__members__.values()]
- for value in enum_values:
- self.assertIsInstance(value, Color)
- example = self.Example()
- example.color = value
- self.assertEqual(example.color, value)
- self.assertIsInstance(value, Color)
-
- def test_assign_enum_value__with_other_enum_raises_error(self):
- example = self.Example()
- with self.assertRaises(TraitError):
- example.color = OtherColor.green
-
- def test_assign_enum_name_1(self):
- # -- CONVERT: string => Enum value (item)
- example = self.Example()
- example.color = "red"
- self.assertEqual(example.color, Color.red)
-
- def test_assign_enum_value_name(self):
- # -- CONVERT: string => Enum value (item)
- # pylint: disable=no-member
- enum_names = [enum_val.name for enum_val in Color.__members__.values()]
- for value in enum_names:
+# -----------------------------------------------------------------------------
+# TESTSUITE:
+# -----------------------------------------------------------------------------
+class TestUseEnum(unittest.TestCase):
+ # pylint: disable=invalid-name
+
+ class Example(HasTraits):
+ color = UseEnum(Color, help="Color enum")
+
+ def test_assign_enum_value(self):
+ example = self.Example()
+ example.color = Color.green
+ self.assertEqual(example.color, Color.green)
+
+ def test_assign_all_enum_values(self):
+ # pylint: disable=no-member
+ enum_values = [value for value in Color.__members__.values()]
+ for value in enum_values:
+ self.assertIsInstance(value, Color)
+ example = self.Example()
+ example.color = value
+ self.assertEqual(example.color, value)
+ self.assertIsInstance(value, Color)
+
+ def test_assign_enum_value__with_other_enum_raises_error(self):
+ example = self.Example()
+ with self.assertRaises(TraitError):
+ example.color = OtherColor.green
+
+ def test_assign_enum_name_1(self):
+ # -- CONVERT: string => Enum value (item)
+ example = self.Example()
+ example.color = "red"
+ self.assertEqual(example.color, Color.red)
+
+ def test_assign_enum_value_name(self):
+ # -- CONVERT: string => Enum value (item)
+ # pylint: disable=no-member
+ enum_names = [enum_val.name for enum_val in Color.__members__.values()]
+ for value in enum_names:
self.assertIsInstance(value, str)
- example = self.Example()
- enum_value = Color.__members__.get(value)
- example.color = value
- self.assertIs(example.color, enum_value)
- self.assertEqual(example.color.name, value)
-
- def test_assign_scoped_enum_value_name(self):
- # -- CONVERT: string => Enum value (item)
- scoped_names = ["Color.red", "Color.green", "Color.blue", "Color.yellow"]
- for value in scoped_names:
- example = self.Example()
- example.color = value
- self.assertIsInstance(example.color, Color)
+ example = self.Example()
+ enum_value = Color.__members__.get(value)
+ example.color = value
+ self.assertIs(example.color, enum_value)
+ self.assertEqual(example.color.name, value)
+
+ def test_assign_scoped_enum_value_name(self):
+ # -- CONVERT: string => Enum value (item)
+ scoped_names = ["Color.red", "Color.green", "Color.blue", "Color.yellow"]
+ for value in scoped_names:
+ example = self.Example()
+ example.color = value
+ self.assertIsInstance(example.color, Color)
self.assertEqual(str(example.color), value)
-
- def test_assign_bad_enum_value_name__raises_error(self):
- # -- CONVERT: string => Enum value (item)
- bad_enum_names = ["UNKNOWN_COLOR", "RED", "Green", "blue2"]
- for value in bad_enum_names:
- example = self.Example()
- with self.assertRaises(TraitError):
- example.color = value
-
- def test_assign_enum_value_number_1(self):
- # -- CONVERT: number => Enum value (item)
- example = self.Example()
- example.color = 1 # == Color.red.value
- example.color = Color.red.value
- self.assertEqual(example.color, Color.red)
-
- def test_assign_enum_value_number(self):
- # -- CONVERT: number => Enum value (item)
- # pylint: disable=no-member
- enum_numbers = [enum_val.value
- for enum_val in Color.__members__.values()]
- for value in enum_numbers:
- self.assertIsInstance(value, int)
- example = self.Example()
- example.color = value
- self.assertIsInstance(example.color, Color)
- self.assertEqual(example.color.value, value)
-
- def test_assign_bad_enum_value_number__raises_error(self):
- # -- CONVERT: number => Enum value (item)
- bad_numbers = [-1, 0, 5]
- for value in bad_numbers:
- self.assertIsInstance(value, int)
- assert UseEnum(Color).select_by_number(value, None) is None
- example = self.Example()
- with self.assertRaises(TraitError):
- example.color = value
-
- def test_ctor_without_default_value(self):
- # -- IMPLICIT: default_value = Color.red (first enum-value)
- class Example2(HasTraits):
- color = UseEnum(Color)
-
- example = Example2()
- self.assertEqual(example.color, Color.red)
-
- def test_ctor_with_default_value_as_enum_value(self):
- # -- CONVERT: number => Enum value (item)
- class Example2(HasTraits):
- color = UseEnum(Color, default_value=Color.green)
-
- example = Example2()
- self.assertEqual(example.color, Color.green)
-
-
- def test_ctor_with_default_value_none_and_not_allow_none(self):
- # -- IMPLICIT: default_value = Color.red (first enum-value)
- class Example2(HasTraits):
- color1 = UseEnum(Color, default_value=None, allow_none=False)
- color2 = UseEnum(Color, default_value=None)
- example = Example2()
- self.assertEqual(example.color1, Color.red)
- self.assertEqual(example.color2, Color.red)
-
- def test_ctor_with_default_value_none_and_allow_none(self):
- class Example2(HasTraits):
- color1 = UseEnum(Color, default_value=None, allow_none=True)
- color2 = UseEnum(Color, allow_none=True)
-
- example = Example2()
- self.assertIs(example.color1, None)
- self.assertIs(example.color2, None)
-
- def test_assign_none_without_allow_none_resets_to_default_value(self):
- class Example2(HasTraits):
- color1 = UseEnum(Color, allow_none=False)
- color2 = UseEnum(Color)
-
- example = Example2()
- example.color1 = None
- example.color2 = None
- self.assertIs(example.color1, Color.red)
- self.assertIs(example.color2, Color.red)
-
- def test_assign_none_to_enum_or_none(self):
- class Example2(HasTraits):
- color = UseEnum(Color, allow_none=True)
-
- example = Example2()
- example.color = None
- self.assertIs(example.color, None)
-
- def test_assign_bad_value_with_to_enum_or_none(self):
- class Example2(HasTraits):
- color = UseEnum(Color, allow_none=True)
-
- example = Example2()
- with self.assertRaises(TraitError):
- example.color = "BAD_VALUE"
-
+
+ def test_assign_bad_enum_value_name__raises_error(self):
+ # -- CONVERT: string => Enum value (item)
+ bad_enum_names = ["UNKNOWN_COLOR", "RED", "Green", "blue2"]
+ for value in bad_enum_names:
+ example = self.Example()
+ with self.assertRaises(TraitError):
+ example.color = value
+
+ def test_assign_enum_value_number_1(self):
+ # -- CONVERT: number => Enum value (item)
+ example = self.Example()
+ example.color = 1 # == Color.red.value
+ example.color = Color.red.value
+ self.assertEqual(example.color, Color.red)
+
+ def test_assign_enum_value_number(self):
+ # -- CONVERT: number => Enum value (item)
+ # pylint: disable=no-member
+ enum_numbers = [enum_val.value
+ for enum_val in Color.__members__.values()]
+ for value in enum_numbers:
+ self.assertIsInstance(value, int)
+ example = self.Example()
+ example.color = value
+ self.assertIsInstance(example.color, Color)
+ self.assertEqual(example.color.value, value)
+
+ def test_assign_bad_enum_value_number__raises_error(self):
+ # -- CONVERT: number => Enum value (item)
+ bad_numbers = [-1, 0, 5]
+ for value in bad_numbers:
+ self.assertIsInstance(value, int)
+ assert UseEnum(Color).select_by_number(value, None) is None
+ example = self.Example()
+ with self.assertRaises(TraitError):
+ example.color = value
+
+ def test_ctor_without_default_value(self):
+ # -- IMPLICIT: default_value = Color.red (first enum-value)
+ class Example2(HasTraits):
+ color = UseEnum(Color)
+
+ example = Example2()
+ self.assertEqual(example.color, Color.red)
+
+ def test_ctor_with_default_value_as_enum_value(self):
+ # -- CONVERT: number => Enum value (item)
+ class Example2(HasTraits):
+ color = UseEnum(Color, default_value=Color.green)
+
+ example = Example2()
+ self.assertEqual(example.color, Color.green)
+
+
+ def test_ctor_with_default_value_none_and_not_allow_none(self):
+ # -- IMPLICIT: default_value = Color.red (first enum-value)
+ class Example2(HasTraits):
+ color1 = UseEnum(Color, default_value=None, allow_none=False)
+ color2 = UseEnum(Color, default_value=None)
+ example = Example2()
+ self.assertEqual(example.color1, Color.red)
+ self.assertEqual(example.color2, Color.red)
+
+ def test_ctor_with_default_value_none_and_allow_none(self):
+ class Example2(HasTraits):
+ color1 = UseEnum(Color, default_value=None, allow_none=True)
+ color2 = UseEnum(Color, allow_none=True)
+
+ example = Example2()
+ self.assertIs(example.color1, None)
+ self.assertIs(example.color2, None)
+
+ def test_assign_none_without_allow_none_resets_to_default_value(self):
+ class Example2(HasTraits):
+ color1 = UseEnum(Color, allow_none=False)
+ color2 = UseEnum(Color)
+
+ example = Example2()
+ example.color1 = None
+ example.color2 = None
+ self.assertIs(example.color1, Color.red)
+ self.assertIs(example.color2, Color.red)
+
+ def test_assign_none_to_enum_or_none(self):
+ class Example2(HasTraits):
+ color = UseEnum(Color, allow_none=True)
+
+ example = Example2()
+ example.color = None
+ self.assertIs(example.color, None)
+
+ def test_assign_bad_value_with_to_enum_or_none(self):
+ class Example2(HasTraits):
+ color = UseEnum(Color, allow_none=True)
+
+ example = Example2()
+ with self.assertRaises(TraitError):
+ example.color = "BAD_VALUE"
+
def test_info(self):
import sys
diff --git a/contrib/python/traitlets/py3/traitlets/tests/utils.py b/contrib/python/traitlets/py3/traitlets/tests/utils.py
index 7cb76bfa2c..c5ac591435 100644
--- a/contrib/python/traitlets/py3/traitlets/tests/utils.py
+++ b/contrib/python/traitlets/py3/traitlets/tests/utils.py
@@ -1,42 +1,42 @@
from subprocess import Popen, PIPE
import sys
-import os
-
-
-def get_output_error_code(cmd):
- """Get stdout, stderr, and exit code from running a command"""
- env = os.environ.copy()
- env['Y_PYTHON_ENTRY_POINT'] = ':main'
- p = Popen(cmd, stdout=PIPE, stderr=PIPE, env=env)
- out, err = p.communicate()
- out = out.decode('utf8', 'replace')
- err = err.decode('utf8', 'replace')
- return out, err, p.returncode
-
-
-def check_help_output(pkg, subcommand=None):
- """test that `python -m PKG [subcommand] -h` works"""
- cmd = [sys.executable, '-m', pkg]
- if subcommand:
- cmd.extend(subcommand)
- cmd.append('-h')
- out, err, rc = get_output_error_code(cmd)
- assert rc == 0, err
- assert "Traceback" not in err
- assert "Options" in out
- assert "--help-all" in out
- return out, err
-
-
-def check_help_all_output(pkg, subcommand=None):
- """test that `python -m PKG --help-all` works"""
- cmd = [sys.executable, '-m', pkg]
- if subcommand:
- cmd.extend(subcommand)
- cmd.append('--help-all')
- out, err, rc = get_output_error_code(cmd)
- assert rc == 0, err
- assert "Traceback" not in err
- assert "Options" in out
+import os
+
+
+def get_output_error_code(cmd):
+ """Get stdout, stderr, and exit code from running a command"""
+ env = os.environ.copy()
+ env['Y_PYTHON_ENTRY_POINT'] = ':main'
+ p = Popen(cmd, stdout=PIPE, stderr=PIPE, env=env)
+ out, err = p.communicate()
+ out = out.decode('utf8', 'replace')
+ err = err.decode('utf8', 'replace')
+ return out, err, p.returncode
+
+
+def check_help_output(pkg, subcommand=None):
+ """test that `python -m PKG [subcommand] -h` works"""
+ cmd = [sys.executable, '-m', pkg]
+ if subcommand:
+ cmd.extend(subcommand)
+ cmd.append('-h')
+ out, err, rc = get_output_error_code(cmd)
+ assert rc == 0, err
+ assert "Traceback" not in err
+ assert "Options" in out
+ assert "--help-all" in out
+ return out, err
+
+
+def check_help_all_output(pkg, subcommand=None):
+ """test that `python -m PKG --help-all` works"""
+ cmd = [sys.executable, '-m', pkg]
+ if subcommand:
+ cmd.extend(subcommand)
+ cmd.append('--help-all')
+ out, err, rc = get_output_error_code(cmd)
+ assert rc == 0, err
+ assert "Traceback" not in err
+ assert "Options" in out
assert "Class options" in out
- return out, err
+ return out, err
diff --git a/contrib/python/traitlets/py3/ya.make b/contrib/python/traitlets/py3/ya.make
index ea546d53e4..46980f21b3 100644
--- a/contrib/python/traitlets/py3/ya.make
+++ b/contrib/python/traitlets/py3/ya.make
@@ -44,7 +44,7 @@ RESOURCE_FILES(
)
END()
-
-RECURSE_FOR_TESTS(
+
+RECURSE_FOR_TESTS(
tests
-)
+)
diff --git a/contrib/python/traitlets/ya.make b/contrib/python/traitlets/ya.make
index 97655f153c..3156aae8c5 100644
--- a/contrib/python/traitlets/ya.make
+++ b/contrib/python/traitlets/ya.make
@@ -13,8 +13,8 @@ ENDIF()
NO_LINT()
END()
-
+
RECURSE(
py2
py3
-)
+)
diff --git a/contrib/python/ya.make b/contrib/python/ya.make
index e86f722200..d01ced9f3a 100644
--- a/contrib/python/ya.make
+++ b/contrib/python/ya.make
@@ -173,7 +173,7 @@ RECURSE(
constantly
contextdecorator
contextlib2
- convertdate
+ convertdate
cookies
cov-core
coverage
@@ -197,7 +197,7 @@ RECURSE(
databases
dataclasses-json
datadiff
- dateparser
+ dateparser
dateutil
DAWG-Python
dbf_light
@@ -340,7 +340,7 @@ RECURSE(
environ-config
environs
envoy
- ephem
+ ephem
escapism
etcd3
excel-formulas-calculator
@@ -620,7 +620,7 @@ RECURSE(
meld3
memory-profiler
mercurial
- mistune
+ mistune
mitmproxy
mkdocs
mkdocs-material
@@ -641,14 +641,14 @@ RECURSE(
mpmath
msal
msgpack
- mujson
+ mujson
multidict
multitasking
munch
murmurhash
mutablerecords
- mypy
- mypy-extensions
+ mypy
+ mypy-extensions
mypy-protobuf
mypy-zope
MySQL-python
@@ -656,8 +656,8 @@ RECURSE(
namedlist
natsort
nbclient
- nbconvert
- nbformat
+ nbconvert
+ nbformat
ncclient
ndg-httpsclient
nest-asyncio
@@ -668,7 +668,7 @@ RECURSE(
nltk
normality
nose
- notebook
+ notebook
num2words
numpy
oauth2client
@@ -704,7 +704,7 @@ RECURSE(
panamap
panamap_proto
pandas
- pandocfilters
+ pandocfilters
papermill
parameterized
paramiko
@@ -728,7 +728,7 @@ RECURSE(
paypalrestsdk
pdbpp
pdfminer.six
- pecan
+ pecan
peewee
peewee/playhouse
pefile
@@ -752,7 +752,7 @@ RECURSE(
ply
plyvel
polib
- portalocker
+ portalocker
portpicker
ppdeep
pq
@@ -787,7 +787,7 @@ RECURSE(
py-radix
py3c
py4j
- pyaes
+ pyaes
pyahocorasick
pyaml
pyasn1
@@ -895,7 +895,7 @@ RECURSE(
python-decouple
python-docx
python-dotenv
- python-editor
+ python-editor
python-geohash
python-gnupg
python-hglib
@@ -910,7 +910,7 @@ RECURSE(
python-multipart
python-pptx
python-prctl
- python-rapidjson
+ python-rapidjson
python-saml
python-slugify
python-telegram-bot
@@ -954,7 +954,7 @@ RECURSE(
rfc3986-validator
RPi.GPIO
RPI-ST7789
- rsa
+ rsa
rstr
ruamel.std.pathlib
ruamel.yaml
@@ -985,7 +985,7 @@ RECURSE(
selenium
semantic-version
semver
- Send2Trash
+ Send2Trash
sentinels
sentry-sdk
service-identity
@@ -1051,13 +1051,13 @@ RECURSE(
tablib
tabulate
tblib
- Telethon
+ Telethon
tenacity
tensorflow-estimator
termcolor
- terminado
+ terminado
terminaltables
- testpath
+ testpath
text-unidecode
textdata
texttable
@@ -1094,11 +1094,11 @@ RECURSE(
txredisapi
typecode
typed-argument-parser
- typed-ast
+ typed-ast
typeguard
typer
typing
- typing-extensions
+ typing-extensions
typing-inspect
tzlocal
ua-parser
@@ -1106,7 +1106,7 @@ RECURSE(
uhashring
ujson
ulid2
- umalqurra
+ umalqurra
umongo
unicodecsv
Unidecode