Esempio n. 1
0
    def _value_to_graph_object(self, key, value, _raise=True):
        """
        Attempt to convert value to graph object.

        :param (str|unicode) key: Should be an object_name from GRAPH_REFERENCE
        :param (dict) value: This will fail if it's not a dict.
        :param (bool) _raise: Flag to prevent inappropriate erring.

        :return: (PlotlyList|PlotlyDict|None) `None` if `_raise` and failure.

        """
        if key in graph_reference.ARRAYS:
            val_types = (list, )
        else:
            val_types = (dict, )

        if not isinstance(value, val_types):
            if _raise:
                path = self._get_path() + (key, )
                raise exceptions.PlotlyDictValueError(self, path)
            else:
                return

        # this can be `None` when `_raise == False`
        return GraphObjectFactory.create(key,
                                         value,
                                         _raise=_raise,
                                         _parent=self,
                                         _parent_key=key)
Esempio n. 2
0
    def validate(self, caller=True):  # TODO: validate values too?
        """Recursively check the validity of the keys in a PlotlyDict.

        The valid keys constitute the entries in each object
        dictionary in graph_objs_meta.json

        The validation process first requires that all nested collections be
        converted to the appropriate subclass of PlotlyDict/PlotlyList. Then,
        each of these objects call `validate` and so on, recursively,
        until the entire object has been validated.

        """
        if caller:  # change everything to 'checkable' objs
            try:
                self.to_graph_objs(caller=False)
            except exceptions.PlotlyGraphObjectError as err:
                err.prepare()
                raise
        obj_key = NAME_TO_KEY[self.__class__.__name__]
        for key, val in list(self.items()):
            if isinstance(val, (PlotlyDict, PlotlyList)):
                try:
                    val.validate(caller=False)
                except exceptions.PlotlyGraphObjectError as err:
                    err.add_to_error_path(key)
                    err.prepare()
                    raise
            else:
                if key in INFO[obj_key]['keymeta'].keys():
                    if 'key_type' not in INFO[obj_key]['keymeta'][key].keys():
                        continue  # TODO: 'type' may not be documented yet!
                    if INFO[obj_key]['keymeta'][key]['key_type'] == 'object':
                        try:
                            val_types = (
                                INFO[obj_key]['keymeta'][key]['val_types'])
                        except KeyError:
                            val_types = 'undocumented'
                        raise exceptions.PlotlyDictValueError(
                            obj=self,
                            key=key,
                            value=val,
                            val_types=val_types
                        )
                else:
                    matching_objects = [obj for obj in
                                        INFO if key in INFO[obj]['keymeta']]
                    notes = ''
                    if len(matching_objects):
                        notes += "That key is valid only in these objects:\n\n"
                        for obj in matching_objects:
                            notes += "\t{0}".format(KEY_TO_NAME[obj])
                            try:
                                notes += '({0}="{1}")\n'.format(
                                    repr(key),
                                    INFO[obj]['keymeta'][key]['val_types'])
                            except KeyError:
                                notes += '({0}="..")\n'.format(repr(key))
                        notes.expandtabs()
                    else:
                        notes += ("Couldn't find uses for key: {0}\n\n"
                                  "".format(repr(key)))
                    raise exceptions.PlotlyDictKeyError(obj=self,
                                                        key=key,
                                                        notes=notes)
Esempio n. 3
0
    def to_graph_objs(self, caller=True):
        """Walk obj, convert dicts and lists to plotly graph objs.

        For each key in the object, if it corresponds to a special key that
        should be associated with a graph object, the ordinary dict or list
        will be reinitialized as a special PlotlyDict or PlotlyList of the
        appropriate `kind`.

        """
        info_key = NAME_TO_KEY[self.__class__.__name__]
        keys = self.keys()
        updated_keys = graph_objs_tools.update_keys(keys)
        for k_old, k_new in zip(keys, updated_keys):
            if k_old != k_new:
                self[k_new] = self.pop(k_old)
                warnings.warn(
                    "\n"
                    "The key, '{old}', has been depreciated, it's been "
                    "converted to '{new}'. You should change your code to use "
                    "'{new}' in the future."
                    "".format(old=k_old, new=k_new)
                )
        for key in updated_keys:
            if isinstance(self[key], (PlotlyDict, PlotlyList)):
                try:
                    self[key].to_graph_objs(caller=False)
                except exceptions.PlotlyGraphObjectError as err:
                    err.add_to_error_path(key)
                    err.prepare()
                    raise
            elif (key in INFO[info_key]['keymeta'].keys() and
                  'key_type' in INFO[info_key]['keymeta'][key].keys()):
                if INFO[info_key]['keymeta'][key]['key_type'] == 'object':
                    class_name = KEY_TO_NAME[key]
                    obj = get_class_instance_by_name(class_name)
                    if isinstance(obj, PlotlyDict):
                        if not isinstance(self[key], dict):
                            try:
                                val_types = (
                                    INFO[info_key]['keymeta'][key]['val_types']
                                )
                            except KeyError:
                                val_types = 'undocumented'
                            raise exceptions.PlotlyDictValueError(
                                obj=self,
                                key=key,
                                value=self[key],
                                val_types=val_types,
                                notes="value needs to be dictionary-like"
                            )
                        for k, v in list(self.pop(key).items()):
                            obj[k] = v  # finish up momentarily...
                    else:  # if not PlotlyDict, it MUST be a PlotlyList
                        if not isinstance(self[key], list):
                            try:
                                val_types = (
                                    INFO[info_key]['keymeta'][key]['val_types']
                                )
                            except KeyError:
                                val_types = 'undocumented'
                            raise exceptions.PlotlyDictValueError(  # TODO!!!
                                obj=self,
                                key=key,
                                value=self[key],
                                val_types=val_types,
                                notes="value needs to be list-like"
                            )
                        obj += self.pop(key)
                    try:
                        obj.to_graph_objs(caller=False)
                    except exceptions.PlotlyGraphObjectError as err:
                        err.add_to_error_path(key)
                        err.prepare()
                        raise
                    self[key] = obj  # whew! made it!