Skip to content
Python bindings to the Tree-sitter parsing library
C Python Shell Batchfile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
script Add windows CI Mar 22, 2019
tests Add assertion about sexp() method on a leaf node Jul 18, 2019
tree_sitter ⬆️ tree-sitter Jul 18, 2019
.appveyor.yml Avoid some compile warnings on windows Mar 22, 2019
.gitignore Add more Node APIs Mar 21, 2019
.gitmodules Initial commit Mar 20, 2019
.travis.yml Add Travis config file Mar 21, 2019
LICENSE Add license and readme Mar 21, 2019 Add Tree.edit Jun 13, 2019 0.0.8 Jul 18, 2019


Build Status Build status

This module provides Python bindings to the tree-sitter parsing library.


This package currently only works with Python 3. There are no library dependencies.

pip3 install tree_sitter



First you'll need a Tree-sitter language implementation for each language that you want to parse. You can clone some of the existing language repos or create your own:

git clone
git clone
git clone

Use the Language.build_library method to compile these into a library that's usable from Python. This function will return immediately if the library has already been compiled since the last time its source code was modified:

from tree_sitter import Language, Parser

  # Store the library in the `build` directory

  # Include one or more languages

Load the languages into your app as Language objects:

GO_LANGUAGE = Language('build/', 'go')
JS_LANGUAGE = Language('build/', 'javascript')
PY_LANGUAGE = Language('build/', 'python')

Basic Parsing

Create a Parser and configure it to use one of the languages:

parser = Parser()

Parse some source code:

tree = parser.parse(bytes("""
def foo():
    if bar:
""", "utf8"))

Inspect the resulting Tree:

root_node = tree.root_node
assert root_node.type == 'module'
assert root_node.start_point == (1, 0)
assert root_node.end_point == (3, 13)

function_node = root_node.children[0]
assert root_node.type == 'function_definition'

function_name_node = function_node.children[1]
assert function_name_node.type == 'identifier'
assert function_name_node.start_point == (1, 4)
assert function_name_node.end_point == (1, 7)

assert root_node.sexp() == ''

Walking Syntax Trees

If you need to traverse a large number of nodes efficiently, you can use a TreeCursor:

cursor = tree.walk()

assert cursor.node.type == 'module'

assert cursor.goto_first_child()
assert cursor.node.type == 'function_definition'

assert cursor.goto_first_child()
assert cursor.node.type == 'def'

# Returns `False` because the `def` node has no children
assert not cursor.goto_first_child()

assert cursor.goto_next_sibling()
assert cursor.node.type == 'identifier'

assert cursor.goto_next_sibling()
assert cursor.node.type == 'parameters'

assert cursor.goto_parent()
assert cursor.node.type == 'function_definition'


When a source file is edited, you can edit the syntax tree to keep it in sync with the source:

    start_byte = 5,
    old_end_byte = 5,
    new_end_byte = 5 + 2,
    start_point = (0, 5),
    old_end_point = (0, 5),
    new_end_point = (0, 5 + 2),

Then, when you're ready to incorporate the changes into a new syntax tree, you can call Parser.parse again, but pass in the old tree:

new_tree = parser.parse(new_source, tree)

This will run much faster than if you were parsing from scratch.

You can’t perform that action at this time.