def __repr__(self):
        """Return nearest unambiguous string representation.

        Since the menu object is too complex to have its
        instantiation call or contents faithfully
        communicated through a string representation, we
        stick to returning the menu label and the string
        representation of each child.

        Overrides object.__repr__.
        """
        ### define a base text
        base_text = 'Menu "{}"'

        ### add the number of direct children
        base_text += " ({} direct children)".format(len(self.children))

        ### change the base text to indicate the menu is
        ### scrollable if it is the case
        if self.is_scrollable():
            base_text += " (scrollable)"

        ### finally return the base text plus each children
        ### string representation, separated by a new line
        ### character plus double dashes '--' multiplied
        ### by the number of parents until the top (the
        ### height of the menu branch)

        ## build the separator string

        # calculate height

        widget = self
        height = 0

        while True:

            try:
                parent = widget.parent

            except AttributeError:
                break

            else:

                height += 1
                widget = parent

        # use height to concatenate the separator
        sep = "\n" + "--" * height

        ## return the string representation
        return sep.join([base_text.format(self.label_text), *map(repr, self.children)])
Return nearest unambiguous string representation.

        Since the menu object is too complex to have its
        instantiation call or contents faithfully
        communicated through a string representation, we
        stick to returning the menu label and the string
        representation of each child.

        Overrides object.__repr__.
        
nodezator/menu/submenu/main.py