aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/traitlets
diff options
context:
space:
mode:
authorNikita Slyusarev <nslus@yandex-team.com>2022-02-10 16:46:53 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:46:53 +0300
commit469afdc4e2587bf62ecdd096b75a0baa444c4012 (patch)
tree49e222ea1c5804306084bb3ae065bb702625360f /contrib/python/traitlets
parentcd77cecfc03a3eaf87816af28a33067c4f0cdb59 (diff)
downloadydb-469afdc4e2587bf62ecdd096b75a0baa444c4012.tar.gz
Restoring authorship annotation for Nikita Slyusarev <nslus@yandex-team.com>. Commit 2 of 2.
Diffstat (limited to 'contrib/python/traitlets')
-rw-r--r--contrib/python/traitlets/py2/traitlets/config/application.py256
-rw-r--r--contrib/python/traitlets/py2/traitlets/config/configurable.py100
-rw-r--r--contrib/python/traitlets/py2/traitlets/config/loader.py78
-rw-r--r--contrib/python/traitlets/py2/traitlets/config/manager.py2
-rw-r--r--contrib/python/traitlets/py2/traitlets/log.py12
-rw-r--r--contrib/python/traitlets/py2/traitlets/traitlets.py1026
-rw-r--r--contrib/python/traitlets/py2/traitlets/utils/bunch.py50
-rw-r--r--contrib/python/traitlets/py2/traitlets/utils/getargspec.py2
-rw-r--r--contrib/python/traitlets/py2/traitlets/utils/importstring.py4
-rw-r--r--contrib/python/traitlets/py2/ya.make4
-rw-r--r--contrib/python/traitlets/py3/traitlets/config/application.py220
-rw-r--r--contrib/python/traitlets/py3/traitlets/config/configurable.py88
-rw-r--r--contrib/python/traitlets/py3/traitlets/config/loader.py62
-rw-r--r--contrib/python/traitlets/py3/traitlets/log.py12
-rw-r--r--contrib/python/traitlets/py3/traitlets/traitlets.py754
-rw-r--r--contrib/python/traitlets/py3/traitlets/utils/bunch.py50
-rw-r--r--contrib/python/traitlets/py3/ya.make4
17 files changed, 1362 insertions, 1362 deletions
diff --git a/contrib/python/traitlets/py2/traitlets/config/application.py b/contrib/python/traitlets/py2/traitlets/config/application.py
index 5f750b5138..d3a4c45e77 100644
--- a/contrib/python/traitlets/py2/traitlets/config/application.py
+++ b/contrib/python/traitlets/py2/traitlets/config/application.py
@@ -6,13 +6,13 @@
from __future__ import print_function
-from copy import deepcopy
+from copy import deepcopy
import json
import logging
import os
import re
import sys
-from collections import defaultdict, OrderedDict
+from collections import defaultdict, OrderedDict
from decorator import decorator
@@ -22,14 +22,14 @@ from traitlets.config.loader import (
)
from traitlets.traitlets import (
- Bool, Unicode, List, Enum, Dict, Instance, TraitError, observe, observe_compat, default,
+ Bool, Unicode, List, Enum, Dict, Instance, TraitError, observe, observe_compat, default,
)
from ipython_genutils.importstring import import_item
from ipython_genutils.text import indent, wrap_paragraphs, dedent
from ipython_genutils import py3compat
-import six
-
+import six
+
#-----------------------------------------------------------------------------
# Descriptions for the various sections
#-----------------------------------------------------------------------------
@@ -63,24 +63,24 @@ subcommand 'cmd', do: `{app} cmd -h`.
# Application class
#-----------------------------------------------------------------------------
-
-
-_envvar = os.environ.get('TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR','')
-if _envvar.lower() in {'1','true'}:
- TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR = True
-elif _envvar.lower() in {'0','false',''} :
- TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR = False
-else:
- raise ValueError("Unsupported value for environment variable: 'TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR' is set to '%s' which is none of {'0', '1', 'false', 'true', ''}."% _envvar )
-
-
+
+
+_envvar = os.environ.get('TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR','')
+if _envvar.lower() in {'1','true'}:
+ TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR = True
+elif _envvar.lower() in {'0','false',''} :
+ TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR = False
+else:
+ raise ValueError("Unsupported value for environment variable: 'TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR' is set to '%s' which is none of {'0', '1', 'false', 'true', ''}."% _envvar )
+
+
@decorator
def catch_config_error(method, app, *args, **kwargs):
"""Method decorator for catching invalid config (Trait/ArgumentErrors) during init.
On a TraitError (generally caused by bad config), this will print the trait's
message, and exit the app.
-
+
For use on init methods, to prevent invoking excepthook on invalid input.
"""
try:
@@ -99,16 +99,16 @@ class ApplicationError(Exception):
class LevelFormatter(logging.Formatter):
"""Formatter with additional `highlevel` record
-
+
This field is empty if log level is less than highlevel_limit,
otherwise it is formatted with self.highlevel_format.
-
+
Useful for adding 'WARNING' to warning messages,
without adding 'INFO' to info, etc.
"""
highlevel_limit = logging.WARN
highlevel_format = " %(levelname)s |"
-
+
def format(self, record):
if record.levelno >= self.highlevel_limit:
record.highlevel = self.highlevel_format % record.__dict__
@@ -116,7 +116,7 @@ class LevelFormatter(logging.Formatter):
record.highlevel = ""
return super(LevelFormatter, self).format(record)
-
+
class Application(SingletonConfigurable):
"""A singleton application with full configuration support."""
@@ -131,7 +131,7 @@ class Application(SingletonConfigurable):
option_description = Unicode(option_description)
keyvalue_description = Unicode(keyvalue_description)
subcommand_description = Unicode(subcommand_description)
-
+
python_config_loader_class = PyFileConfigLoader
json_config_loader_class = JSONFileConfigLoader
@@ -158,13 +158,13 @@ class Application(SingletonConfigurable):
# The version string of this application.
version = Unicode(u'0.0')
-
+
# the argv used to initialize the application
argv = List()
- # Whether failing to load config files should prevent startup
- raise_config_file_errors = Bool(TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR)
-
+ # Whether failing to load config files should prevent startup
+ raise_config_file_errors = Bool(TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR)
+
# The log level for the application
log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'),
default_value=logging.WARN,
@@ -174,15 +174,15 @@ class Application(SingletonConfigurable):
@observe_compat
def _log_level_changed(self, change):
"""Adjust the log level when log_level is set."""
- new = change.new
- if isinstance(new, six.string_types):
+ new = change.new
+ if isinstance(new, six.string_types):
new = getattr(logging, new)
self.log_level = new
self.log.setLevel(new)
-
+
_log_formatter_cls = LevelFormatter
-
- log_datefmt = Unicode("%Y-%m-%d %H:%M:%S",
+
+ log_datefmt = Unicode("%Y-%m-%d %H:%M:%S",
help="The date format used by logging formatters for %(asctime)s"
).tag(config=True)
@@ -197,7 +197,7 @@ class Application(SingletonConfigurable):
_log_handler = self.log.handlers[0]
_log_formatter = self._log_formatter_cls(fmt=self.log_format, datefmt=self.log_datefmt)
_log_handler.setFormatter(_log_formatter)
-
+
@default('log')
def _log_default(self):
"""Start logging for this application.
@@ -217,7 +217,7 @@ class Application(SingletonConfigurable):
break
else:
_log = _log.parent
- if sys.executable and sys.executable.endswith('pythonw.exe'):
+ if sys.executable and sys.executable.endswith('pythonw.exe'):
# this should really go to a file, but file-logging is only
# hooked up in parallel applications
_log_handler = logging.StreamHandler(open(os.devnull, 'w'))
@@ -240,11 +240,11 @@ class Application(SingletonConfigurable):
@observe_compat
def _flags_changed(self, change):
"""ensure flags dict is valid"""
- new = change.new
+ new = change.new
for key, value in new.items():
assert len(value) == 2, "Bad flag: %r:%s" % (key, value)
assert isinstance(value[0], (dict, Config)), "Bad flag: %r:%s" % (key, value)
- assert isinstance(value[1], six.string_types), "Bad flag: %r:%s" % (key, value)
+ assert isinstance(value[1], six.string_types), "Bad flag: %r:%s" % (key, value)
# subcommands for launching other applications
@@ -259,34 +259,34 @@ class Application(SingletonConfigurable):
# extra command-line arguments that don't set config values
extra_args = List(Unicode())
- cli_config = Instance(Config, (), {},
- help="""The subset of our configuration that came from the command-line
+ cli_config = Instance(Config, (), {},
+ help="""The subset of our configuration that came from the command-line
+
+ We re-load this configuration after loading config files,
+ to ensure that it maintains highest priority.
+ """
+ )
- We re-load this configuration after loading config files,
- to ensure that it maintains highest priority.
- """
- )
-
_loaded_config_files = List()
-
+
def __init__(self, **kwargs):
SingletonConfigurable.__init__(self, **kwargs)
# Ensure my class is in self.classes, so my attributes appear in command line
# options and config files.
- cls = self.__class__
- if cls not in self.classes:
- if self.classes is cls.classes:
- # class attr, assign instead of insert
- cls.classes = [cls] + self.classes
- else:
- self.classes.insert(0, self.__class__)
-
+ cls = self.__class__
+ if cls not in self.classes:
+ if self.classes is cls.classes:
+ # class attr, assign instead of insert
+ cls.classes = [cls] + self.classes
+ else:
+ self.classes.insert(0, self.__class__)
+
@observe('config')
@observe_compat
def _config_changed(self, change):
super(Application, self)._config_changed(change)
self.log.debug('Config changed:')
- self.log.debug(repr(change.new))
+ self.log.debug(repr(change.new))
@catch_config_error
def initialize(self, argv=None):
@@ -317,7 +317,7 @@ class Application(SingletonConfigurable):
for c in cls.mro()[:-3]:
classdict[c.__name__] = c
- for alias, longname in self.aliases.items():
+ for alias, longname in self.aliases.items():
classname, traitname = longname.split('.',1)
cls = classdict[classname]
@@ -337,7 +337,7 @@ class Application(SingletonConfigurable):
return
lines = []
- for m, (cfg,help) in self.flags.items():
+ for m, (cfg,help) in self.flags.items():
prefix = '--' if len(m) > 1 else '-'
lines.append(prefix+m)
lines.append(indent(dedent(help.strip())))
@@ -370,7 +370,7 @@ class Application(SingletonConfigurable):
app=self.name)):
lines.append(p)
lines.append('')
- for subc, (cls, help) in self.subcommands.items():
+ for subc, (cls, help) in self.subcommands.items():
lines.append(subc)
if help:
lines.append(indent(dedent(help.strip())))
@@ -442,26 +442,26 @@ class Application(SingletonConfigurable):
"""Initialize a subcommand with argv."""
subapp,help = self.subcommands.get(subc)
- if isinstance(subapp, six.string_types):
+ if isinstance(subapp, six.string_types):
subapp = import_item(subapp)
# clear existing instances
self.__class__.clear_instance()
# instantiate
- self.subapp = subapp.instance(parent=self)
+ self.subapp = subapp.instance(parent=self)
# and initialize subapp
self.subapp.initialize(argv)
-
+
def flatten_flags(self):
"""flatten flags and aliases, so cl-args override as expected.
-
+
This prevents issues such as an alias pointing to InteractiveShell,
but a config file setting the same trait in TerminalInteraciveShell
getting inappropriate priority over the command-line arg.
Only aliases with exactly one descendent in the class list
will be promoted.
-
+
"""
# build a tree of classes in our list that inherit from a particular
# it will be a dict by parent classname of classes in our list
@@ -475,20 +475,20 @@ class Application(SingletonConfigurable):
# flatten aliases, which have the form:
# { 'alias' : 'Class.trait' }
aliases = {}
- for alias, cls_trait in self.aliases.items():
+ for alias, cls_trait in self.aliases.items():
cls,trait = cls_trait.split('.',1)
children = mro_tree[cls]
if len(children) == 1:
# exactly one descendent, promote alias
cls = children[0]
aliases[alias] = '.'.join([cls,trait])
-
+
# flatten flags, which are of the form:
# { 'key' : ({'Cls' : {'trait' : value}}, 'help')}
flags = {}
- for key, (flagdict, help) in self.flags.items():
+ for key, (flagdict, help) in self.flags.items():
newflag = {}
- for cls, subdict in flagdict.items():
+ for cls, subdict in flagdict.items():
children = mro_tree[cls]
# exactly one descendent, promote flag section
if len(children) == 1:
@@ -502,7 +502,7 @@ class Application(SingletonConfigurable):
"""Parse the command line arguments."""
argv = sys.argv[1:] if argv is None else argv
self.argv = [ py3compat.cast_unicode(arg) for arg in argv ]
-
+
if argv and argv[0] == 'help':
# turn `ipython help notebook` into `ipython notebook -h`
argv = argv[1:] + ['-h']
@@ -530,33 +530,33 @@ class Application(SingletonConfigurable):
if '--version' in interpreted_argv or '-V' in interpreted_argv:
self.print_version()
self.exit(0)
-
+
# flatten flags&aliases, so cl-args get appropriate priority:
flags,aliases = self.flatten_flags()
loader = KVArgParseConfigLoader(argv=argv, aliases=aliases,
flags=flags, log=self.log)
- self.cli_config = deepcopy(loader.load_config())
- self.update_config(self.cli_config)
+ self.cli_config = deepcopy(loader.load_config())
+ self.update_config(self.cli_config)
# store unparsed args in extra_args
self.extra_args = loader.extra_args
@classmethod
- def _load_config_files(cls, basefilename, path=None, log=None, raise_config_file_errors=False):
+ def _load_config_files(cls, basefilename, path=None, log=None, raise_config_file_errors=False):
"""Load config files (py,json) by filename and path.
yield each config object in turn.
"""
-
+
if not isinstance(path, list):
path = [path]
for path in path[::-1]:
# path list is in descending priority order, so load files backwards:
pyloader = cls.python_config_loader_class(basefilename+'.py', path=path, log=log)
if log:
- log.debug("Looking for %s in %s", basefilename, path or os.getcwd())
+ log.debug("Looking for %s in %s", basefilename, path or os.getcwd())
jsonloader = cls.json_config_loader_class(basefilename+'.json', path=path, log=log)
- loaded = []
- filenames = []
+ loaded = []
+ filenames = []
for loader in [pyloader, jsonloader]:
config = None
try:
@@ -568,8 +568,8 @@ class Application(SingletonConfigurable):
# unlikely event that the error raised before filefind finished
filename = loader.full_filename or basefilename
# problem while running the file
- if raise_config_file_errors:
- raise
+ if raise_config_file_errors:
+ raise
if log:
log.error("Exception while loading config file %s",
filename, exc_info=True)
@@ -577,16 +577,16 @@ class Application(SingletonConfigurable):
if log:
log.debug("Loaded config file: %s", loader.full_filename)
if config:
- for filename, earlier_config in zip(filenames, loaded):
- collisions = earlier_config.collisions(config)
- if collisions and log:
- log.warning("Collisions detected in {0} and {1} config files."
- " {1} has higher priority: {2}".format(
- filename, loader.full_filename, json.dumps(collisions, indent=2),
- ))
+ for filename, earlier_config in zip(filenames, loaded):
+ collisions = earlier_config.collisions(config)
+ if collisions and log:
+ log.warning("Collisions detected in {0} and {1} config files."
+ " {1} has higher priority: {2}".format(
+ filename, loader.full_filename, json.dumps(collisions, indent=2),
+ ))
yield (config, loader.full_filename)
- loaded.append(config)
- filenames.append(loader.full_filename)
+ loaded.append(config)
+ filenames.append(loader.full_filename)
@property
def loaded_config_files(self):
@@ -597,55 +597,55 @@ class Application(SingletonConfigurable):
def load_config_file(self, filename, path=None):
"""Load config files by filename and path."""
filename, ext = os.path.splitext(filename)
- new_config = Config()
+ new_config = Config()
for (config, filename) in self._load_config_files(filename, path=path, log=self.log,
- raise_config_file_errors=self.raise_config_file_errors,
- ):
- new_config.merge(config)
+ raise_config_file_errors=self.raise_config_file_errors,
+ ):
+ new_config.merge(config)
if filename not in self._loaded_config_files: # only add to list of loaded files if not previously loaded
self._loaded_config_files.append(filename)
- # add self.cli_config to preserve CLI config priority
- new_config.merge(self.cli_config)
- self.update_config(new_config)
-
-
- def _classes_in_config_sample(self):
- """
- Yields only classes with own traits, and their subclasses.
-
- Thus, produced sample config-file will contain all classes
- on which a trait-value may be overridden:
-
- - either on the class owning the trait,
- - or on its subclasses, even if those subclasses do not define
- any traits themselves.
- """
- cls_to_config = OrderedDict( (cls, bool(cls.class_own_traits(config=True)))
- for cls
- in self._classes_inc_parents())
-
- def is_any_parent_included(cls):
- return any(b in cls_to_config and cls_to_config[b] for b in cls.__bases__)
-
- ## Mark "empty" classes for inclusion if their parents own-traits,
- # and loop until no more classes gets marked.
- #
- while True:
- to_incl_orig = cls_to_config.copy()
- cls_to_config = OrderedDict( (cls, inc_yes or is_any_parent_included(cls))
- for cls, inc_yes
- in cls_to_config.items())
- if cls_to_config == to_incl_orig:
- break
- for cl, inc_yes in cls_to_config.items():
- if inc_yes:
- yield cl
-
+ # add self.cli_config to preserve CLI config priority
+ new_config.merge(self.cli_config)
+ self.update_config(new_config)
+
+
+ def _classes_in_config_sample(self):
+ """
+ Yields only classes with own traits, and their subclasses.
+
+ Thus, produced sample config-file will contain all classes
+ on which a trait-value may be overridden:
+
+ - either on the class owning the trait,
+ - or on its subclasses, even if those subclasses do not define
+ any traits themselves.
+ """
+ cls_to_config = OrderedDict( (cls, bool(cls.class_own_traits(config=True)))
+ for cls
+ in self._classes_inc_parents())
+
+ def is_any_parent_included(cls):
+ return any(b in cls_to_config and cls_to_config[b] for b in cls.__bases__)
+
+ ## Mark "empty" classes for inclusion if their parents own-traits,
+ # and loop until no more classes gets marked.
+ #
+ while True:
+ to_incl_orig = cls_to_config.copy()
+ cls_to_config = OrderedDict( (cls, inc_yes or is_any_parent_included(cls))
+ for cls, inc_yes
+ in cls_to_config.items())
+ if cls_to_config == to_incl_orig:
+ break
+ for cl, inc_yes in cls_to_config.items():
+ if inc_yes:
+ yield cl
+
def generate_config_file(self):
"""generate default config file from Configurables"""
lines = ["# Configuration file for %s." % self.name]
lines.append('')
- for cls in self._classes_in_config_sample():
+ for cls in self._classes_in_config_sample():
lines.append(cls.class_config_section())
return '\n'.join(lines)
@@ -656,7 +656,7 @@ class Application(SingletonConfigurable):
@classmethod
def launch_instance(cls, argv=None, **kwargs):
"""Launch a global instance of this Application
-
+
If a global instance already exists, this reinitializes and starts it
"""
app = cls.instance(**kwargs)
@@ -702,7 +702,7 @@ def boolean_flag(name, configurable, set_help='', unset_help=''):
def get_config():
"""Get the config object for the global Application instance, if there is one
-
+
otherwise return an empty config object
"""
if Application.initialized():
diff --git a/contrib/python/traitlets/py2/traitlets/config/configurable.py b/contrib/python/traitlets/py2/traitlets/config/configurable.py
index 7e34c5a84a..1174fcf017 100644
--- a/contrib/python/traitlets/py2/traitlets/config/configurable.py
+++ b/contrib/python/traitlets/py2/traitlets/config/configurable.py
@@ -4,12 +4,12 @@
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
-from __future__ import print_function, absolute_import
+from __future__ import print_function, absolute_import
from copy import deepcopy
-import warnings
+import warnings
-from .loader import Config, LazyConfigValue, _is_section_key
+from .loader import Config, LazyConfigValue, _is_section_key
from traitlets.traitlets import HasTraits, Instance, observe, observe_compat, default
from ipython_genutils.text import indent, dedent, wrap_paragraphs
@@ -66,12 +66,12 @@ class Configurable(HasTraits):
if kwargs.get('config', None) is None:
kwargs['config'] = parent.config
self.parent = parent
-
+
config = kwargs.pop('config', None)
-
+
# load kwarg traits, other than config
super(Configurable, self).__init__(**kwargs)
-
+
# load config
if config is not None:
# We used to deepcopy, but for now we are trying to just save
@@ -85,7 +85,7 @@ class Configurable(HasTraits):
else:
# allow _config_default to return something
self._load_config(self.config)
-
+
# Ensure explicit kwargs are applied after loading config.
# This is usually redundant, but ensures config doesn't override
# explicitly assigned values.
@@ -95,25 +95,25 @@ class Configurable(HasTraits):
#-------------------------------------------------------------------------
# Static trait notifiations
#-------------------------------------------------------------------------
-
+
@classmethod
def section_names(cls):
"""return section names as a list"""
return [c.__name__ for c in reversed(cls.__mro__) if
issubclass(c, Configurable) and issubclass(cls, c)
]
-
+
def _find_my_config(self, cfg):
"""extract my config from a global Config object
-
+
will construct a Config object of only the config values that apply to me
based on my mro(), as well as those of my parent(s) if they exist.
-
+
If I am Bar and my parent is Foo, and their parent is Tim,
this will return merge following config sections, in this order::
-
+
[Bar, Foo.bar, Tim.Foo.Bar]
-
+
With the last item being the highest priority.
"""
cfgs = [cfg]
@@ -127,20 +127,20 @@ class Configurable(HasTraits):
if c._has_section(sname):
my_config.merge(c[sname])
return my_config
-
+
def _load_config(self, cfg, section_names=None, traits=None):
"""load traits from a Config object"""
-
+
if traits is None:
traits = self.traits(config=True)
if section_names is None:
section_names = self.section_names()
-
+
my_config = self._find_my_config(cfg)
-
+
# hold trait notifications until after all config has been loaded
with self.hold_trait_notifications():
- for name, config_value in my_config.items():
+ for name, config_value in my_config.items():
if name in traits:
if isinstance(config_value, LazyConfigValue):
# ConfigValue is a wrapper for using append / update on containers
@@ -151,21 +151,21 @@ class Configurable(HasTraits):
# config object. If we don't, a mutable config_value will be
# shared by all instances, effectively making it a class attribute.
setattr(self, name, deepcopy(config_value))
- elif not _is_section_key(name) and not isinstance(config_value, Config):
+ elif not _is_section_key(name) and not isinstance(config_value, Config):
from difflib import get_close_matches
- if isinstance(self, LoggingConfigurable):
- warn = self.log.warning
- else:
- warn = lambda msg: warnings.warn(msg, stacklevel=9)
+ if isinstance(self, LoggingConfigurable):
+ warn = self.log.warning
+ else:
+ warn = lambda msg: warnings.warn(msg, stacklevel=9)
matches = get_close_matches(name, traits)
- msg = u"Config option `{option}` not recognized by `{klass}`.".format(
- option=name, klass=self.__class__.__name__)
-
+ msg = u"Config option `{option}` not recognized by `{klass}`.".format(
+ option=name, klass=self.__class__.__name__)
+
if len(matches) == 1:
- msg += u" Did you mean `{matches}`?".format(matches=matches[0])
+ msg += u" Did you mean `{matches}`?".format(matches=matches[0])
elif len(matches) >= 1:
- msg +=" Did you mean one of: `{matches}`?".format(matches=', '.join(sorted(matches)))
- warn(msg)
+ msg +=" Did you mean one of: `{matches}`?".format(matches=', '.join(sorted(matches)))
+ warn(msg)
@observe('config')
@observe_compat
@@ -183,23 +183,23 @@ class Configurable(HasTraits):
# classes that are Configurable subclasses. This starts with Configurable
# and works down the mro loading the config for each section.
section_names = self.section_names()
- self._load_config(change.new, traits=traits, section_names=section_names)
+ self._load_config(change.new, traits=traits, section_names=section_names)
def update_config(self, config):
- """Update config and load the new values"""
- # traitlets prior to 4.2 created a copy of self.config in order to trigger change events.
- # Some projects (IPython < 5) relied upon one side effect of this,
- # that self.config prior to update_config was not modified in-place.
- # For backward-compatibility, we must ensure that self.config
- # is a new object and not modified in-place,
- # but config consumers should not rely on this behavior.
- self.config = deepcopy(self.config)
- # load config
- self._load_config(config)
- # merge it into self.config
+ """Update config and load the new values"""
+ # traitlets prior to 4.2 created a copy of self.config in order to trigger change events.
+ # Some projects (IPython < 5) relied upon one side effect of this,
+ # that self.config prior to update_config was not modified in-place.
+ # For backward-compatibility, we must ensure that self.config
+ # is a new object and not modified in-place,
+ # but config consumers should not rely on this behavior.
+ self.config = deepcopy(self.config)
+ # load config
+ self._load_config(config)
+ # merge it into self.config
self.config.merge(config)
- # TODO: trigger change event if/when dict-update change events take place
- # DO NOT trigger full trait-change
+ # TODO: trigger change event if/when dict-update change events take place
+ # DO NOT trigger full trait-change
@classmethod
def class_get_help(cls, inst=None):
@@ -220,7 +220,7 @@ class Configurable(HasTraits):
@classmethod
def class_get_trait_help(cls, trait, inst=None):
"""Get the help string for a single trait.
-
+
If `inst` is given, it's current trait values will be used in place of
the class default.
"""
@@ -261,19 +261,19 @@ class Configurable(HasTraits):
"""return a commented, wrapped block."""
s = '\n\n'.join(wrap_paragraphs(s, 78))
- return '## ' + s.replace('\n', '\n# ')
+ return '## ' + s.replace('\n', '\n# ')
# section header
breaker = '#' + '-'*78
- parent_classes = ','.join(p.__name__ for p in cls.__bases__)
- s = "# %s(%s) configuration" % (cls.__name__, parent_classes)
+ parent_classes = ','.join(p.__name__ for p in cls.__bases__)
+ s = "# %s(%s) configuration" % (cls.__name__, parent_classes)
lines = [breaker, s, breaker, '']
# get the description trait
desc = cls.class_traits().get('description')
if desc:
desc = desc.default_value
- if not desc:
- # no description from trait, use __doc__
+ if not desc:
+ # no description from trait, use __doc__
desc = getattr(cls, '__doc__', '')
if desc:
lines.append(c(desc))
@@ -281,7 +281,7 @@ class Configurable(HasTraits):
for name, trait in sorted(cls.class_own_traits(config=True).items()):
lines.append(c(trait.help))
- lines.append('#c.%s.%s = %s' % (cls.__name__, name, trait.default_value_repr()))
+ lines.append('#c.%s.%s = %s' % (cls.__name__, name, trait.default_value_repr()))
lines.append('')
return '\n'.join(lines)
diff --git a/contrib/python/traitlets/py2/traitlets/config/loader.py b/contrib/python/traitlets/py2/traitlets/config/loader.py
index a79a398c3d..803b36276f 100644
--- a/contrib/python/traitlets/py2/traitlets/config/loader.py
+++ b/contrib/python/traitlets/py2/traitlets/config/loader.py
@@ -16,7 +16,7 @@ from ast import literal_eval
from ipython_genutils.path import filefind
from ipython_genutils import py3compat
from ipython_genutils.encoding import DEFAULT_ENCODING
-from six import text_type
+from six import text_type
from traitlets.traitlets import HasTraits, List, Any
#-----------------------------------------------------------------------------
@@ -182,7 +182,7 @@ class Config(dict):
def merge(self, other):
"""merge another config object into this one"""
to_update = {}
- for k, v in other.items():
+ for k, v in other.items():
if k not in self:
to_update[k] = v
else: # I have this key
@@ -385,17 +385,17 @@ class FileConfigLoader(ConfigLoader):
self.full_filename = filefind(self.filename, self.path)
class JSONFileConfigLoader(FileConfigLoader):
- """A JSON file loader for config
-
- Can also act as a context manager that rewrite the configuration file to disk on exit.
-
- Example::
-
- with JSONFileConfigLoader('myapp.json','/home/jupyter/configurations/') as c:
- c.MyNewConfigurable.new_value = 'Updated'
-
- """
-
+ """A JSON file loader for config
+
+ Can also act as a context manager that rewrite the configuration file to disk on exit.
+
+ Example::
+
+ with JSONFileConfigLoader('myapp.json','/home/jupyter/configurations/') as c:
+ c.MyNewConfigurable.new_value = 'Updated'
+
+ """
+
def load_config(self):
"""Load the config from a file and return it as a Config object."""
self.clear()
@@ -422,24 +422,24 @@ class JSONFileConfigLoader(FileConfigLoader):
else:
raise ValueError('Unknown version of JSON config file: {version}'.format(version=version))
- def __enter__(self):
- self.load_config()
- return self.config
-
- def __exit__(self, exc_type, exc_value, traceback):
- """
- Exit the context manager but do not handle any errors.
-
- In case of any error, we do not want to write the potentially broken
- configuration to disk.
- """
- self.config.version = 1
- json_config = json.dumps(self.config, indent=2)
- with open(self.full_filename, 'w') as f:
- f.write(json_config)
-
-
-
+ def __enter__(self):
+ self.load_config()
+ return self.config
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ """
+ Exit the context manager but do not handle any errors.
+
+ In case of any error, we do not want to write the potentially broken
+ configuration to disk.
+ """
+ self.config.version = 1
+ json_config = json.dumps(self.config, indent=2)
+ with open(self.full_filename, 'w') as f:
+ f.write(json_config)
+
+
+
class PyFileConfigLoader(FileConfigLoader):
"""A config loader for pure python files.
@@ -521,7 +521,7 @@ class CommandLineConfigLoader(ConfigLoader):
if isinstance(cfg, (dict, Config)):
# don't clobber whole config sections, update
# each section from config:
- for sec,c in cfg.items():
+ for sec,c in cfg.items():
self.config[sec].update(c)
else:
raise TypeError("Invalid flag: %r" % cfg)
@@ -603,7 +603,7 @@ class KeyValueConfigLoader(CommandLineConfigLoader):
if enc is None:
enc = DEFAULT_ENCODING
for arg in argv:
- if not isinstance(arg, text_type):
+ if not isinstance(arg, text_type):
# only decode if not already decoded
arg = arg.decode(enc)
uargv.append(arg)
@@ -769,7 +769,7 @@ class ArgParseConfigLoader(CommandLineConfigLoader):
def _convert_to_config(self):
"""self.parsed_data->self.config"""
- for k, v in vars(self.parsed_data).items():
+ for k, v in vars(self.parsed_data).items():
exec("self.config.%s = v"%k, locals(), globals())
class KVArgParseConfigLoader(ArgParseConfigLoader):
@@ -786,17 +786,17 @@ class KVArgParseConfigLoader(ArgParseConfigLoader):
if flags is None:
flags = self.flags
paa = self.parser.add_argument
- for key,value in aliases.items():
+ for key,value in aliases.items():
if key in flags:
# flags
nargs = '?'
else:
nargs = None
if len(key) is 1:
- paa('-'+key, '--'+key, type=text_type, dest=value, nargs=nargs)
+ paa('-'+key, '--'+key, type=text_type, dest=value, nargs=nargs)
else:
- paa('--'+key, type=text_type, dest=value, nargs=nargs)
- for key, (value, help) in flags.items():
+ paa('--'+key, type=text_type, dest=value, nargs=nargs)
+ for key, (value, help) in flags.items():
if key in self.aliases:
#
self.alias_flags[self.aliases[key]] = value
@@ -815,7 +815,7 @@ class KVArgParseConfigLoader(ArgParseConfigLoader):
else:
subcs = []
- for k, v in vars(self.parsed_data).items():
+ for k, v in vars(self.parsed_data).items():
if v is None:
# it was a flag that shares the name of an alias
subcs.append(self.alias_flags[k])
diff --git a/contrib/python/traitlets/py2/traitlets/config/manager.py b/contrib/python/traitlets/py2/traitlets/config/manager.py
index f5cf21904e..5e5ebde9af 100644
--- a/contrib/python/traitlets/py2/traitlets/config/manager.py
+++ b/contrib/python/traitlets/py2/traitlets/config/manager.py
@@ -7,7 +7,7 @@ import io
import json
import os
-from six import PY3
+from six import PY3
from traitlets.config import LoggingConfigurable
from traitlets.traitlets import Unicode
diff --git a/contrib/python/traitlets/py2/traitlets/log.py b/contrib/python/traitlets/py2/traitlets/log.py
index c7166c14c8..af86b325f5 100644
--- a/contrib/python/traitlets/py2/traitlets/log.py
+++ b/contrib/python/traitlets/py2/traitlets/log.py
@@ -9,19 +9,19 @@ _logger = None
def get_logger():
"""Grab the global logger instance.
-
+
If a global Application is instantiated, grab its logger.
Otherwise, grab the root logger.
"""
global _logger
-
+
if _logger is None:
from .config import Application
if Application.initialized():
_logger = Application.instance().log
else:
- _logger = logging.getLogger('traitlets')
- # Add a NullHandler to silence warnings about not being
- # initialized, per best practice for libraries.
- _logger.addHandler(logging.NullHandler())
+ _logger = logging.getLogger('traitlets')
+ # Add a NullHandler to silence warnings about not being
+ # initialized, per best practice for libraries.
+ _logger.addHandler(logging.NullHandler())
return _logger
diff --git a/contrib/python/traitlets/py2/traitlets/traitlets.py b/contrib/python/traitlets/py2/traitlets/traitlets.py
index b3134c819b..c07daf7400 100644
--- a/contrib/python/traitlets/py2/traitlets/traitlets.py
+++ b/contrib/python/traitlets/py2/traitlets/traitlets.py
@@ -42,11 +42,11 @@ Inheritance diagram:
import contextlib
import inspect
-import os
+import os
import re
import sys
import types
-import enum
+import enum
try:
from types import ClassType, InstanceType
ClassTypes = (ClassType, type)
@@ -54,12 +54,12 @@ except:
ClassTypes = (type,)
from warnings import warn, warn_explicit
-import six
+import six
from .utils.getargspec import getargspec
from .utils.importstring import import_item
from .utils.sentinel import Sentinel
-from .utils.bunch import Bunch
+from .utils.bunch import Bunch
SequenceTypes = (list, tuple, set, frozenset)
@@ -91,39 +91,39 @@ class TraitError(Exception):
# Utilities
#-----------------------------------------------------------------------------
-from ipython_genutils.py3compat import cast_unicode_py2
-
-_name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
-
-def isidentifier(s):
- if six.PY2:
- return bool(_name_re.match(s))
- else:
- return s.isidentifier()
-
-_deprecations_shown = set()
-def _should_warn(key):
- """Add our own checks for too many deprecation warnings.
-
- Limit to once per package.
- """
- env_flag = os.environ.get('TRAITLETS_ALL_DEPRECATIONS')
- if env_flag and env_flag != '0':
- return True
-
- if key not in _deprecations_shown:
- _deprecations_shown.add(key)
- return True
- else:
- return False
-
+from ipython_genutils.py3compat import cast_unicode_py2
+
+_name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
+
+def isidentifier(s):
+ if six.PY2:
+ return bool(_name_re.match(s))
+ else:
+ return s.isidentifier()
+
+_deprecations_shown = set()
+def _should_warn(key):
+ """Add our own checks for too many deprecation warnings.
+
+ Limit to once per package.
+ """
+ env_flag = os.environ.get('TRAITLETS_ALL_DEPRECATIONS')
+ if env_flag and env_flag != '0':
+ return True
+
+ if key not in _deprecations_shown:
+ _deprecations_shown.add(key)
+ return True
+ else:
+ return False
+
def _deprecated_method(method, cls, method_name, msg):
"""Show deprecation warning about a magic method definition.
Uses warn_explicit to bind warning to method definition instead of triggering code,
which isn't relevant.
"""
- warn_msg = "{classname}.{method_name} is deprecated in traitlets 4.1: {msg}".format(
+ warn_msg = "{classname}.{method_name} is deprecated in traitlets 4.1: {msg}".format(
classname=cls.__name__, method_name=method_name, msg=msg
)
@@ -131,15 +131,15 @@ def _deprecated_method(method, cls, method_name, msg):
if method_name in parent.__dict__:
cls = parent
break
- # limit deprecation messages to once per package
- package_name = cls.__module__.split('.', 1)[0]
- key = (package_name, msg)
- if not _should_warn(key):
- return
+ # limit deprecation messages to once per package
+ package_name = cls.__module__.split('.', 1)[0]
+ key = (package_name, msg)
+ if not _should_warn(key):
+ return
try:
fname = inspect.getsourcefile(method) or "<unknown>"
lineno = inspect.getsourcelines(method)[1] or 0
- except (IOError, TypeError) as e:
+ except (IOError, TypeError) as e:
# Failed to inspect for some reason
warn(warn_msg + ('\n(inspection failed) %s' % e), DeprecationWarning)
else:
@@ -150,7 +150,7 @@ def class_of(object):
correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image',
'a PlotValue').
"""
- if isinstance( object, six.string_types ):
+ if isinstance( object, six.string_types ):
return add_article( object )
return add_article( object.__class__.__name__ )
@@ -171,7 +171,7 @@ def repr_type(obj):
error messages.
"""
the_type = type(obj)
- if six.PY2 and the_type is InstanceType:
+ if six.PY2 and the_type is InstanceType:
# Old-style class.
the_type = obj.__class__
msg = '%r %r' % (obj, the_type)
@@ -200,14 +200,14 @@ def parse_notifier_name(names):
>>> parse_notifier_name(All)
[All]
"""
- if names is All or isinstance(names, six.string_types):
+ if names is All or isinstance(names, six.string_types):
return [names]
- else:
+ else:
if not names or All in names:
return [All]
for n in names:
- if not isinstance(n, six.string_types):
- raise TypeError("names must be strings, not %r" % n)
+ if not isinstance(n, six.string_types):
+ raise TypeError("names must be strings, not %r" % n)
return names
@@ -288,13 +288,13 @@ class link(object):
if self.updating:
return
with self._busy_updating():
- setattr(self.target[0], self.target[1], change.new)
+ setattr(self.target[0], self.target[1], change.new)
def _update_source(self, change):
if self.updating:
return
with self._busy_updating():
- setattr(self.source[0], self.source[1], change.new)
+ setattr(self.source[0], self.source[1], change.new)
def unlink(self):
self.source[0].unobserve(self._update_target, names=self.source[1])
@@ -344,7 +344,7 @@ class directional_link(object):
return
with self._busy_updating():
setattr(self.target[0], self.target[1],
- self._transform(change.new))
+ self._transform(change.new))
def unlink(self):
self.source[0].unobserve(self._update, names=self.source[1])
@@ -354,7 +354,7 @@ dlink = directional_link
#-----------------------------------------------------------------------------
-# Base Descriptor Class
+# Base Descriptor Class
#-----------------------------------------------------------------------------
@@ -429,32 +429,32 @@ class TraitType(BaseDescriptor):
"""
if default_value is not Undefined:
self.default_value = default_value
- if allow_none:
+ if allow_none:
self.allow_none = allow_none
if read_only is not None:
self.read_only = read_only
self.help = help if help is not None else ''
- if len(kwargs) > 0:
+ if len(kwargs) > 0:
stacklevel = 1
f = inspect.currentframe()
# count supers to determine stacklevel for warning
while f.f_code.co_name == '__init__':
stacklevel += 1
f = f.f_back
- mod = f.f_globals.get('__name__') or ''
- pkg = mod.split('.', 1)[0]
- key = tuple(['metadata-tag', pkg] + sorted(kwargs))
- if _should_warn(key):
- warn("metadata %s was set from the constructor. "
- "With traitlets 4.1, metadata should be set using the .tag() method, "
- "e.g., Int().tag(key1='value1', key2='value2')" % (kwargs,),
- DeprecationWarning, stacklevel=stacklevel)
+ mod = f.f_globals.get('__name__') or ''
+ pkg = mod.split('.', 1)[0]
+ key = tuple(['metadata-tag', pkg] + sorted(kwargs))
+ if _should_warn(key):
+ warn("metadata %s was set from the constructor. "
+ "With traitlets 4.1, metadata should be set using the .tag() method, "
+ "e.g., Int().tag(key1='value1', key2='value2')" % (kwargs,),
+ DeprecationWarning, stacklevel=stacklevel)
if len(self.metadata) > 0:
self.metadata = self.metadata.copy()
- self.metadata.update(kwargs)
+ self.metadata.update(kwargs)
else:
- self.metadata = kwargs
+ self.metadata = kwargs
else:
self.metadata = self.metadata.copy()
if config is not None:
@@ -470,14 +470,14 @@ class TraitType(BaseDescriptor):
Use self.default_value instead
"""
- warn("get_default_value is deprecated in traitlets 4.0: use the .default_value attribute", DeprecationWarning,
+ warn("get_default_value is deprecated in traitlets 4.0: use the .default_value attribute", DeprecationWarning,
stacklevel=2)
return self.default_value
def init_default_value(self, obj):
"""DEPRECATED: Set the static default value for the trait type.
"""
- warn("init_default_value is deprecated in traitlets 4.0, and may be removed in the future", DeprecationWarning,
+ warn("init_default_value is deprecated in traitlets 4.0, and may be removed in the future", DeprecationWarning,
stacklevel=2)
value = self._validate(obj, self.default_value)
obj._trait_values[self.name] = value
@@ -488,7 +488,7 @@ class TraitType(BaseDescriptor):
This looks for:
- * default generators registered with the @default descriptor.
+ * default generators registered with the @default descriptor.
* obj._{name}_default() on the class with the traitlet, or a subclass
that obj belongs to.
* trait.make_dynamic_default, which is defined by Instance
@@ -516,14 +516,14 @@ class TraitType(BaseDescriptor):
def instance_init(self, obj):
# If no dynamic initialiser is present, and the trait implementation or
# use provides a static default, transfer that to obj._trait_values.
- with obj.cross_validation_lock:
- if (self._dynamic_default_callable(obj) is None) \
- and (self.default_value is not Undefined):
- v = self._validate(obj, self.default_value)
- if self.name is not None:
- obj._trait_values[self.name] = v
-
- def get(self, obj, cls=None):
+ with obj.cross_validation_lock:
+ if (self._dynamic_default_callable(obj) is None) \
+ and (self.default_value is not Undefined):
+ v = self._validate(obj, self.default_value)
+ if self.name is not None:
+ obj._trait_values[self.name] = v
+
+ def get(self, obj, cls=None):
try:
value = obj._trait_values[self.name]
except KeyError:
@@ -595,7 +595,7 @@ class TraitType(BaseDescriptor):
def _cross_validate(self, obj, value):
if self.name in obj._trait_validators:
- proposal = Bunch({'trait': self, 'value': value, 'owner': obj})
+ proposal = Bunch({'trait': self, 'value': value, 'owner': obj})
value = obj._trait_validators[self.name](obj, proposal)
elif hasattr(obj, '_%s_validate' % self.name):
meth_name = '_%s_validate' % self.name
@@ -633,7 +633,7 @@ class TraitType(BaseDescriptor):
msg = "use the instance .help string directly, like x.help"
else:
msg = "use the instance .metadata dictionary directly, like x.metadata[key] or x.metadata.get(key, default)"
- warn("Deprecated in traitlets 4.1, " + msg, DeprecationWarning, stacklevel=2)
+ warn("Deprecated in traitlets 4.1, " + msg, DeprecationWarning, stacklevel=2)
return self.metadata.get(key, default)
def set_metadata(self, key, value):
@@ -645,7 +645,7 @@ class TraitType(BaseDescriptor):
msg = "use the instance .help string directly, like x.help = value"
else:
msg = "use the instance .metadata dictionary directly, like x.metadata[key] = value"
- warn("Deprecated in traitlets 4.1, " + msg, DeprecationWarning, stacklevel=2)
+ warn("Deprecated in traitlets 4.1, " + msg, DeprecationWarning, stacklevel=2)
self.metadata[key] = value
def tag(self, **metadata):
@@ -655,11 +655,11 @@ class TraitType(BaseDescriptor):
>>> Int(0).tag(config=True, sync=True)
"""
- maybe_constructor_keywords = set(metadata.keys()).intersection({'help','allow_none', 'read_only', 'default_value'})
- if maybe_constructor_keywords:
- warn('The following attributes are set in using `tag`, but seem to be constructor keywords arguments: %s '%
- maybe_constructor_keywords, UserWarning, stacklevel=2)
-
+ maybe_constructor_keywords = set(metadata.keys()).intersection({'help','allow_none', 'read_only', 'default_value'})
+ if maybe_constructor_keywords:
+ warn('The following attributes are set in using `tag`, but seem to be constructor keywords arguments: %s '%
+ maybe_constructor_keywords, UserWarning, stacklevel=2)
+
self.metadata.update(metadata)
return self
@@ -697,13 +697,13 @@ class _CallbackWrapper(object):
if self.nargs == 0:
self.cb()
elif self.nargs == 1:
- self.cb(change.name)
+ self.cb(change.name)
elif self.nargs == 2:
- self.cb(change.name, change.new)
+ self.cb(change.name, change.new)
elif self.nargs == 3:
- self.cb(change.name, change.old, change.new)
+ self.cb(change.name, change.old, change.new)
elif self.nargs == 4:
- self.cb(change.name, change.old, change.new, change.owner)
+ self.cb(change.name, change.old, change.new, change.owner)
def _callback_wrapper(cb):
if isinstance(cb, _CallbackWrapper):
@@ -721,13 +721,13 @@ class MetaHasDescriptors(type):
def __new__(mcls, name, bases, classdict):
"""Create the HasDescriptors class."""
- for k, v in classdict.items():
+ for k, v in classdict.items():
# ----------------------------------------------------------------
# Support of deprecated behavior allowing for TraitType types
# to be used instead of TraitType instances.
if inspect.isclass(v) and issubclass(v, TraitType):
- warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)."
- " Passing types is deprecated in traitlets 4.1.",
+ warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)."
+ " Passing types is deprecated in traitlets 4.1.",
DeprecationWarning, stacklevel=2)
classdict[k] = v()
# ----------------------------------------------------------------
@@ -746,7 +746,7 @@ class MetaHasDescriptors(type):
BaseDescriptor in the class dict of the newly created ``cls`` before
calling their :attr:`class_init` method.
"""
- for k, v in classdict.items():
+ for k, v in classdict.items():
if isinstance(v, BaseDescriptor):
v.class_init(cls, k)
@@ -762,10 +762,10 @@ class MetaHasTraits(MetaHasDescriptors):
def observe(*names, **kwargs):
"""A decorator which can be used to observe Traits on a class.
- The handler passed to the decorator will be called with one ``change``
- dict argument. The change dictionary at least holds a 'type' key and a
- 'name' key, corresponding respectively to the type of notification and the
- name of the attribute that triggered the notification.
+ The handler passed to the decorator will be called with one ``change``
+ dict argument. The change dictionary at least holds a 'type' key and a
+ 'name' key, corresponding respectively to the type of notification and the
+ name of the attribute that triggered the notification.
Other keys may be passed depending on the value of 'type'. In the case
where type is 'change', we also have the following keys:
@@ -778,27 +778,27 @@ def observe(*names, **kwargs):
----------
*names
The str names of the Traits to observe on the object.
- type: str, kwarg-only
- The type of event to observe (e.g. 'change')
+ type: str, kwarg-only
+ The type of event to observe (e.g. 'change')
"""
- if not names:
- raise TypeError("Please specify at least one trait name to observe.")
- for name in names:
- if name is not All and not isinstance(name, six.string_types):
- raise TypeError("trait names to observe must be strings or All, not %r" % name)
+ if not names:
+ raise TypeError("Please specify at least one trait name to observe.")
+ for name in names:
+ if name is not All and not isinstance(name, six.string_types):
+ raise TypeError("trait names to observe must be strings or All, not %r" % name)
return ObserveHandler(names, type=kwargs.get('type', 'change'))
def observe_compat(func):
"""Backward-compatibility shim decorator for observers
-
+
Use with:
-
+
@observe('name')
@observe_compat
def _foo_changed(self, change):
...
-
+
With this, `super()._foo_changed(self, name, old, new)` in subclasses will still work.
Allows adoption of new observer API without breaking subclasses that override and super.
"""
@@ -807,15 +807,15 @@ def observe_compat(func):
change = change_or_name
else:
clsname = self.__class__.__name__
- warn("A parent of %s._%s_changed has adopted the new (traitlets 4.1) @observe(change) API" % (
+ warn("A parent of %s._%s_changed has adopted the new (traitlets 4.1) @observe(change) API" % (
clsname, change_or_name), DeprecationWarning)
- change = Bunch(
- type='change',
- old=old,
- new=new,
- name=change_or_name,
- owner=self,
- )
+ change = Bunch(
+ type='change',
+ old=old,
+ new=new,
+ name=change_or_name,
+ owner=self,
+ )
return func(self, change)
return compatible_observer
@@ -837,18 +837,18 @@ def validate(*names):
Notes
-----
- Since the owner has access to the ``HasTraits`` instance via the 'owner' key,
+ Since the owner has access to the ``HasTraits`` instance via the 'owner' key,
the registered cross validator could potentially make changes to attributes
of the ``HasTraits`` instance. However, we recommend not to do so. The reason
is that the cross-validation of attributes may run in arbitrary order when
- exiting the ``hold_trait_notifications`` context, and such changes may not
+ exiting the ``hold_trait_notifications`` context, and such changes may not
commute.
"""
- if not names:
- raise TypeError("Please specify at least one trait name to validate.")
- for name in names:
- if name is not All and not isinstance(name, six.string_types):
- raise TypeError("trait names to validate must be strings or All, not %r" % name)
+ if not names:
+ raise TypeError("Please specify at least one trait name to validate.")
+ for name in names:
+ if name is not All and not isinstance(name, six.string_types):
+ raise TypeError("trait names to validate must be strings or All, not %r" % name)
return ValidateHandler(names)
@@ -890,8 +890,8 @@ def default(name):
return 3.0 # ignored since it is defined in a
# class derived from B.a.this_class.
"""
- if not isinstance(name, six.string_types):
- raise TypeError("Trait name must be a string or All, not %r" % name)
+ if not isinstance(name, six.string_types):
+ raise TypeError("Trait name must be a string or All, not %r" % name)
return DefaultHandler(name)
@@ -902,7 +902,7 @@ class EventHandler(BaseDescriptor):
return self
def __call__(self, *args, **kwargs):
- """Pass `*args` and `**kwargs` to the handler's function if it exists."""
+ """Pass `*args` and `**kwargs` to the handler's function if it exists."""
if hasattr(self, 'func'):
return self.func(*args, **kwargs)
else:
@@ -943,26 +943,26 @@ class DefaultHandler(EventHandler):
cls._trait_default_generators[self.trait_name] = self
-class HasDescriptors(six.with_metaclass(MetaHasDescriptors, object)):
+class HasDescriptors(six.with_metaclass(MetaHasDescriptors, object)):
"""The base class for all classes that have descriptors.
"""
- def __new__(cls, *args, **kwargs):
+ def __new__(cls, *args, **kwargs):
# This is needed because object.__new__ only accepts
# the cls argument.
new_meth = super(HasDescriptors, cls).__new__
if new_meth is object.__new__:
inst = new_meth(cls)
else:
- inst = new_meth(cls, *args, **kwargs)
- inst.setup_instance(*args, **kwargs)
+ inst = new_meth(cls, *args, **kwargs)
+ inst.setup_instance(*args, **kwargs)
return inst
- def setup_instance(self, *args, **kwargs):
- """
- This is called **before** self.__init__ is called.
- """
- self._cross_validation_lock = False
+ def setup_instance(self, *args, **kwargs):
+ """
+ This is called **before** self.__init__ is called.
+ """
+ self._cross_validation_lock = False
cls = self.__class__
for key in dir(cls):
# Some descriptors raise AttributeError like zope.interface's
@@ -977,46 +977,46 @@ class HasDescriptors(six.with_metaclass(MetaHasDescriptors, object)):
value.instance_init(self)
-class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
+class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
- def setup_instance(self, *args, **kwargs):
+ def setup_instance(self, *args, **kwargs):
self._trait_values = {}
self._trait_notifiers = {}
self._trait_validators = {}
- super(HasTraits, self).setup_instance(*args, **kwargs)
+ super(HasTraits, self).setup_instance(*args, **kwargs)
- def __init__(self, *args, **kwargs):
+ def __init__(self, *args, **kwargs):
# Allow trait values to be set using keyword arguments.
# We need to use setattr for this to trigger validation and
# notifications.
- super_args = args
- super_kwargs = {}
+ super_args = args
+ super_kwargs = {}
with self.hold_trait_notifications():
- for key, value in kwargs.items():
- if self.has_trait(key):
- setattr(self, key, value)
- else:
- # passthrough args that don't set traits to super
- super_kwargs[key] = value
- try:
- super(HasTraits, self).__init__(*super_args, **super_kwargs)
- except TypeError as e:
- arg_s_list = [ repr(arg) for arg in super_args ]
- for k, v in super_kwargs.items():
- arg_s_list.append("%s=%r" % (k, v))
- arg_s = ', '.join(arg_s_list)
- warn(
- "Passing unrecoginized arguments to super({classname}).__init__({arg_s}).\n"
- "{error}\n"
- "This is deprecated in traitlets 4.2."
- "This error will be raised in a future release of traitlets."
- .format(
- arg_s=arg_s, classname=self.__class__.__name__,
- error=e,
- ),
- DeprecationWarning,
- stacklevel=2,
- )
+ for key, value in kwargs.items():
+ if self.has_trait(key):
+ setattr(self, key, value)
+ else:
+ # passthrough args that don't set traits to super
+ super_kwargs[key] = value
+ try:
+ super(HasTraits, self).__init__(*super_args, **super_kwargs)
+ except TypeError as e:
+ arg_s_list = [ repr(arg) for arg in super_args ]
+ for k, v in super_kwargs.items():
+ arg_s_list.append("%s=%r" % (k, v))
+ arg_s = ', '.join(arg_s_list)
+ warn(
+ "Passing unrecoginized arguments to super({classname}).__init__({arg_s}).\n"
+ "{error}\n"
+ "This is deprecated in traitlets 4.2."
+ "This error will be raised in a future release of traitlets."
+ .format(
+ arg_s=arg_s, classname=self.__class__.__name__,
+ error=e,
+ ),
+ DeprecationWarning,
+ stacklevel=2,
+ )
def __getstate__(self):
d = self.__dict__.copy()
@@ -1044,27 +1044,27 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
if isinstance(value, EventHandler):
value.instance_init(self)
- @property
+ @property
+ @contextlib.contextmanager
+ def cross_validation_lock(self):
+ """
+ A contextmanager for running a block with our cross validation lock set
+ to True.
+
+ At the end of the block, the lock's value is restored to its value
+ prior to entering the block.
+ """
+ if self._cross_validation_lock:
+ yield
+ return
+ else:
+ try:
+ self._cross_validation_lock = True
+ yield
+ finally:
+ self._cross_validation_lock = False
+
@contextlib.contextmanager
- def cross_validation_lock(self):
- """
- A contextmanager for running a block with our cross validation lock set
- to True.
-
- At the end of the block, the lock's value is restored to its value
- prior to entering the block.
- """
- if self._cross_validation_lock:
- yield
- return
- else:
- try:
- self._cross_validation_lock = True
- yield
- finally:
- self._cross_validation_lock = False
-
- @contextlib.contextmanager
def hold_trait_notifications(self):
"""Context manager for bundling trait change notifications and cross
validation.
@@ -1073,7 +1073,7 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
race conditions in trait notifiers requesting other trait values.
All trait notifications will fire after all values have been assigned.
"""
- if self._cross_validation_lock:
+ if self._cross_validation_lock:
yield
return
else:
@@ -1085,15 +1085,15 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
if past_changes is None:
return [change]
else:
- if past_changes[-1]['type'] == 'change' and change.type == 'change':
- past_changes[-1]['new'] = change.new
+ if past_changes[-1]['type'] == 'change' and change.type == 'change':
+ past_changes[-1]['new'] = change.new
else:
# In case of changes other than 'change', append the notification.
past_changes.append(change)
return past_changes
def hold(change):
- name = change.name
+ name = change.name
cache[name] = compress(cache.get(name), change)
try:
@@ -1106,24 +1106,24 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
for name in list(cache.keys()):
trait = getattr(self.__class__, name)
value = trait._cross_validate(self, getattr(self, name))
- self.set_trait(name, value)
+ self.set_trait(name, value)
except TraitError as e:
# Roll back in case of TraitError during final cross validation.
self.notify_change = lambda x: None
for name, changes in cache.items():
for change in changes[::-1]:
# TODO: Separate in a rollback function per notification type.
- if change.type == 'change':
- if change.old is not Undefined:
- self.set_trait(name, change.old)
+ if change.type == 'change':
+ if change.old is not Undefined:
+ self.set_trait(name, change.old)
else:
self._trait_values.pop(name)
cache = {}
raise e
finally:
self._cross_validation_lock = False
- # Restore method retrieval from class
- del self.notify_change
+ # Restore method retrieval from class
+ del self.notify_change
# trigger delayed notifications
for changes in cache.values():
@@ -1131,19 +1131,19 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
self.notify_change(change)
def _notify_trait(self, name, old_value, new_value):
- self.notify_change(Bunch(
- name=name,
- old=old_value,
- new=new_value,
- owner=self,
- type='change',
- ))
+ self.notify_change(Bunch(
+ name=name,
+ old=old_value,
+ new=new_value,
+ owner=self,
+ type='change',
+ ))
def notify_change(self, change):
- if not isinstance(change, Bunch):
- # cast to bunch if given a dict
- change = Bunch(change)
- name, type = change.name, change.type
+ if not isinstance(change, Bunch):
+ # cast to bunch if given a dict
+ change = Bunch(change)
+ name, type = change.name, change.type
callables = []
callables.extend(self._trait_notifiers.get(name, {}).get(type, []))
@@ -1170,9 +1170,9 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
if isinstance(c, _CallbackWrapper):
c = c.__call__
- elif isinstance(c, EventHandler) and c.name is not None:
+ elif isinstance(c, EventHandler) and c.name is not None:
c = getattr(self, c.name)
-
+
c(change)
def _add_notifiers(self, handler, name, type):
@@ -1225,7 +1225,7 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
If False (the default), then install the handler. If True
then unintall it.
"""
- warn("on_trait_change is deprecated in traitlets 4.1: use observe instead",
+ warn("on_trait_change is deprecated in traitlets 4.1: use observe instead",
DeprecationWarning, stacklevel=2)
if name is None:
name = All
@@ -1243,8 +1243,8 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
----------
handler : callable
A callable that is called when a trait changes. Its
- signature should be ``handler(change)``, where ``change`` is a
- dictionary. The change dictionary at least holds a 'type' key.
+ signature should be ``handler(change)``, where ``change`` is a
+ dictionary. The change dictionary at least holds a 'type' key.
* ``type``: the type of notification.
Other keys may be passed depending on the value of 'type'. In the
case where type is 'change', we also have the following keys:
@@ -1267,7 +1267,7 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
def unobserve(self, handler, names=All, type='change'):
"""Remove a trait change handler.
- This is used to unregister handlers to trait change notifications.
+ This is used to unregister handlers to trait change notifications.
Parameters
----------
@@ -1297,19 +1297,19 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
pass
def _register_validator(self, handler, names):
- """Setup a handler to be called when a trait should be cross validated.
+ """Setup a handler to be called when a trait should be cross validated.
This is used to setup dynamic notifications for cross-validation.
If a validator is already registered for any of the provided names, a
- TraitError is raised and no new validator is registered.
+ TraitError is raised and no new validator is registered.
Parameters
----------
handler : callable
A callable that is called when the given trait is cross-validated.
- Its signature is handler(proposal), where proposal is a Bunch (dictionary with attribute access)
- with the following attributes/keys:
+ Its signature is handler(proposal), where proposal is a Bunch (dictionary with attribute access)
+ with the following attributes/keys:
* ``owner`` : the HasTraits instance
* ``value`` : the proposed value for the modified trait attribute
* ``trait`` : the TraitType instance associated with the attribute
@@ -1326,22 +1326,22 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
for name in names:
self._trait_validators[name] = handler
- def add_traits(self, **traits):
- """Dynamically add trait attributes to the HasTraits instance."""
- self.__class__ = type(self.__class__.__name__, (self.__class__,),
- traits)
- for trait in traits.values():
- trait.instance_init(self)
-
- def set_trait(self, name, value):
- """Forcibly sets trait attribute, including read-only attributes."""
- cls = self.__class__
- if not self.has_trait(name):
- raise TraitError("Class %s does not have a trait named %s" %
- (cls.__name__, name))
- else:
- getattr(cls, name).set(self, value)
-
+ def add_traits(self, **traits):
+ """Dynamically add trait attributes to the HasTraits instance."""
+ self.__class__ = type(self.__class__.__name__, (self.__class__,),
+ traits)
+ for trait in traits.values():
+ trait.instance_init(self)
+
+ def set_trait(self, name, value):
+ """Forcibly sets trait attribute, including read-only attributes."""
+ cls = self.__class__
+ if not self.has_trait(name):
+ raise TraitError("Class %s does not have a trait named %s" %
+ (cls.__name__, name))
+ else:
+ getattr(cls, name).set(self, value)
+
@classmethod
def class_trait_names(cls, **metadata):
"""Get a list of all the names of this class' traits.
@@ -1349,7 +1349,7 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
This method is just like the :meth:`trait_names` method,
but is unbound.
"""
- return list(cls.class_traits(**metadata))
+ return list(cls.class_traits(**metadata))
@classmethod
def class_traits(cls, **metadata):
@@ -1399,10 +1399,10 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
def has_trait(self, name):
"""Returns True if the object has a trait with the specified name."""
return isinstance(getattr(self.__class__, name, None), TraitType)
-
+
def trait_names(self, **metadata):
"""Get a list of all the names of this class' traits."""
- return list(self.traits(**metadata))
+ return list(self.traits(**metadata))
def traits(self, **metadata):
"""Get a ``dict`` of all the traits of this class. The dictionary
@@ -1443,48 +1443,48 @@ class HasTraits(six.with_metaclass(MetaHasTraits, HasDescriptors)):
except AttributeError:
raise TraitError("Class %s does not have a trait named %s" %
(self.__class__.__name__, traitname))
- metadata_name = '_' + traitname + '_metadata'
- if hasattr(self, metadata_name) and key in getattr(self, metadata_name):
- return getattr(self, metadata_name).get(key, default)
+ metadata_name = '_' + traitname + '_metadata'
+ if hasattr(self, metadata_name) and key in getattr(self, metadata_name):
+ return getattr(self, metadata_name).get(key, default)
else:
return trait.metadata.get(key, default)
- @classmethod
- def class_own_trait_events(cls, name):
- """Get a dict of all event handlers defined on this class, not a parent.
-
- Works like ``event_handlers``, except for excluding traits from parents.
- """
- sup = super(cls, cls)
- return {n: e for (n, e) in cls.events(name).items()
- if getattr(sup, n, None) is not e}
-
- @classmethod
- def trait_events(cls, name=None):
- """Get a ``dict`` of all the event handlers of this class.
-
- Parameters
- ----------
- name: str (default: None)
- The name of a trait of this class. If name is ``None`` then all
- the event handlers of this class will be returned instead.
-
- Returns
- -------
- The event handlers associated with a trait name, or all event handlers.
- """
- events = {}
- for k, v in getmembers(cls):
- if isinstance(v, EventHandler):
- if name is None:
- events[k] = v
- elif name in v.trait_names:
- events[k] = v
- elif hasattr(v, 'tags'):
- if cls.trait_names(**v.tags):
- events[k] = v
- return events
-
+ @classmethod
+ def class_own_trait_events(cls, name):
+ """Get a dict of all event handlers defined on this class, not a parent.
+
+ Works like ``event_handlers``, except for excluding traits from parents.
+ """
+ sup = super(cls, cls)
+ return {n: e for (n, e) in cls.events(name).items()
+ if getattr(sup, n, None) is not e}
+
+ @classmethod
+ def trait_events(cls, name=None):
+ """Get a ``dict`` of all the event handlers of this class.
+
+ Parameters
+ ----------
+ name: str (default: None)
+ The name of a trait of this class. If name is ``None`` then all
+ the event handlers of this class will be returned instead.
+
+ Returns
+ -------
+ The event handlers associated with a trait name, or all event handlers.
+ """
+ events = {}
+ for k, v in getmembers(cls):
+ if isinstance(v, EventHandler):
+ if name is None:
+ events[k] = v
+ elif name in v.trait_names:
+ events[k] = v
+ elif hasattr(v, 'tags'):
+ if cls.trait_names(**v.tags):
+ events[k] = v
+ return events
+
#-----------------------------------------------------------------------------
# Actual TraitTypes implementations/subclasses
#-----------------------------------------------------------------------------
@@ -1508,7 +1508,7 @@ class ClassBasedTraitType(TraitType):
def error(self, obj, value):
kind = type(value)
- if six.PY2 and kind is InstanceType:
+ if six.PY2 and kind is InstanceType:
msg = 'class %s' % value.__class__.__name__
else:
msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
@@ -1527,7 +1527,7 @@ class ClassBasedTraitType(TraitType):
class Type(ClassBasedTraitType):
"""A trait whose value must be a subclass of a specified class."""
- def __init__ (self, default_value=Undefined, klass=None, **kwargs):
+ def __init__ (self, default_value=Undefined, klass=None, **kwargs):
"""Construct a Type trait
A Type trait specifies that its values must be subclasses of
@@ -1562,16 +1562,16 @@ class Type(ClassBasedTraitType):
else:
klass = default_value
- if not (inspect.isclass(klass) or isinstance(klass, six.string_types)):
+ if not (inspect.isclass(klass) or isinstance(klass, six.string_types)):
raise TraitError("A Type trait must specify a class.")
self.klass = klass
- super(Type, self).__init__(new_default_value, **kwargs)
+ super(Type, self).__init__(new_default_value, **kwargs)
def validate(self, obj, value):
"""Validates that the value is a valid object instance."""
- if isinstance(value, six.string_types):
+ if isinstance(value, six.string_types):
try:
value = self._resolve_string(value)
except ImportError:
@@ -1587,10 +1587,10 @@ class Type(ClassBasedTraitType):
def info(self):
""" Returns a description of the trait."""
- if isinstance(self.klass, six.string_types):
+ if isinstance(self.klass, six.string_types):
klass = self.klass
else:
- klass = self.klass.__module__ + '.' + self.klass.__name__
+ klass = self.klass.__module__ + '.' + self.klass.__name__
result = "a subclass of '%s'" % klass
if self.allow_none:
return result + ' or None'
@@ -1601,14 +1601,14 @@ class Type(ClassBasedTraitType):
super(Type, self).instance_init(obj)
def _resolve_classes(self):
- if isinstance(self.klass, six.string_types):
+ if isinstance(self.klass, six.string_types):
self.klass = self._resolve_string(self.klass)
- if isinstance(self.default_value, six.string_types):
+ if isinstance(self.default_value, six.string_types):
self.default_value = self._resolve_string(self.default_value)
def default_value_repr(self):
value = self.default_value
- if isinstance(value, six.string_types):
+ if isinstance(value, six.string_types):
return repr(value)
else:
return repr('{}.{}'.format(value.__module__, value.__name__))
@@ -1624,7 +1624,7 @@ class Instance(ClassBasedTraitType):
klass = None
- def __init__(self, klass=None, args=None, kw=None, **kwargs):
+ def __init__(self, klass=None, args=None, kw=None, **kwargs):
"""Construct an Instance trait.
This trait allows values that are instances of a particular
@@ -1653,8 +1653,8 @@ class Instance(ClassBasedTraitType):
"""
if klass is None:
klass = self.klass
-
- if (klass is not None) and (inspect.isclass(klass) or isinstance(klass, six.string_types)):
+
+ if (klass is not None) and (inspect.isclass(klass) or isinstance(klass, six.string_types)):
self.klass = klass
else:
raise TraitError('The klass attribute must be a class'
@@ -1668,7 +1668,7 @@ class Instance(ClassBasedTraitType):
self.default_args = args
self.default_kwargs = kw
- super(Instance, self).__init__(**kwargs)
+ super(Instance, self).__init__(**kwargs)
def validate(self, obj, value):
if isinstance(value, self.klass):
@@ -1677,7 +1677,7 @@ class Instance(ClassBasedTraitType):
self.error(obj, value)
def info(self):
- if isinstance(self.klass, six.string_types):
+ if isinstance(self.klass, six.string_types):
klass = self.klass
else:
klass = self.klass.__name__
@@ -1692,7 +1692,7 @@ class Instance(ClassBasedTraitType):
super(Instance, self).instance_init(obj)
def _resolve_classes(self):
- if isinstance(self.klass, six.string_types):
+ if isinstance(self.klass, six.string_types):
self.klass = self._resolve_string(self.klass)
def make_dynamic_default(self):
@@ -1742,8 +1742,8 @@ class This(ClassBasedTraitType):
info_text = 'an instance of the same type as the receiver or None'
- def __init__(self, **kwargs):
- super(This, self).__init__(None, **kwargs)
+ def __init__(self, **kwargs):
+ super(This, self).__init__(None, **kwargs)
def validate(self, obj, value):
# What if value is a superclass of obj.__class__? This is
@@ -1758,7 +1758,7 @@ class This(ClassBasedTraitType):
class Union(TraitType):
"""A trait type representing a Union type."""
- def __init__(self, trait_types, **kwargs):
+ def __init__(self, trait_types, **kwargs):
"""Construct a Union trait.
This trait allows values that are allowed by at least one of the
@@ -1776,8 +1776,8 @@ class Union(TraitType):
with the validation function of Float, then Bool, and finally Int.
"""
self.trait_types = trait_types
- self.info_text = " or ".join([tt.info() for tt in self.trait_types])
- super(Union, self).__init__(**kwargs)
+ self.info_text = " or ".join([tt.info() for tt in self.trait_types])
+ super(Union, self).__init__(**kwargs)
def class_init(self, cls, name):
for trait_type in self.trait_types:
@@ -1790,13 +1790,13 @@ class Union(TraitType):
super(Union, self).instance_init(obj)
def validate(self, obj, value):
- with obj.cross_validation_lock:
+ with obj.cross_validation_lock:
for trait_type in self.trait_types:
try:
v = trait_type._validate(obj, value)
- # In the case of an element trait, the name is None
- if self.name is not None:
- setattr(obj, '_' + self.name + '_metadata', trait_type.metadata)
+ # In the case of an element trait, the name is None
+ if self.name is not None:
+ setattr(obj, '_' + self.name + '_metadata', trait_type.metadata)
return v
except TraitError:
continue
@@ -1808,16 +1808,16 @@ class Union(TraitType):
else:
return Union(self.trait_types + [other])
- def make_dynamic_default(self):
- if self.default_value is not Undefined:
- return self.default_value
- for trait_type in self.trait_types:
- if trait_type.default_value is not Undefined:
- return trait_type.default_value
- elif hasattr(trait_type, 'make_dynamic_default'):
- return trait_type.make_dynamic_default()
-
-
+ def make_dynamic_default(self):
+ if self.default_value is not Undefined:
+ return self.default_value
+ for trait_type in self.trait_types:
+ if trait_type.default_value is not Undefined:
+ return trait_type.default_value
+ elif hasattr(trait_type, 'make_dynamic_default'):
+ return trait_type.make_dynamic_default()
+
+
#-----------------------------------------------------------------------------
# Basic TraitTypes implementations/subclasses
#-----------------------------------------------------------------------------
@@ -1829,37 +1829,37 @@ class Any(TraitType):
info_text = 'any value'
-def _validate_bounds(trait, obj, value):
- """
- Validate that a number to be applied to a trait is between bounds.
-
- If value is not between min_bound and max_bound, this raises a
- TraitError with an error message appropriate for this trait.
- """
- if trait.min is not None and value < trait.min:
- raise TraitError(
- "The value of the '{name}' trait of {klass} instance should "
- "not be less than {min_bound}, but a value of {value} was "
- "specified".format(
- name=trait.name, klass=class_of(obj),
- value=value, min_bound=trait.min))
- if trait.max is not None and value > trait.max:
- raise TraitError(
- "The value of the '{name}' trait of {klass} instance should "
- "not be greater than {max_bound}, but a value of {value} was "
- "specified".format(
- name=trait.name, klass=class_of(obj),
- value=value, max_bound=trait.max))
- return value
-
-
+def _validate_bounds(trait, obj, value):
+ """
+ Validate that a number to be applied to a trait is between bounds.
+
+ If value is not between min_bound and max_bound, this raises a
+ TraitError with an error message appropriate for this trait.
+ """
+ if trait.min is not None and value < trait.min:
+ raise TraitError(
+ "The value of the '{name}' trait of {klass} instance should "
+ "not be less than {min_bound}, but a value of {value} was "
+ "specified".format(
+ name=trait.name, klass=class_of(obj),
+ value=value, min_bound=trait.min))
+ if trait.max is not None and value > trait.max:
+ raise TraitError(
+ "The value of the '{name}' trait of {klass} instance should "
+ "not be greater than {max_bound}, but a value of {value} was "
+ "specified".format(
+ name=trait.name, klass=class_of(obj),
+ value=value, max_bound=trait.max))
+ return value
+
+
class Int(TraitType):
"""An int trait."""
default_value = 0
info_text = 'an int'
- def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
+ def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
self.min = kwargs.pop('min', None)
self.max = kwargs.pop('max', None)
super(Int, self).__init__(default_value=default_value,
@@ -1868,7 +1868,7 @@ class Int(TraitType):
def validate(self, obj, value):
if not isinstance(value, int):
self.error(obj, value)
- return _validate_bounds(self, obj, value)
+ return _validate_bounds(self, obj, value)
class CInt(Int):
@@ -1876,49 +1876,49 @@ class CInt(Int):
def validate(self, obj, value):
try:
- value = int(value)
+ value = int(value)
except:
self.error(obj, value)
- return _validate_bounds(self, obj, value)
+ return _validate_bounds(self, obj, value)
+
-
-if six.PY2:
+if six.PY2:
class Long(TraitType):
"""A long integer trait."""
default_value = 0
info_text = 'a long'
- def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
- self.min = kwargs.pop('min', None)
- self.max = kwargs.pop('max', None)
- super(Long, self).__init__(
- default_value=default_value,
- allow_none=allow_none, **kwargs)
-
- def _validate_long(self, obj, value):
+ def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
+ self.min = kwargs.pop('min', None)
+ self.max = kwargs.pop('max', None)
+ super(Long, self).__init__(
+ default_value=default_value,
+ allow_none=allow_none, **kwargs)
+
+ def _validate_long(self, obj, value):
if isinstance(value, long):
return value
if isinstance(value, int):
return long(value)
self.error(obj, value)
- def validate(self, obj, value):
- value = self._validate_long(obj, value)
- return _validate_bounds(self, obj, value)
+ def validate(self, obj, value):
+ value = self._validate_long(obj, value)
+ return _validate_bounds(self, obj, value)
+
-
class CLong(Long):
"""A casting version of the long integer trait."""
def validate(self, obj, value):
try:
- value = long(value)
+ value = long(value)
except:
self.error(obj, value)
- return _validate_bounds(self, obj, value)
+ return _validate_bounds(self, obj, value)
+
-
class Integer(TraitType):
"""An integer trait.
@@ -1927,14 +1927,14 @@ if six.PY2:
default_value = 0
info_text = 'an integer'
- def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
- self.min = kwargs.pop('min', None)
- self.max = kwargs.pop('max', None)
- super(Integer, self).__init__(
- default_value=default_value,
- allow_none=allow_none, **kwargs)
-
- def _validate_int(self, obj, value):
+ def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
+ self.min = kwargs.pop('min', None)
+ self.max = kwargs.pop('max', None)
+ super(Integer, self).__init__(
+ default_value=default_value,
+ allow_none=allow_none, **kwargs)
+
+ def _validate_int(self, obj, value):
if isinstance(value, int):
return value
if isinstance(value, long):
@@ -1948,25 +1948,25 @@ if six.PY2:
return int(value)
self.error(obj, value)
- def validate(self, obj, value):
- value = self._validate_int(obj, value)
- return _validate_bounds(self, obj, value)
+ def validate(self, obj, value):
+ value = self._validate_int(obj, value)
+ return _validate_bounds(self, obj, value)
+
+else:
+ Long, CLong = Int, CInt
+ Integer = Int
+
-else:
- Long, CLong = Int, CInt
- Integer = Int
-
-
class Float(TraitType):
"""A float trait."""
default_value = 0.0
info_text = 'a float'
- def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
+ def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
self.min = kwargs.pop('min', -float('inf'))
self.max = kwargs.pop('max', float('inf'))
- super(Float, self).__init__(default_value=default_value,
+ super(Float, self).__init__(default_value=default_value,
allow_none=allow_none, **kwargs)
def validate(self, obj, value):
@@ -1974,7 +1974,7 @@ class Float(TraitType):
value = float(value)
if not isinstance(value, float):
self.error(obj, value)
- return _validate_bounds(self, obj, value)
+ return _validate_bounds(self, obj, value)
class CFloat(Float):
@@ -1982,12 +1982,12 @@ class CFloat(Float):
def validate(self, obj, value):
try:
- value = float(value)
+ value = float(value)
except:
self.error(obj, value)
- return _validate_bounds(self, obj, value)
+ return _validate_bounds(self, obj, value)
+
-
class Complex(TraitType):
"""A trait for complex numbers."""
@@ -2043,7 +2043,7 @@ class Unicode(TraitType):
info_text = 'a unicode string'
def validate(self, obj, value):
- if isinstance(value, six.text_type):
+ if isinstance(value, six.text_type):
return value
if isinstance(value, bytes):
try:
@@ -2059,7 +2059,7 @@ class CUnicode(Unicode):
def validate(self, obj, value):
try:
- return six.text_type(value)
+ return six.text_type(value)
except:
self.error(obj, value)
@@ -2070,7 +2070,7 @@ class ObjectName(TraitType):
This does not check that the name exists in any scope."""
info_text = "a valid object identifier in Python"
- if six.PY2:
+ if six.PY2:
# Python 2:
def coerce_str(self, obj, value):
"In Python 2, coerce ascii-only unicode to str"
@@ -2080,13 +2080,13 @@ class ObjectName(TraitType):
except UnicodeEncodeError:
self.error(obj, value)
return value
- else:
- coerce_str = staticmethod(lambda _,s: s)
+ else:
+ coerce_str = staticmethod(lambda _,s: s)
def validate(self, obj, value):
value = self.coerce_str(obj, value)
- if isinstance(value, six.string_types) and isidentifier(value):
+ if isinstance(value, six.string_types) and isidentifier(value):
return value
self.error(obj, value)
@@ -2095,8 +2095,8 @@ class DottedObjectName(ObjectName):
def validate(self, obj, value):
value = self.coerce_str(obj, value)
- if isinstance(value, six.string_types) and all(isidentifier(a)
- for a in value.split('.')):
+ if isinstance(value, six.string_types) and all(isidentifier(a)
+ for a in value.split('.')):
return value
self.error(obj, value)
@@ -2126,11 +2126,11 @@ class CBool(Bool):
class Enum(TraitType):
"""An enum whose value must be in a given sequence."""
- def __init__(self, values, default_value=Undefined, **kwargs):
+ def __init__(self, values, default_value=Undefined, **kwargs):
self.values = values
- if kwargs.get('allow_none', False) and default_value is Undefined:
+ if kwargs.get('allow_none', False) and default_value is Undefined:
default_value = None
- super(Enum, self).__init__(default_value, **kwargs)
+ super(Enum, self).__init__(default_value, **kwargs)
def validate(self, obj, value):
if value in self.values:
@@ -2146,15 +2146,15 @@ class Enum(TraitType):
class CaselessStrEnum(Enum):
"""An enum of strings where the case should be ignored."""
-
- def __init__(self, values, default_value=Undefined, **kwargs):
- values = [cast_unicode_py2(value) for value in values]
- super(CaselessStrEnum, self).__init__(values, default_value=default_value, **kwargs)
-
+
+ def __init__(self, values, default_value=Undefined, **kwargs):
+ values = [cast_unicode_py2(value) for value in values]
+ super(CaselessStrEnum, self).__init__(values, default_value=default_value, **kwargs)
+
def validate(self, obj, value):
if isinstance(value, str):
- value = cast_unicode_py2(value)
- if not isinstance(value, six.string_types):
+ value = cast_unicode_py2(value)
+ if not isinstance(value, six.string_types):
self.error(obj, value)
for v in self.values:
@@ -2172,7 +2172,7 @@ class Container(Instance):
_valid_defaults = SequenceTypes
_trait = None
- def __init__(self, trait=None, default_value=None, **kwargs):
+ def __init__(self, trait=None, default_value=None, **kwargs):
"""Create a container trait type from a list, set, or tuple.
The default value is created by doing ``List(default_value)``,
@@ -2200,7 +2200,7 @@ class Container(Instance):
allow_none : bool [ default False ]
Whether to allow the value to be None
- **kwargs : any
+ **kwargs : any
further keys for extensions to the Trait (e.g. config)
"""
@@ -2218,14 +2218,14 @@ class Container(Instance):
if is_trait(trait):
if isinstance(trait, type):
- warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)."
- " Passing types is deprecated in traitlets 4.1.",
+ warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)."
+ " Passing types is deprecated in traitlets 4.1.",
DeprecationWarning, stacklevel=3)
self._trait = trait() if isinstance(trait, type) else trait
elif trait is not None:
raise TypeError("`trait` must be a Trait or None, got %s" % repr_type(trait))
- super(Container,self).__init__(klass=self.klass, args=args, **kwargs)
+ super(Container,self).__init__(klass=self.klass, args=args, **kwargs)
def element_error(self, obj, element, validator):
e = "Element of the '%s' trait of %s instance must be %s, but a value of %s was specified." \
@@ -2272,7 +2272,7 @@ class List(Container):
klass = list
_cast_types = (tuple,)
- def __init__(self, trait=None, default_value=None, minlen=0, maxlen=sys.maxsize, **kwargs):
+ def __init__(self, trait=None, default_value=None, minlen=0, maxlen=sys.maxsize, **kwargs):
"""Create a List trait type from a list, set, or tuple.
The default value is created by doing ``list(default_value)``,
@@ -2306,7 +2306,7 @@ class List(Container):
self._minlen = minlen
self._maxlen = maxlen
super(List, self).__init__(trait=trait, default_value=default_value,
- **kwargs)
+ **kwargs)
def length_error(self, obj, value):
e = "The '%s' trait of %s instance must be of length %i <= L <= %i, but a value of %s was specified." \
@@ -2333,7 +2333,7 @@ class Set(List):
# Redefine __init__ just to make the docstring more accurate.
def __init__(self, trait=None, default_value=None, minlen=0, maxlen=sys.maxsize,
- **kwargs):
+ **kwargs):
"""Create a Set trait type from a list, set, or tuple.
The default value is created by doing ``set(default_value)``,
@@ -2364,7 +2364,7 @@ class Set(List):
maxlen : Int [ default sys.maxsize ]
The maximum length of the input list
"""
- super(Set, self).__init__(trait, default_value, minlen, maxlen, **kwargs)
+ super(Set, self).__init__(trait, default_value, minlen, maxlen, **kwargs)
class Tuple(Container):
@@ -2372,7 +2372,7 @@ class Tuple(Container):
klass = tuple
_cast_types = (list,)
- def __init__(self, *traits, **kwargs):
+ def __init__(self, *traits, **kwargs):
"""Create a tuple from a list, set, or tuple.
Create a fixed-type tuple with Traits:
@@ -2402,7 +2402,7 @@ class Tuple(Container):
will be cast to a tuple. If ``traits`` are specified,
``default_value`` must conform to the shape and type they specify.
"""
- default_value = kwargs.pop('default_value', Undefined)
+ default_value = kwargs.pop('default_value', Undefined)
# allow Tuple((values,)):
if len(traits) == 1 and default_value is Undefined and not is_trait(traits[0]):
default_value = traits[0]
@@ -2418,8 +2418,8 @@ class Tuple(Container):
self._traits = []
for trait in traits:
if isinstance(trait, type):
- warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)"
- " Passing types is deprecated in traitlets 4.1.",
+ warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)"
+ " Passing types is deprecated in traitlets 4.1.",
DeprecationWarning, stacklevel=2)
t = trait() if isinstance(trait, type) else trait
self._traits.append(t)
@@ -2427,7 +2427,7 @@ class Tuple(Container):
if self._traits and default_value is None:
# don't allow default to be an empty container if length is specified
args = None
- super(Container,self).__init__(klass=self.klass, args=args, **kwargs)
+ super(Container,self).__init__(klass=self.klass, args=args, **kwargs)
def validate_elements(self, obj, value):
if not self._traits:
@@ -2466,22 +2466,22 @@ class Dict(Instance):
_trait = None
def __init__(self, trait=None, traits=None, default_value=Undefined,
- **kwargs):
- """Create a dict trait type from a Python dict.
+ **kwargs):
+ """Create a dict trait type from a Python dict.
The default value is created by doing ``dict(default_value)``,
which creates a copy of the ``default_value``.
- Parameters
- ----------
-
+ Parameters
+ ----------
+
trait : TraitType [ optional ]
- The specified trait type to check and use to restrict contents of
- the Container. If unspecified, trait types are not checked.
+ The specified trait type to check and use to restrict contents of
+ the Container. If unspecified, trait types are not checked.
- traits : Dictionary of trait types [ optional ]
- A Python dictionary containing the types that are valid for
- restricting the content of the Dict Container for certain keys.
+ traits : Dictionary of trait types [ optional ]
+ A Python dictionary containing the types that are valid for
+ restricting the content of the Dict Container for certain keys.
default_value : SequenceType [ optional ]
The default value for the Dict. Must be dict, tuple, or None, and
@@ -2509,8 +2509,8 @@ class Dict(Instance):
# Case where a type of TraitType is provided rather than an instance
if is_trait(trait):
if isinstance(trait, type):
- warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)"
- " Passing types is deprecated in traitlets 4.1.",
+ warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)"
+ " Passing types is deprecated in traitlets 4.1.",
DeprecationWarning, stacklevel=2)
self._trait = trait() if isinstance(trait, type) else trait
elif trait is not None:
@@ -2518,7 +2518,7 @@ class Dict(Instance):
self._traits = traits
- super(Dict, self).__init__(klass=dict, args=args, **kwargs)
+ super(Dict, self).__init__(klass=dict, args=args, **kwargs)
def element_error(self, obj, element, validator):
e = "Element of the '%s' trait of %s instance must be %s, but a value of %s was specified." \
@@ -2533,26 +2533,26 @@ class Dict(Instance):
return value
def validate_elements(self, obj, value):
- use_dict = bool(self._traits)
- default_to = (self._trait or Any())
- if not use_dict and isinstance(default_to, Any):
+ use_dict = bool(self._traits)
+ default_to = (self._trait or Any())
+ if not use_dict and isinstance(default_to, Any):
return value
-
+
validated = {}
for key in value:
- if use_dict and key in self._traits:
- validate_with = self._traits[key]
- else:
- validate_with = default_to
+ if use_dict and key in self._traits:
+ validate_with = self._traits[key]
+ else:
+ validate_with = default_to
try:
- v = value[key]
- if not isinstance(validate_with, Any):
- v = validate_with._validate(obj, v)
+ v = value[key]
+ if not isinstance(validate_with, Any):
+ v = validate_with._validate(obj, v)
except TraitError:
- self.element_error(obj, v, validate_with)
+ self.element_error(obj, v, validate_with)
else:
validated[key] = v
-
+
return self.klass(validated)
def class_init(self, cls, name):
@@ -2584,7 +2584,7 @@ class TCPAddress(TraitType):
def validate(self, obj, value):
if isinstance(value, tuple):
if len(value) == 2:
- if isinstance(value[0], six.string_types) and isinstance(value[1], int):
+ if isinstance(value[0], six.string_types) and isinstance(value[1], int):
port = value[1]
if port >= 0 and port <= 65535:
return value
@@ -2603,88 +2603,88 @@ class CRegExp(TraitType):
return re.compile(value)
except:
self.error(obj, value)
-
-
-class UseEnum(TraitType):
- """Use a Enum class as model for the data type description.
- Note that if no default-value is provided, the first enum-value is used
- as default-value.
-
- .. sourcecode:: python
-
- # -- SINCE: Python 3.4 (or install backport: pip install enum34)
- import enum
- from traitlets import HasTraits, UseEnum
-
- class Color(enum.Enum):
- red = 1 # -- IMPLICIT: default_value
- blue = 2
- green = 3
-
- class MyEntity(HasTraits):
- color = UseEnum(Color, default_value=Color.blue)
-
- entity = MyEntity(color=Color.red)
- entity.color = Color.green # USE: Enum-value (preferred)
- entity.color = "green" # USE: name (as string)
- entity.color = "Color.green" # USE: scoped-name (as string)
- entity.color = 3 # USE: number (as int)
- assert entity.color is Color.green
- """
- default_value = None
- info_text = "Trait type adapter to a Enum class"
-
- def __init__(self, enum_class, default_value=None, **kwargs):
- assert issubclass(enum_class, enum.Enum), \
- "REQUIRE: enum.Enum, but was: %r" % enum_class
- allow_none = kwargs.get("allow_none", False)
- if default_value is None and not allow_none:
- default_value = list(enum_class.__members__.values())[0]
- super(UseEnum, self).__init__(default_value=default_value, **kwargs)
- self.enum_class = enum_class
- self.name_prefix = enum_class.__name__ + "."
-
- def select_by_number(self, value, default=Undefined):
- """Selects enum-value by using its number-constant."""
- assert isinstance(value, int)
- enum_members = self.enum_class.__members__
- for enum_item in enum_members.values():
- if enum_item.value == value:
- return enum_item
- # -- NOT FOUND:
- return default
-
- def select_by_name(self, value, default=Undefined):
- """Selects enum-value by using its name or scoped-name."""
- assert isinstance(value, six.string_types)
- if value.startswith(self.name_prefix):
- # -- SUPPORT SCOPED-NAMES, like: "Color.red" => "red"
- value = value.replace(self.name_prefix, "", 1)
- return self.enum_class.__members__.get(value, default)
-
- def validate(self, obj, value):
- if isinstance(value, self.enum_class):
- return value
- elif isinstance(value, int):
- # -- CONVERT: number => enum_value (item)
- value2 = self.select_by_number(value)
- if value2 is not Undefined:
- return value2
- elif isinstance(value, six.string_types):
- # -- CONVERT: name or scoped_name (as string) => enum_value (item)
- value2 = self.select_by_name(value)
- if value2 is not Undefined:
- return value2
- elif value is None:
- if self.allow_none:
- return None
- else:
- return self.default_value
- self.error(obj, value)
-
- def info(self):
- """Returns a description of this Enum trait (in case of errors)."""
- result = "Any of: %s" % ", ".join(self.enum_class.__members__.keys())
- if self.allow_none:
- return result + " or None"
- return result
+
+
+class UseEnum(TraitType):
+ """Use a Enum class as model for the data type description.
+ Note that if no default-value is provided, the first enum-value is used
+ as default-value.
+
+ .. sourcecode:: python
+
+ # -- SINCE: Python 3.4 (or install backport: pip install enum34)
+ import enum
+ from traitlets import HasTraits, UseEnum
+
+ class Color(enum.Enum):
+ red = 1 # -- IMPLICIT: default_value
+ blue = 2
+ green = 3
+
+ class MyEntity(HasTraits):
+ color = UseEnum(Color, default_value=Color.blue)
+
+ entity = MyEntity(color=Color.red)
+ entity.color = Color.green # USE: Enum-value (preferred)
+ entity.color = "green" # USE: name (as string)
+ entity.color = "Color.green" # USE: scoped-name (as string)
+ entity.color = 3 # USE: number (as int)
+ assert entity.color is Color.green
+ """
+ default_value = None
+ info_text = "Trait type adapter to a Enum class"
+
+ def __init__(self, enum_class, default_value=None, **kwargs):
+ assert issubclass(enum_class, enum.Enum), \
+ "REQUIRE: enum.Enum, but was: %r" % enum_class
+ allow_none = kwargs.get("allow_none", False)
+ if default_value is None and not allow_none:
+ default_value = list(enum_class.__members__.values())[0]
+ super(UseEnum, self).__init__(default_value=default_value, **kwargs)
+ self.enum_class = enum_class
+ self.name_prefix = enum_class.__name__ + "."
+
+ def select_by_number(self, value, default=Undefined):
+ """Selects enum-value by using its number-constant."""
+ assert isinstance(value, int)
+ enum_members = self.enum_class.__members__
+ for enum_item in enum_members.values():
+ if enum_item.value == value:
+ return enum_item
+ # -- NOT FOUND:
+ return default
+
+ def select_by_name(self, value, default=Undefined):
+ """Selects enum-value by using its name or scoped-name."""
+ assert isinstance(value, six.string_types)
+ if value.startswith(self.name_prefix):
+ # -- SUPPORT SCOPED-NAMES, like: "Color.red" => "red"
+ value = value.replace(self.name_prefix, "", 1)
+ return self.enum_class.__members__.get(value, default)
+
+ def validate(self, obj, value):
+ if isinstance(value, self.enum_class):
+ return value
+ elif isinstance(value, int):
+ # -- CONVERT: number => enum_value (item)
+ value2 = self.select_by_number(value)
+ if value2 is not Undefined:
+ return value2
+ elif isinstance(value, six.string_types):
+ # -- CONVERT: name or scoped_name (as string) => enum_value (item)
+ value2 = self.select_by_name(value)
+ if value2 is not Undefined:
+ return value2
+ elif value is None:
+ if self.allow_none:
+ return None
+ else:
+ return self.default_value
+ self.error(obj, value)
+
+ def info(self):
+ """Returns a description of this Enum trait (in case of errors)."""
+ result = "Any of: %s" % ", ".join(self.enum_class.__members__.keys())
+ if self.allow_none:
+ return result + " or None"
+ return result
diff --git a/contrib/python/traitlets/py2/traitlets/utils/bunch.py b/contrib/python/traitlets/py2/traitlets/utils/bunch.py
index dc40b5df7d..2edb830ad6 100644
--- a/contrib/python/traitlets/py2/traitlets/utils/bunch.py
+++ b/contrib/python/traitlets/py2/traitlets/utils/bunch.py
@@ -1,25 +1,25 @@
-"""Yet another implementation of bunch
-
-attribute-access of items on a dict.
-"""
-
-# Copyright (c) Jupyter Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-class Bunch(dict):
- """A dict with attribute-access"""
- def __getattr__(self, key):
- try:
- return self.__getitem__(key)
- except KeyError:
- raise AttributeError(key)
-
- def __setattr__(self, key, value):
- self.__setitem__(key, value)
-
- def __dir__(self):
- # py2-compat: can't use super because dict doesn't have __dir__
- names = dir({})
- names.extend(self.keys())
- return names
-
+"""Yet another implementation of bunch
+
+attribute-access of items on a dict.
+"""
+
+# Copyright (c) Jupyter Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+class Bunch(dict):
+ """A dict with attribute-access"""
+ def __getattr__(self, key):
+ try:
+ return self.__getitem__(key)
+ except KeyError:
+ raise AttributeError(key)
+
+ def __setattr__(self, key, value):
+ self.__setitem__(key, value)
+
+ def __dir__(self):
+ # py2-compat: can't use super because dict doesn't have __dir__
+ names = dir({})
+ names.extend(self.keys())
+ return names
+
diff --git a/contrib/python/traitlets/py2/traitlets/utils/getargspec.py b/contrib/python/traitlets/py2/traitlets/utils/getargspec.py
index f23750cbc1..0a047379fe 100644
--- a/contrib/python/traitlets/py2/traitlets/utils/getargspec.py
+++ b/contrib/python/traitlets/py2/traitlets/utils/getargspec.py
@@ -10,7 +10,7 @@
"""
import inspect
-from six import PY3
+from six import PY3
# Unmodified from sphinx below this line
diff --git a/contrib/python/traitlets/py2/traitlets/utils/importstring.py b/contrib/python/traitlets/py2/traitlets/utils/importstring.py
index 0228367446..5b4f643f41 100644
--- a/contrib/python/traitlets/py2/traitlets/utils/importstring.py
+++ b/contrib/python/traitlets/py2/traitlets/utils/importstring.py
@@ -5,8 +5,8 @@ A simple utility to import something by its string name.
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
-from ipython_genutils.py3compat import cast_bytes_py2
-from six import string_types
+from ipython_genutils.py3compat import cast_bytes_py2
+from six import string_types
def import_item(name):
"""Import and return ``bar`` given the string ``foo.bar``.
diff --git a/contrib/python/traitlets/py2/ya.make b/contrib/python/traitlets/py2/ya.make
index 1efff6da42..4a60107101 100644
--- a/contrib/python/traitlets/py2/ya.make
+++ b/contrib/python/traitlets/py2/ya.make
@@ -14,7 +14,7 @@ PEERDIR(
contrib/python/decorator
contrib/python/enum34
contrib/python/ipython-genutils
- contrib/python/six
+ contrib/python/six
)
NO_LINT()
@@ -31,7 +31,7 @@ PY_SRCS(
traitlets/log.py
traitlets/traitlets.py
traitlets/utils/__init__.py
- traitlets/utils/bunch.py
+ traitlets/utils/bunch.py
traitlets/utils/getargspec.py
traitlets/utils/importstring.py
traitlets/utils/sentinel.py
diff --git a/contrib/python/traitlets/py3/traitlets/config/application.py b/contrib/python/traitlets/py3/traitlets/config/application.py
index b81fd45b85..99a6ef7ee0 100644
--- a/contrib/python/traitlets/py3/traitlets/config/application.py
+++ b/contrib/python/traitlets/py3/traitlets/config/application.py
@@ -5,7 +5,7 @@
from collections import defaultdict, OrderedDict
-from copy import deepcopy
+from copy import deepcopy
import functools
import json
import logging
@@ -20,7 +20,7 @@ from traitlets.config.loader import (
KVArgParseConfigLoader, PyFileConfigLoader, Config, ArgumentError, ConfigFileNotFound, JSONFileConfigLoader
)
from traitlets.traitlets import (
- Bool, Unicode, List, Enum, Dict, Instance, TraitError, observe, observe_compat, default,
+ Bool, Unicode, List, Enum, Dict, Instance, TraitError, observe, observe_compat, default,
)
from ..utils.importstring import import_item
@@ -28,7 +28,7 @@ from ..utils import cast_unicode
from traitlets.utils.text import indent, wrap_paragraphs
from textwrap import dedent
-
+
#-----------------------------------------------------------------------------
# Descriptions for the various sections
#-----------------------------------------------------------------------------
@@ -63,23 +63,23 @@ subcommand 'cmd', do: `{app} cmd -h`.
# Application class
#-----------------------------------------------------------------------------
-
-
-_envvar = os.environ.get('TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR','')
-if _envvar.lower() in {'1','true'}:
- TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR = True
-elif _envvar.lower() in {'0','false',''} :
- TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR = False
-else:
- raise ValueError("Unsupported value for environment variable: 'TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR' is set to '%s' which is none of {'0', '1', 'false', 'true', ''}."% _envvar )
-
-
+
+
+_envvar = os.environ.get('TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR','')
+if _envvar.lower() in {'1','true'}:
+ TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR = True
+elif _envvar.lower() in {'0','false',''} :
+ TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR = False
+else:
+ raise ValueError("Unsupported value for environment variable: 'TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR' is set to '%s' which is none of {'0', '1', 'false', 'true', ''}."% _envvar )
+
+
def catch_config_error(method):
"""Method decorator for catching invalid config (Trait/ArgumentErrors) during init.
On a TraitError (generally caused by bad config), this will print the trait's
message, and exit the app.
-
+
For use on init methods, to prevent invoking excepthook on invalid input.
"""
@functools.wraps(method)
@@ -99,16 +99,16 @@ class ApplicationError(Exception):
class LevelFormatter(logging.Formatter):
"""Formatter with additional `highlevel` record
-
+
This field is empty if log level is less than highlevel_limit,
otherwise it is formatted with self.highlevel_format.
-
+
Useful for adding 'WARNING' to warning messages,
without adding 'INFO' to info, etc.
"""
highlevel_limit = logging.WARN
highlevel_format = " %(levelname)s |"
-
+
def format(self, record):
if record.levelno >= self.highlevel_limit:
record.highlevel = self.highlevel_format % record.__dict__
@@ -116,7 +116,7 @@ class LevelFormatter(logging.Formatter):
record.highlevel = ""
return super(LevelFormatter, self).format(record)
-
+
class Application(SingletonConfigurable):
"""A singleton application with full configuration support."""
@@ -131,7 +131,7 @@ class Application(SingletonConfigurable):
option_description = Unicode(option_description)
keyvalue_description = Unicode(keyvalue_description)
subcommand_description = Unicode(subcommand_description)
-
+
python_config_loader_class = PyFileConfigLoader
json_config_loader_class = JSONFileConfigLoader
@@ -164,13 +164,13 @@ class Application(SingletonConfigurable):
# The version string of this application.
version = Unicode('0.0')
-
+
# the argv used to initialize the application
argv = List()
- # Whether failing to load config files should prevent startup
- raise_config_file_errors = Bool(TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR)
-
+ # Whether failing to load config files should prevent startup
+ raise_config_file_errors = Bool(TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR)
+
# The log level for the application
log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'),
default_value=logging.WARN,
@@ -180,15 +180,15 @@ class Application(SingletonConfigurable):
@observe_compat
def _log_level_changed(self, change):
"""Adjust the log level when log_level is set."""
- new = change.new
+ new = change.new
if isinstance(new, str):
new = getattr(logging, new)
self.log_level = new
self.log.setLevel(new)
-
+
_log_formatter_cls = LevelFormatter
-
- log_datefmt = Unicode("%Y-%m-%d %H:%M:%S",
+
+ log_datefmt = Unicode("%Y-%m-%d %H:%M:%S",
help="The date format used by logging formatters for %(asctime)s"
).tag(config=True)
@@ -209,7 +209,7 @@ class Application(SingletonConfigurable):
return
_log_formatter = self._log_formatter_cls(fmt=self.log_format, datefmt=self.log_datefmt)
_log_handler.setFormatter(_log_formatter)
-
+
@default('log')
def _log_default(self):
"""Start logging for this application.
@@ -229,7 +229,7 @@ class Application(SingletonConfigurable):
break
else:
_log = _log.parent
- if sys.executable and sys.executable.endswith('pythonw.exe'):
+ if sys.executable and sys.executable.endswith('pythonw.exe'):
# this should really go to a file, but file-logging is only
# hooked up in parallel applications
_log_handler = logging.StreamHandler(open(os.devnull, 'w'))
@@ -279,16 +279,16 @@ class Application(SingletonConfigurable):
# extra command-line arguments that don't set config values
extra_args = List(Unicode())
- cli_config = Instance(Config, (), {},
- help="""The subset of our configuration that came from the command-line
+ cli_config = Instance(Config, (), {},
+ help="""The subset of our configuration that came from the command-line
+
+ We re-load this configuration after loading config files,
+ to ensure that it maintains highest priority.
+ """
+ )
- We re-load this configuration after loading config files,
- to ensure that it maintains highest priority.
- """
- )
-
_loaded_config_files = List()
-
+
show_config = Bool(
help="Instead of starting the Application, dump configuration to stdout"
).tag(config=True)
@@ -311,14 +311,14 @@ class Application(SingletonConfigurable):
SingletonConfigurable.__init__(self, **kwargs)
# Ensure my class is in self.classes, so my attributes appear in command line
# options and config files.
- cls = self.__class__
- if cls not in self.classes:
- if self.classes is cls.classes:
- # class attr, assign instead of insert
+ cls = self.__class__
+ if cls not in self.classes:
+ if self.classes is cls.classes:
+ # class attr, assign instead of insert
self.classes = [cls] + self.classes
- else:
- self.classes.insert(0, self.__class__)
-
+ else:
+ self.classes.insert(0, self.__class__)
+
@observe('config')
@observe_compat
def _config_changed(self, change):
@@ -394,7 +394,7 @@ class Application(SingletonConfigurable):
for c in cls.mro()[:-3]:
classdict[c.__name__] = c
- for alias, longname in self.aliases.items():
+ for alias, longname in self.aliases.items():
try:
if isinstance(longname, tuple):
longname, fhelp = longname
@@ -489,7 +489,7 @@ class Application(SingletonConfigurable):
app=self.name)):
yield p
yield ''
- for subc, (cls, help) in self.subcommands.items():
+ for subc, (cls, help) in self.subcommands.items():
yield subc
if help:
yield indent(dedent(help.strip()))
@@ -602,10 +602,10 @@ class Application(SingletonConfigurable):
# ... and finally initialize subapp.
self.subapp.initialize(argv)
-
+
def flatten_flags(self):
"""Flatten flags and aliases for loaders, so cl-args override as expected.
-
+
This prevents issues such as an alias pointing to InteractiveShell,
but a config file setting the same trait in TerminalInteraciveShell
getting inappropriate priority over the command-line arg.
@@ -613,7 +613,7 @@ class Application(SingletonConfigurable):
Only aliases with exactly one descendent in the class list
will be promoted.
-
+
"""
# build a tree of classes in our list that inherit from a particular
# it will be a dict by parent classname of classes in our list
@@ -639,13 +639,13 @@ class Application(SingletonConfigurable):
alias = (alias, )
for al in alias:
aliases[al] = '.'.join([cls,trait])
-
+
# flatten flags, which are of the form:
# { 'key' : ({'Cls' : {'trait' : value}}, 'help')}
flags = {}
- for key, (flagdict, help) in self.flags.items():
+ for key, (flagdict, help) in self.flags.items():
newflag = {}
- for cls, subdict in flagdict.items():
+ for cls, subdict in flagdict.items():
children = mro_tree[cls]
# exactly one descendent, promote flag section
if len(children) == 1:
@@ -672,7 +672,7 @@ class Application(SingletonConfigurable):
assert not isinstance(argv, str)
argv = sys.argv[1:] if argv is None else argv
self.argv = [cast_unicode(arg) for arg in argv ]
-
+
if argv and argv[0] == 'help':
# turn `ipython help notebook` into `ipython notebook -h`
argv = argv[1:] + ['-h']
@@ -700,7 +700,7 @@ class Application(SingletonConfigurable):
if '--version' in interpreted_argv or '-V' in interpreted_argv:
self.print_version()
self.exit(0)
-
+
# flatten flags&aliases, so cl-args get appropriate priority:
flags, aliases = self.flatten_flags()
classes = tuple(self._classes_with_config_traits())
@@ -711,27 +711,27 @@ class Application(SingletonConfigurable):
# traitlets 5: no longer print help output on error
# help output is huge, and comes after the error
raise
- self.update_config(self.cli_config)
+ self.update_config(self.cli_config)
# store unparsed args in extra_args
self.extra_args = loader.extra_args
@classmethod
- def _load_config_files(cls, basefilename, path=None, log=None, raise_config_file_errors=False):
+ def _load_config_files(cls, basefilename, path=None, log=None, raise_config_file_errors=False):
"""Load config files (py,json) by filename and path.
yield each config object in turn.
"""
-
+
if not isinstance(path, list):
path = [path]
for path in path[::-1]:
# path list is in descending priority order, so load files backwards:
pyloader = cls.python_config_loader_class(basefilename+'.py', path=path, log=log)
if log:
- log.debug("Looking for %s in %s", basefilename, path or os.getcwd())
+ log.debug("Looking for %s in %s", basefilename, path or os.getcwd())
jsonloader = cls.json_config_loader_class(basefilename+'.json', path=path, log=log)
- loaded = []
- filenames = []
+ loaded = []
+ filenames = []
for loader in [pyloader, jsonloader]:
config = None
try:
@@ -743,8 +743,8 @@ class Application(SingletonConfigurable):
# unlikely event that the error raised before filefind finished
filename = loader.full_filename or basefilename
# problem while running the file
- if raise_config_file_errors:
- raise
+ if raise_config_file_errors:
+ raise
if log:
log.error("Exception while loading config file %s",
filename, exc_info=True)
@@ -752,16 +752,16 @@ class Application(SingletonConfigurable):
if log:
log.debug("Loaded config file: %s", loader.full_filename)
if config:
- for filename, earlier_config in zip(filenames, loaded):
- collisions = earlier_config.collisions(config)
- if collisions and log:
- log.warning("Collisions detected in {0} and {1} config files."
- " {1} has higher priority: {2}".format(
- filename, loader.full_filename, json.dumps(collisions, indent=2),
- ))
+ for filename, earlier_config in zip(filenames, loaded):
+ collisions = earlier_config.collisions(config)
+ if collisions and log:
+ log.warning("Collisions detected in {0} and {1} config files."
+ " {1} has higher priority: {2}".format(
+ filename, loader.full_filename, json.dumps(collisions, indent=2),
+ ))
yield (config, loader.full_filename)
- loaded.append(config)
- filenames.append(loader.full_filename)
+ loaded.append(config)
+ filenames.append(loader.full_filename)
@property
def loaded_config_files(self):
@@ -772,55 +772,55 @@ class Application(SingletonConfigurable):
def load_config_file(self, filename, path=None):
"""Load config files by filename and path."""
filename, ext = os.path.splitext(filename)
- new_config = Config()
+ new_config = Config()
for (config, filename) in self._load_config_files(filename, path=path, log=self.log,
- raise_config_file_errors=self.raise_config_file_errors,
- ):
- new_config.merge(config)
+ raise_config_file_errors=self.raise_config_file_errors,
+ ):
+ new_config.merge(config)
if filename not in self._loaded_config_files: # only add to list of loaded files if not previously loaded
self._loaded_config_files.append(filename)
- # add self.cli_config to preserve CLI config priority
- new_config.merge(self.cli_config)
- self.update_config(new_config)
+ # add self.cli_config to preserve CLI config priority
+ new_config.merge(self.cli_config)
+ self.update_config(new_config)
def _classes_with_config_traits(self, classes=None):
- """
+ """
Yields only classes with configurable traits, and their subclasses.
-
+
:param classes:
The list of classes to iterate; if not set, uses :attr:`classes`.
- Thus, produced sample config-file will contain all classes
- on which a trait-value may be overridden:
-
- - either on the class owning the trait,
- - or on its subclasses, even if those subclasses do not define
- any traits themselves.
- """
+ Thus, produced sample config-file will contain all classes
+ on which a trait-value may be overridden:
+
+ - either on the class owning the trait,
+ - or on its subclasses, even if those subclasses do not define
+ any traits themselves.
+ """
if classes is None:
classes = self.classes
- cls_to_config = OrderedDict( (cls, bool(cls.class_own_traits(config=True)))
- for cls
+ cls_to_config = OrderedDict( (cls, bool(cls.class_own_traits(config=True)))
+ for cls
in self._classes_inc_parents(classes))
-
- def is_any_parent_included(cls):
- return any(b in cls_to_config and cls_to_config[b] for b in cls.__bases__)
-
- ## Mark "empty" classes for inclusion if their parents own-traits,
- # and loop until no more classes gets marked.
- #
- while True:
- to_incl_orig = cls_to_config.copy()
- cls_to_config = OrderedDict( (cls, inc_yes or is_any_parent_included(cls))
- for cls, inc_yes
- in cls_to_config.items())
- if cls_to_config == to_incl_orig:
- break
- for cl, inc_yes in cls_to_config.items():
- if inc_yes:
- yield cl
-
+
+ def is_any_parent_included(cls):
+ return any(b in cls_to_config and cls_to_config[b] for b in cls.__bases__)
+
+ ## Mark "empty" classes for inclusion if their parents own-traits,
+ # and loop until no more classes gets marked.
+ #
+ while True:
+ to_incl_orig = cls_to_config.copy()
+ cls_to_config = OrderedDict( (cls, inc_yes or is_any_parent_included(cls))
+ for cls, inc_yes
+ in cls_to_config.items())
+ if cls_to_config == to_incl_orig:
+ break
+ for cl, inc_yes in cls_to_config.items():
+ if inc_yes:
+ yield cl
+
def generate_config_file(self, classes=None):
"""generate default config file from Configurables"""
lines = ["# Configuration file for %s." % self.name]
@@ -838,7 +838,7 @@ class Application(SingletonConfigurable):
@classmethod
def launch_instance(cls, argv=None, **kwargs):
"""Launch a global instance of this Application
-
+
If a global instance already exists, this reinitializes and starts it
"""
app = cls.instance(**kwargs)
@@ -885,7 +885,7 @@ def boolean_flag(name, configurable, set_help='', unset_help=''):
def get_config():
"""Get the config object for the global Application instance, if there is one
-
+
otherwise return an empty config object
"""
if Application.initialized():
diff --git a/contrib/python/traitlets/py3/traitlets/config/configurable.py b/contrib/python/traitlets/py3/traitlets/config/configurable.py
index 0f80aa3a0b..3b2044a01b 100644
--- a/contrib/python/traitlets/py3/traitlets/config/configurable.py
+++ b/contrib/python/traitlets/py3/traitlets/config/configurable.py
@@ -6,7 +6,7 @@
from copy import deepcopy
import logging
-import warnings
+import warnings
from .loader import Config, LazyConfigValue, DeferredConfig, _is_section_key
from traitlets.traitlets import (
@@ -78,12 +78,12 @@ class Configurable(HasTraits):
if kwargs.get('config', None) is None:
kwargs['config'] = parent.config
self.parent = parent
-
+
config = kwargs.pop('config', None)
-
+
# load kwarg traits, other than config
super(Configurable, self).__init__(**kwargs)
-
+
# record traits set by config
config_override_names = set()
def notice_config_override(change):
@@ -109,7 +109,7 @@ class Configurable(HasTraits):
# allow _config_default to return something
self._load_config(self.config)
self.unobserve(notice_config_override)
-
+
for name in config_override_names:
setattr(self, name, kwargs[name])
@@ -117,25 +117,25 @@ class Configurable(HasTraits):
#-------------------------------------------------------------------------
# Static trait notifiations
#-------------------------------------------------------------------------
-
+
@classmethod
def section_names(cls):
"""return section names as a list"""
return [c.__name__ for c in reversed(cls.__mro__) if
issubclass(c, Configurable) and issubclass(cls, c)
]
-
+
def _find_my_config(self, cfg):
"""extract my config from a global Config object
-
+
will construct a Config object of only the config values that apply to me
based on my mro(), as well as those of my parent(s) if they exist.
-
+
If I am Bar and my parent is Foo, and their parent is Tim,
this will return merge following config sections, in this order::
-
+
[Bar, Foo.Bar, Tim.Foo.Bar]
-
+
With the last item being the highest priority.
"""
cfgs = [cfg]
@@ -149,20 +149,20 @@ class Configurable(HasTraits):
if c._has_section(sname):
my_config.merge(c[sname])
return my_config
-
+
def _load_config(self, cfg, section_names=None, traits=None):
"""load traits from a Config object"""
-
+
if traits is None:
traits = self.traits(config=True)
if section_names is None:
section_names = self.section_names()
-
+
my_config = self._find_my_config(cfg)
-
+
# hold trait notifications until after all config has been loaded
with self.hold_trait_notifications():
- for name, config_value in my_config.items():
+ for name, config_value in my_config.items():
if name in traits:
if isinstance(config_value, LazyConfigValue):
# ConfigValue is a wrapper for using append / update on containers
@@ -176,21 +176,21 @@ class Configurable(HasTraits):
# config object. If we don't, a mutable config_value will be
# shared by all instances, effectively making it a class attribute.
setattr(self, name, deepcopy(config_value))
- elif not _is_section_key(name) and not isinstance(config_value, Config):
+ elif not _is_section_key(name) and not isinstance(config_value, Config):
from difflib import get_close_matches
- if isinstance(self, LoggingConfigurable):
- warn = self.log.warning
- else:
- warn = lambda msg: warnings.warn(msg, stacklevel=9)
+ if isinstance(self, LoggingConfigurable):
+ warn = self.log.warning
+ else:
+ warn = lambda msg: warnings.warn(msg, stacklevel=9)
matches = get_close_matches(name, traits)
msg = "Config option `{option}` not recognized by `{klass}`.".format(
- option=name, klass=self.__class__.__name__)
-
+ option=name, klass=self.__class__.__name__)
+
if len(matches) == 1:
msg += " Did you mean `{matches}`?".format(matches=matches[0])
elif len(matches) >= 1:
- msg +=" Did you mean one of: `{matches}`?".format(matches=', '.join(sorted(matches)))
- warn(msg)
+ msg +=" Did you mean one of: `{matches}`?".format(matches=', '.join(sorted(matches)))
+ warn(msg)
@observe('config')
@observe_compat
@@ -208,23 +208,23 @@ class Configurable(HasTraits):
# classes that are Configurable subclasses. This starts with Configurable
# and works down the mro loading the config for each section.
section_names = self.section_names()
- self._load_config(change.new, traits=traits, section_names=section_names)
+ self._load_config(change.new, traits=traits, section_names=section_names)
def update_config(self, config):
- """Update config and load the new values"""
- # traitlets prior to 4.2 created a copy of self.config in order to trigger change events.
- # Some projects (IPython < 5) relied upon one side effect of this,
- # that self.config prior to update_config was not modified in-place.
- # For backward-compatibility, we must ensure that self.config
- # is a new object and not modified in-place,
- # but config consumers should not rely on this behavior.
- self.config = deepcopy(self.config)
- # load config
- self._load_config(config)
- # merge it into self.config
+ """Update config and load the new values"""
+ # traitlets prior to 4.2 created a copy of self.config in order to trigger change events.
+ # Some projects (IPython < 5) relied upon one side effect of this,
+ # that self.config prior to update_config was not modified in-place.
+ # For backward-compatibility, we must ensure that self.config
+ # is a new object and not modified in-place,
+ # but config consumers should not rely on this behavior.
+ self.config = deepcopy(self.config)
+ # load config
+ self._load_config(config)
+ # merge it into self.config
self.config.merge(config)
- # TODO: trigger change event if/when dict-update change events take place
- # DO NOT trigger full trait-change
+ # TODO: trigger change event if/when dict-update change events take place
+ # DO NOT trigger full trait-change
@classmethod
def class_get_help(cls, inst=None):
@@ -246,7 +246,7 @@ class Configurable(HasTraits):
@classmethod
def class_get_trait_help(cls, trait, inst=None, helptext=None):
"""Get the helptext string for a single trait.
-
+
:param inst:
If given, it's current trait values will be used in place of
the class default.
@@ -340,7 +340,7 @@ class Configurable(HasTraits):
"""return a commented, wrapped block."""
s = '\n\n'.join(wrap_paragraphs(s, 78))
- return '## ' + s.replace('\n', '\n# ')
+ return '## ' + s.replace('\n', '\n# ')
# section header
breaker = '#' + '-' * 78
@@ -349,14 +349,14 @@ class Configurable(HasTraits):
if issubclass(p, Configurable)
)
- s = "# %s(%s) configuration" % (cls.__name__, parent_classes)
+ s = "# %s(%s) configuration" % (cls.__name__, parent_classes)
lines = [breaker, s, breaker]
# get the description trait
desc = cls.class_traits().get('description')
if desc:
desc = desc.default_value
- if not desc:
- # no description from trait, use __doc__
+ if not desc:
+ # no description from trait, use __doc__
desc = getattr(cls, '__doc__', '')
if desc:
lines.append(c(desc))
diff --git a/contrib/python/traitlets/py3/traitlets/config/loader.py b/contrib/python/traitlets/py3/traitlets/config/loader.py
index bbab151db8..5360f889ab 100644
--- a/contrib/python/traitlets/py3/traitlets/config/loader.py
+++ b/contrib/python/traitlets/py3/traitlets/config/loader.py
@@ -255,7 +255,7 @@ class Config(dict):
def merge(self, other):
"""merge another config object into this one"""
to_update = {}
- for k, v in other.items():
+ for k, v in other.items():
if k not in self:
to_update[k] = v
else: # I have this key
@@ -542,17 +542,17 @@ class FileConfigLoader(ConfigLoader):
self.full_filename = filefind(self.filename, self.path)
class JSONFileConfigLoader(FileConfigLoader):
- """A JSON file loader for config
-
- Can also act as a context manager that rewrite the configuration file to disk on exit.
-
- Example::
-
- with JSONFileConfigLoader('myapp.json','/home/jupyter/configurations/') as c:
- c.MyNewConfigurable.new_value = 'Updated'
-
- """
-
+ """A JSON file loader for config
+
+ Can also act as a context manager that rewrite the configuration file to disk on exit.
+
+ Example::
+
+ with JSONFileConfigLoader('myapp.json','/home/jupyter/configurations/') as c:
+ c.MyNewConfigurable.new_value = 'Updated'
+
+ """
+
def load_config(self):
"""Load the config from a file and return it as a Config object."""
self.clear()
@@ -579,24 +579,24 @@ class JSONFileConfigLoader(FileConfigLoader):
else:
raise ValueError('Unknown version of JSON config file: {version}'.format(version=version))
- def __enter__(self):
- self.load_config()
- return self.config
-
- def __exit__(self, exc_type, exc_value, traceback):
- """
- Exit the context manager but do not handle any errors.
-
- In case of any error, we do not want to write the potentially broken
- configuration to disk.
- """
- self.config.version = 1
- json_config = json.dumps(self.config, indent=2)
- with open(self.full_filename, 'w') as f:
- f.write(json_config)
-
-
-
+ def __enter__(self):
+ self.load_config()
+ return self.config
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ """
+ Exit the context manager but do not handle any errors.
+
+ In case of any error, we do not want to write the potentially broken
+ configuration to disk.
+ """
+ self.config.version = 1
+ json_config = json.dumps(self.config, indent=2)
+ with open(self.full_filename, 'w') as f:
+ f.write(json_config)
+
+
+
class PyFileConfigLoader(FileConfigLoader):
"""A config loader for pure python files.
@@ -910,7 +910,7 @@ class ArgParseConfigLoader(CommandLineConfigLoader):
def _convert_to_config(self):
"""self.parsed_data->self.config"""
- for k, v in vars(self.parsed_data).items():
+ for k, v in vars(self.parsed_data).items():
*path, key = k.split(".")
section = self.config
for p in path:
diff --git a/contrib/python/traitlets/py3/traitlets/log.py b/contrib/python/traitlets/py3/traitlets/log.py
index c7166c14c8..af86b325f5 100644
--- a/contrib/python/traitlets/py3/traitlets/log.py
+++ b/contrib/python/traitlets/py3/traitlets/log.py
@@ -9,19 +9,19 @@ _logger = None
def get_logger():
"""Grab the global logger instance.
-
+
If a global Application is instantiated, grab its logger.
Otherwise, grab the root logger.
"""
global _logger
-
+
if _logger is None:
from .config import Application
if Application.initialized():
_logger = Application.instance().log
else:
- _logger = logging.getLogger('traitlets')
- # Add a NullHandler to silence warnings about not being
- # initialized, per best practice for libraries.
- _logger.addHandler(logging.NullHandler())
+ _logger = logging.getLogger('traitlets')
+ # Add a NullHandler to silence warnings about not being
+ # initialized, per best practice for libraries.
+ _logger.addHandler(logging.NullHandler())
return _logger
diff --git a/contrib/python/traitlets/py3/traitlets/traitlets.py b/contrib/python/traitlets/py3/traitlets/traitlets.py
index 7643cbd132..6bdf7414d3 100644
--- a/contrib/python/traitlets/py3/traitlets/traitlets.py
+++ b/contrib/python/traitlets/py3/traitlets/traitlets.py
@@ -42,17 +42,17 @@ Inheritance diagram:
from ast import literal_eval
import contextlib
import inspect
-import os
+import os
import re
import sys
import types
-import enum
+import enum
from warnings import warn, warn_explicit
from .utils.getargspec import getargspec
from .utils.importstring import import_item
from .utils.sentinel import Sentinel
-from .utils.bunch import Bunch
+from .utils.bunch import Bunch
from .utils.descriptions import describe, class_of, add_article, repr_type
SequenceTypes = (list, tuple, set, frozenset)
@@ -113,34 +113,34 @@ class TraitError(Exception):
# Utilities
#-----------------------------------------------------------------------------
-_name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
-
-def isidentifier(s):
+_name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
+
+def isidentifier(s):
return s.isidentifier()
-
-_deprecations_shown = set()
-def _should_warn(key):
- """Add our own checks for too many deprecation warnings.
-
- Limit to once per package.
- """
- env_flag = os.environ.get('TRAITLETS_ALL_DEPRECATIONS')
- if env_flag and env_flag != '0':
- return True
-
- if key not in _deprecations_shown:
- _deprecations_shown.add(key)
- return True
- else:
- return False
-
+
+_deprecations_shown = set()
+def _should_warn(key):
+ """Add our own checks for too many deprecation warnings.
+
+ Limit to once per package.
+ """
+ env_flag = os.environ.get('TRAITLETS_ALL_DEPRECATIONS')
+ if env_flag and env_flag != '0':
+ return True
+
+ if key not in _deprecations_shown:
+ _deprecations_shown.add(key)
+ return True
+ else:
+ return False
+
def _deprecated_method(method, cls, method_name, msg):
"""Show deprecation warning about a magic method definition.
Uses warn_explicit to bind warning to method definition instead of triggering code,
which isn't relevant.
"""
- warn_msg = "{classname}.{method_name} is deprecated in traitlets 4.1: {msg}".format(
+ warn_msg = "{classname}.{method_name} is deprecated in traitlets 4.1: {msg}".format(
classname=cls.__name__, method_name=method_name, msg=msg
)
@@ -148,11 +148,11 @@ def _deprecated_method(method, cls, method_name, msg):
if method_name in parent.__dict__:
cls = parent
break
- # limit deprecation messages to once per package
- package_name = cls.__module__.split('.', 1)[0]
- key = (package_name, msg)
- if not _should_warn(key):
- return
+ # limit deprecation messages to once per package
+ package_name = cls.__module__.split('.', 1)[0]
+ key = (package_name, msg)
+ if not _should_warn(key):
+ return
try:
fname = inspect.getsourcefile(method) or "<unknown>"
lineno = inspect.getsourcelines(method)[1] or 0
@@ -197,12 +197,12 @@ def parse_notifier_name(names):
"""
if names is All or isinstance(names, str):
return [names]
- else:
+ else:
if not names or All in names:
return [All]
for n in names:
if not isinstance(n, str):
- raise TypeError("names must be strings, not %r" % n)
+ raise TypeError("names must be strings, not %r" % n)
return names
@@ -358,7 +358,7 @@ class directional_link(object):
return
with self._busy_updating():
setattr(self.target[0], self.target[1],
- self._transform(change.new))
+ self._transform(change.new))
def unlink(self):
self.source[0].unobserve(self._update, names=self.source[1])
@@ -367,7 +367,7 @@ dlink = directional_link
#-----------------------------------------------------------------------------
-# Base Descriptor Class
+# Base Descriptor Class
#-----------------------------------------------------------------------------
@@ -447,32 +447,32 @@ class TraitType(BaseDescriptor):
"""
if default_value is not Undefined:
self.default_value = default_value
- if allow_none:
+ if allow_none:
self.allow_none = allow_none
if read_only is not None:
self.read_only = read_only
self.help = help if help is not None else ''
- if len(kwargs) > 0:
+ if len(kwargs) > 0:
stacklevel = 1
f = inspect.currentframe()
# count supers to determine stacklevel for warning
while f.f_code.co_name == '__init__':
stacklevel += 1
f = f.f_back
- mod = f.f_globals.get('__name__') or ''
- pkg = mod.split('.', 1)[0]
- key = tuple(['metadata-tag', pkg] + sorted(kwargs))
- if _should_warn(key):
- warn("metadata %s was set from the constructor. "
- "With traitlets 4.1, metadata should be set using the .tag() method, "
- "e.g., Int().tag(key1='value1', key2='value2')" % (kwargs,),
- DeprecationWarning, stacklevel=stacklevel)
+ mod = f.f_globals.get('__name__') or ''
+ pkg = mod.split('.', 1)[0]
+ key = tuple(['metadata-tag', pkg] + sorted(kwargs))
+ if _should_warn(key):
+ warn("metadata %s was set from the constructor. "
+ "With traitlets 4.1, metadata should be set using the .tag() method, "
+ "e.g., Int().tag(key1='value1', key2='value2')" % (kwargs,),
+ DeprecationWarning, stacklevel=stacklevel)
if len(self.metadata) > 0:
self.metadata = self.metadata.copy()
- self.metadata.update(kwargs)
+ self.metadata.update(kwargs)
else:
- self.metadata = kwargs
+ self.metadata = kwargs
else:
self.metadata = self.metadata.copy()
if config is not None:
@@ -519,20 +519,20 @@ class TraitType(BaseDescriptor):
"""DEPRECATED: Retrieve the static default value for this trait.
Use self.default_value instead
"""
- warn("get_default_value is deprecated in traitlets 4.0: use the .default_value attribute", DeprecationWarning,
+ warn("get_default_value is deprecated in traitlets 4.0: use the .default_value attribute", DeprecationWarning,
stacklevel=2)
return self.default_value
def init_default_value(self, obj):
"""DEPRECATED: Set the static default value for the trait type.
"""
- warn("init_default_value is deprecated in traitlets 4.0, and may be removed in the future", DeprecationWarning,
+ warn("init_default_value is deprecated in traitlets 4.0, and may be removed in the future", DeprecationWarning,
stacklevel=2)
value = self._validate(obj, self.default_value)
obj._trait_values[self.name] = value
return value
- def get(self, obj, cls=None):
+ def get(self, obj, cls=None):
try:
value = obj._trait_values[self.name]
except KeyError:
@@ -616,7 +616,7 @@ class TraitType(BaseDescriptor):
def _cross_validate(self, obj, value):
if self.name in obj._trait_validators:
- proposal = Bunch({'trait': self, 'value': value, 'owner': obj})
+ proposal = Bunch({'trait': self, 'value': value, 'owner': obj})
value = obj._trait_validators[self.name](obj, proposal)
elif hasattr(obj, '_%s_validate' % self.name):
meth_name = '_%s_validate' % self.name
@@ -700,7 +700,7 @@ class TraitType(BaseDescriptor):
msg = "use the instance .help string directly, like x.help"
else:
msg = "use the instance .metadata dictionary directly, like x.metadata[key] or x.metadata.get(key, default)"
- warn("Deprecated in traitlets 4.1, " + msg, DeprecationWarning, stacklevel=2)
+ warn("Deprecated in traitlets 4.1, " + msg, DeprecationWarning, stacklevel=2)
return self.metadata.get(key, default)
def set_metadata(self, key, value):
@@ -712,7 +712,7 @@ class TraitType(BaseDescriptor):
msg = "use the instance .help string directly, like x.help = value"
else:
msg = "use the instance .metadata dictionary directly, like x.metadata[key] = value"
- warn("Deprecated in traitlets 4.1, " + msg, DeprecationWarning, stacklevel=2)
+ warn("Deprecated in traitlets 4.1, " + msg, DeprecationWarning, stacklevel=2)
self.metadata[key] = value
def tag(self, **metadata):
@@ -722,11 +722,11 @@ class TraitType(BaseDescriptor):
>>> Int(0).tag(config=True, sync=True)
"""
- maybe_constructor_keywords = set(metadata.keys()).intersection({'help','allow_none', 'read_only', 'default_value'})
- if maybe_constructor_keywords:
- warn('The following attributes are set in using `tag`, but seem to be constructor keywords arguments: %s '%
- maybe_constructor_keywords, UserWarning, stacklevel=2)
-
+ maybe_constructor_keywords = set(metadata.keys()).intersection({'help','allow_none', 'read_only', 'default_value'})
+ if maybe_constructor_keywords:
+ warn('The following attributes are set in using `tag`, but seem to be constructor keywords arguments: %s '%
+ maybe_constructor_keywords, UserWarning, stacklevel=2)
+
self.metadata.update(metadata)
return self
@@ -764,13 +764,13 @@ class _CallbackWrapper(object):
if self.nargs == 0:
self.cb()
elif self.nargs == 1:
- self.cb(change.name)
+ self.cb(change.name)
elif self.nargs == 2:
- self.cb(change.name, change.new)
+ self.cb(change.name, change.new)
elif self.nargs == 3:
- self.cb(change.name, change.old, change.new)
+ self.cb(change.name, change.old, change.new)
elif self.nargs == 4:
- self.cb(change.name, change.old, change.new, change.owner)
+ self.cb(change.name, change.old, change.new, change.owner)
def _callback_wrapper(cb):
if isinstance(cb, _CallbackWrapper):
@@ -788,13 +788,13 @@ class MetaHasDescriptors(type):
def __new__(mcls, name, bases, classdict):
"""Create the HasDescriptors class."""
- for k, v in classdict.items():
+ for k, v in classdict.items():
# ----------------------------------------------------------------
# Support of deprecated behavior allowing for TraitType types
# to be used instead of TraitType instances.
if inspect.isclass(v) and issubclass(v, TraitType):
- warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)."
- " Passing types is deprecated in traitlets 4.1.",
+ warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)."
+ " Passing types is deprecated in traitlets 4.1.",
DeprecationWarning, stacklevel=2)
classdict[k] = v()
# ----------------------------------------------------------------
@@ -813,7 +813,7 @@ class MetaHasDescriptors(type):
BaseDescriptor in the class dict of the newly created ``cls`` before
calling their :attr:`class_init` method.
"""
- for k, v in classdict.items():
+ for k, v in classdict.items():
if isinstance(v, BaseDescriptor):
v.class_init(cls, k)
@@ -833,10 +833,10 @@ class MetaHasTraits(MetaHasDescriptors):
def observe(*names, type="change"):
"""A decorator which can be used to observe Traits on a class.
- The handler passed to the decorator will be called with one ``change``
- dict argument. The change dictionary at least holds a 'type' key and a
- 'name' key, corresponding respectively to the type of notification and the
- name of the attribute that triggered the notification.
+ The handler passed to the decorator will be called with one ``change``
+ dict argument. The change dictionary at least holds a 'type' key and a
+ 'name' key, corresponding respectively to the type of notification and the
+ name of the attribute that triggered the notification.
Other keys may be passed depending on the value of 'type'. In the case
where type is 'change', we also have the following keys:
@@ -850,26 +850,26 @@ def observe(*names, type="change"):
*names
The str names of the Traits to observe on the object.
type : str, kwarg-only
- The type of event to observe (e.g. 'change')
+ The type of event to observe (e.g. 'change')
"""
- if not names:
- raise TypeError("Please specify at least one trait name to observe.")
- for name in names:
+ if not names:
+ raise TypeError("Please specify at least one trait name to observe.")
+ for name in names:
if name is not All and not isinstance(name, str):
- raise TypeError("trait names to observe must be strings or All, not %r" % name)
+ raise TypeError("trait names to observe must be strings or All, not %r" % name)
return ObserveHandler(names, type=type)
def observe_compat(func):
"""Backward-compatibility shim decorator for observers
-
+
Use with:
-
+
@observe('name')
@observe_compat
def _foo_changed(self, change):
...
-
+
With this, `super()._foo_changed(self, name, old, new)` in subclasses will still work.
Allows adoption of new observer API without breaking subclasses that override and super.
"""
@@ -878,15 +878,15 @@ def observe_compat(func):
change = change_or_name
else:
clsname = self.__class__.__name__
- warn("A parent of %s._%s_changed has adopted the new (traitlets 4.1) @observe(change) API" % (
+ warn("A parent of %s._%s_changed has adopted the new (traitlets 4.1) @observe(change) API" % (
clsname, change_or_name), DeprecationWarning)
- change = Bunch(
- type='change',
- old=old,
- new=new,
- name=change_or_name,
- owner=self,
- )
+ change = Bunch(
+ type='change',
+ old=old,
+ new=new,
+ name=change_or_name,
+ owner=self,
+ )
return func(self, change)
return compatible_observer
@@ -909,18 +909,18 @@ def validate(*names):
Notes
-----
- Since the owner has access to the ``HasTraits`` instance via the 'owner' key,
+ Since the owner has access to the ``HasTraits`` instance via the 'owner' key,
the registered cross validator could potentially make changes to attributes
of the ``HasTraits`` instance. However, we recommend not to do so. The reason
is that the cross-validation of attributes may run in arbitrary order when
- exiting the ``hold_trait_notifications`` context, and such changes may not
+ exiting the ``hold_trait_notifications`` context, and such changes may not
commute.
"""
- if not names:
- raise TypeError("Please specify at least one trait name to validate.")
- for name in names:
+ if not names:
+ raise TypeError("Please specify at least one trait name to validate.")
+ for name in names:
if name is not All and not isinstance(name, str):
- raise TypeError("trait names to validate must be strings or All, not %r" % name)
+ raise TypeError("trait names to validate must be strings or All, not %r" % name)
return ValidateHandler(names)
@@ -961,7 +961,7 @@ def default(name):
# class derived from B.a.this_class.
"""
if not isinstance(name, str):
- raise TypeError("Trait name must be a string or All, not %r" % name)
+ raise TypeError("Trait name must be a string or All, not %r" % name)
return DefaultHandler(name)
@@ -972,7 +972,7 @@ class EventHandler(BaseDescriptor):
return self
def __call__(self, *args, **kwargs):
- """Pass `*args` and `**kwargs` to the handler's function if it exists."""
+ """Pass `*args` and `**kwargs` to the handler's function if it exists."""
if hasattr(self, 'func'):
return self.func(*args, **kwargs)
else:
@@ -1028,19 +1028,19 @@ class HasDescriptors(metaclass=MetaHasDescriptors):
if new_meth is object.__new__:
inst = new_meth(cls)
else:
- inst = new_meth(cls, *args, **kwargs)
- inst.setup_instance(*args, **kwargs)
+ inst = new_meth(cls, *args, **kwargs)
+ inst.setup_instance(*args, **kwargs)
return inst
def setup_instance(*args, **kwargs):
- """
- This is called **before** self.__init__ is called.
- """
+ """
+ This is called **before** self.__init__ is called.
+ """
# Pass self as args[0] to allow "self" as keyword argument
self = args[0]
args = args[1:]
- self._cross_validation_lock = False
+ self._cross_validation_lock = False
cls = self.__class__
for key in dir(cls):
# Some descriptors raise AttributeError like zope.interface's
@@ -1065,40 +1065,40 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
self._trait_values = {}
self._trait_notifiers = {}
self._trait_validators = {}
- super(HasTraits, self).setup_instance(*args, **kwargs)
+ super(HasTraits, self).setup_instance(*args, **kwargs)
- def __init__(self, *args, **kwargs):
+ def __init__(self, *args, **kwargs):
# Allow trait values to be set using keyword arguments.
# We need to use setattr for this to trigger validation and
# notifications.
- super_args = args
- super_kwargs = {}
+ super_args = args
+ super_kwargs = {}
with self.hold_trait_notifications():
- for key, value in kwargs.items():
- if self.has_trait(key):
- setattr(self, key, value)
- else:
- # passthrough args that don't set traits to super
- super_kwargs[key] = value
- try:
- super(HasTraits, self).__init__(*super_args, **super_kwargs)
- except TypeError as e:
- arg_s_list = [ repr(arg) for arg in super_args ]
- for k, v in super_kwargs.items():
- arg_s_list.append("%s=%r" % (k, v))
- arg_s = ', '.join(arg_s_list)
- warn(
+ for key, value in kwargs.items():
+ if self.has_trait(key):
+ setattr(self, key, value)
+ else:
+ # passthrough args that don't set traits to super
+ super_kwargs[key] = value
+ try:
+ super(HasTraits, self).__init__(*super_args, **super_kwargs)
+ except TypeError as e:
+ arg_s_list = [ repr(arg) for arg in super_args ]
+ for k, v in super_kwargs.items():
+ arg_s_list.append("%s=%r" % (k, v))
+ arg_s = ', '.join(arg_s_list)
+ warn(
"Passing unrecognized arguments to super({classname}).__init__({arg_s}).\n"
- "{error}\n"
- "This is deprecated in traitlets 4.2."
- "This error will be raised in a future release of traitlets."
- .format(
- arg_s=arg_s, classname=self.__class__.__name__,
- error=e,
- ),
- DeprecationWarning,
- stacklevel=2,
- )
+ "{error}\n"
+ "This is deprecated in traitlets 4.2."
+ "This error will be raised in a future release of traitlets."
+ .format(
+ arg_s=arg_s, classname=self.__class__.__name__,
+ error=e,
+ ),
+ DeprecationWarning,
+ stacklevel=2,
+ )
def __getstate__(self):
d = self.__dict__.copy()
@@ -1129,27 +1129,27 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
if isinstance(value, EventHandler):
value.instance_init(self)
- @property
+ @property
+ @contextlib.contextmanager
+ def cross_validation_lock(self):
+ """
+ A contextmanager for running a block with our cross validation lock set
+ to True.
+
+ At the end of the block, the lock's value is restored to its value
+ prior to entering the block.
+ """
+ if self._cross_validation_lock:
+ yield
+ return
+ else:
+ try:
+ self._cross_validation_lock = True
+ yield
+ finally:
+ self._cross_validation_lock = False
+
@contextlib.contextmanager
- def cross_validation_lock(self):
- """
- A contextmanager for running a block with our cross validation lock set
- to True.
-
- At the end of the block, the lock's value is restored to its value
- prior to entering the block.
- """
- if self._cross_validation_lock:
- yield
- return
- else:
- try:
- self._cross_validation_lock = True
- yield
- finally:
- self._cross_validation_lock = False
-
- @contextlib.contextmanager
def hold_trait_notifications(self):
"""Context manager for bundling trait change notifications and cross
validation.
@@ -1158,7 +1158,7 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
race conditions in trait notifiers requesting other trait values.
All trait notifications will fire after all values have been assigned.
"""
- if self._cross_validation_lock:
+ if self._cross_validation_lock:
yield
return
else:
@@ -1170,15 +1170,15 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
if past_changes is None:
return [change]
else:
- if past_changes[-1]['type'] == 'change' and change.type == 'change':
- past_changes[-1]['new'] = change.new
+ if past_changes[-1]['type'] == 'change' and change.type == 'change':
+ past_changes[-1]['new'] = change.new
else:
# In case of changes other than 'change', append the notification.
past_changes.append(change)
return past_changes
def hold(change):
- name = change.name
+ name = change.name
cache[name] = compress(cache.get(name), change)
try:
@@ -1191,24 +1191,24 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
for name in list(cache.keys()):
trait = getattr(self.__class__, name)
value = trait._cross_validate(self, getattr(self, name))
- self.set_trait(name, value)
+ self.set_trait(name, value)
except TraitError as e:
# Roll back in case of TraitError during final cross validation.
self.notify_change = lambda x: None
for name, changes in cache.items():
for change in changes[::-1]:
# TODO: Separate in a rollback function per notification type.
- if change.type == 'change':
- if change.old is not Undefined:
- self.set_trait(name, change.old)
+ if change.type == 'change':
+ if change.old is not Undefined:
+ self.set_trait(name, change.old)
else:
self._trait_values.pop(name)
cache = {}
raise e
finally:
self._cross_validation_lock = False
- # Restore method retrieval from class
- del self.notify_change
+ # Restore method retrieval from class
+ del self.notify_change
# trigger delayed notifications
for changes in cache.values():
@@ -1216,13 +1216,13 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
self.notify_change(change)
def _notify_trait(self, name, old_value, new_value):
- self.notify_change(Bunch(
- name=name,
- old=old_value,
- new=new_value,
- owner=self,
- type='change',
- ))
+ self.notify_change(Bunch(
+ name=name,
+ old=old_value,
+ new=new_value,
+ owner=self,
+ type='change',
+ ))
def notify_change(self, change):
"""Notify observers of a change event"""
@@ -1231,7 +1231,7 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
def _notify_observers(self, event):
"""Notify observers of any event"""
if not isinstance(event, Bunch):
- # cast to bunch if given a dict
+ # cast to bunch if given a dict
event = Bunch(event)
name, type = event.name, event.type
@@ -1260,9 +1260,9 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
if isinstance(c, _CallbackWrapper):
c = c.__call__
- elif isinstance(c, EventHandler) and c.name is not None:
+ elif isinstance(c, EventHandler) and c.name is not None:
c = getattr(self, c.name)
-
+
c(event)
def _add_notifiers(self, handler, name, type):
@@ -1315,7 +1315,7 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
If False (the default), then install the handler. If True
then unintall it.
"""
- warn("on_trait_change is deprecated in traitlets 4.1: use observe instead",
+ warn("on_trait_change is deprecated in traitlets 4.1: use observe instead",
DeprecationWarning, stacklevel=2)
if name is None:
name = All
@@ -1333,8 +1333,8 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
----------
handler : callable
A callable that is called when a trait changes. Its
- signature should be ``handler(change)``, where ``change`` is a
- dictionary. The change dictionary at least holds a 'type' key.
+ signature should be ``handler(change)``, where ``change`` is a
+ dictionary. The change dictionary at least holds a 'type' key.
* ``type``: the type of notification.
Other keys may be passed depending on the value of 'type'. In the
case where type is 'change', we also have the following keys:
@@ -1357,7 +1357,7 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
def unobserve(self, handler, names=All, type='change'):
"""Remove a trait change handler.
- This is used to unregister handlers to trait change notifications.
+ This is used to unregister handlers to trait change notifications.
Parameters
----------
@@ -1387,19 +1387,19 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
pass
def _register_validator(self, handler, names):
- """Setup a handler to be called when a trait should be cross validated.
+ """Setup a handler to be called when a trait should be cross validated.
This is used to setup dynamic notifications for cross-validation.
If a validator is already registered for any of the provided names, a
- TraitError is raised and no new validator is registered.
+ TraitError is raised and no new validator is registered.
Parameters
----------
handler : callable
A callable that is called when the given trait is cross-validated.
- Its signature is handler(proposal), where proposal is a Bunch (dictionary with attribute access)
- with the following attributes/keys:
+ Its signature is handler(proposal), where proposal is a Bunch (dictionary with attribute access)
+ with the following attributes/keys:
* ``owner`` : the HasTraits instance
* ``value`` : the proposed value for the modified trait attribute
* ``trait`` : the TraitType instance associated with the attribute
@@ -1416,8 +1416,8 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
for name in names:
self._trait_validators[name] = handler
- def add_traits(self, **traits):
- """Dynamically add trait attributes to the HasTraits instance."""
+ def add_traits(self, **traits):
+ """Dynamically add trait attributes to the HasTraits instance."""
cls = self.__class__
attrs = {"__module__": cls.__module__}
if hasattr(cls, "__qualname__"):
@@ -1425,18 +1425,18 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
attrs["__qualname__"] = cls.__qualname__
attrs.update(traits)
self.__class__ = type(cls.__name__, (cls,), attrs)
- for trait in traits.values():
- trait.instance_init(self)
-
- def set_trait(self, name, value):
- """Forcibly sets trait attribute, including read-only attributes."""
- cls = self.__class__
- if not self.has_trait(name):
- raise TraitError("Class %s does not have a trait named %s" %
- (cls.__name__, name))
- else:
- getattr(cls, name).set(self, value)
-
+ for trait in traits.values():
+ trait.instance_init(self)
+
+ def set_trait(self, name, value):
+ """Forcibly sets trait attribute, including read-only attributes."""
+ cls = self.__class__
+ if not self.has_trait(name):
+ raise TraitError("Class %s does not have a trait named %s" %
+ (cls.__name__, name))
+ else:
+ getattr(cls, name).set(self, value)
+
@classmethod
def class_trait_names(cls, **metadata):
"""Get a list of all the names of this class' traits.
@@ -1444,7 +1444,7 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
This method is just like the :meth:`trait_names` method,
but is unbound.
"""
- return list(cls.class_traits(**metadata))
+ return list(cls.class_traits(**metadata))
@classmethod
def class_traits(cls, **metadata):
@@ -1494,7 +1494,7 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
def has_trait(self, name):
"""Returns True if the object has a trait with the specified name."""
return isinstance(getattr(self.__class__, name, None), TraitType)
-
+
def trait_has_value(self, name):
"""Returns True if the specified trait has a value.
@@ -1589,7 +1589,7 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
def trait_names(self, **metadata):
"""Get a list of all the names of this class' traits."""
- return list(self.traits(**metadata))
+ return list(self.traits(**metadata))
def traits(self, **metadata):
"""Get a ``dict`` of all the traits of this class. The dictionary
@@ -1630,48 +1630,48 @@ class HasTraits(HasDescriptors, metaclass=MetaHasTraits):
except AttributeError:
raise TraitError("Class %s does not have a trait named %s" %
(self.__class__.__name__, traitname))
- metadata_name = '_' + traitname + '_metadata'
- if hasattr(self, metadata_name) and key in getattr(self, metadata_name):
- return getattr(self, metadata_name).get(key, default)
+ metadata_name = '_' + traitname + '_metadata'
+ if hasattr(self, metadata_name) and key in getattr(self, metadata_name):
+ return getattr(self, metadata_name).get(key, default)
else:
return trait.metadata.get(key, default)
- @classmethod
- def class_own_trait_events(cls, name):
- """Get a dict of all event handlers defined on this class, not a parent.
-
- Works like ``event_handlers``, except for excluding traits from parents.
- """
- sup = super(cls, cls)
- return {n: e for (n, e) in cls.events(name).items()
- if getattr(sup, n, None) is not e}
-
- @classmethod
- def trait_events(cls, name=None):
- """Get a ``dict`` of all the event handlers of this class.
-
- Parameters
- ----------
+ @classmethod
+ def class_own_trait_events(cls, name):
+ """Get a dict of all event handlers defined on this class, not a parent.
+
+ Works like ``event_handlers``, except for excluding traits from parents.
+ """
+ sup = super(cls, cls)
+ return {n: e for (n, e) in cls.events(name).items()
+ if getattr(sup, n, None) is not e}
+
+ @classmethod
+ def trait_events(cls, name=None):
+ """Get a ``dict`` of all the event handlers of this class.
+
+ Parameters
+ ----------
name : str (default: None)
- The name of a trait of this class. If name is ``None`` then all
- the event handlers of this class will be returned instead.
-
- Returns
- -------
- The event handlers associated with a trait name, or all event handlers.
- """
- events = {}
- for k, v in getmembers(cls):
- if isinstance(v, EventHandler):
- if name is None:
- events[k] = v
- elif name in v.trait_names:
- events[k] = v
- elif hasattr(v, 'tags'):
- if cls.trait_names(**v.tags):
- events[k] = v
- return events
-
+ The name of a trait of this class. If name is ``None`` then all
+ the event handlers of this class will be returned instead.
+
+ Returns
+ -------
+ The event handlers associated with a trait name, or all event handlers.
+ """
+ events = {}
+ for k, v in getmembers(cls):
+ if isinstance(v, EventHandler):
+ if name is None:
+ events[k] = v
+ elif name in v.trait_names:
+ events[k] = v
+ elif hasattr(v, 'tags'):
+ if cls.trait_names(**v.tags):
+ events[k] = v
+ return events
+
#-----------------------------------------------------------------------------
# Actual TraitTypes implementations/subclasses
#-----------------------------------------------------------------------------
@@ -1762,7 +1762,7 @@ class Type(ClassBasedTraitType):
if isinstance(self.klass, str):
klass = self.klass
else:
- klass = self.klass.__module__ + '.' + self.klass.__name__
+ klass = self.klass.__module__ + '.' + self.klass.__name__
result = "a subclass of '%s'" % klass
if self.allow_none:
return result + ' or None'
@@ -1796,7 +1796,7 @@ class Instance(ClassBasedTraitType):
klass = None
- def __init__(self, klass=None, args=None, kw=None, **kwargs):
+ def __init__(self, klass=None, args=None, kw=None, **kwargs):
"""Construct an Instance trait.
This trait allows values that are instances of a particular
@@ -1827,7 +1827,7 @@ class Instance(ClassBasedTraitType):
"""
if klass is None:
klass = self.klass
-
+
if (klass is not None) and (inspect.isclass(klass) or isinstance(klass, str)):
self.klass = klass
else:
@@ -1842,7 +1842,7 @@ class Instance(ClassBasedTraitType):
self.default_args = args
self.default_kwargs = kw
- super(Instance, self).__init__(**kwargs)
+ super(Instance, self).__init__(**kwargs)
def validate(self, obj, value):
if isinstance(value, self.klass):
@@ -1917,8 +1917,8 @@ class This(ClassBasedTraitType):
info_text = 'an instance of the same type as the receiver or None'
- def __init__(self, **kwargs):
- super(This, self).__init__(None, **kwargs)
+ def __init__(self, **kwargs):
+ super(This, self).__init__(None, **kwargs)
def validate(self, obj, value):
# What if value is a superclass of obj.__class__? This is
@@ -1933,7 +1933,7 @@ class This(ClassBasedTraitType):
class Union(TraitType):
"""A trait type representing a Union type."""
- def __init__(self, trait_types, **kwargs):
+ def __init__(self, trait_types, **kwargs):
"""Construct a Union trait.
This trait allows values that are allowed by at least one of the
@@ -1951,8 +1951,8 @@ class Union(TraitType):
with the validation function of Float, then Bool, and finally Int.
"""
self.trait_types = list(trait_types)
- self.info_text = " or ".join([tt.info() for tt in self.trait_types])
- super(Union, self).__init__(**kwargs)
+ self.info_text = " or ".join([tt.info() for tt in self.trait_types])
+ super(Union, self).__init__(**kwargs)
def default(self, obj=None):
default = super(Union, self).default(obj)
@@ -1974,13 +1974,13 @@ class Union(TraitType):
super(Union, self).instance_init(obj)
def validate(self, obj, value):
- with obj.cross_validation_lock:
+ with obj.cross_validation_lock:
for trait_type in self.trait_types:
try:
v = trait_type._validate(obj, value)
- # In the case of an element trait, the name is None
- if self.name is not None:
- setattr(obj, '_' + self.name + '_metadata', trait_type.metadata)
+ # In the case of an element trait, the name is None
+ if self.name is not None:
+ setattr(obj, '_' + self.name + '_metadata', trait_type.metadata)
return v
except TraitError:
continue
@@ -1992,7 +1992,7 @@ class Union(TraitType):
else:
return Union(self.trait_types + [other])
-
+
#-----------------------------------------------------------------------------
# Basic TraitTypes implementations/subclasses
#-----------------------------------------------------------------------------
@@ -2005,37 +2005,37 @@ class Any(TraitType):
info_text = 'any value'
-def _validate_bounds(trait, obj, value):
- """
- Validate that a number to be applied to a trait is between bounds.
-
- If value is not between min_bound and max_bound, this raises a
- TraitError with an error message appropriate for this trait.
- """
- if trait.min is not None and value < trait.min:
- raise TraitError(
- "The value of the '{name}' trait of {klass} instance should "
- "not be less than {min_bound}, but a value of {value} was "
- "specified".format(
- name=trait.name, klass=class_of(obj),
- value=value, min_bound=trait.min))
- if trait.max is not None and value > trait.max:
- raise TraitError(
- "The value of the '{name}' trait of {klass} instance should "
- "not be greater than {max_bound}, but a value of {value} was "
- "specified".format(
- name=trait.name, klass=class_of(obj),
- value=value, max_bound=trait.max))
- return value
-
-
+def _validate_bounds(trait, obj, value):
+ """
+ Validate that a number to be applied to a trait is between bounds.
+
+ If value is not between min_bound and max_bound, this raises a
+ TraitError with an error message appropriate for this trait.
+ """
+ if trait.min is not None and value < trait.min:
+ raise TraitError(
+ "The value of the '{name}' trait of {klass} instance should "
+ "not be less than {min_bound}, but a value of {value} was "
+ "specified".format(
+ name=trait.name, klass=class_of(obj),
+ value=value, min_bound=trait.min))
+ if trait.max is not None and value > trait.max:
+ raise TraitError(
+ "The value of the '{name}' trait of {klass} instance should "
+ "not be greater than {max_bound}, but a value of {value} was "
+ "specified".format(
+ name=trait.name, klass=class_of(obj),
+ value=value, max_bound=trait.max))
+ return value
+
+
class Int(TraitType):
"""An int trait."""
default_value = 0
info_text = 'an int'
- def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
+ def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
self.min = kwargs.pop('min', None)
self.max = kwargs.pop('max', None)
super(Int, self).__init__(default_value=default_value,
@@ -2044,7 +2044,7 @@ class Int(TraitType):
def validate(self, obj, value):
if not isinstance(value, int):
self.error(obj, value)
- return _validate_bounds(self, obj, value)
+ return _validate_bounds(self, obj, value)
def from_string(self, s):
if self.allow_none and s == 'None':
@@ -2057,12 +2057,12 @@ class CInt(Int):
def validate(self, obj, value):
try:
- value = int(value)
+ value = int(value)
except Exception:
self.error(obj, value)
- return _validate_bounds(self, obj, value)
+ return _validate_bounds(self, obj, value)
+
-
Long, CLong = Int, CInt
Integer = Int
@@ -2073,10 +2073,10 @@ class Float(TraitType):
default_value = 0.0
info_text = 'a float'
- def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
+ def __init__(self, default_value=Undefined, allow_none=False, **kwargs):
self.min = kwargs.pop('min', -float('inf'))
self.max = kwargs.pop('max', float('inf'))
- super(Float, self).__init__(default_value=default_value,
+ super(Float, self).__init__(default_value=default_value,
allow_none=allow_none, **kwargs)
def validate(self, obj, value):
@@ -2084,7 +2084,7 @@ class Float(TraitType):
value = float(value)
if not isinstance(value, float):
self.error(obj, value)
- return _validate_bounds(self, obj, value)
+ return _validate_bounds(self, obj, value)
def from_string(self, s):
if self.allow_none and s == 'None':
@@ -2097,12 +2097,12 @@ class CFloat(Float):
def validate(self, obj, value):
try:
- value = float(value)
+ value = float(value)
except Exception:
self.error(obj, value)
- return _validate_bounds(self, obj, value)
+ return _validate_bounds(self, obj, value)
+
-
class Complex(TraitType):
"""A trait for complex numbers."""
@@ -2243,7 +2243,7 @@ class DottedObjectName(ObjectName):
value = self.coerce_str(obj, value)
if isinstance(value, str) and all(isidentifier(a)
- for a in value.split('.')):
+ for a in value.split('.')):
return value
self.error(obj, value)
@@ -2289,11 +2289,11 @@ class CBool(Bool):
class Enum(TraitType):
"""An enum whose value must be in a given sequence."""
- def __init__(self, values, default_value=Undefined, **kwargs):
+ def __init__(self, values, default_value=Undefined, **kwargs):
self.values = values
- if kwargs.get('allow_none', False) and default_value is Undefined:
+ if kwargs.get('allow_none', False) and default_value is Undefined:
default_value = None
- super(Enum, self).__init__(default_value, **kwargs)
+ super(Enum, self).__init__(default_value, **kwargs)
def validate(self, obj, value):
if value in self.values:
@@ -2331,10 +2331,10 @@ class Enum(TraitType):
class CaselessStrEnum(Enum):
"""An enum of strings where the case should be ignored."""
-
- def __init__(self, values, default_value=Undefined, **kwargs):
+
+ def __init__(self, values, default_value=Undefined, **kwargs):
super().__init__(values, default_value=default_value, **kwargs)
-
+
def validate(self, obj, value):
if not isinstance(value, str):
self.error(obj, value)
@@ -2444,7 +2444,7 @@ class Container(Instance):
will be cast to the container type.
allow_none : bool [ default False ]
Whether to allow the value to be None
- **kwargs : any
+ **kwargs : any
further keys for extensions to the Trait (e.g. config)
"""
@@ -2630,7 +2630,7 @@ class List(Container):
self._minlen = minlen
self._maxlen = maxlen
super(List, self).__init__(trait=trait, default_value=default_value,
- **kwargs)
+ **kwargs)
def length_error(self, obj, value):
e = "The '%s' trait of %s instance must be of length %i <= L <= %i, but a value of %s was specified." \
@@ -2693,7 +2693,7 @@ class Set(List):
maxlen : Int [ default sys.maxsize ]
The maximum length of the input list
"""
- super(Set, self).__init__(trait, default_value, minlen, maxlen, **kwargs)
+ super(Set, self).__init__(trait, default_value, minlen, maxlen, **kwargs)
def default_value_repr(self):
# Ensure default value is sorted for a reproducible build
@@ -2709,7 +2709,7 @@ class Tuple(Container):
klass = tuple
_cast_types = (list,)
- def __init__(self, *traits, **kwargs):
+ def __init__(self, *traits, **kwargs):
"""Create a tuple from a list, set, or tuple.
Create a fixed-type tuple with Traits:
@@ -2849,14 +2849,14 @@ class Dict(Instance):
_key_trait = None
def __init__(self, value_trait=None, per_key_traits=None, key_trait=None, default_value=Undefined,
- **kwargs):
- """Create a dict trait type from a Python dict.
+ **kwargs):
+ """Create a dict trait type from a Python dict.
The default value is created by doing ``dict(default_value)``,
which creates a copy of the ``default_value``.
- Parameters
- ----------
+ Parameters
+ ----------
value_trait : TraitType [ optional ]
The specified trait type to check and use to restrict the values of
the dict. If unspecified, values are not checked.
@@ -2871,7 +2871,7 @@ class Dict(Instance):
The default value for the Dict. Must be dict, tuple, or None, and
will be cast to a dict if not None. If any key or value traits are specified,
the `default_value` must conform to the constraints.
-
+
Examples
--------
>>> d = Dict(Unicode())
@@ -2934,8 +2934,8 @@ class Dict(Instance):
# Case where a type of TraitType is provided rather than an instance
if is_trait(value_trait):
if isinstance(value_trait, type):
- warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)"
- " Passing types is deprecated in traitlets 4.1.",
+ warn("Traits should be given as instances, not types (for example, `Int()`, not `Int`)"
+ " Passing types is deprecated in traitlets 4.1.",
DeprecationWarning, stacklevel=2)
value_trait = value_trait()
self._value_trait = value_trait
@@ -2954,7 +2954,7 @@ class Dict(Instance):
self._per_key_traits = per_key_traits
- super(Dict, self).__init__(klass=dict, args=args, **kwargs)
+ super(Dict, self).__init__(klass=dict, args=args, **kwargs)
def element_error(self, obj, element, validator, side='Values'):
e = side + " of the '%s' trait of %s instance must be %s, but a value of %s was specified." \
@@ -2974,7 +2974,7 @@ class Dict(Instance):
value_trait = self._value_trait
if not (key_trait or value_trait or per_key_override):
return value
-
+
validated = {}
for key in value:
v = value[key]
@@ -2990,7 +2990,7 @@ class Dict(Instance):
except TraitError:
self.element_error(obj, v, active_value_trait, 'Values')
validated[key] = v
-
+
return self.klass(validated)
def class_init(self, cls, name):
@@ -3127,85 +3127,85 @@ class CRegExp(TraitType):
return re.compile(value)
except Exception:
self.error(obj, value)
-
-
-class UseEnum(TraitType):
- """Use a Enum class as model for the data type description.
- Note that if no default-value is provided, the first enum-value is used
- as default-value.
-
- .. sourcecode:: python
-
- # -- SINCE: Python 3.4 (or install backport: pip install enum34)
- import enum
- from traitlets import HasTraits, UseEnum
-
- class Color(enum.Enum):
- red = 1 # -- IMPLICIT: default_value
- blue = 2
- green = 3
-
- class MyEntity(HasTraits):
- color = UseEnum(Color, default_value=Color.blue)
-
- entity = MyEntity(color=Color.red)
- entity.color = Color.green # USE: Enum-value (preferred)
- entity.color = "green" # USE: name (as string)
- entity.color = "Color.green" # USE: scoped-name (as string)
- entity.color = 3 # USE: number (as int)
- assert entity.color is Color.green
- """
- default_value = None
- info_text = "Trait type adapter to a Enum class"
-
- def __init__(self, enum_class, default_value=None, **kwargs):
- assert issubclass(enum_class, enum.Enum), \
- "REQUIRE: enum.Enum, but was: %r" % enum_class
- allow_none = kwargs.get("allow_none", False)
- if default_value is None and not allow_none:
- default_value = list(enum_class.__members__.values())[0]
- super(UseEnum, self).__init__(default_value=default_value, **kwargs)
- self.enum_class = enum_class
- self.name_prefix = enum_class.__name__ + "."
-
- def select_by_number(self, value, default=Undefined):
- """Selects enum-value by using its number-constant."""
- assert isinstance(value, int)
- enum_members = self.enum_class.__members__
- for enum_item in enum_members.values():
- if enum_item.value == value:
- return enum_item
- # -- NOT FOUND:
- return default
-
- def select_by_name(self, value, default=Undefined):
- """Selects enum-value by using its name or scoped-name."""
+
+
+class UseEnum(TraitType):
+ """Use a Enum class as model for the data type description.
+ Note that if no default-value is provided, the first enum-value is used
+ as default-value.
+
+ .. sourcecode:: python
+
+ # -- SINCE: Python 3.4 (or install backport: pip install enum34)
+ import enum
+ from traitlets import HasTraits, UseEnum
+
+ class Color(enum.Enum):
+ red = 1 # -- IMPLICIT: default_value
+ blue = 2
+ green = 3
+
+ class MyEntity(HasTraits):
+ color = UseEnum(Color, default_value=Color.blue)
+
+ entity = MyEntity(color=Color.red)
+ entity.color = Color.green # USE: Enum-value (preferred)
+ entity.color = "green" # USE: name (as string)
+ entity.color = "Color.green" # USE: scoped-name (as string)
+ entity.color = 3 # USE: number (as int)
+ assert entity.color is Color.green
+ """
+ default_value = None
+ info_text = "Trait type adapter to a Enum class"
+
+ def __init__(self, enum_class, default_value=None, **kwargs):
+ assert issubclass(enum_class, enum.Enum), \
+ "REQUIRE: enum.Enum, but was: %r" % enum_class
+ allow_none = kwargs.get("allow_none", False)
+ if default_value is None and not allow_none:
+ default_value = list(enum_class.__members__.values())[0]
+ super(UseEnum, self).__init__(default_value=default_value, **kwargs)
+ self.enum_class = enum_class
+ self.name_prefix = enum_class.__name__ + "."
+
+ def select_by_number(self, value, default=Undefined):
+ """Selects enum-value by using its number-constant."""
+ assert isinstance(value, int)
+ enum_members = self.enum_class.__members__
+ for enum_item in enum_members.values():
+ if enum_item.value == value:
+ return enum_item
+ # -- NOT FOUND:
+ return default
+
+ def select_by_name(self, value, default=Undefined):
+ """Selects enum-value by using its name or scoped-name."""
assert isinstance(value, str)
- if value.startswith(self.name_prefix):
- # -- SUPPORT SCOPED-NAMES, like: "Color.red" => "red"
- value = value.replace(self.name_prefix, "", 1)
- return self.enum_class.__members__.get(value, default)
-
- def validate(self, obj, value):
- if isinstance(value, self.enum_class):
- return value
- elif isinstance(value, int):
- # -- CONVERT: number => enum_value (item)
- value2 = self.select_by_number(value)
- if value2 is not Undefined:
- return value2
+ if value.startswith(self.name_prefix):
+ # -- SUPPORT SCOPED-NAMES, like: "Color.red" => "red"
+ value = value.replace(self.name_prefix, "", 1)
+ return self.enum_class.__members__.get(value, default)
+
+ def validate(self, obj, value):
+ if isinstance(value, self.enum_class):
+ return value
+ elif isinstance(value, int):
+ # -- CONVERT: number => enum_value (item)
+ value2 = self.select_by_number(value)
+ if value2 is not Undefined:
+ return value2
elif isinstance(value, str):
- # -- CONVERT: name or scoped_name (as string) => enum_value (item)
- value2 = self.select_by_name(value)
- if value2 is not Undefined:
- return value2
- elif value is None:
- if self.allow_none:
- return None
- else:
- return self.default_value
- self.error(obj, value)
-
+ # -- CONVERT: name or scoped_name (as string) => enum_value (item)
+ value2 = self.select_by_name(value)
+ if value2 is not Undefined:
+ return value2
+ elif value is None:
+ if self.allow_none:
+ return None
+ else:
+ return self.default_value
+ self.error(obj, value)
+
def _choices_str(self, as_rst=False):
""" Returns a description of the trait choices (not none)."""
choices = self.enum_class.__members__.keys()
@@ -3221,7 +3221,7 @@ class UseEnum(TraitType):
'')
return 'any of %s%s' % (self._choices_str(as_rst), none)
- def info(self):
+ def info(self):
return self._info(as_rst=False)
def info_rst(self):
diff --git a/contrib/python/traitlets/py3/traitlets/utils/bunch.py b/contrib/python/traitlets/py3/traitlets/utils/bunch.py
index dc40b5df7d..2edb830ad6 100644
--- a/contrib/python/traitlets/py3/traitlets/utils/bunch.py
+++ b/contrib/python/traitlets/py3/traitlets/utils/bunch.py
@@ -1,25 +1,25 @@
-"""Yet another implementation of bunch
-
-attribute-access of items on a dict.
-"""
-
-# Copyright (c) Jupyter Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-class Bunch(dict):
- """A dict with attribute-access"""
- def __getattr__(self, key):
- try:
- return self.__getitem__(key)
- except KeyError:
- raise AttributeError(key)
-
- def __setattr__(self, key, value):
- self.__setitem__(key, value)
-
- def __dir__(self):
- # py2-compat: can't use super because dict doesn't have __dir__
- names = dir({})
- names.extend(self.keys())
- return names
-
+"""Yet another implementation of bunch
+
+attribute-access of items on a dict.
+"""
+
+# Copyright (c) Jupyter Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+class Bunch(dict):
+ """A dict with attribute-access"""
+ def __getattr__(self, key):
+ try:
+ return self.__getitem__(key)
+ except KeyError:
+ raise AttributeError(key)
+
+ def __setattr__(self, key, value):
+ self.__setitem__(key, value)
+
+ def __dir__(self):
+ # py2-compat: can't use super because dict doesn't have __dir__
+ names = dir({})
+ names.extend(self.keys())
+ return names
+
diff --git a/contrib/python/traitlets/py3/ya.make b/contrib/python/traitlets/py3/ya.make
index 99460fa8ed..46980f21b3 100644
--- a/contrib/python/traitlets/py3/ya.make
+++ b/contrib/python/traitlets/py3/ya.make
@@ -9,7 +9,7 @@ OWNER(borman nslus g:python-contrib)
VERSION(5.1.1)
LICENSE(BSD-3-Clause)
-
+
NO_LINT()
PY_SRCS(
@@ -28,7 +28,7 @@ PY_SRCS(
traitlets/tests/utils.py
traitlets/traitlets.py
traitlets/utils/__init__.py
- traitlets/utils/bunch.py
+ traitlets/utils/bunch.py
traitlets/utils/decorators.py
traitlets/utils/descriptions.py
traitlets/utils/getargspec.py