pyRPC
← Back to Blog

v0.3.1 - Lazy imports, pyrpc_codegen decoupled from CLI

·4 min read

v0.3.1 is a small patch with one structural change: the pyrpc_codegenlibrary is no longer loaded when you run pyrpc version, pyrpc inspect,pyrpc serve, pyrpc pull, or pyrpc --help. Only pyrpc codegen and pyrpc dev actually need it.

The bug that led here

After the v0.3.0 merge (pyrpc-cli into pyrpc-core), a user ran pyrpc dev on a fresh install and hit:

ModuleNotFoundError: No module named 'pyrpc_codegen.main'

The error came from a stale pyrpc.exe shim left behind by the old pyrpc-clipackage. The shim pointed to a module that no longer existed. The root cause wasn't just the stale shim — it was that every CLI command required pyrpc_codegen. Even version and --help imported it at the top of cli.py.

What changed

We moved the from pyrpc_codegen import ... from a top-level module import into a lazy loader, only called inside the commands that actually generate TypeScript:

Before (top-level in cli.py):
  from pyrpc_codegen import DEFAULT_OUTPUT, save_typescript_client
  # Loaded for EVERY command: version, inspect, serve, pull, help...

After (lazy, per-command):
  def _lazy_import_codegen():
      from pyrpc_codegen import DEFAULT_OUTPUT, save_typescript_client
      return DEFAULT_OUTPUT, save_typescript_client
  # Only loaded inside codegen() and dev()

Now a stale shim only matters if you actually run a codegen command. Commands that don't need the codegen library work with a correctly-installed pyrpc-core alone.

This is capability boundaries, not performance

The lazy import isn't about shaving milliseconds off startup time. It's aboutdecoupling what the CLI needs from what individual commands need. A quick table of which commands require what:

Command          Needs pyrpc_codegen?   Needs pyrpc_core?
───────────────   ───────────────────   ───────────────
version          No                    No
--help           No                    No
inspect          No                    Yes (lazy)
serve            No                    Yes (lazy)
pull             No                    Yes (lazy)
codegen          Yes (lazy)            Yes (lazy)
dev              Yes (lazy)            Yes (lazy)

Every command that needs a dependency imports it inside the handler, not at module level. This means you can install pyrpc-core partially and still getversion and --help to work — useful for CI scripts and minimal environments.

A note on backward compatibility

The initial fix added a forwarding module at the oldpyrpc_codegen.main path that re-exported from pyrpc_core.cli. But this created a circular dependency (pyrpc-core → pyrpc-codegen ← pyrpc_core) and we have no users with stale shims yet. We removed it.

If you hit the stale shim error, the fix is simple:

pip uninstall pyrpc-cli
pip install --upgrade pyrpc-core

Full changelog

  • CLI: pyrpc_codegen import moved from top-level to per-command lazy loader. Commands version, inspect, serve, pull, and --help no longer require the codegen library.
  • Tests: Mock targets updated to match lazy import pattern. All 17 tests pass.

See the full changelog for details.