Modifying — RedBaron 0.8 documentation

# Modifying

## Principle

When it comes to modifying the tree, the normal classical way would tell you to use the RedBaron nodes constructors, like this:

    In [1]: from redbaron import RedBaron, NameNode

    In [2]: red = RedBaron("a = 1")

    In [3]: red[0].value
    Out[3]: 1

    In [4]: red[0].value = NameNode({'first_formatting': [{'type': 'space', 'value': ' '}], 'value': '+', 'second_formatting': [{'type': 'space', 'value': ' '}], 'second': {'section': 'number', 'type': 'int', 'value': '1'}, 'type': 'binary_operator', 'first': {'section': 'number', 'type': 'int', 'value': '1'}})

    In [5]: red
    Out[5]: 0   a = 1 + 1

As you can see, this is totally impracticable. So, to solve this problem, RedBaron adopt a simple logic: you already know how to code in python, so, just send python code in form of a string, RedBaron will takes care or parsing and injecting it into its tree. This give an extremely simple and intuitive API:

    In [6]: red = RedBaron("a = 1")

    In [7]: red[0].value
    Out[7]: 1

    In [8]: red[0].value = "1 + 1"

    In [9]: red
    Out[9]: 0   a = 1 + 1

The details on how you can modify every nodes can be found here: Nodes References Page.

## Code block modifications

The modification of python code block (like the body of a function or a while loop) is also possible this way. RedBaron will takes care for you or formatting you input the right way (adding surrounding blank lines and settings the correct indentation for the every line).

Example:

    In [10]: red = RedBaron("while True: pass")

    In [11]: red[0].value = "plop"

    In [12]: red
    Out[12]:
    0   while True:
            plop

    In [13]: red[0].value = "                        this_will_be_correctly_indented"

    In [14]: red
    Out[14]:
    0   while True:
            this_will_be_correctly_indented

You have the full list of cases handled on this page: Nodes References Page.

## Details

As you might have already noticed, you can set attributes of a node with a string or a RedBaron node. This is also possible by directly passing FST.

Here is an IPython session illustrating all the possibilities (be sure to have read the “node structures” in basics to understand what is happening):

    In [15]: from redbaron import RedBaron

    In [16]: red = RedBaron("a = b")

### Data attribute, no parsing

    In [17]: red.name.help()
    NameNode()
      # identifiers: name, name_, namenode
      value='a'

    In [18]: red.name.value = "something_else"

    In [19]: red
    Out[19]: 0   something_else = b

### Node attribute with a string: parsing with RedBaron

    In [20]: red[0].help()
    AssignmentNode()
      # identifiers: assign, assignment, assignment_, assignmentnode
      operator=''
      target ->
        NameNode()
          # identifiers: name, name_, namenode
          value='something_else'
      annotation ->
        None
      value ->
        NameNode()
          # identifiers: name, name_, namenode
          value='b'

    In [21]: red[0].value = "42 * pouet"

    In [22]: red
    Out[22]: 0   something_else = 42 * pouet

### Node attribute with FST data: transformation into RedBaron objects

    In [23]: red[0].value = {"type": "name", "value": "pouet"}

    In [24]: red
    Out[24]: 0   something_else = pouet

### List attribute with a string: parsing with RedBaron

    In [25]: red = RedBaron("[1, 2, 3]")

    In [26]: red[0].help()
    ListNode()
      # identifiers: list, list_, listnode
      value ->
        * IntNode()
            # identifiers: int, int_, intnode
            value='1'
        * IntNode()
            # identifiers: int, int_, intnode
            value='2'
        * IntNode()
            # identifiers: int, int_, intnode
            value='3'

    In [27]: red[0].value = "caramba"

    In [28]: red
    Out[28]: 0   [caramba]

    In [29]: red[0].value = "4, 5, 6"

    In [30]: red
    Out[30]: 0   [4, 5, 6]

### List node attribute with FST: transformation into RedBaron objects

    In [31]: red[0].value = {"type": "name", "value": "pouet"}

    In [32]: red
    Out[32]: 0   [pouet]

    In [33]: red[0].value = [{"type": "name", "value": "pouet"}]

    In [34]: red
    Out[34]: 0   [pouet]

### List node attribute with mixed content: parsing/transformation depending of the context

    In [35]: red[0].value = [{"type": "name", "value": "pouet"}, {"type": "comma", "first_formatting": [], "second_formatting": []}, "pouet ,", NameNode({"type": "name", "value": "plop"})]

    In [36]: red
    Out[36]: 0   [pouet,pouet ,plop]

## Auto assignment of .parent and .on_attribute

When you modify an attribute of a node or a node list, RedBaron will take care of setting the `.parent` value of the new attribute to the corresponding node.

This will be done if you set the attribute value using either a `string`, a `fst node`, an instance of a node or a node list.

The same is done for `.on_attribute`.

### Next

To learn how to work with list of things in RedBaron read Proxy List.