# Extension points — pypa/virtualenv

> Canonical page: https://codevetter.com/unpack/virtualenv/extension-points

# Extension points — pypa/virtualenv

Scanned commit 571bc2041dae5ecbd250d82ec7ef482cfd3c3b69 (2026-10-02). Generated by codevetter codevetter 1.15.0 on 2026-10-02.

Source inspection; upstream code and tests were not executed.

Installed Python entry points form the principal extension mechanism. Each stage has a selection adapter and an implementation interface, with interpreter capabilities constraining applicable choices. Creation can extend filesystem references and layouts, while seeding can replace installation strategy. Activators pair shell-specific classes with templates, and storage/build hooks provide additional internal seams.
- Plugins register under virtualenv.discovery, virtualenv.create, virtualenv.seed, or virtualenv.activate; installed metadata supplies CLI choices, and built-in entry-point values win duplicate names. — [docs/plugin/architecture.rst#L11-L24](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/docs/plugin/architecture.rst#L11-L24) [src/virtualenv/run/plugin/base.py#L20-L30](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/run/plugin/base.py#L20-L30) [pyproject.toml#L70-L103](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/pyproject.toml#L70-L103)
- Discovery plugins implement Discover.run and add_parser_arguments, consume VirtualEnvOptions, and expose a lazily cached interpreter; get_discover installs their CLI options before construction. — [src/virtualenv/discovery/discover.py#L18-L38](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/discovery/discover.py#L18-L38) [src/virtualenv/run/plugin/discovery.py#L37-L50](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/run/plugin/discovery.py#L37-L50)
- Creator plugins provide can_create metadata, add_parser_arguments, and create; CreatorSelector rejects the reserved builtin registration name, reports capability errors, and passes selected metadata into construction. — [src/virtualenv/create/creator.py#L97-L124](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/create/creator.py#L97-L124) [src/virtualenv/create/creator.py#L162-L165](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/create/creator.py#L162-L165) [src/virtualenv/run/plugin/creators.py#L33-L64](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/run/plugin/creators.py#L33-L64) [src/virtualenv/run/plugin/creators.py#L82-L92](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/run/plugin/creators.py#L82-L92)
- Builtin creator families extend sources, setup_meta, and _executables; PathRefToDest maps host resources to destinations, while ExePathRefToDest handles executable aliases and copy/link differences. — [src/virtualenv/create/via_global_ref/builtin/via_global_self_do.py#L39-L85](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/create/via_global_ref/builtin/via_global_self_do.py#L39-L85) [src/virtualenv/create/via_global_ref/builtin/ref.py#L125-L172](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/create/via_global_ref/builtin/ref.py#L125-L172)
- Describe supplies interpreter-derived layout properties and can_describe; non-Describe creators receive a compatible describer, and Venv delegates noncallable layout attributes to it. — [src/virtualenv/create/describe.py#L29-L89](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/create/describe.py#L29-L89) [src/virtualenv/run/plugin/creators.py#L87-L92](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/run/plugin/creators.py#L87-L92) [src/virtualenv/create/via_global_ref/venv.py#L94-L100](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/create/via_global_ref/venv.py#L94-L100)
- SeederSelector constructs selected seeders and checks cannot_seed only when enabled; BaseEmbed exposes distribution_to_versions, and FromAppData selects CopyPipInstall or SymlinkPipInstall strategies. — [src/virtualenv/run/plugin/seeders.py#L44-L49](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/run/plugin/seeders.py#L44-L49) [src/virtualenv/seed/embed/base_embed.py#L54-L89](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/embed/base_embed.py#L54-L89) [src/virtualenv/seed/embed/via_app_data/via_app_data.py#L145-L148](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/embed/via_app_data/via_app_data.py#L145-L148)
- Activator extensions participate through supports, add_parser_arguments, and generation; ViaTemplateActivator offers templates, quote, replacements, substitutions, and as_name overrides, illustrated by BashActivator's activate.sh → activate mapping. — [src/virtualenv/run/plugin/activators.py#L18-L26](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/run/plugin/activators.py#L18-L26) [src/virtualenv/run/plugin/activators.py#L49-L69](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/run/plugin/activators.py#L49-L69) [src/virtualenv/activation/via_template.py#L28-L103](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/activation/via_template.py#L28-L103) [src/virtualenv/activation/bash/__init__.py#L14-L27](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/activation/bash/__init__.py#L14-L27)
- Internal factory seams include make_app_data's disk/read-only/temporary selection and the Hatch custom build hook; ReadOnlyAppData disables updates and overrides cache writes, while SbomBuildHook appends generated SBOM files only for supported wheel builds. — [src/virtualenv/app_data/__init__.py#L49-L72](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/app_data/__init__.py#L49-L72) [src/virtualenv/app_data/read_only.py#L15-L42](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/app_data/read_only.py#L15-L42) [pyproject.toml#L201-L204](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/pyproject.toml#L201-L204) [hatch_build.py#L240-L253](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/hatch_build.py#L240-L253)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
