{"id":23514656,"url":"https://github.com/glyphack/enderpy","last_synced_at":"2025-04-04T14:07:48.589Z","repository":{"id":86252930,"uuid":"603158742","full_name":"Glyphack/enderpy","owner":"Glyphack","description":"WIP: Experimental Python Type Checker and LSP 🔎","archived":false,"fork":false,"pushed_at":"2024-10-17T15:43:31.000Z","size":2008,"stargazers_count":76,"open_issues_count":19,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-29T16:41:51.429Z","etag":null,"topics":["auto-com","auto-complete","language-server","lsp","python","rust","static-analysis","type-checker","type-inference"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Glyphack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-17T18:35:19.000Z","updated_at":"2024-10-21T09:19:59.000Z","dependencies_parsed_at":"2024-03-02T09:29:37.707Z","dependency_job_id":"94a6197f-bb4b-4cc5-9426-40c32535dc54","html_url":"https://github.com/Glyphack/enderpy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Glyphack%2Fenderpy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Glyphack%2Fenderpy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Glyphack%2Fenderpy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Glyphack%2Fenderpy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Glyphack","download_url":"https://codeload.github.com/Glyphack/enderpy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247190250,"owners_count":20898702,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auto-com","auto-complete","language-server","lsp","python","rust","static-analysis","type-checker","type-inference"],"created_at":"2024-12-25T14:06:02.415Z","updated_at":"2025-04-04T14:07:48.568Z","avatar_url":"https://github.com/Glyphack.png","language":"Rust","readme":"\u003c!-- markdownlint-configure-file {\n  \"MD033\": false,\n  \"MD041\": false\n} --\u003e\n\u003cdiv align=\"center\"\u003e\n\n\u003c!-- \u003cimg src=\"\" width=\"200\" height=\"100\"/\u003e --\u003e\n\n# Enderpy\n\nEnderpy is a code completion engine, static type checker \u0026 language server for python.\n\n🏗️The project is under active development. There are breaking changes, and it's not considered ready to use unless you want to contribute to it and have fun.\n\nhttps://github.com/Glyphack/enderpy/assets/20788334/c18720be-7a27-4cdb-a27c-5018597ba0cf\n\n\u003c/div\u003e\n\n## Why Do I Need It?\n\nit provides developers with fast autocompletion and fast feedback loop when writing Python.\n\n## Goals\n\n[Ruff](https://github.com/charliermarsh/ruff) showed that there is a value\nin providing faster implementation of static checkers.\n\nThis project aims to build the components needed to achieve the goal of\nproviding fast autocompletion and type checking, including:\n\n- Python parser\n- Python semantic analyzer \u0026 type checker\n- Python language server protocol implementation\n- CLI for parsing \u0026 analysis of Python programs\n\n## Development Setup\n\nClone the repository\n\n```\ngit submodule init\ngit submodule update\ncargo build\n```\n\nThe above test should run without any issues.\n\nThen use the [editor client](#open-in-editor). Currently, supported editors are:\n\n- [x] neovim\n- [x] vscode\n\n## Contributing\n\nIf you are here then you want to write some rust code, let's get to it.\nYou can [ send me a message ](discordapp.com/users/glyphack) for discussions/help.\n\nYou can use [these learning](https://glyphack.com/blog/compiler-resources/) resources\nto learn about each part of project.\n\nThe following will be a brief introduction into the project and how it works.\nBut it's always better to consult the code to see what exactly is going on.\n\n\n### Open In Editor\n\n#### vscode\n\n1. Open vscode\n2. Navigate to Run and Debug tab\n3. Select \"Launch Client\" and run the app\n\nBy default the extension uses `enderpy-lsp` command to run the language server.\nTo change it set the `SERVER_PATH` env variable to custom executable.\n\n#### neovim\n\nAdd the following snippet to your `init.lua` file.\n\n```lua\n-- Replace this ↓ with the actual path to your copy of the repository.\nlocal enderpy_path = \"/path/to/enderpy\"\nvim.api.nvim_create_autocmd(\"FileType\", {\n  pattern = \"python\",\n  callback = function()\n    vim.lsp.start({\n      name = \"enderpy\",\n      cmd = {enderpy_path .. \"/target/debug/enderpy-lsp\"},\n    })\n  end,\n})\n```\n\n### Core Concepts\n\nThe project consist of multiple crates each are separately published to crates.io:\n\n- parser: parser and lexer\n- typechecker: semantic analyzer and type checker\n- enderpy: the CLI for interacting with lexer, parser, and type checker\n- lsp: lsp for using with\n- client: editor clients for using the language server\n\nThe cli and lsp are two ways to use this project. For example this is what happens when you use enderpy in an editor:\n\n1. Editor connects to language server using the client extension\n2. Language server receives text edit events like file save and send them for analysis for diagnosis\n3. Typechecker uses parser to parse the code (code first goes through lexer and then parer) and get AST\n4. Typechecker runs the semantic analysis pass and then runs the type checking path\n5. Typechecker returns the errors to language server and language server sends them to editor\n6. Editor shows the messages to user\n\n\n### Tests\n\nAll the tests are done with [ insta.rs ](https://insta.rs/).\n\nIn each crate you find a folder called `test_data` which has inputs inside it.\nThese inputs are Python files that are used for testing that crate.\nFor example this is how the parser is tested againts the inputs:\nhttps://github.com/Glyphack/enderpy/blob/4a6f49d88965b774a6780bffb9563a4a87da974a/parser/src/parser/parser.rs#L3695\n\nWhen tests are run with insta they produce a snapshot that you can review,\nand after saving those snapshots they will be the expected output of the tests.\nRead the insta.rs documents to see how you can run and review tests.\n\n\n### Parsing Phase\n\nThe parsing phase is about taking Python source code and turning it into AST.\n\nThe [lexer](https://github.com/Glyphack/enderpy/blob/4a6f49d88965b774a6780bffb9563a4a87da974a/parser/src/lexer/lexer.rs#L1)\nis responsible for tokenizing the Python source code.\n\nThe [ parser ](https://github.com/Glyphack/enderpy/blob/4a6f49d88965b774a6780bffb9563a4a87da974a/parser/src/parser/parser.rs#L1)\nuses the output of lexer to read the tokens and produce AST.\n\nYou can see the output of each of these steps using the CLI tool(use the help to find how to use it).\n\nAlso to compare the results to Python you can use the following Python modules:\n- tokenizer: https://docs.python.org/3/library/tokenize.html\n- ast: https://docs.python.org/3/library/ast.html#ast.Module\n\n### Analysis Phase\n\nAnalysis phase starts with getting path to initial files to type check.\nThere's a struct called `Builder` which manages everything from getting the path to creating the diagnostics.\n\nThe `Builder` first resolves the imports in the initial files and import those for checking.\nThen it will do a first pass on the files to bind the definitions and store them in symbol table.\n\nProject uses visitor pattern to traverse the AST.\n\nPython has a symbol table that you can use to see symbol table for a program. There's a script in `./scripts` folder.\n\nAfter the symbol table is created bulider runs the typecheck for each file.\n\nAt the end builder populates errors in a list.\n\n## Usage\n\nThe project can be used in two ways, first as a CLI tool that can check your python projects, and also as a LSP inside an editor.\n\n### CLI\n\nThe following commands are available:\n\n```bash\nUsage: enderpy \u003cCOMMAND\u003e\n\nCommands:\n  tokenize  Print lexer tokens\n  parse     Print abstract syntax tree\n  check     Type check\n  symbols   Prints Symbol table\n  help      Print this message or the help of the given subcommand(s)\n```\n\n### LSP\n\nFor LSP you need to have the `enderpy-lsp` program installed, and then install the extention for your editor.\n\nLSP supports:\n\n- Type checking \u0026 showing diagnostic messages in files\n\n### Configuration\n\nThere are no configuration available currently. These are the default behavior of the program.\n\n**Project Root**: The path that is considered the project root. This affects import resolving, and gathering the files to check.\n\n**Python Executable**: The path to python executable. This is for resovling 3rd party dependencies.\n\n## Inspired By\n\n- [oxc](https://github.com/Boshen/oxc)\n- [ruff](https://github.com/charliermarsh/ruff)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglyphack%2Fenderpy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fglyphack%2Fenderpy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglyphack%2Fenderpy/lists"}