diff --git a/Architecture.md b/Architecture.md
index 2b081a487e4..dfd4d4b959d 100644
--- a/Architecture.md
+++ b/Architecture.md
@@ -151,9 +151,8 @@ Some of the functionality of `pyo3-build-config`:
entirely and only abi3 extensions can be built.
- Check if we are building a Python extension.
- If we are building an extension (e.g., Python library installable by `pip`),
- we don't link `libpython`.
- Currently we use the `extension-module` feature for this purpose. This may change in the future.
- See [#1123](https://github.com/PyO3/pyo3/pull/1123).
+ we don't link `libpython` on most platforms (to allow for statically-linked Python interpreters).
+ The `PYO3_BUILD_EXTENSION_MODULE` environment variable suppresses linking.
- Cross-compiling configuration
- If `TARGET` architecture and `HOST` architecture differ, we can find cross compile information
from environment variables (`PYO3_CROSS_LIB_DIR`, `PYO3_CROSS_PYTHON_VERSION` and
diff --git a/Cargo.toml b/Cargo.toml
index 1a7588b5f95..3e2629bd4ca 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -101,9 +101,9 @@ macros = ["pyo3-macros"]
# Enables multiple #[pymethods] per #[pyclass]
multiple-pymethods = ["inventory", "pyo3-macros/multiple-pymethods"]
-# Use this feature when building an extension module.
-# It tells the linker to keep the python symbols unresolved,
-# so that the module can also be used with statically linked python interpreters.
+# Deprecated: use the `PYO3_BUILD_EXTENSION_MODULE` environment variable when
+# building a Python extension module (set automatically by `setuptools-rust` and
+# `maturin`).
extension-module = ["pyo3-ffi/extension-module"]
# Use the Python limited API. See https://www.python.org/dev/peps/pep-0384/ for more.
diff --git a/README.md b/README.md
index 71b2c69d014..f6a92771b71 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@ name = "string_sum"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { version = "0.27.1", features = ["extension-module"] }
+pyo3 = "0.27.1"
```
**`src/lib.rs`**
@@ -138,6 +138,7 @@ Start a new project with `cargo new` and add `pyo3` to the `Cargo.toml` like th
```toml
[dependencies.pyo3]
version = "0.27.1"
+# Enabling this cargo feature will cause PyO3 to start a Python interpreter on first call to `Python::attach`
features = ["auto-initialize"]
```
diff --git a/examples/Cargo.toml b/examples/Cargo.toml
index 68aa8be7a76..5ce9d547625 100644
--- a/examples/Cargo.toml
+++ b/examples/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2021"
rust-version = "1.83"
[dev-dependencies]
-pyo3 = { path = "..", features = ["auto-initialize", "extension-module"] }
+pyo3 = { path = "..", features = ["auto-initialize"] }
[[example]]
name = "decorator"
diff --git a/examples/decorator/.template/Cargo.toml b/examples/decorator/.template/Cargo.toml
index 95c3f0f14ae..e0aa857a0d9 100644
--- a/examples/decorator/.template/Cargo.toml
+++ b/examples/decorator/.template/Cargo.toml
@@ -9,4 +9,4 @@ name = "decorator"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { version = "{{PYO3_VERSION}}", features = ["extension-module"] }
+pyo3 = "{{PYO3_VERSION}}"
diff --git a/examples/decorator/Cargo.toml b/examples/decorator/Cargo.toml
index ef7e5dc2e1c..01d3cf0e0d7 100644
--- a/examples/decorator/Cargo.toml
+++ b/examples/decorator/Cargo.toml
@@ -9,6 +9,6 @@ name = "decorator"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { path = "../../", features = ["extension-module"] }
+pyo3 = { path = "../../" }
[workspace]
diff --git a/examples/getitem/.template/Cargo.toml b/examples/getitem/.template/Cargo.toml
index 47dbb7b0ed5..e40f51caacd 100644
--- a/examples/getitem/.template/Cargo.toml
+++ b/examples/getitem/.template/Cargo.toml
@@ -9,4 +9,4 @@ name = "getitem"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { version = "{{PYO3_VERSION}}", features = ["extension-module"] }
+pyo3 = "{{PYO3_VERSION}}"
diff --git a/examples/getitem/Cargo.toml b/examples/getitem/Cargo.toml
index c31047eba24..61f456bd08f 100644
--- a/examples/getitem/Cargo.toml
+++ b/examples/getitem/Cargo.toml
@@ -9,6 +9,6 @@ name = "getitem"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { path = "../../", features = ["extension-module"] }
+pyo3 = { path = "../../" }
[workspace]
diff --git a/examples/maturin-starter/.template/Cargo.toml b/examples/maturin-starter/.template/Cargo.toml
index e67e1240519..ad324cf7cb0 100644
--- a/examples/maturin-starter/.template/Cargo.toml
+++ b/examples/maturin-starter/.template/Cargo.toml
@@ -9,4 +9,4 @@ name = "maturin_starter"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { version = "{{PYO3_VERSION}}", features = ["extension-module"] }
+pyo3 = "{{PYO3_VERSION}}"
diff --git a/examples/maturin-starter/Cargo.toml b/examples/maturin-starter/Cargo.toml
index 53e464bbffe..c5aedf197e8 100644
--- a/examples/maturin-starter/Cargo.toml
+++ b/examples/maturin-starter/Cargo.toml
@@ -9,7 +9,7 @@ name = "maturin_starter"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { path = "../../", features = ["extension-module"] }
+pyo3 = { path = "../../" }
[features]
abi3 = ["pyo3/abi3-py37", "generate-import-lib"]
diff --git a/examples/plugin/.template/plugin_api/Cargo.toml b/examples/plugin/.template/plugin_api/Cargo.toml
index dfbd855aebc..9a7c5fb9ac1 100644
--- a/examples/plugin/.template/plugin_api/Cargo.toml
+++ b/examples/plugin/.template/plugin_api/Cargo.toml
@@ -9,9 +9,4 @@ name = "plugin_api"
crate-type = ["cdylib", "rlib"]
[dependencies]
-#!!! Important - DO NOT ENABLE extension-module FEATURE HERE!!!
pyo3 = "{{PYO3_VERSION}}"
-
-[features]
-# instead extension-module feature for pyo3 is enabled conditionally when we want to build a standalone extension module to test our plugins without "main" program
-extension-module = ["pyo3/extension-module"]
diff --git a/examples/plugin/README.md b/examples/plugin/README.md
index 17f2cf740bd..3d980368fc0 100644
--- a/examples/plugin/README.md
+++ b/examples/plugin/README.md
@@ -5,7 +5,7 @@ interface types that can be used to exchange data between Rust and Python. This
# Building and Testing
## Host application
-To run the app itself, you only need to run
+To run the app itself, you only need to run
```shell
cargo run
@@ -14,20 +14,14 @@ It will build the app, as well as the plugin API, then run the app, load the plu
## Plugin API testing
-The plugin API is in a separate crate `plugin_api`, so you can test it separately from the main app.
+The plugin API is in a separate crate `plugin_api`, so you can test it separately from the main app.
-To build the API only package, first install `maturin`:
+To build the API only package, install and build with `maturin`:
```shell
pip install maturin
-```
-
-When building the plugin, simply using `maturin develop` will fail to produce a viable extension module due to the features arrangement of PyO3.
-Instead, one needs to enable the optional feature as follows:
-
-```shell
cd plugin_api
-maturin build --features "extension-module"
+maturin build
```
Alternatively, install nox and run the tests inside an isolated environment:
diff --git a/examples/plugin/plugin_api/Cargo.toml b/examples/plugin/plugin_api/Cargo.toml
index 870ad76a377..dd8a1f51d37 100644
--- a/examples/plugin/plugin_api/Cargo.toml
+++ b/examples/plugin/plugin_api/Cargo.toml
@@ -9,9 +9,4 @@ name = "plugin_api"
crate-type = ["cdylib", "rlib"]
[dependencies]
-#!!! Important - DO NOT ENABLE extension-module FEATURE HERE!!!
pyo3 = { path = "../../../" }
-
-[features]
-# instead extension-module feature for pyo3 is enabled conditionally when we want to build a standalone extension module to test our plugins without "main" program
-extension-module = ["pyo3/extension-module"]
diff --git a/examples/setuptools-rust-starter/.template/Cargo.toml b/examples/setuptools-rust-starter/.template/Cargo.toml
index d0e43066ac5..7448e278347 100644
--- a/examples/setuptools-rust-starter/.template/Cargo.toml
+++ b/examples/setuptools-rust-starter/.template/Cargo.toml
@@ -9,4 +9,4 @@ name = "setuptools_rust_starter"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { version = "{{PYO3_VERSION}}", features = ["extension-module"] }
+pyo3 = "{{PYO3_VERSION}}"
diff --git a/examples/setuptools-rust-starter/Cargo.toml b/examples/setuptools-rust-starter/Cargo.toml
index e7ae56a7612..02b399c3779 100644
--- a/examples/setuptools-rust-starter/Cargo.toml
+++ b/examples/setuptools-rust-starter/Cargo.toml
@@ -9,6 +9,6 @@ name = "setuptools_rust_starter"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { path = "../../", features = ["extension-module"] }
+pyo3 = { path = "../../" }
[workspace]
diff --git a/examples/word-count/.template/Cargo.toml b/examples/word-count/.template/Cargo.toml
index 5d6bffafcbb..011f5e776d6 100644
--- a/examples/word-count/.template/Cargo.toml
+++ b/examples/word-count/.template/Cargo.toml
@@ -9,5 +9,5 @@ name = "word_count"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { version = "{{PYO3_VERSION}}", features = ["extension-module"] }
+pyo3 = "{{PYO3_VERSION}}"
rayon = "1.0.2"
diff --git a/examples/word-count/Cargo.toml b/examples/word-count/Cargo.toml
index 816e3dd9a34..c1bb4552114 100644
--- a/examples/word-count/Cargo.toml
+++ b/examples/word-count/Cargo.toml
@@ -9,7 +9,7 @@ name = "word_count"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { path = "../..", features = ["extension-module"] }
+pyo3 = { path = "../.." }
rayon = "1.0.2"
[workspace]
diff --git a/guide/src/building-and-distribution.md b/guide/src/building-and-distribution.md
index fb176843707..c319c74841b 100644
--- a/guide/src/building-and-distribution.md
+++ b/guide/src/building-and-distribution.md
@@ -71,13 +71,13 @@ Package vendors can opt-in to the "abi3" limited Python API which allows their w
There are many ways to go about this: it is possible to use `cargo` to build the extension module (along with some manual work, which varies with OS).
The PyO3 ecosystem has two packaging tools, [`maturin`] and [`setuptools-rust`], which abstract over the OS difference and also support building wheels for PyPI upload.
-PyO3 has some Cargo features to configure projects for building Python extension modules:
+PyO3 has some functionality for configuring projects when building Python extension modules:
-- The `extension-module` feature, which must be enabled when building Python extension modules.
-- The `abi3` feature and its version-specific `abi3-pyXY` companions, which are used to opt-in to the limited Python API in order to support multiple Python versions in a single wheel.
+- The `PYO3_BUILD_EXTENSION_MODULE` environment variable, which must be set when building Python extension modules. `maturin` and `setuptools-rust` set this automatically.
+- The `abi3` Cargo feature and its version-specific `abi3-pyXY` companions, which are used to opt-in to the limited Python API in order to support multiple Python versions in a single wheel.
-This section describes each of these packaging tools before describing how to build manually without them.
-It then proceeds with an explanation of the `extension-module` feature.
+This section describes the packaging tools before describing how to build manually without them.
+It then proceeds with an explanation of the `PYO3_BUILD_EXTENSION_MODULE` environment variable.
Finally, there is a section describing PyO3's `abi3` features.
### Packaging tools
@@ -97,7 +97,7 @@ There are also [`maturin-starter`] and [`setuptools-rust-starter`] examples in t
### Manual builds
-To build a PyO3-based Python extension manually, start by running `cargo build` as normal in a library project which uses PyO3's `extension-module` feature and has the [`cdylib` crate type](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-crate-type-field).
+To build a PyO3-based Python extension manually, start by running `cargo build` as normal in a library project with the [`cdylib` crate type](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-crate-type-field) while the `PYO3_BUILD_EXTENSION_MODULE` environment variable is set.
Once built, symlink (or copy) and rename the shared library from Cargo's `target/` directory to your desired output directory:
@@ -142,7 +142,7 @@ See [PEP 3149](https://peps.python.org/pep-3149/) for more background on platfor
#### macOS
-On macOS, because the `extension-module` feature disables linking to `libpython` ([see the next section](#the-extension-module-feature)), some additional linker arguments need to be set. `maturin` and `setuptools-rust` both pass these arguments for PyO3 automatically, but projects using manual builds will need to set these directly in order to support macOS.
+On macOS, because the `PYO3_BUILD_EXTENSION_MODULE` environment variable disables linking to `libpython` ([see the next section](#the-extension-module-feature)), some additional linker arguments need to be set. `maturin` and `setuptools-rust` both pass these arguments for PyO3 automatically, but projects using manual builds will need to set these directly in order to support macOS.
The easiest way to set the correct linker arguments is to add a [`build.rs`](https://doc.rust-lang.org/cargo/reference/build-scripts.html) with the following content:
@@ -193,17 +193,24 @@ For more discussion on and workarounds for MacOS linking problems [see this issu
Finally, don't forget that on MacOS the `extension-module` feature will cause `cargo test` to fail without the `--no-default-features` flag (see [the FAQ](https://pyo3.rs/main/faq.html#i-cant-run-cargo-test-or-i-cant-build-in-a-cargo-workspace-im-having-linker-issues-like-symbol-not-found-or-undefined-reference-to-_pyexc_systemerror)).
-### The `extension-module` feature
+### The `PYO3_BUILD_EXTENSION_MODULE` environment variable
-PyO3's `extension-module` feature is used to disable [linking](https://en.wikipedia.org/wiki/Linker_(computing)) to `libpython` on Unix targets.
+
-This is necessary because by default PyO3 links to `libpython`.
+By default PyO3 links to `libpython`.
This makes binaries, tests, and examples "just work".
However, Python extensions on Unix must not link to libpython for [manylinux](https://www.python.org/dev/peps/pep-0513/) compliance.
The downside of not linking to `libpython` is that binaries, tests, and examples (which usually embed Python) will fail to build.
-If you have an extension module as well as other outputs in a single project, you need to use optional Cargo features to disable the `extension-module` when you're not building the extension module.
-See [the FAQ](faq.md#i-cant-run-cargo-test-or-i-cant-build-in-a-cargo-workspace-im-having-linker-issues-like-symbol-not-found-or-undefined-reference-to-_pyexc_systemerror) for an example workaround.
+As a result, PyO3 uses an envionment variable `PYO3_BUILD_EXTENSION_MODULE` to disable linking to `libpython`.
+This should only be set when building a library for distribution.
+`maturin >= 1.9.4` and `setuptools-rust >= 1.12` will set this for you automatically.
+
+> [!NOTE]
+> Historically PyO3 used an `extension-module` feature to perform the same function now done by the `PYO3_BUILD_EXTENSION_MODULE` env var.
+> This feature caused linking to be disabled for all compile targets, including Rust tests and benchmarks.
+>
+> Projects are encouraged to migrate off the feature, as it caused [major development pain](faq.md#i-cant-run-cargo-test-or-i-cant-build-in-a-cargo-workspace-im-having-linker-issues-like-symbol-not-found-or-undefined-reference-to-_pyexc_systemerror) due to the lack of linking.
### `Py_LIMITED_API`/`abi3`
diff --git a/guide/src/faq.md b/guide/src/faq.md
index 1ecb3740982..501773becb8 100644
--- a/guide/src/faq.md
+++ b/guide/src/faq.md
@@ -26,47 +26,18 @@ See the documentation for [`PyOnceLock`] and [`OnceExt`] for further details and
## I can't run `cargo test`; or I can't build in a Cargo workspace: I'm having linker issues like "Symbol not found" or "Undefined reference to _PyExc_SystemError"
-Currently, [#340](https://github.com/PyO3/pyo3/issues/340) causes `cargo test` to fail with linking errors when the `extension-module` feature is activated.
-Linking errors can also happen when building in a cargo workspace where a different crate also uses PyO3 (see [#2521](https://github.com/PyO3/pyo3/issues/2521)).
-For now, there are three ways we can work around these issues.
+The `extension-module` feature (now deprecated) disables linking to `libpython`.
+This breaks binaries and tests which need to load symbols from `libpython` to execute.
-1. Make the `extension-module` feature optional.
- Build with `maturin develop --features "extension-module"`
+Remove the `extension-module` feature and upgrade to `maturin >= 1.9.4` or `setuptools-rust 1.12`.
- ```toml
- [dependencies.pyo3]
- {{#PYO3_CRATE_VERSION}}
-
- [features]
- extension-module = ["pyo3/extension-module"]
- ```
-
-2. Make the `extension-module` feature optional and default.
- Run tests with `cargo test --no-default-features`:
-
- ```toml
- [dependencies.pyo3]
- {{#PYO3_CRATE_VERSION}}
-
- [features]
- extension-module = ["pyo3/extension-module"]
- default = ["extension-module"]
- ```
-
-3. If you are using a [`pyproject.toml`](https://maturin.rs/metadata.html) file to control maturin settings, add the following section:
-
- ```toml
- [tool.maturin]
- features = ["pyo3/extension-module"]
- # Or for maturin 0.12:
- # cargo-extra-args = ["--features", "pyo3/extension-module"]
- ```
+If building manually, see the [`PYO3_BUILD_EXTENSION_MODULE` environment variable](./building-and-distribution.md#the-pyo3_build_extension_module-environment-variable).
## I can't run `cargo test`: my crate cannot be found for tests in `tests/` directory
The Rust book suggests to [put integration tests inside a `tests/` directory](https://doc.rust-lang.org/book/ch11-03-test-organization.html#integration-tests).
-For a PyO3 `extension-module` project where the `crate-type` is set to `"cdylib"` in your `Cargo.toml`, the compiler won't be able to find your crate and will display errors such as `E0432` or `E0463`:
+For a PyO3 project where the `crate-type` is set to `"cdylib"` in your `Cargo.toml`, the compiler won't be able to find your crate and will display errors such as `E0432` or `E0463`:
```text
error[E0432]: unresolved import `my_crate`
diff --git a/guide/src/features.md b/guide/src/features.md
index fd66f91d4b1..361ff68997b 100644
--- a/guide/src/features.md
+++ b/guide/src/features.md
@@ -9,9 +9,7 @@ By default, only the `macros` feature is enabled.
### `extension-module`
-This feature is required when building a Python extension module using PyO3.
-
-It tells PyO3's build script to skip linking against `libpython.so` on Unix platforms, where this must not be done.
+Deprecated, users should remove this feature and upgrade to `maturin >= 1.9.4` or `setuptools-rust >= 1.12`.
See the [building and distribution](building-and-distribution.md#the-extension-module-feature) section for further detail.
diff --git a/guide/src/getting-started.md b/guide/src/getting-started.md
index 821b7fc2989..f7e35a3f1bb 100644
--- a/guide/src/getting-started.md
+++ b/guide/src/getting-started.md
@@ -139,7 +139,7 @@ name = "pyo3_example"
crate-type = ["cdylib"]
[dependencies]
-pyo3 = { {{#PYO3_CRATE_VERSION}}, features = ["extension-module"] }
+pyo3 = {{#PYO3_CRATE_VERSION}}
```
## pyproject.toml
@@ -148,7 +148,7 @@ You should also create a `pyproject.toml` with the following contents:
```toml
[build-system]
-requires = ["maturin>=1,<2"]
+requires = ["maturin>=1.9.4,<2"]
build-backend = "maturin"
[project]
diff --git a/pyo3-build-config/Cargo.toml b/pyo3-build-config/Cargo.toml
index dd2af861968..ca4680bf166 100644
--- a/pyo3-build-config/Cargo.toml
+++ b/pyo3-build-config/Cargo.toml
@@ -26,7 +26,7 @@ default = []
# script. If this feature isn't enabled, the build script no-ops.
resolve-config = []
-# This feature is enabled by pyo3 when building an extension module.
+# deprecated
extension-module = []
# Automatically generates `python3.dll` import libraries for Windows targets.
diff --git a/pyo3-build-config/src/impl_.rs b/pyo3-build-config/src/impl_.rs
index 7cf2d0eb600..55679e6e71a 100644
--- a/pyo3-build-config/src/impl_.rs
+++ b/pyo3-build-config/src/impl_.rs
@@ -881,7 +881,7 @@ pub fn get_abi3_version() -> Option {
/// Checks if the `extension-module` feature is enabled for the PyO3 crate.
///
/// This can be triggered either by:
-/// - The `extension-module` Cargo feature
+/// - The `extension-module` Cargo feature (deprecated)
/// - Setting the `PYO3_BUILD_EXTENSION_MODULE` environment variable
///
/// Must be called from a PyO3 crate build script.
diff --git a/pyo3-build-config/src/lib.rs b/pyo3-build-config/src/lib.rs
index 5011470bfa9..5d8002d8c91 100644
--- a/pyo3-build-config/src/lib.rs
+++ b/pyo3-build-config/src/lib.rs
@@ -49,7 +49,7 @@ pub fn use_pyo3_cfgs() {
}
}
-/// Adds linker arguments suitable for PyO3's `extension-module` feature.
+/// Adds linker arguments suitable for linking an extension module.
///
/// This should be called from a build script.
///
diff --git a/pyo3-ffi/Cargo.toml b/pyo3-ffi/Cargo.toml
index b5e17fdfd71..f54b194dd6a 100644
--- a/pyo3-ffi/Cargo.toml
+++ b/pyo3-ffi/Cargo.toml
@@ -19,9 +19,7 @@ libc = "0.2.62"
default = []
-# Use this feature when building an extension module.
-# It tells the linker to keep the python symbols unresolved,
-# so that the module can also be used with statically linked python interpreters.
+# deprecated
extension-module = ["pyo3-build-config/extension-module"]
# Use the Python limited API. See https://www.python.org/dev/peps/pep-0384/ for more.
diff --git a/pyo3-ffi/README.md b/pyo3-ffi/README.md
index f68c8b47009..0ef4a6209cb 100644
--- a/pyo3-ffi/README.md
+++ b/pyo3-ffi/README.md
@@ -40,9 +40,8 @@ name = "string_sum"
# crate-type = ["cdylib", "rlib"]
crate-type = ["cdylib"]
-[dependencies.pyo3-ffi]
-version = "0.27.1"
-features = ["extension-module"]
+[dependencies]
+pyo3-ffi = "0.27.1"
[build-dependencies]
# This is only necessary if you need to configure your build based on
diff --git a/pyo3-ffi/examples/sequential/.template/Cargo.toml b/pyo3-ffi/examples/sequential/.template/Cargo.toml
index cd0ece4291f..d5165c429d9 100644
--- a/pyo3-ffi/examples/sequential/.template/Cargo.toml
+++ b/pyo3-ffi/examples/sequential/.template/Cargo.toml
@@ -9,4 +9,4 @@ name = "sequential"
crate-type = ["cdylib", "lib"]
[dependencies]
-pyo3-ffi = { version = "{{PYO3_VERSION}}", features = ["extension-module"] }
+pyo3-ffi = { version = "{{PYO3_VERSION}}" }
diff --git a/pyo3-ffi/examples/sequential/Cargo.toml b/pyo3-ffi/examples/sequential/Cargo.toml
index 21e87c09496..1ee76c48114 100644
--- a/pyo3-ffi/examples/sequential/Cargo.toml
+++ b/pyo3-ffi/examples/sequential/Cargo.toml
@@ -9,7 +9,7 @@ name = "sequential"
crate-type = ["cdylib", "lib"]
[dependencies]
-pyo3-ffi = { path = "../../", features = ["extension-module"] }
+pyo3-ffi = { path = "../../" }
[build-dependencies]
pyo3-build-config = { path = "../../../pyo3-build-config" }
diff --git a/pyo3-ffi/examples/string-sum/.template/Cargo.toml b/pyo3-ffi/examples/string-sum/.template/Cargo.toml
index 40afa2504c3..48c3fdc53c5 100644
--- a/pyo3-ffi/examples/string-sum/.template/Cargo.toml
+++ b/pyo3-ffi/examples/string-sum/.template/Cargo.toml
@@ -9,4 +9,4 @@ name = "string_sum"
crate-type = ["cdylib"]
[dependencies]
-pyo3-ffi = { version = "{{PYO3_VERSION}}", features = ["extension-module"] }
+pyo3-ffi = { version = "{{PYO3_VERSION}}" }
diff --git a/pyo3-ffi/examples/string-sum/Cargo.toml b/pyo3-ffi/examples/string-sum/Cargo.toml
index 173521eaab5..e4baa38abec 100644
--- a/pyo3-ffi/examples/string-sum/Cargo.toml
+++ b/pyo3-ffi/examples/string-sum/Cargo.toml
@@ -9,7 +9,7 @@ name = "string_sum"
crate-type = ["cdylib"]
[dependencies]
-pyo3-ffi = { path = "../../", features = ["extension-module"] }
+pyo3-ffi = { path = "../../" }
[build-dependencies]
pyo3-build-config = { path = "../../../pyo3-build-config" }
diff --git a/pyo3-ffi/src/lib.rs b/pyo3-ffi/src/lib.rs
index cb26f52c5d1..c88e7151af1 100644
--- a/pyo3-ffi/src/lib.rs
+++ b/pyo3-ffi/src/lib.rs
@@ -34,9 +34,6 @@
//!
//! - `abi3`: Restricts PyO3's API to a subset of the full Python API which is guaranteed by
//! [PEP 384] to be forward-compatible with future Python versions.
-//! - `extension-module`: This will tell the linker to keep the Python symbols unresolved, so that
-//! your module can also be used with statically linked Python interpreters. Use this feature when
-//! building an extension module.
//!
//! ## `rustc` environment flags
//!
@@ -105,9 +102,8 @@
//! # crate-type = ["cdylib", "rlib"]
//! crate-type = ["cdylib"]
//!
-//! [dependencies.pyo3-ffi]
-#![doc = concat!("version = \"", env!("CARGO_PKG_VERSION"), "\"")]
-//! features = ["extension-module"]
+//! [dependencies]
+#![doc = concat!("pyo3-ffi = \"", env!("CARGO_PKG_VERSION"), "\"")]
//!
//! [build-dependencies]
//! # This is only necessary if you need to configure your build based on
diff --git a/src/lib.rs b/src/lib.rs
index 35ac1ba1c10..ed9ed27698d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -93,9 +93,6 @@
//! [PEP 384] to be forward-compatible with future Python versions.
//! - `auto-initialize`: Changes [`Python::attach`] to automatically initialize the Python
//! interpreter if needed.
-//! - `extension-module`: This will tell the linker to keep the Python symbols unresolved, so that
-//! your module can also be used with statically linked Python interpreters. Use this feature when
-//! building an extension module.
//! - `multiple-pymethods`: Enables the use of multiple [`#[pymethods]`](macro@crate::pymethods)
//! blocks per [`#[pyclass]`](macro@crate::pyclass). This adds a dependency on the [inventory]
//! crate, which is not supported on all platforms.
@@ -181,9 +178,8 @@
//! # crate-type = ["cdylib", "rlib"]
//! crate-type = ["cdylib"]
//!
-//! [dependencies.pyo3]
-#![doc = concat!("version = \"", env!("CARGO_PKG_VERSION"), "\"")]
-//! features = ["extension-module"]
+//! [dependencies]
+#![doc = concat!("pyo3 = \"", env!("CARGO_PKG_VERSION"), "\"")]
//! ```
//!
//! **`src/lib.rs`**