<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/fwpython-part-1-setting-the-stage-i0w2jydk7" -->

---
title: FwPython, Part 1: Setting the Stage | daily.dev
description: Pyrefly developer Jia Chen introduces FwPython, a compact Python-like object-oriented language formalized in Lean 4, designed to stress-test the parts of...
canonical: https://daily.dev/posts/fwpython-part-1-setting-the-stage-i0w2jydk7
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: FwPython, Part 1: Setting the Stage | daily.dev
og:description: Pyrefly developer Jia Chen introduces FwPython, a compact Python-like object-oriented language formalized in Lean 4, designed to stress-test the parts of...
og:url: https://daily.dev/posts/fwpython-part-1-setting-the-stage-i0w2jydk7
og:image: https://api.daily.dev/og/posts/I0w2jyDK7.png
og:image:alt: FwPython, Part 1: Setting the Stage
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# FwPython, Part 1: Setting the Stage

**[Pyrefly: A Fast Python Type Checker and Language Server \| Pyrefly](https://daily.dev/sources/pyrefly)** · 11 min read · 0 upvotes · 0 comments

## Summary

Pyrefly developer Jia Chen introduces FwPython, a compact Python-like object-oriented language formalized in Lean 4, designed to stress-test the parts of Python's type system that checkers actually implement, such as method dispatch, isinstance narrowing, and callable subtyping. This first post in a series defines the source language (class table plus a nine-form expression language), its runtime model (heap objects, bound methods as the sole callable carrier, built-ins like Bool and NoneType as ordinary classes), and explains the deliberate omissions (no fields, mutation, constructors, generics, or descriptors) that keep the formal proofs tractable while still exposing real typing tradeoffs. Later posts will cover narrowing, negation types, subtyping, and gradual typing extensions. The project is open source on GitHub.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://pyrefly.org/blog/fwpython-part-1>

## Questions this post answers

### What is FwPython and why was it created?

FwPython is a compact, Python-like object-oriented language formalized in Lean 4, built to put controlled pressure on the parts of Python typing that type checkers actually have to reason about, such as narrowing in unions, isinstance interactions with Any, and callable intersections. It keeps nominal classes, multiple inheritance via C3 linearization, runtime method lookup, and first-class bound methods, but omits fields, mutation, constructors, generics, and descriptors to keep proofs tractable.

_Developers refining Python type checker behavior can follow formal typing research like this through daily.dev._

### How does FwPython handle bound methods differently from real Python?

FwPython collapses Python's many callable carriers (functions, lambdas, bound methods, descriptors, callable instances, class objects) into a single producer: method binding. Attribute access resolves a method through the receiver's MRO, allocates a BoundMethod heap object storing the receiver id and method declaration, and returns a reference to it, simplifying the callable typing rules the proofs rely on.

_Engineers comparing type checker internals can track deep dives like this on daily.dev._

### Why does FwPython's isinstance only accept a variable as its first argument?

Because isinstance in FwPython is also a narrowing construct: after the test, the type system refines the environment entry for that specific variable. Allowing an arbitrary expression as the first argument would require a separate account of what value is being tracked across the true and false branches, so the restriction keeps the narrowing semantics precise.

_Developers working through type narrowing edge cases can find explainers like this on daily.dev._

## Similar posts on daily.dev

- [Adopting Pyrefly as the Python type checker at Google](https://daily.dev/posts/adopting-pyrefly-as-the-python-type-checker-at-google-ixrvzgxi3) · Google Open Source Blog · 0 upvotes · 0 comments
- [Pyrefly 1.0: A fast, forward-looking Python linter](https://daily.dev/posts/pyrefly-1-0-a-fast-forward-looking-python-linter-k4vukcqpr) · InfoWorld · 0 upvotes · 0 comments
- [Pyrefly v1.4: Fewer false positives](https://daily.dev/posts/pyrefly-v1-4-fewer-false-positives-3ntvgylhx) · Pyrefly: A Fast Python Type Checker and Language Server \| Pyrefly · 0 upvotes · 0 comments

---

Tags: [#python](https://daily.dev/tags/python), [#type-systems](https://daily.dev/tags/type-systems)

[View this post on daily.dev](https://daily.dev/posts/fwpython-part-1-setting-the-stage-i0w2jydk7)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"FwPython, Part 1: Setting the Stage","url":"https://daily.dev/posts/fwpython-part-1-setting-the-stage-i0w2jydk7","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/fwpython-part-1-setting-the-stage-i0w2jydk7"},"datePublished":"2026-08-23T12:17:16.779Z","dateModified":"2026-08-23T12:24:22.431Z","description":"Pyrefly developer Jia Chen introduces FwPython, a compact Python-like object-oriented language formalized in Lean 4, designed to stress-test the parts of...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/ce7cceb523e1bdb0e6d2d6310d2d101d?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/ce7cceb523e1bdb0e6d2d6310d2d101d?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Pyrefly: A Fast Python Type Checker and Language Server | Pyrefly","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Pyrefly: A Fast Python Type Checker and Language Server | Pyrefly","logo":"https://media.daily.dev/image/upload/s--Qzw5NpnF--/c_limit,w_256/f_auto,q_auto/v1787487420/logos/pyrefly?_a=BAMAMicg0","url":"https://daily.dev/sources/pyrefly"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/fwpython-part-1-setting-the-stage-i0w2jydk7","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"python,type-systems","timeRequired":"PT11M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Pyrefly: A Fast Python Type Checker and Language Server | Pyrefly","item":"https://daily.dev/sources/pyrefly"},{"@type":"ListItem","position":3,"name":"FwPython, Part 1: Setting the Stage"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/fwpython-part-1-setting-the-stage-i0w2jydk7#faq","mainEntity":[{"@type":"Question","name":"What is FwPython and why was it created?","acceptedAnswer":{"@type":"Answer","text":"FwPython is a compact, Python-like object-oriented language formalized in Lean 4, built to put controlled pressure on the parts of Python typing that type checkers actually have to reason about, such as narrowing in unions, isinstance interactions with Any, and callable intersections. It keeps nominal classes, multiple inheritance via C3 linearization, runtime method lookup, and first-class bound methods, but omits fields, mutation, constructors, generics, and descriptors to keep proofs tractable. Developers refining Python type checker behavior can follow formal typing research like this through daily.dev."}},{"@type":"Question","name":"How does FwPython handle bound methods differently from real Python?","acceptedAnswer":{"@type":"Answer","text":"FwPython collapses Python's many callable carriers (functions, lambdas, bound methods, descriptors, callable instances, class objects) into a single producer: method binding. Attribute access resolves a method through the receiver's MRO, allocates a BoundMethod heap object storing the receiver id and method declaration, and returns a reference to it, simplifying the callable typing rules the proofs rely on. Engineers comparing type checker internals can track deep dives like this on daily.dev."}},{"@type":"Question","name":"Why does FwPython's isinstance only accept a variable as its first argument?","acceptedAnswer":{"@type":"Answer","text":"Because isinstance in FwPython is also a narrowing construct: after the test, the type system refines the environment entry for that specific variable. Allowing an arbitrary expression as the first argument would require a separate account of what value is being tracked across the true and false branches, so the restriction keeps the narrowing semantics precise. Developers working through type narrowing edge cases can find explainers like this on daily.dev."}}]}
```

