Spyder's Editor Isn't Running Your Code: What the Kernel Split Changes
Spyder's editor and the process running your code are different programs. That explains most "which Python am I in?" confusion — and enables remote execution.
27 Dec 2025, 22:29 UTC

The symptom: your code runs somewhere you didn't pick
You install a library into a conda environment, point Spyder at that environment, and the import still fails. Or it succeeds, and you can't tell which copy of the library you're actually using. The confusion usually traces back to a design decision that is easy to miss: Spyder's window and the process that executes your code are two different programs.
The window is the frontend — editor, Variable Explorer, debugger UI, plots pane. The code runs in a kernel: a long-running process that holds your namespace and answers requests over a socket. That kernel is supplied by a separate package, spyder-kernels, not by the Spyder application itself.
Once you internalize that split, most "which Python am I in?" questions answer themselves. It's also the feature that lets you keep one editor while executing against a different interpreter, or a machine you aren't sitting at.
What the frontend/kernel split actually buys you
Because the frontend only sends requests and renders replies, everything stateful belongs to the kernel:
- The Variable Explorer shows the kernel's namespace, not the frontend's.
- Code completion and introspection reflect packages installed in the kernel's environment.
- Debugger stepping and plot rendering are driven by the connected kernel.
The practical upshot is one editor with many possible execution targets. A lightweight laptop UI can drive a kernel on a workstation with more memory, or a project pinned to an older Python can run without disturbing your day-to-day environment.
A worked example: attach Spyder to a different environment
Goal: execute code in a target environment — a conda env, a virtualenv, or a remote host — while keeping Spyder's interface. The shape of the workflow is stable; exact menu labels and command-line options have changed across releases, so confirm each step against the documentation for your installed versions.
- Install
spyder-kernelsinto the target environment, not the frontend's. With that environment active, this is typicallyconda install spyder-kernelsorpip install spyder-kernels. The version should be compatible with your Spyder release; mismatched pairs can fail to connect or behave unpredictably. - Start a kernel in that environment. Many releases expose a console entry point along the lines of
python -m spyder_kernels.console. Verify the exact invocation and available options in the docs before scripting it — this is one of the details most likely to have shifted. - Locate the connection file. The kernel writes a JSON file containing a transport address and an authentication key. Treat it as a credential: it grants code execution, so keep it out of version control and shared storage.
- Connect from Spyder. Use the IPython console's menu for connecting to an existing kernel and point it at that file. Label wording differs between releases.
Expected checks — described here as things to look at, not as output you should assume:
- In the connected console, print
sys.executableandsys.versionto confirm which interpreter is really executing your code. - Create a variable in the console and confirm it appears in the Variable Explorer.
- Render a plot and note which matplotlib backend is in use.
Two remote-specific caveats. First, plot output from a remote kernel usually needs an explicit non-interactive backend such as Agg, because interactive GUI backends generally cannot draw on the client machine. Second, an exposed kernel port is a code-execution surface — reach remote kernels over SSH or another secured channel, never a publicly reachable address.
Where the split costs you
The separation is not free. Every execution and introspection request is a round trip, so interactive exploration feels slightly less immediate than an in-process console. Workflows that assume a shared filesystem get friction: working-directory handling, opening files from traceback links, and some debugging paths may need manual path mapping between the kernel's filesystem and yours.
Version pairing is the other sharp edge. A frontend and a spyder-kernels package from very different releases are not guaranteed to work together. If a connection silently fails, checking both versions against the compatibility guidance is a better first move than reinstalling anything.
When you don't need a kernel at all
If the real goal is reproducible chunks and selective re-running, cell markers using # %% in the editor deliver that inside a single environment — no connection file, no version pairing, no round-trip latency. Reach for the kernel split when the environment or the machine is genuinely different, not merely when you want to run one block at a time.
Before you build a workflow on it
Run a short acceptance check rather than trusting the setup on faith: confirm sys.executable in the console, compare the installed spyder-kernels version with your Spyder release's compatibility notes, read a file by absolute path from the kernel, trigger an exception and see whether the traceback link resolves, and render a plot to identify the backend. For remote setups, repeat that list from the remote side.
Several details above — entry-point commands, menu labels, connection-file format — are version-dependent and flagged for confirmation against the official Spyder documentation on the IPython console and remote kernels. Verify them for your installed versions before standardizing a team workflow on them.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.