Browser-based Pyright

1.39.3 · active · verified Tue Apr 21

This package provides a browser-compatible build of `basedpyright`, an advanced static type checker for Python. As a fork of Microsoft's Pyright, `basedpyright` offers robust type analysis, diagnostic reporting, and language server capabilities. `browser-basedpyright` enables the integration of these features directly into web environments, such as online Python playgrounds, web-based IDEs, and educational tools, without requiring a Node.js backend. It follows a rapid release cadence, frequently updating to incorporate the latest upstream Pyright features and bug fixes, with the current stable version being `1.39.3`. Its primary differentiator is enabling comprehensive Python type checking entirely within the client-side browser context.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates how to initialize the `browser-basedpyright` language service in a browser environment, provide it with virtual Python code, and retrieve type diagnostics. It also shows how to update file content and re-evaluate diagnostics.

import { createLanguageService, createInMemoryLanguageServiceHost, type LanguageService } from 'browser-basedpyright';

// --- Setup the host for the language service ---
// This host simulates a file system and provides content for the language service.
const pythonCode = `
class MyClass:
    def __init__(self, name: str):
        self.name = name

    def greet(self) -> str:
        return f"Hello, {self.name}!"

def process_data(value: int):
    # This should be flagged if 'value' is not an int or if 'value' is a str
    if value == "test": # This will cause a pyright warning
        print("Test string")

obj = MyClass("World")
print(obj.greet())

process_data(123)
process_data("hello") # Pyright should flag this as type error
`;

const virtualFilePath = '/src/main.py';

const host = createInMemoryLanguageServiceHost({
  getOpenFileContents: (path: string) => {
    if (path === virtualFilePath) {
      return pythonCode;
    }
    return undefined; // Or throw error for unknown files
  },
  getWorkspaceFiles: () => [virtualFilePath],
  getPythonVersion: () => '3.10',
  getPyrightConfig: () => ({
    reportMissingImports: "warning",
    reportUnknownMemberType: "warning"
  }),
});

// --- Initialize the language service ---
const service: LanguageService = createLanguageService(host);

// --- Get diagnostics for the file ---
async function getAndPrintDiagnostics() {
  const diagnostics = await service.getDiagnostics(virtualFilePath);
  console.log(`Diagnostics for ${virtualFilePath}:`);
  if (diagnostics.length === 0) {
    console.log("No issues found.");
  } else {
    diagnostics.forEach(d => {
      console.log(`  [${d.severity}] ${d.message} at line ${d.range.start.line + 1}, col ${d.range.start.character + 1}`);
    });
  }
}

getAndPrintDiagnostics();

// Example of updating content and re-checking
setTimeout(async () => {
    const updatedCode = `
class AnotherClass:
    def say_hi(self):
        print("Hi!")

another_obj = AnotherClass()
another_obj.say_hi()

# Fix the previous error
def process_data_fixed(value: int):
    if value == 1:
        print("One")

process_data_fixed(42)
# process_data_fixed("oops") // This would still be an error if uncommented
`;
    host.setOpenFileContents(virtualFilePath, updatedCode);
    console.log("\n--- Updated code and re-checking ---");
    await getAndPrintDiagnostics();
}, 2000);

view raw JSON →