Instagram / Instagram/LibCST

Cannot deep_replace multiple nodes

Open
#277 0 comments 0 reactions 0 assignees View on GitHub
enhancement machinery
Dominant language
Python
Stars
1.9k
Forks
229
PR merge metrics
No merged PRs in 30d

Description

One consequence of the issue mentioned [here](https://github.com/Instagram/LibCST/pull/269#issuecomment-604640756), where CSTTransformer always replaces nodes, is that methods that rely on nodes-by-identity become harder to use in bulk.

For example, I'm trying to implement a `rename(mod, src, dst)` function that takes all instances of a `src` variable and renames them to `dst`, using the `ScopeProvider`. However, this code does not work:

```python
for access in scope.accesses[src]:
mod = mod.deep_replace(access.node, cst.Name(dst))
```

This is because after the first `deep_replace`, all nodes have been replaced, and the original `scope` is now invalidated. To fix this, you either have to rebuild the scopes after every deep_replace (inefficient), or batch-replace all nodes at the same time.

Perhaps y'all can consider adding a `deep_replace_many`? That is, enhance the `_ChildReplacementTransformer` to take multiple nodes. For example, I'm using the following class:

```python

class ReplaceNodes(cst.CSTTransformer):
def __init__(self, replacements):
self.replacements = replacements

def on_leave(self, original_node, updated_node):
return self.replacements.get(original_node, updated_node)
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.