PyCon 2016
Anthony Scopatz argues Python's dynamic AST manipulation and signal handling make it uniquely qualified to replace fragile Unix shells without sacrificing existing POSIX workflows.
AI-assisted summary of Anthony Scopatz - xonsh - PyCon 2016 — original source. Check the original for full context.
Source published:
Key ideas
- Anthony Scopatz introduces xonsh at PyCon 2016, a cross-platform command-line shell combining Python with features from Bash, Zsh, and Fish that relies solely on Python's standard library and PLY. (0:01)
- The xonsh language operates as a strict superset of Python that compiles into standard Python AST nodes, allowing seamless intermixing of shell commands and pure Python code. (17:01)
- A foreign shell execution bridge enables sourcing existing Bash, Zsh, and cmd.exe scripts to load environment variables, aliases, and shell functions directly into the xonsh runtime. (13:14)
- The shell features native Jupyter notebook hooks, importable .xsh script files, in-memory tab completions, and terminal-rendered Matplotlib graphics. (15:33)
Detailed notes
## Background Published on YouTube by the PyCon 2016 channel on May 31, 2016, this talk features speaker Anthony Scopatz presenting xonsh. The page description details xonsh as a general-purpose shell combining Python with the best features of Bash, Zsh, and Fish, compiling directly to a Python AST with zero external dependencies beyond Python and PLY.
## TL;DR Scopatz introduces xonsh, an interactive command-line shell and general-purpose scripting language that functions as a strict superset of Python while integrating native POSIX shell primitives. He demonstrates how xonsh seamlessly bridges Python objects and subprocess execution using syntax like `@()` argument expansion, `!()` command capture, callable Python aliases, and regex-based file globbing. The architecture relies on PLY and a two-phase syntax tree transformation that compiles ambiguous commands into standard Python AST nodes, allowing direct execution via Python's native runtime. Addressing practical integrations, Scopatz outlines foreign shell bridging for Bash and Zsh environments, script execution via `.xsh` files, and dynamic integrations with packages like Matplotlib and NLTK before answering audience questions about prompt customization, startup performance, and line-editing backends.
## Atmosphere & style The presentation is energetic, lighthearted, and deeply pragmatic, driven by Scopatz's self-deprecating humor and candid technical admissions. Despite an early on-stage display hiccup, he maintains effortless rapport with the audience, drawing frequent laughs when poking fun at Bash's clunky conventions and confessing that his slick terminal demonstrations were actually simulated keystroke playbacks. The session feels like an enthusiastic open-source workshop where complex language parsing and compiler concepts are demystified with clarity, wit, and contagious enthusiasm.
## Bulletin - [00:01](https://www.youtube.com/watch?v=uaje5I22kgE&t=1s) Anthony Scopatz introduces xonsh at PyCon 2016, a cross-platform command-line shell combining Python with features from Bash, Zsh, and Fish that relies solely on Python's standard library and PLY. - [17:01](https://www.youtube.com/watch?v=uaje5I22kgE&t=1021s) The xonsh language operates as a strict superset of Python that compiles into standard Python AST nodes, allowing seamless intermixing of shell commands and pure Python code. - [13:14](https://www.youtube.com/watch?v=uaje5I22kgE&t=794s) A foreign shell execution bridge enables sourcing existing Bash, Zsh, and cmd.exe scripts to load environment variables, aliases, and shell functions directly into the xonsh runtime. - [15:33](https://www.youtube.com/watch?v=uaje5I22kgE&t=933s) The shell features native Jupyter notebook hooks, importable .xsh script files, in-memory tab completions, and terminal-rendered Matplotlib graphics.
## Key takeaways - [00:01](https://www.youtube.com/watch?v=uaje5I22kgE&t=1s) Xonsh requires no dependencies beyond Python and PLY, enabling seamless cross-platform execution on Linux, macOS, and Windows. - [01:11](https://www.youtube.com/watch?v=uaje5I22kgE&t=71s) A primary architectural motivation was replacing fragile Bash scripting patterns—like mutating $IFS—with clean, memorable Python APIs. - [03:49](https://www.youtube.com/watch?v=uaje5I22kgE&t=229s) The shell evaluates pure Python expressions natively while integrating shell primitives like $NAME and ${...} for environment variable manipulation. - [07:04](https://www.youtube.com/watch?v=uaje5I22kgE&t=424s) Subprocess outputs can be captured as Python strings via $(cmd) or as metadata-rich command objects via !(cmd) and streamed ![cmd]. - [09:23](https://www.youtube.com/watch?v=uaje5I22kgE&t=563s) The @() operator evaluates arbitrary Python expressions and flattens iterable structures into individual command-line arguments for subprocesses. - [11:41](https://www.youtube.com/watch?v=uaje5I22kgE&t=701s) File globbing using regular expressions enclosed in backticks returns lists of strings in Python mode and passes expanded arguments in subprocess mode. - [13:14](https://www.youtube.com/watch?v=uaje5I22kgE&t=794s) Aliases can be defined as callable Python functions and lambdas accepting command-line arguments and standard input. - [13:14](https://www.youtube.com/watch?v=uaje5I22kgE&t=794s) Foreign shell sourcing parses Bash, Zsh, and cmd.exe scripts in background subshells to import environment variables and functions without rewriting code. - [15:33](https://www.youtube.com/watch?v=uaje5I22kgE&t=933s) Custom import hooks allow .xsh script files to be imported and executed like standard Python modules across projects. - [17:01](https://www.youtube.com/watch?v=uaje5I22kgE&t=1021s) Ambiguous statements are resolved by checking if the leftmost token exists in the Python scope; if absent, the line executes as a subprocess command. - [20:15](https://www.youtube.com/watch?v=uaje5I22kgE&t=1215s) Command output from utilities like curl can be directly piped into standard library modules like json.loads() or third-party libraries like nltk. - [23:46](https://www.youtube.com/watch?v=uaje5I22kgE&t=1426s) Interactive runtime execution and tab completion are highly responsive due to in-memory caching, despite admitted startup latency bottlenecks in early releases. - [25:31](https://www.youtube.com/watch?v=uaje5I22kgE&t=1531s) Xonsh includes built-in integration with Jupyter notebooks and provides dedicated commands to manage virtual environments. - [28:38](https://www.youtube.com/watch?v=uaje5I22kgE&t=1718s) Python was chosen over alternatives like JavaScript and Ruby because of its robust OS-level signal handling and dynamic syntax tree manipulation capabilities. - [28:38](https://www.youtube.com/watch?v=uaje5I22kgE&t=1718s) Line editing supports both GNU readline and prompt_toolkit backends, including native support for Vi keybindings.
## Detailed walkthrough ### [00:01](https://www.youtube.com/watch?v=uaje5I22kgE&t=1s) Introducing xonsh: A Python Superset Shell
Anthony Scopatz introduces xonsh, a general-purpose command-line shell designed to replace traditional shells like Bash, Fish, or Zsh while simultaneously operating as a strict superset of Python. The project requires no external dependencies outside of Python itself and the standard library; consequently, any system capable of running Python—including Linux, macOS, and Windows—can run xonsh out of the box.
Beyond general scripting convenience, Scopatz explains that his underlying goal was scientific tooling: “And sort of the purpose of xonsh, at least in my mind, is to trick scientists and engineers into being more reproducible, but I don’t have time to go into that into this talk, so you'll just have to talk to me about that later.” He notes that users can unlock additional fancy features if they are willing to install companion packages, which he previews throughout the presentation.
[01:11](https://www.youtube.com/watch?v=uaje5I22kgE&t=71s) The Motivation: Bash Frustrations vs. Python Cleanliness
Scopatz motivates the creation of xonsh by contrasting everyday shell operations in sh-based languages with their Python counterparts. While a basic `for` loop in sh requires extra boilerplate, standard Python syntax is universally familiar and clean. During this explanation, Scopatz pauses to resolve a display resolution issue on stage before laughing off the hiccup with the audience: “The best-laid technical plans. Woo! All right. Live debugging. This is what we're all about.”
Returning to comparisons, he points out how cumbersome checking if a file exists is in shell languages: they rely on strange, overlapping flags and commands that users almost invariably have to look up in documentation, whereas Python provides a clear, memorable API. Even worse is splitting a string by a non-whitespace delimiter. In Bash, the user must mutate global shell state by modifying the internal field separator (`$IFS`) and then remember to reset it afterward, which Scopatz labels “an absolute disaster.”
He humorously charts the emotional stages of building xonsh: - **Conceptualization**: Realizing that the current shell situation cannot stand, prompting the thought of merging the best parts of Python with the best parts of Bash. - **Research**: Investigating parsers like PLY and realizing that implementing it might not be so difficult after all. - **Compulsion**: Seeing the path forward clearly and feeling an irresistible drive to build the library. - **The Future**: Scopatz quips, “And the following stages of anger, regret, and acceptance are sure to follow any day now.”
[03:49](https://www.youtube.com/watch?v=uaje5I22kgE&t=229s) Python Mode and Shell Primitives
Opening a live shell demonstration, Scopatz illustrates how xonsh functions as an everyday interactive shell. The prompt presents standard terminal contextual information, displaying the current user and path in the file system. However, the environment evaluates pure Python directly: users can add numbers, import standard or third-party modules, access attributes, instantiate and query dictionary literals, write multi-line `if`, `for`, or `while` blocks, and define or call functions inside the current execution context:
```mermaid flowchart TD accTitle: Dual-Mode Architecture in xonsh accDescr: Diagram showing how xonsh routes commands between Python mode and Subprocess mode.
Input["xonsh Command Input"] --> ModeCheck{"Evaluation Mode?"}
subgraph PyMode["Python Mode"] ModeCheck -->|"Python Syntax"| PyExec["Python Statements / AST"] PyExec --> PyObj["Direct Object Manipulation / Types"] end
subgraph SubMode["Subprocess Mode"] ModeCheck -->|"Shell Command"| SubExec["Subprocess Execution"] SubExec --> Streams["Pipes, Redirection, Metadata"] end
PyMode <-->|"@() / $() /!() Bridges"| SubMode ```
Scopatz stresses that xonsh is more than vanilla Python because it introduces native shell primitives to the language. An environment lookup operator `$NAME` retrieves variables just like in Bash, but variables can be set using standard Python assignments and immediately consumed by subprocesses. Furthermore, environment variables like `$PATH` are exposed not as rigid, colon-delimited strings, but as native Python lists of strings. Arbitrary custom objects and class instances can be injected straight into the environment.
Key environment operators include: - `$NAME`: Accesses an individual environment variable by identifier. - `${<expr>}`: Dynamically evaluates the inner Python expression to determine which environment variable name to fetch. - `${...}`: References the entire environment object itself, allowing dictionary-like operations such as testing containment with `in` or invoking environment object methods directly.
[07:04](https://www.youtube.com/watch?v=uaje5I22kgE&t=424s) Subprocess Capture and Git Integrations
Navigating the filesystem demonstrates developer-centric features. Changing directories into the xonsh source repository instantly renders the active branch name in color within the prompt, an integration that works seamlessly for both Git and Mercurial. Tab completion brings up a navigable drop-down menu for commands such as `git status`. Rather than reinventing completions for every binary, xonsh parses and reuses existing Bash completion scripts, functioning even on Windows.
To capture command output back into Python, xonsh provides specialized syntax: - `$(cmd)`: Behaves identically to standard POSIX shells, capturing a subprocess's standard output as a Python string. This can be assigned to a variable and manipulated using standard Python string methods in a single expression. - `!(cmd)`: Returns a completed command object containing not only standard output, but complete metadata such as process start and end timestamps, any alias used, and boolean evaluation mapping a exit status of `0` to `True`. - `![cmd]`: Functions identically to `!(cmd)`, but actively streams command output to the console during execution instead of buffering it silently.
[09:23](https://www.youtube.com/watch?v=uaje5I22kgE&t=563s) Injecting Python into Subprocesses
Scopatz details the reverse pathway: feeding Python expressions directly into subprocess execution using the `@()` operator. Placing `@(<expr>)` within a shell command evaluates the Python expression inside the parentheses, converts the outcome to a string, and supplies it as a single argument to the target command (e.g., `echo @(2+2)` outputs `4`).
```mermaid flowchart LR accTitle: Python Expression Expansion with @() accDescr: Flow demonstrating how Python data structures are expanded into command-line arguments.
PData["Python Expression: @(list_or_val)"] --> Eval["Evaluate Expression"] Eval --> TypeCheck{"Type?"} TypeCheck -->|"Single Value"| SingleArg["Pass as single string argument"] TypeCheck -->|"Iterable / List"| MultiArg["Unpack into separate CLI arguments"] SingleArg --> Exec["Subprocess Call"] MultiArg --> Exec ```
If the expression inside `@()` evaluates to a list or iterable, xonsh automatically flattens each item into its own distinct argument in the subprocess argument array. The syntax is fully nestable: subprocess captures can encompass `@()` expressions, which can themselves invoke subprocesses. This operator can even be used in the command position to dynamically resolve which executable to invoke. As Scopatz highlights: “But the place where this @() stuff really shines for me is the fact that you can now use normal Python looping semantics to loop over a set of data, and then run over subprocess commands very, very easily, like we see in this example here.”
Rounding out classic shell requirements, xonsh supports: - **Pipes and Redirections**: Standard syntax for piping between processes (`|`) and redirecting file streams (including standard error to standard out) works identically to traditional shells. - **Chaining Subprocesses**: By popular demand, commands can be chained using Python's `and` and `or` keywords, which automatically wraps the underlying subprocesses in `![]` checks to evaluate process exit codes. - **POSIX Muscle Memory**: For users accustomed to Bash conventions, standard `&&` and `||` operators are fully supported. Scopatz reassures the audience: “And don't worry if you have a lot of muscle memory and you want to use && ||. You're welcome to do so. I won't hold it against you.”
[11:41](https://www.youtube.com/watch?v=uaje5I22kgE&t=701s) Regex Globbing and IPython-Style Object Inspection
Building on shell logic, xonsh allows standard Python boolean operations for file system checks. Testing whether a file exists, or chaining conditions with `and`, `or`, parentheses groupings, and negation semantics, simply evaluates to a native Python boolean value. In addition to standard wildcard expansion, xonsh introduces regular expression file globbing enclosed in backticks. Any pattern inside backticks is compiled as a regular expression; in subprocess mode, the matched paths are forwarded directly to the underlying subprocess command, while in Python mode, the expression returns a standard list of strings. This enables complex path matching, such as selecting all Python files in a directory that do not contain an underscore, or running Python functions like `len()` directly on the matched glob list.
To assist with interactive exploration, xonsh adopts inspection operators popularized by IPython. Appending a single question mark (`?`) to any object opens contextual documentation. Appending a double question mark (`??`) triggers "super help," which inspects the object, locates its source definition, applies syntax highlighting to the code, and prints it directly in the terminal.
- Regular expression globbing using backticks (`` `regex` ``) yields lists of strings in Python context and expanded arguments in subprocess context. - Single `?` displays docstrings and object metadata. - Double `??` fetches and syntax-highlights original source definitions before rendering.
---
[13:14](https://www.youtube.com/watch?v=uaje5I22kgE&t=794s) Callable Aliases and Foreign Shell Execution
Command aliasing in xonsh extends far beyond standard POSIX string replacements. While traditional list-of-string aliases familiar from Bash are supported, xonsh allows aliases to be defined as native Python functions and lambdas. A callable alias accepts command-line arguments and standard input, and can return a string, or optionally a tuple containing standard error and an exit return code. Anthony Scopatz demonstrates this by defining a lambda that takes standard input, applies standard Python string formatting, and outputs an ominous greeting after piping text into it from `echo`.
```mermaid flowchart LR accTitle: Foreign Shell Execution Pipeline accDescr: Diagram showing how foreign shell scripts are sourced and imported into xonsh environment
subgraph Foreign ["Foreign Shell Script (owl.sh)"] ENV["Environment Variables"] AL["Shell Aliases"] FN["Shell Functions"] end
subgraph Parser ["xonsh Foreign Bridge"] SRC["source-bash / foreign parser"] end
subgraph XonshEnv ["xonsh Runtime Context"] XENV["os.environ / ${...}"] XAL["aliases['...']"] XCALL["Callable Function Bridge"] end
ENV --> SRC AL --> SRC FN --> SRC SRC --> XENV SRC --> XAL SRC --> XCALL ```
Xonsh also introduces a formal mechanism for interacting with foreign shells. Sourcing shell setups—such as a Bash script named `owl.sh` that exports environment variables, creates aliases, and defines shell functions—traditionally forces users to rewrite configurations. In xonsh, running the built-in foreign sourcing command parses the Bash file within a background Bash subshell, extracts the resulting modifications, and loads the environment variables, aliases, and functions directly into the live xonsh environment. Scopatz notes that this bridge is implemented for Bash, Zsh, and `cmd.exe`, while quipping about future support: “And clearly there's still a big fish in the room here.”
- Callable aliases accept `(args, stdin=None)` and can return stdout, or `(stdout, stderr, exit_code)`. - Foreign shell integration natively captures environment variables, command aliases, and functions from Bash, Zsh, and Windows `cmd.exe`. - Sourced bash functions can be invoked directly from xonsh command prompts without modification.
---
[15:33](https://www.youtube.com/watch?v=uaje5I22kgE&t=933s) The `.xsh` File Format and Modular Imports
To serve as a general-purpose programming language and automation tool, xonsh defines its own script file format with the `.xsh` extension. Sourcing an `.xsh` file—such as an updated version of `owl.xsh` containing a Python function that times network calls using `ping`—evaluates both shell expressions and Python statements, retaining definitions in the active session. Furthermore, xonsh leverages Python's modular import machinery by implementing import hooks. Scopatz explicitly credits core developers like Brett Cannon for making custom import hooks accessible. Users can place `.xsh` files on the Python path and write standard `import owl` statements, subsequently invoking module functions such as `owl.time_ping()` within pure Python workflows.
Beyond script execution, xonsh incorporates an extensive history backend designed for session auditing and reproducibility. Rather than storing a simple flat file of executed commands, the shell records structured metadata for commands, outputs, and environments. Due to time constraints, Scopatz directs attendees to consult the online documentation for the full architecture of the history subsystem.
- Script files use the `.xsh` extension, mixing arbitrary Python and subprocess commands. - Python import hooks allow `.xsh` scripts to be imported like standard Python modules (`import owl`). - Structured session history preserves rich command context to support scientific reproducibility.
---
[17:01](https://www.youtube.com/watch?v=uaje5I22kgE&t=1021s) Architecture: Resolving Syntax Ambiguities
Like traditional compilers, xonsh relies on tokenization, lexing, parsing, compilation, and execution stages. However, bridging shell syntax with Python requires a custom syntax tree transformation phase. In pure Python, whitespace within expressions carries no semantic weight, meaning varying spaces around an expression like `ls -l` compile to identical abstract syntax tree (AST) structures representing subtraction. In shell subprocess mode, whitespace acts as an argument delimiter, transforming `ls -l` into distinct invocations depending on how tokens are separated.
```mermaid flowchart TD accTitle: xonsh Compilation Pipeline accDescr: Step-by-step pipeline from source code to execution showing the AST transformation phase
A["xonsh Source Code"] --> B["Tokenizer & Lexer"] B --> C["PLY LALR Parser"] C --> D["Python AST Nodes"] D --> E{"Syntax Tree Transformation"}
subgraph Transformation ["Transformation Phases"] E --> F["Phase 1: Context-Insensitive"] F --> G["Phase 2: Context-Sensitive"] G --> H{"Leftmost token in Python scope?"} H -- "Yes" --> I["Parse as Pure Python"] H -- "No (valid command)" --> J["Wrap in Subprocess Mode![ ]"] H -- "Fails both" --> K["Raise SyntaxError"] end
I --> L["Python compile() / exec()"] J --> L ```
The lexer and parser (built with PLY) generate standard Python AST nodes, identical to the output of `ast.parse`. Because standard Python AST nodes are produced, xonsh simply feeds the transformed tree directly into Python’s native `compile()` and `exec()` built-ins. To resolve mode ambiguity, the syntax tree transformation uses a context-sensitive heuristic: if the leftmost identifier in an ambiguous statement does not exist in the active Python scope and the line successfully parses as a valid subprocess command, xonsh wraps the statement in subprocess delimiters (`![]`). If the identifier is present in Python scope, “Python always wins and we parse it as Python.” Users who prefer deterministic parsing can manually wrap commands using the `![]` subprocess literal syntax, Scopatz observing, “It's your fingers.”
- PLY generates standard Python AST instances that hand off directly to native `exec` and `compile`. - Subprocess resolution inspects the leftmost symbol: unassigned identifiers fallback to subprocess execution. - Shared runtime helpers and shell hooks are injected directly into Python's `builtins` namespace.
---
[20:15](https://www.youtube.com/watch?v=uaje5I22kgE&t=1215s) Practical Ecosystem Integration, Terminal Graphics, and Wrap-Up
Because xonsh retains immediate access to Python's package ecosystem, terminal commands can be directly piped into complex data processing pipelines. Scopatz showcases fetching remote text over `curl` and feeding the stream into the Natural Language Toolkit (`nltk`) to tokenize and extract sentences in a one-liner. Similarly, outputs from HTTP APIs fetched with `curl` can be piped directly into `json.loads()` and parsed into formatted terminal output without separate intermediary parsing utilities like `jq`.
```python # Streaming JSON API responses straight into Python dictionary parsing !(curl -s https://api.example.com/data) parsed = json.loads(__xonsh__.history[-1].out) print(f"Status: {parsed['status']}") ```
Scopatz highlights the shell's dedicated color management system, noting that customizable color schemes are essential for readability across terminal profiles and provide crucial accessibility for colorblind users. To conclude the demonstrations, he presents a third-party extension hook for Matplotlib and NumPy that renders graphical figures straight into the terminal grid using colored ANSI background cells, generating enthusiastic laughter and applause from the audience. Scopatz closes by highlighting version 0.3.2, urging the community to adopt and contribute to the shell, and referencing the previous year's proposal: “And just remember that a vote for the shell in 2015 yields xonsh in 2016.”
- Web utilities like `curl` pipe directly into standard library modules (`json.loads`) and third-party tools (`nltk`). - Terminal styling supports custom color palettes tailored for visual accessibility and colorblindness. - Matplotlib figures can render directly inside text terminals using ANSI terminal background pixel blocks. - The talk concludes at version 0.3.2, transitioning directly into attendee Q&A.
[23:46](https://www.youtube.com/watch?v=uaje5I22kgE&t=1426s) Prompt Customization, Python Syntax, and Execution Performance
An audience member opens the Q&A by asking whether xonsh includes something equivalent to a `PROMPT_COMMAND`—a hook to re-run logic and construct the prompt every time the user presses Enter (similar to Bash's `PS1`). Anthony Scopatz clarifies that xonsh features a fully customizable `$PROMPT` environment variable documented extensively in the official manuals. Users can configure colors, select desired metadata components, set up right-aligned prompts (`$RIGHT_PROMPT`), and style multi-line prompts.
Another attendee checks whether xonsh is truly a strict superset of Python syntax and whether it includes process substitution from shells like Bash and ksh. Scopatz confirms both points, though he caveats with a laugh that “the process substitution may be buggy still, but it has been implemented.”
When asked how xonsh performs against traditional Unix shells, Scopatz gives an honest assessment of its strengths and current bottlenecks. He admits that “startup times currently suck, but we're working on that,” noting that startup latencies actually worsened in the most recent release, though the core team understands the root cause and knows how to resolve it. On the other hand, interactive runtime performance is solid. The AST compilation and execution pipeline is fast, and interactive features like tab completion outpace traditional shells because xonsh caches completion components directly in memory rather than reading them from disk repeatedly.
```mermaid flowchart TD accTitle: xonsh Interactive Loop and Environment Structure accDescr: Diagram showing how prompt evaluation, user input, AST execution, and shell completions interact.
subgraph Config ["Prompt & Interface"] P["$PROMPT & $RIGHT_PROMPT"] ML["Multi-line Prompt Engine"] end
subgraph Runtime ["Execution Pipeline"] Input["User Command / Script"] --> Parser["PLY Parser (Superset AST)"] Parser --> Exec["Compilation & Execution"] end
subgraph Memory ["In-Memory Caching"] Comps["Tab Completions & Components"] end
Config --> Input Exec -.->|"Fast interactive evaluation"| Input Comps -->|"Instant lookup"| Input ```
- `$PROMPT` controls dynamic prompt generation, with built-in styling, color formatting, and right-hand prompt support. - Strict Python superset syntax allows blending standard Python expressions directly with shell commands. - Process substitution (e.g., `<(command)`) is implemented. - Startup latency is the primary known performance issue, whereas runtime interactive typing and in-memory tab completion remain very responsive.
---
[25:31](https://www.youtube.com/watch?v=uaje5I22kgE&t=1531s) Integrations: Jupyter Notebooks, Virtual Environments, and Bash Profiles
Attendees query xonsh's interoperability with common Python workflow tools, starting with Jupyter notebooks. Scopatz confirms that xonsh ships out of the box with native Jupyter notebook hooks. When asked about `virtualenv`, Scopatz explains that supporting virtual environments was one of the primary historical drivers behind building xonsh's foreign shell interface. Because standard `virtualenv` activation scripts execute unorthodox shell hacks, xonsh bundles dedicated virtual environment commands to provide seamless alternative pathways if standard activation scripts misbehave.
A question is raised about why a tool like xonsh took until 2016 to exist, and when it might become an industry standard. Scopatz quips that it required a “moral compulsion to act, and probably the fact that no one wanted to re-implement the Python language spec, which I did as a stress reliever project while writing a book.” When asked when it will become standard, he jokes, “Hopefully tonight.”
Regarding startup configuration files, Scopatz explains that xonsh's foreign shell interface automatically reads standard files like `.bash_profile` and `.bashrc` by default. Users have full flexibility: they can configure xonsh to source profiles from any supported foreign shell or disable foreign profile loading altogether.
- Jupyter notebook integration is included stock with the xonsh distribution. - Foreign shell interfaces bridge the gap for legacy tools like `virtualenv`, `.bash_profile`, and `.bashrc`. - Built-in fallback commands exist for virtual environments if Bash-specific activation scripts fail.
---
[27:24](https://www.youtube.com/watch?v=uaje5I22kgE&t=1644s) Real vs. Fake Demos, Third-Party Packages, and Magics
An audience member asks about a slight delay observed during an `ls` command in the slide presentation, wondering whether it was caused by terminal latency or a browser extension. Scopatz reveals the secret behind the presentation: “Oh, this was not live. This was me fake typing. Yeah, I was not going to do that live. Did you see that URL for the Weather Underground? Come on.”
The questions shift to extending xonsh with the broader Python ecosystem. Scopatz confirms that users can `pip install` third-party libraries such as `requests` and import them directly on the command line: “Anything—it is Python, so anything that you can import in Python you can import in xonsh directly and just start using it.”
When asked whether xonsh implements IPython-style magic commands or dedicated debugger hooks, Scopatz explains that while an integrated debugger has been requested, none is built-in yet. Furthermore, xonsh avoids blanket magic syntax; Scopatz invites the community to specify exactly which individual magic functions they actually need so they can be implemented purposefully.
- Presentation demos were recorded and simulated via keystroke playback rather than executed live over network APIs. - Any package installed in the active Python environment (such as `requests`) can be imported directly into the shell prompt. - IPython magics are not universally mirrored; additions depend on user demand for specific workflows.
---
[28:38](https://www.youtube.com/watch?v=uaje5I22kgE&t=1718s) Why Python, Reasons Not to Switch, and Line Editing Backends
The discussion turns to architectural language choice. Scopatz is asked whether Python is objectively the best language for building this type of hybrid shell or merely his personal favorite. Scopatz makes the case that Python is uniquely qualified: > “I do feel that Python is the best language for this because it's a high-level dynamic language and you can do this syntax tree transformation stuff dynamically.”
He contrasts Python with alternatives: - **Ruby:** Lacks the broad ecosystem and scoped design needed for such shell integration. - **JavaScript / Node.js:** Lacks critical OS-level primitives: “You can't really manage signals very well. And Python has this beautiful—maybe not beautiful but functional interface for handling signals.” - **Scala / Ammonite:** While the Ammonite shell does something similar in the Scala ecosystem, Scopatz believes xonsh offers a superior developer experience.
When asked if there is any reason *not* to adopt xonsh as a primary daily driver, Scopatz answers: “I don't think so, but if you find them, please report them.”
The session concludes with a question regarding multi-line input and Vi keybindings. Scopatz explains that xonsh supports two distinct line-editing backends: classic GNU `readline` and `prompt_toolkit`. Both backends support Vi mode natively. While setting `$VI_MODE = True` in xonsh engages the functionality, refining a completely unified configuration interface across both backends remains ongoing work. With that, the host wraps up the session to applause, announcing the next talk in ten minutes.
## Notable quotes > [00:01](https://www.youtube.com/watch?v=uaje5I22kgE&t=1s) the purpose of xonsh, at least in my mind, is to trick scientists and engineers into being more reproducible — Anthony Scopatz
## Mentioned Anthony Scopatz, xonsh, Python, Bash, Fish, Zsh, cmd.exe, PLY, Git, Mercurial, IPython, Brett Cannon, Natural Language Toolkit (nltk), curl, Matplotlib, NumPy, Jupyter, virtualenv, requests, Ruby, Node.js, Ammonite, Scala, GNU readline, prompt_toolkit
## Video description Speaker: Anthony Scopatz
Xonsh is general purpose shell that combines Python and the best features of Bash, zsh, and fish. Relying only the standard library and PLY, the xonsh language is a strict superset of Python that compiles to a Python AST. The shell provides exciting features such as a rich history, tab completion from bash and man pages, syntax highlighting, auto-suggestion, foreign-function aliases and more!
Slides can be found at: https://speakerdeck.com/pycon2016 and https://github.com/PyCon/2016-slides
[Source](https://www.youtube.com/watch?v=uaje5I22kgE)