Git Product home page Git Product logo

glyphack / enderpy Goto Github PK

View Code? Open in Web Editor NEW
53.0 3.0 3.0 1.72 MB

WIP: Python Type Checker and LSP πŸ”Ž

Home Page: https://glyphack.notion.site/Enderpy-4b99306cbdbf4dccaa3b9a4363aa3d61

License: GNU Affero General Public License v3.0

Rust 96.63% Python 2.96% TypeScript 0.25% Makefile 0.06% JavaScript 0.10%
lsp python auto-complete language-server rust static-analysis type-checker type-inference auto-com

enderpy's Introduction

Enderpy

Enderpy is a code completion engine, static type checker & language server for python.

πŸ—οΈThe project is under active development. There are breaking changes and it's not consider ready to use unless you want to contribute to it and have fun.

Why Do I Need It?

it provides developers with faster autocompletion and fast feedback loop when writing Python.

Goals

The primary goal of this project is providing instant feedback as you type. Ruff showed that there is a value in providing faster implementation of static checkers. That's why I'm continuing this path.

This project aims to build the components needed to achieve the goal of providing fast autocompletion and type checking, including:

  • Python parser
  • Python semantic analyzer & type checker
  • Python language server protocol implementation
  • CLI for parsing & analysis of Python programs

Installation

cargo install enderpy_lsp

Then install the editor client. Currently supported editors are:

  • neovim
  • vscode

Building From Source

For building Rust components all you need to do is:

cargo run enderpy tokenize

For using the language client like VS VS Code, you can open the project in VS Code and use the Run & Debug tab to run the extention from source. For more information read: https://code.visualstudio.com/api/language-extensions/language-server-extension-guide

Contributing

If you are here then you want to write some rust code, let's get to it. You can send me a message for discussions/help.

You can use these learning resources to learn about each component.

The following will be a brief introduction into the project and how it works. But it's always better to consult the code to see what exactly is going on.

Developing Extension

  1. Open vscode
  2. Navigate to Run and Debug tab
  3. Select "Launch Client" and run the app

By default the extension uses enderpy-lsp command to run the language server. To change it set the SERVER_PATH env variable to custom executable.

Core Concepts

The project consist of multiple crates each are separately published to crates.io:

  • parser: parser and lexer
  • typechecker: semantic analyzer and type checker
  • enderpy: the CLI for interacting with lexer, parser, and type checker
  • lsp: lsp for using with
  • client: editor clients for using the language server

The cli and lsp are two ways to use this project. For example this is what happens when you use enderpy in an editor:

  1. Editor connects to language server using the client extension
  2. Language server receives text edit events like file save and send them for analysis for diagnosis
  3. Typechecker uses parser to parse the code (code first goes through lexer and then parer) and get AST
  4. Typechecker runs the semantic analysis pass and then runs the type checking path
  5. Typechecker returns the errors to language server and language server sends them to editor
  6. Editor shows the messages to user

Tests

All the tests are done with insta.rs .

In each crate you find a folder called test_data which has inputs inside it. These inputs are Python files that are used for testing that crate. For example this is how the parser is tested againts the inputs:

fn test_complete() {

When tests are run with insta they produce a snapshot that you can review, and after saving those snapshots they will be the expected output of the tests. Read the insta.rs documents to see how you can run and review tests.

Parsing Phase

The parsing phase is about taking Python source code and turning it into AST.

The lexer is responsible for tokenizing the Python source code.

The parser uses the output of lexer to read the tokens and produce AST.

You can see the output of each of these steps using the CLI tool(use the help to find how to use it).

Also to compare the results to Python you can use the following Python modules:

Analysis Phase

Analysis phase starts with getting path to initial files to type check. There's a struct called Builder which manages everything from getting the path to creating the diagnostics.

The Builder first resolves the imports in the initial files and import those for checking. Then it will do a first pass on the files to bind the definitions and store them in symbol table.

Project uses visitor pattern to traverse the AST.

Python has a symbol table that you can use to see symbol table for a program. There's a script in ./scripts folder.

After the symbol table is created bulider runs the typecheck for each file.

At the end builder populates errors in a list.

Usage

The 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.

CLI

The following commands are available:

Usage: enderpy <COMMAND>

Commands:
  tokenize  Print lexer tokens
  parse     Print abstract syntax tree
  check     Type check
  symbols   Prints Symbol table
  help      Print this message or the help of the given subcommand(s)

LSP

For LSP you need to have the enderpy-lsp program installed, and then install the extention for your editor.

LSP supports:

  • Type checking & showing diagnostic messages in files

Configuration

There are no configuration available currently. These are the default behavior of the program.

Project Root: The path that is considered the project root. This affects import resolving, and gathering the files to check.

Python Executable: The path to python executable. This is for resovling 3rd party dependencies.

Inspired By

enderpy's People

Contributors

frustak avatar ghodsizadeh avatar glyphack avatar limiteinductive avatar malivix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

enderpy's Issues

Use snapshot testing

Since there are a lot of code to test and most of it involves multiple asserts to check the lexer is doing alright it's good to use a snapshot testing framework and we only inspect the result.

Decide on a error handling pattern

Use a consistent way to report errors that happen inside the parser. Currently only panic is used to identify impossible cases(like trying to use 0b33 as a binary value).

Ellipsis in lexer and parser

A sequence of three periods has a special meaning as an ellipsis literal.
This has to be implemented in lexer and parser

Run tests in functions to avoid conflicts

Currently all snapshot tests are ran from snapshot_test_lexer. We can run tests from separate functions so insta will name their files differently, and two branches will not overwrite each other test cases. currently all tests are named the same and have a number that auto increments. we should have different names for different tests(like keywords, numbers, string literals).

Support type comments

If type_comments=True is given, the parser is modified to check and return type comments as specified by PEP 484 and PEP 526. This is equivalent to adding ast.PyCF_TYPE_COMMENTS to the flags passed to compile(). This will report syntax errors for misplaced type comments. Without this flag, type comments will be ignored, and the type_comment field on selected AST nodes will always be None. In addition, the locations of # type: ignore comments will be returned as the type_ignores attribute of Module (otherwise it is always an empty list).

Currently the comments are fully skipped. The correct way is to parse them and if they have valuable information put them in the ast.

Store numbers in correct types

The numbers are not stored as a type like f64 or i64. They are all strings now.

This requires refactoring in Lexer and in Parser.

The behavior must not change we already save numbers in a number like field but the value of it is just a string(or we can even not store the value) because it's not used.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.