1. What dictation does to a sentence about Python
A speech model has never seen your repository. Say “why does send reminder email fire twice in invoice service” and it writes ordinary English: lowercase words, spaces where your underscores were, perhaps a capital at the start of the sentence. Library names get the same treatment, so pytest can come back as “pie test”, NumPy as “num pie”, and the .py on a file name as “pie” or “pi”. None of that is wrong as English. It just is not the identifier.
In a commit message the damage is cosmetic. In a prompt for Claude Code, Codex or Cursor it costs a search: the agent looks for a function that does not exist under the name you gave and settles on the closest match. In a pull request review the reader has to translate your sentence back into code. Speaking punctuation aloud (“send underscore reminder underscore email”) works but is slow. The better fix is a dictation tool that already knows which names your project contains.
2. PEP 8 names and how each one sounds
PEP 8, the style guide for Python code, fixes the shapes you will be saying. Function and variable names are lowercase, with words separated by underscores as needed for readability, and method names follow the same rule. Class names use CapWords, and exception classes end in Error. Constants are usually defined at module level in capital letters with underscores, such as MAX_OVERFLOW. Modules have short, all-lowercase names where underscores are allowed if they help readability; for packages, underscores are discouraged.
Two finer points matter once you speak. When a CapWords name contains an acronym, PEP 8 capitalizes the whole acronym, so HTTPServerError is preferred over HttpServerError. A single leading underscore marks a name for internal use, and names with double leading and trailing underscores, such as __init__ and __file__, are “magic” names you should never invent. File names carry conventions too: pytest collects tests from test_*.py and *_test.py files, and pyproject.toml is the configuration file that packaging tools, linters and type checkers read.
- send_reminder_email is said “send reminder email”; the underscores are silent.
- InvoiceService is said “invoice service”, the same two words as the module invoice_service.
- MAX_RETRIES is said “max retries”, which sounds exactly like the phrase in a sentence.
- _load_cache is said “load cache”; nobody pronounces the leading underscore.
- __init__ is said “dunder init” or just “init”, and neither spells the name.
3. Python names IraVoice types from your project
When you dictate into a recognized terminal, editor or coding agent on a Mac or Windows PC, IraVoice finds the Git project that app is working in and gathers its names: file and folder names, and the names your Python files declare with def and class, async def included. It keeps names only, never source text, skips secrets and dependency folders such as a virtual environment, and nothing leaves the computer. When a spoken phrase matches one of those names, the name is typed exactly as the project spells it, whatever capitalization the speech model chose.
Here is what those rules produce for a small billing project containing billing/invoice_service.py, billing/settings.py, tests/conftest.py, a test module and a pyproject.toml:
- “why does send reminder email fire twice” → why does send_reminder_email fire twice
- “add a retry to fetch exchange rates” → add a retry to fetch_exchange_rates
- “raise HTTP server error when the gateway times out” → raise HTTPServerError when the gateway times out
- “move the lookup into load cache” → move the lookup into _load_cache, leading underscore included
- “check conf test dot py for the stripe client fixture” → check conftest.py for the stripe_client fixture
- “update py project dot toml” → update pyproject.toml
- “pin it in requirements dot text” → pin it in requirements.txt, because a long name tolerates one slip
- “test refund rounds to cents fails” → test_refund_rounds_to_cents fails
4. Four Python cases that need a different phrase
What stays as words is just as deliberate. “Line item” remains two words even in a project with a LineItem class, because two everyday words never become an identifier on their own; three or more words, or one distinctive word, are needed. “The invoice model” stays prose because a one-word class such as Invoice has no underscore or inner capital, and IraVoice never forces a plain word into a sentence. Near misses are accepted only for names of ten or more letters, so “app dot pi” is not corrected to app.py. Beyond that, four Python habits need care.
A module and a class with the same words. invoice_service.py and class InvoiceService reduce to identical letters, and one phrase can only produce one name; in a layout like this, IraVoice types the module. An agent finds the class from its module easily, so in a prompt this rarely matters; in a review comment, fix the capitals by hand.
Module-level constants. MAX_RETRIES = 5 is a plain assignment with no def or class in front of it, so it may not be among the names IraVoice collects, and “bump max retries to 8” can stay as words. If you mention a constant often, add a Replacement that types MAX_RETRIES when you say “max retries”.
File names that mix underscores and an extension. For test_invoice_service.py, say the words and the extension without punctuation: “test invoice service py” arrives as test_invoice_service.py. Saying “dot” without also saying each “underscore” mixes two spellings, and you get test_invoice_service followed by “dot py”. A one-word file such as settings.py works either way, as “settings dot py” or “settings py”.
Dunder names. IraVoice does not treat __init__ or __init__.py as code-shaped names, so neither “init” nor “dunder init” changes. A Replacement that types __init__ when you say “dunder init” is the dependable answer.
5. pytest, NumPy and other names from outside the repository
Libraries you install are not part of your project’s own files, and IraVoice skips virtual environments, so pytest, NumPy and their kin are not in its list. Learned fixes cover them. Dictate the sentence, press Quick Fix (⌃⌥⇧F on a Mac, Ctrl+Alt+Shift+F on Windows and Linux), correct “pie test” to pytest in the window that opens, and press Enter. The corrected text is copied so you can paste it back, and IraVoice types pytest from then on. The tray menu’s Fix Last Dictation… item and History → Fix do the same. On a Mac, IraVoice also notices corrections you make by hand in most apps, by reading the text box it just typed into, once, on the computer.
A lesson applies everywhere you dictate, not only in Python projects, so teach pairs you only ever mean as code. Correcting “pedantic” to Pydantic would also rewrite the English word in your email. Only the word pairs are kept, and you can review or forget them under Advanced → Learn from my fixes.
Replacements suit fixed text: a phrase that should always type the same thing. Useful ones for Python work include “dunder init” → __init__, a constant you mention in every review, or “type hints note” for a sentence you paste into pull requests, such as a request to annotate the public functions in a module.
6. PyCharm, VS Code, notebooks and the alternatives
On a Mac, names are spelled in Terminal, iTerm2, Ghostty, Warp and the other recognized terminals, in VS Code, Cursor, Windsurf, Zed, Sublime Text and the JetBrains IDEs including PyCharm, and in the Claude and Codex desktop apps. On Windows the list includes Windows Terminal, PowerShell, cmd, VS Code, Cursor, Windsurf, Zed, PyCharm, IntelliJ IDEA and Visual Studio. A Jupyter notebook in a browser is not on either list, so dictation there is plain text; a notebook opened in VS Code is inside a recognized editor. On Linux, IraVoice is a beta that dictates without code names, and over SSH the names come only from a Git project on your own computer.
IraVoice is not voice programming. It will not type colons, brackets, operators or indentation, and Python’s significant whitespace makes dictating statements a poor fit for any plain dictation tool. Use it for the words around the code and let the agent or the editor write the code.
Other tools fit other needs. macOS Dictation and Windows voice typing (Win+H, which uses online speech recognition powered by Azure) are free and fine for prose, with no knowledge of your names. Claude Code’s /voice is tuned for coding vocabulary and adds your project and Git branch names as recognition hints, but it streams audio to Anthropic’s servers and needs a Claude.ai login. Talon is built for writing code by voice: its community commands include a force python language mode and formatters such as snake, which turns one two three into one_two_three. Serenade, an open-source speech-to-code tool that lists Python support, has had no commits in its public repository since its 2.0.2 release in July 2022.
IraVoice runs on macOS 13+ on Apple silicon, Windows 10 or 11 (64-bit), and Linux (beta), and it recognizes speech on the computer with NVIDIA Parakeet. Hold Right Command on a Mac or Right Ctrl on Windows, speak, release, and read the text before you send it; IraVoice does not press Enter by default. It costs $79 once for one computer, $109 for two, or $149 for three, after a 3-day free trial.