Exemple #1
0
def _get_prefix(node):
    """Find the indentation used by `node`.

    This function ignores newlines and just gets the spaces / tabs used.

    Args:
        node (:class:`parso.python.tree.PythonBaseNode`):
            A parso object that is assumed to define a "requires" attribute.

    Returns:
        str: The leading indentation found, if any.

    """
    prefixes = set()

    for child in _get_inner_list_entries(node):
        prefix_node = node_seek.get_node_with_first_prefix(child)
        prefixes.add(prefix_node.prefix)

    counter = collections.Counter(prefixes)

    try:
        common = counter.most_common(1)[0]

        return common[0].strip("\n")
    except IndexError:
        return ""
    def _adjust_prefix(node):
        """Put `node` on its own line but retain its original leading indent."""
        prefix_node = node_seek.get_node_with_first_prefix(node)
        original = prefix_node.prefix
        prefix_node.prefix = "\n{original}".format(original=original)

        return original
def _replace_namespace(nodes, old_parts, new_parts, partial=False):
    """Change `nodes` into an import resembling the Python namespace defined by `new_parts`.

    If there's no common namespace between `nodes` and `old_parts` then
    this function does nothing.

    Args:
        node (:class:`parso.python.tree.ImportFrom`):
            A parso object that represents a Python import.
        old_parts (list[str]):
            The namespace that is expected to be all or part of the
            namespace that `node` defines.
        new_parts (list[str]):
            The namespace to replace `node` with. e.g. ["foo", "bar"].

    """

    def _is_fully_defined_by(names, parts):
        for index, name in enumerate(names):
            try:
                part = parts[index]
            except IndexError:
                return False

            if part != name:
                return False

        return True

    names = [
        child
        for node in nodes
        for child in itertools.chain([node], node_seek.iter_nested_children(node))
        if isinstance(child, tree.Name)
    ]
    prefix = node_seek.get_node_with_first_prefix(names[0]).prefix
    start, end = import_helper.get_replacement_indices(names, old_parts)

    if start == -1 or end == -1:
        # There's nothing to replace, in this case
        return

    if not partial and not _is_fully_defined_by(
        [name.value for name in names], old_parts
    ):
        return

    new_nodes = import_helper.make_replacement_nodes(new_parts, prefix)
    names[0].parent.children[start : end + 1] = new_nodes
Exemple #4
0
 def test_nested_prefix(self):
     """Get the prefix of a node whose prefix is stored in one of its child nodes."""
     graph = parso.parse(
         textwrap.dedent(
             """\
             foo = [
                 blah,
                     another,
             ]
             """
         )
     )
     name_node = graph.get_first_leaf()
     self.assertEqual(
         name_node,
         node_seek.get_node_with_first_prefix(graph),
     )
Exemple #5
0
 def test_current_node(self):
     """Get the given node assuming it defines its own prefix."""
     graph = parso.parse(
         textwrap.dedent(
             """\
             foo = [
                 blah,
                     another,
             ]
             """
         )
     )
     name_node = graph.get_first_leaf()
     self.assertEqual(
         name_node,
         node_seek.get_node_with_first_prefix(name_node),
     )
Exemple #6
0
def insert_or_append_raw_node(node, graph, assignment, attribute):
    """Add a new `attribute` to `graph`, according to pre-existing data.

    Args:
        node (:class:`parso.python.tree.PythonNode`):
            The main data that will be added to `graph`.
        graph (:class:`parso.python.tree.PythonNode`):
            A Python module that may already contain an assignment for
            `attribute`. If it doesn't the attribute will be added,
            automatically.
        assignment (:class:`parso.python.tree.PythonNode` or NoneType):
            If `graph` has an existing node where `attribute` is
            defined, this node will represent that position. If this
            parameter is None, a new position for `attribute` will be
            automatically found and used.
        attribute (str):
            The name of the Rez-related object to use.

    Returns:
        :class:`parso.python.tree.PythonNode`: The main module with a modified `attribute`.

    """
    if assignment:
        index = _find_nearest_node_index(graph.children, attribute)
        del graph.children[index]
        graph.children.insert(index, tree.PythonNode("assignment", [node]))

        return graph

    index = _find_nearest_node_index(graph.children, attribute)

    if index == -1:
        graph.children.append(tree.PythonNode("assignment", [node]))

        return graph

    prefix_node = node_seek.get_node_with_first_prefix(node)
    prefix_node.prefix = "\n\n"
    graph.children.insert(index, tree.PythonNode("assignment", [node]))

    return graph
Exemple #7
0
def _adjust_prefix(nodes, index):
    """Remove whitespace information or add it, if needed.

    This function should be applied directly to whatever node lies
    **after** the Rez attribute that was inserted.

    The logic goes like this.

    - If the index after the inserted attribute doesn't have an
      EndMarker then that means the attribute was inserted at the end of the
      parso graph
      - This means the attribute is at the end of the parsed graph.
      - Because it's at the end, we don't need any newlines.
    - If the index does exist but it's at the end of the graph, same
      thing. We don't need newlines.
    - If there's a node after `index` and it's not an EndMarker then that means
      the inserted attribute was inserted between two parso nodes. Which
      means it's in the middle of the file.
      - Add 2 newlines

    Args:
        nodes (iter[:class:`parso.python.tree.PythonNode`]): The direct children
            of a Rez package.py which had some attribute inserted.
        index (int): The 0-based position where the attribute was inserted.

    """
    try:
        marker = nodes[index + 1]
    except IndexError:
        return

    node = node_seek.get_node_with_first_prefix(marker)

    if isinstance(node, tree.EndMarker):
        node.prefix = ""

        return

    if hasattr(node, "prefix"):
        node.prefix = "\n\n"