diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2bded739..37c09d50 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+### Changed
+
+- Allow `#[pyo3(crate = "...", text_signature = "...")]` options to be used directly in `#[pyclass(crate = "...", text_signature = "...")]`. [#2234](https://github.com/PyO3/pyo3/pull/2234)
+
### Fixed
- Considered `PYTHONFRAMEWORK` when cross compiling in order that on macos cross compiling against a [Framework bundle](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html) is considered shared. [#2233](https://github.com/PyO3/pyo3/pull/2233)
diff --git a/guide/src/class.md b/guide/src/class.md
index e40e4a5f..3b6ad618 100644
--- a/guide/src/class.md
+++ b/guide/src/class.md
@@ -195,22 +195,16 @@ Python::with_gil(|py|{
## Customizing the class
-The `#[pyclass]` macro accepts the following parameters:
+{{#include ../../pyo3-macros/docs/pyclass_parameters.md}}
-* `name="XXX"` - Set the class name shown in Python code. By default, the struct name is used as the class name.
-* `freelist=XXX` - The `freelist` parameter adds support of free allocation list to custom class.
-The performance improvement applies to types that are often created and deleted in a row,
-so that they can benefit from a freelist. `XXX` is a number of items for the free list.
-* `gc` - Classes with the `gc` parameter participate in Python garbage collection.
-If a custom class contains references to other Python objects that can be collected, the [`PyGCProtocol`]({{#PYO3_DOCS_URL}}/pyo3/class/gc/trait.PyGCProtocol.html) trait has to be implemented.
-* `weakref` - Adds support for Python weak references.
-* `extends=BaseType` - Use a custom base class. The base `BaseType` must implement `PyTypeInfo`. `enum` pyclasses can't use a custom base class.
-* `subclass` - Allows Python classes to inherit from this class. `enum` pyclasses can't be inherited from.
-* `dict` - Adds `__dict__` support, so that the instances of this type have a dictionary containing arbitrary instance variables.
-* `unsendable` - Making it safe to expose `!Send` structs to Python, where all object can be accessed
- by multiple threads. A class marked with `unsendable` panics when accessed by another thread.
-* `module="XXX"` - Set the name of the module the class will be shown as defined in. If not given, the class
- will be a virtual member of the `builtins` module.
+[params-1]: {{#PYO3_DOCS_URL}}/pyo3/prelude/struct.PyAny.html
+[params-2]: https://en.wikipedia.org/wiki/Free_list
+[params-3]: https://doc.rust-lang.org/stable/std/marker/trait.Send.html
+[params-4]: https://doc.rust-lang.org/stable/std/rc/struct.Rc.html
+[params-5]: https://doc.rust-lang.org/stable/std/sync/struct.Rc.html
+[params-6]: https://docs.python.org/3/library/weakref.html
+
+These parameters are covered in various sections of this guide.
### Return type
@@ -716,7 +710,7 @@ num=-1
## Making class method signatures available to Python
-The [`#[pyo3(text_signature = "...")]`](./function.md#text_signature) option for `#[pyfunction]` also works for classes and methods:
+The [`text_signature = "..."`](./function.md#text_signature) option for `#[pyfunction]` also works for classes and methods:
```rust
# #![allow(dead_code)]
@@ -724,8 +718,7 @@ use pyo3::prelude::*;
use pyo3::types::PyType;
// it works even if the item is not documented:
-#[pyclass]
-#[pyo3(text_signature = "(c, d, /)")]
+#[pyclass(text_signature = "(c, d, /)")]
struct MyClass {}
#[pymethods]
diff --git a/pyo3-macros/docs/pyclass_parameters.md b/pyo3-macros/docs/pyclass_parameters.md
new file mode 100644
index 00000000..ae5ef9dd
--- /dev/null
+++ b/pyo3-macros/docs/pyclass_parameters.md
@@ -0,0 +1,28 @@
+`#[pyclass]` can be used with the following parameters:
+
+| Parameter | Description |
+| :- | :- |
+| `crate = "some::path"` | Path to import the `pyo3` crate, if it's not accessible at `::pyo3`. |
+| `dict` | Gives instances of this class an empty `__dict__` to store custom attributes. |
+| `extends = BaseType` | Use a custom baseclass. Defaults to [`PyAny`][params-1] |
+| `freelist = N` | Implements a [free list][params-2] of size N. This can improve performance for types that are often created and deleted in quick succession. Profile your code to see whether `freelist` is right for you. |
+| `module = "module_name"` | Python code will see the class as being defined in this module. Defaults to `builtins`. |
+| `name = "python_name"` | Sets the name that Python sees this class as. Defaults to the name of the Rust struct. |
+| `text_signature = "(arg1, arg2, ...)"` | Sets the text signature for the Python class' `__new__` method. |
+| `subclass` | Allows other Python classes and `#[pyclass]` to inherit from this class. Enums cannot be subclassed. |
+| `unsendable` | Required if your struct is not [`Send`][params-3]. Rather than using `unsendable`, consider implementing your struct in a threadsafe way by e.g. substituting [`Rc`][params-4] with [`Arc`][params-5]. By using `unsendable`, your class will panic when accessed by another thread.|
+| `weakref` | Allows this class to be [weakly referenceable][params-6]. |
+
+All of these parameters can either be passed directly on the `#[pyclass(...)]` annotation, or as one or
+more accompanying `#[pyo3(...)]` annotations, e.g.:
+
+```rust,ignore
+// Argument supplied directly to the `#[pyclass]` annotation.
+#[pyclass(name = "SomeName", subclass)]
+struct MyClass { }
+
+// Argument supplied as a separate annotation.
+#[pyclass]
+#[pyo3(name = "SomeName", subclass)]
+struct MyClass { }
+```
diff --git a/pyo3-macros/src/lib.rs b/pyo3-macros/src/lib.rs
index 367b37fa..a5f7faa7 100644
--- a/pyo3-macros/src/lib.rs
+++ b/pyo3-macros/src/lib.rs
@@ -81,47 +81,18 @@ pub fn pyproto(_: TokenStream, input: TokenStream) -> TokenStream {
/// A proc macro used to expose Rust structs and fieldless enums as Python objects.
///
-/// `#[pyclass]` can be used the following [parameters][2]:
-///
-/// | Parameter | Description |
-/// | :- | :- |
-/// | `crate = "some::path"` | Path to import the `pyo3` crate, if it's not accessible at `::pyo3`. |
-/// | `dict` | Gives instances of this class an empty `__dict__` to store custom attributes. |
-/// | `extends = BaseType` | Use a custom baseclass. Defaults to [`PyAny`][4] |
-/// | `freelist = N` | Implements a [free list][9] of size N. This can improve performance for types that are often created and deleted in quick succession. Profile your code to see whether `freelist` is right for you. |
-/// | `module = "module_name"` | Python code will see the class as being defined in this module. Defaults to `builtins`. |
-/// | `name = "python_name"` | Sets the name that Python sees this class as. Defaults to the name of the Rust struct. |
-/// | `text_signature = "(arg1, arg2, ...)"` | Sets the text signature for the Python class' `__new__` method. |
-/// | `subclass` | Allows other Python classes and `#[pyclass]` to inherit from this class. Enums cannot be subclassed. |
-/// | `unsendable` | Required if your struct is not [`Send`][3]. Rather than using `unsendable`, consider implementing your struct in a threadsafe way by e.g. substituting [`Rc`][7] with [`Arc`][8]. By using `unsendable`, your class will panic when accessed by another thread.|
-/// | `weakref` | Allows this class to be [weakly referenceable][6]. |
-///
-/// All of these parameters can either be passed directly on the `#[pyclass(...)]` annotation, or as one or
-/// more accompanying `#[pyo3(...)]` annotations, e.g.:
-///
-/// ```rust,ignore
-/// // Argument supplied directly to the `#[pyclass]` annotation.
-/// #[pyclass(name = "SomeName", subclass)]
-/// struct MyClass { }
-///
-/// // Argument supplied as a separate annotation.
-/// #[pyclass]
-/// #[pyo3(name = "SomeName", subclass)]
-/// struct MyClass { }
-/// ```
+#[cfg_attr(docsrs, cfg_attr(docsrs, doc = include_str!("../docs/pyclass_parameters.md")))]
///
/// For more on creating Python classes,
/// see the [class section of the guide][1].
///
/// [1]: https://pyo3.rs/latest/class.html
-/// [2]: https://pyo3.rs/latest/class.html#customizing-the-class
-/// [3]: std::marker::Send
-/// [4]: ../prelude/struct.PyAny.html
-/// [5]: https://pyo3.rs/latest/class/protocols.html#garbage-collector-integration
-/// [6]: https://docs.python.org/3/library/weakref.html
-/// [7]: std::rc::Rc
-/// [8]: std::sync::Arc
-/// [9]: https://en.wikipedia.org/wiki/Free_list
+/// [params-1]: ../prelude/struct.PyAny.html
+/// [params-2]: https://en.wikipedia.org/wiki/Free_list
+/// [params-3]: std::marker::Send
+/// [params-4]: std::rc::Rc
+/// [params-5]: std::sync::Arc
+/// [params-6]: https://docs.python.org/3/library/weakref.html
#[proc_macro_attribute]
pub fn pyclass(attr: TokenStream, input: TokenStream) -> TokenStream {
use syn::Item;