pypet/naturalnaming.py
def _add_generic(self, start_node, type_name, group_type_name, args, kwargs,
                     add_prefix=True, check_naming=True):
        """Adds a given item to the tree irrespective of the subtree.

        Infers the subtree from the arguments.

        :param start_node: The parental node the adding was initiated from

        :param type_name:

            The type of the new instance. Whether it is a parameter, parameter group, config,
            config group, etc. See the name of the corresponding constants at the top of this
            python module.


        :param group_type_name:

            Type of the subbranch. i.e. whether the item is added to the 'parameters',
            'results' etc. These subbranch types are named as the group names
            (e.g. 'PARAMETER_GROUP') in order to have less constants.
            For all constants used see beginning of this python module.

        :param args:

            Arguments specifying how the item is added.

            If len(args)==1 and the argument is the a given instance of a result or parameter,
            this one is added to the tree.

            Otherwise it is checked if the first argument is a class specifying how to
            construct a new item and the second argument is the name of the new class.

            If the first argument is not a class but a string, the string is assumed to be
            the name of the new instance.

            Additional args are later on used for the construction of the instance.

        :param kwargs:

            Additional keyword arguments that might be handed over to the instance constructor.

        :param add_prefix:

            If a prefix group, i.e. `results`, `config`, etc. should be added

        :param check_naming:

            If it should be checked for correct namings, can be set to ``False`` if data is loaded
            and we know that all names are correct.

        :return: The new added instance

        """
        args = list(args)
        create_new = True
        name = ''
        instance = None
        constructor = None

        add_link = type_name == LINK

        # First check if the item is already a given instance or we want to add a link
        if add_link:
            name = args[0]
            instance = args[1]
            create_new = False
        elif len(args) == 1 and len(kwargs) == 0:
            item = args[0]
            try:
                name = item.v_full_name
                instance = item

                create_new = False
            except AttributeError:
                pass

        # If the item is not an instance yet, check if args[0] is a class and args[1] is
        # a string describing the new name of the instance.
        # If args[0] is not a class it is assumed to be the name of the new instance.
        if create_new:
            if len(args) > 0 and inspect.isclass(args[0]):
                constructor = args.pop(0)
            if len(args) > 0 and isinstance(args[0], str):
                name = args.pop(0)
            elif 'name' in kwargs:
                name = kwargs.pop('name')
            elif 'full_name' in kwargs:
                name = kwargs.pop('full_name')
            else:
                raise ValueError('Could not determine a name of the new item you want to add. '
                                 'Either pass the name as positional argument or as a keyword '
                                 'argument `name`.')

        split_names = name.split('.')
        if check_naming:

            for idx, name in enumerate(split_names):
                translated_shortcut, name = self._translate_shortcut(name)
                replaced, name = self._replace_wildcards(name)
                if translated_shortcut or replaced:
                    split_names[idx] = name

            # First check if the naming of the new item is appropriate
            faulty_names = self._check_names(split_names, start_node)

            if faulty_names:
                full_name = '.'.join(split_names)
                raise ValueError(
                    'Your Parameter/Result/Node `%s` contains the following not admissible names: '
                    '%s please choose other names.' % (full_name, faulty_names))

            if add_link:
                if instance is None:
                    raise ValueError('You must provide an instance to link to!')
                if instance.v_is_root:
                    raise ValueError('You cannot create a link to the root node')
                if start_node.v_is_root and name in SUBTREE_MAPPING:
                    raise ValueError('`%s` is a reserved name for a group under root.' % name)
                if not self._root_instance.f_contains(instance, with_links=False, shortcuts=False):
                    raise ValueError('You can only link to items within the trajectory tree!')

        # Check if the name fulfils the prefix conditions, if not change the name accordingly.
        if add_prefix:
            split_names = self._add_prefix(split_names, start_node, group_type_name)

        if group_type_name == GROUP:
            add_leaf = type_name != group_type_name and not add_link
            # If this is equal we add a group node
            group_type_name, type_name = self._determine_types(start_node, split_names[0],
                                                               add_leaf, add_link)

        # Check if we are allowed to add the data
        if self._root_instance._is_run and type_name in SENSITIVE_TYPES:
            raise TypeError('You are not allowed to add config or parameter data or groups '
                            'during a single run.')

        return self._add_to_tree(start_node, split_names, type_name, group_type_name, instance,
                                 constructor, args, kwargs)
def _add_generic(self, start_node, type_name, group_type_name, args, kwargs,
                     add_prefix=True, check_naming=True):
        """Adds a given item to the tree irrespective of the subtree.

        Infers the subtree from the arguments.

        :param start_node: The parental node the adding was initiated from

        :param type_name:

            The type of the new instance. Whether it is a parameter, parameter group, config,
            config group, etc. See the name of the corresponding constants at the top of this
            python module.


        :param group_type_name:

            Type of the subbranch. i.e. whether the item is added to the 'parameters',
            'results' etc. These subbranch types are named as the group names
            (e.g. 'PARAMETER_GROUP') in order to have less constants.
            For all constants used see beginning of this python module.

        :param args:

            Arguments specifying how the item is added.

            If len(args)==1 and the argument is the a given instance of a result or parameter,
            this one is added to the tree.

            Otherwise it is checked if the first argument is a class specifying how to
            construct a new item and the second argument is the name of the new class.

            If the first argument is not a class but a string, the string is assumed to be
            the name of the new instance.

            Additional args are later on used for the construction of the instance.

        :param kwargs:

            Additional keyword arguments that might be handed over to the instance constructor.

        :param add_prefix:

            If a prefix group, i.e. `results`, `config`, etc. should be added

        :param check_naming:

            If it should be checked for correct namings, can be set to ``False`` if data is loaded
            and we know that all names are correct.

        :return: The new added instance

        """
        args = list(args)
        create_new = True
        name = ''
        instance = None
        constructor = None

        add_link = type_name == LINK

        # First check if the item is already a given instance or we want to add a link
        if add_link:
            name = args[0]
            instance = args[1]
            create_new = False
        elif len(args) == 1 and len(kwargs) == 0:
            item = args[0]
            try:
                name = item.v_full_name
                instance = item

                create_new = False
            except AttributeError:
                pass

        # If the item is not an instance yet, check if args[0] is a class and args[1] is
        # a string describing the new name of the instance.
        # If args[0] is not a class it is assumed to be the name of the new instance.
        if create_new:
            if len(args) > 0 and inspect.isclass(args[0]):
                constructor = args.pop(0)
            if len(args) > 0 and isinstance(args[0], str):
                name = args.pop(0)
            elif 'name' in kwargs:
                name = kwargs.pop('name')
            elif 'full_name' in kwargs:
                name = kwargs.pop('full_name')
            else:
                raise ValueError('Could not determine a name of the new item you want to add. '
                                 'Either pass the name as positional argument or as a keyword '
                                 'argument `name`.')

        split_names = name.split('.')
        if check_naming:

            for idx, name in enumerate(split_names):
                translated_shortcut, name = self._translate_shortcut(name)
                replaced, name = self._replace_wildcards(name)
                if translated_shortcut or replaced:
                    split_names[idx] = name

            # First check if the naming of the new item is appropriate
            faulty_names = self._check_names(split_names, start_node)

            if faulty_names:
                full_name = '.'.join(split_names)
                raise ValueError(
                    'Your Parameter/Result/Node `%s` contains the following not admissible names: '
                    '%s please choose other names.' % (full_name, faulty_names))

            if add_link:
                if instance is None:
                    raise ValueError('You must provide an instance to link to!')
                if instance.v_is_root:
                    raise ValueError('You cannot create a link to the root node')
                if start_node.v_is_root and name in SUBTREE_MAPPING:
                    raise ValueError('`%s` is a reserved name for a group under root.' % name)
                if not self._root_instance.f_contains(instance, with_links=False, shortcuts=False):
                    raise ValueError('You can only link to items within the trajectory tree!')

        # Check if the name fulfils the prefix conditions, if not change the name accordingly.
        if add_prefix:
            split_names = self._add_prefix(split_names, start_node, group_type_name)

        if group_type_name == GROUP:
            add_leaf = type_name != group_type_name and not add_link
            # If this is equal we add a group node
            group_type_name, type_name = self._determine_types(start_node, split_names[0],
                                                               add_leaf, add_link)

        # Check if we are allowed to add the data
        if self._root_instance._is_run and type_name in SENSITIVE_TYPES:
            raise TypeError('You are not allowed to add config or parameter data or groups '
                            'during a single run.')

        return self._add_to_tree(start_node, split_names, type_name, group_type_name, instance,
                                 constructor, args, kwargs)
Adds a given item to the tree irrespective of the subtree.

        Infers the subtree from the arguments.

        :param start_node: The parental node the adding was initiated from

        :param type_name:

            The type of the new instance. Whether it is a parameter, parameter group, config,
            config group, etc. See the name of the corresponding constants at the top of this
            python module.


        :param group_type_name:

            Type of the subbranch. i.e. whether the item is added to the 'parameters',
            'results' etc. These subbranch types are named as the group names
            (e.g. 'PARAMETER_GROUP') in order to have less constants.
            For all constants used see beginning of this python module.

        :param args:

            Arguments specifying how the item is added.

            If len(args)==1 and the argument is the a given instance of a result or parameter,
            this one is added to the tree.

            Otherwise it is checked if the first argument is a class specifying how to
            construct a new item and the second argument is the name of the new class.

            If the first argument is not a class but a string, the string is assumed to be
            the name of the new instance.

            Additional args are later on used for the construction of the instance.

        :param kwargs:

            Additional keyword arguments that might be handed over to the instance constructor.

        :param add_prefix:

            If a prefix group, i.e. `results`, `config`, etc. should be added

        :param check_naming:

            If it should be checked for correct namings, can be set to ``False`` if data is loaded
            and we know that all names are correct.

        :return: The new added instance