Skip to main content

Turbo Python

A Python IDE in the shape of Turbo Pascal 7.0: a desktop of windows, a menu bar, a status line, and the compile-land-on-the-error-fix-recompile loop that made the original worth using.

   File  Edit  Search  Run  Compile  Debug  Tools  Options  Window  Help
╔[■]════════════════════════════ GREET.PY ═════════════════════════════ 1 [↑]╗
║ 1 def greet(name):                                                         ║
║ 2     """Say hello."""                                                     ║
║ 3     return f"hello {name}"                                               ║
║ 4                                                                          ║
║ 5                                                                          ║
║ 6 for who in ['world', 'turbodesk']:                                       ║
║ 7     print(greet(who))                                                    ║
║ 8                                                                          ║
║                                                                            ║
╚  1:1 ══════════════════════════════════════════════════════════════════════◢
 F1 Help  F2 Save  F3 Open  Alt+F9 Compile  F9 Make  F10 Menu

Run it

uv sync
uv run turbopython greet.py

F10 opens the menu bar and File ▸ Exit leaves, so there is a way out before you have learned a single key.

What it does today

Run a program and land on the line that broke it. A traceback goes into the Messages window as a jump list, and the cursor lands on the deepest frame in your code — not the one inside json/decoder.py, which is not a file you can fix.

Compile without running. Alt-F9 is compile(src, name, "exec"): instant, and a SyntaxError puts the message on the window's top line with the cursor on the column it names.

Make and test the way Python projects actually do. Compile ▸ Make reads the nearest Makefile and lists its targets; Run ▸ Tests runs pytest and puts every failure where Enter jumps to it. Borland's Make byte-compiled the units a program needed, which is a step Python does for itself.

   File  Edit  Search  Run  Compile  Debug  Tools  Options  Window  Help
╔[■]══════════════════┌────────────────────────┐═══════════════════════ 1 [↑]╗
║ 1 def greet(name):  │ Run            Ctrl-F9 │                             ║
║ 2     """Say hello."│ Tests                  │                             ║
║ 3     return f"hello├────────────────────────┤                             ║
║ 4                   │ Step over           F8 │                             ║
║ 5                   │ Trace into          F7 │                             ║
║ 6 for who in ['world│ Go to cursor        F4 │                             ║
║ 7     print(greet(wh├────────────────────────┤                             ║
║ 8                   │ Program reset  Ctrl-F2 │                             ║
║                     │ Parameters...          │                             ║
║                     └────────────────────────┘                             ║
╚  1:1 ══════════════════════════════════════════════════════════════════════◢
 F1 Help  F2 Save  F3 Open  Alt+F9 Compile  F9 Make  F10 Menu

Greyed items are the ones with nothing behind them right now — no window open, no program running — which is how Borland's menus worked. It is worth knowing what that greying cannot tell you: an item naming a command nobody ever wrote greys identically, and three of those sat on these menus for months. A test now reads commands.py and fails if a menu item names something unimplemented.

See the shape of the project. Search ▸ Outline docks a window showing what is in the file in front, rebuilt from the live buffer as you type. Search ▸ Class browser is the same ast walk read across every file: what derives from what, project-wide, with the module beside each class. Arrows walk either one and open the file it names; Space folds. Both are stdlib and neither needs a language server. Ctrl+Enter on a name goes to where this file defines it, and looks for a module only when it does not.

A language server, when there is one. ruff server starts in the background after the first frame and never before it: the IDE is up and working without one, which is the rule the whole layer is built to. Diagnostics land in the Messages window as the same jump list the compiler's errors and the test failures use — Enter goes to the line. Tools ▸ Diagnostics lists them, and the status line says which mode you are in (lsp, lsp down, or nothing at all when none was asked for). No node runtime, and nothing on any menu exists only when a server is running.

Find a file by typing at it. File ▸ Find file (Shift-F3) is a fuzzy picker over the project — wfr finds widgets/frame.py. F3 still opens the tree, because the two answer different questions: one is for looking around, the other for when you already know the name.

A primary file, which is what 7.0 called a run configuration. Compile ▸ Primary file... names the program Run acts on however many windows are open over it, so editing a module and pressing Run does not run the module. Clear primary file gives the front window back.

An editor with the things an editor needs. Syntax colouring, line numbers, find and replace, undo that groups a run of keystrokes, standard / vim / emacs keymaps, and a mouse that puts the caret where you press and selects what you drag over.

Windows. Overlapping, draggable by the title bar, resizable from any corner, zoom, tile, cascade. Alt-1 to Alt-9 raise one by number.

Ruff, mypy and pytest in the Tools menu, each parsed into the same jump list.

Keys

Two schemes, and it asks which on first run rather than guessing:

  • Turbo Pascal — what Borland shipped. Needs a terminal that sends Alt.
  • Modern — every Turbo binding that works anyway, plus a second key for each one Borland put on Alt: F7 for Alt-F9, F12 for Alt-F5, Ctrl-W for Alt-F3, Ctrl-Q for Alt-X.

macOS sends no Alt by default. The Option key composes characters there — Option-E then e is é — so Alt-X never arrives. Modern is the default on a Mac, and Help ▸ Key test says which setting turns Alt on for your terminal (Use Option as Meta key in Terminal.app, Esc+ in iTerm2).

The menu shows the key the active scheme binds, so an accelerator never promises something that does nothing.

What it is not, yet

No debugger. That is the next milestone: breakpoints in the gutter, step and trace, a watch window and the call stack, over bdb in a subprocess. No class browser, no project files, no REPL window. notes/turbopython-ide.md in this repository is the plan, and it is honest about what is missing.

Why it exists

It is the largest application built on turbodesk, and it was built to find out what the library was missing. It found a great deal: the window stack, the menu bar, focus groups, drag gestures, an editor gutter and syntax colouring are all in the library now because this needed them. notes/turbodesk-roadmap.md records that trade in both directions.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

turbopython_ide-0.5.0.tar.gz (78.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

turbopython_ide-0.5.0-py3-none-any.whl (92.3 kB view details)

Uploaded Python 3

File details

Details for the file turbopython_ide-0.5.0.tar.gz.

File metadata

  • Download URL: turbopython_ide-0.5.0.tar.gz
  • Upload date:
  • Size: 78.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for turbopython_ide-0.5.0.tar.gz
Algorithm Hash digest
SHA256 53ba8b4630afe67005aa98245cd897f8bf2977fc2ec12d322eb1ce66682a9e05
MD5 f51720f6379ef50c880c0cffa1f784fa
BLAKE2b-256 089ebc38396a05637f45290523bb789b126c5731e48c994d5a6bc46edafb550a

See more details on using hashes here.

File details

Details for the file turbopython_ide-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: turbopython_ide-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 92.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for turbopython_ide-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b1cf1a3293883270c333564199ab591445481b1fb5b7ba5f3c4a6e92f5487ac2
MD5 0d6777394b1e1c1ef0f92ba6cf9e27f3
BLAKE2b-256 1a6eddc91c395bd260faa884ce962d91ebc9c0665f6a39d1d7b20de9e09daec7

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page