Skip to content

Commit 8824dc2

Browse files
Julianhynek
authored andcommitted
Add default_role for Sphinx. (#571)
* Add default_role for Sphinx. Fix a bunch of broken refs along the way, which become errors now via -W if you have default_role set. In theory you can catch those via sphinx-build -n (i.e. nitpick mode), which IMHO is a decent idea anyhow, but it's a longer diff to enable that because it'd involve fixing a bunch of the places that try to reference types that don't exist (e.g. :type foo: Any value). But obviously can be done. Also didn't actually use this anywhere yet (the any role), but will do so in a follow-up if this is acceptable. * Remove the roles from builtin objects to demo any. * Style. * Add z.i to intersphinx. Enables the link to z.i.Interface. * Enable nitpick mode. Fix the remaining broken links or whitelist them via nitpick_ignore. * Kill all :func:s. * Kill all :class:es. * Kill all :doc:s. * Kill all :ref:s. Except one, that probably meant :func:, and which is a duplicate ref. * Kill :exc: and :data:. * Kill :mod:s. * Kill new explicit refs from the merge.
1 parent b8671ad commit 8824dc2

22 files changed

+148
-139
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ Changes:
370370
`#128 <https://github.com/python-attrs/attrs/pull/128>`_
371371
- ``__attrs_post_init__()`` is now run if validation is disabled.
372372
`#130 <https://github.com/python-attrs/attrs/pull/130>`_
373-
- Added ``attr.validators.in_(options)`` that, given the allowed `options`, checks whether the attribute value is in it.
373+
- Added ``attr.validators.in_(options)`` that, given the allowed ``options``, checks whether the attribute value is in it.
374374
This can be used to check constants, enums, mappings, etc.
375375
`#181 <https://github.com/python-attrs/attrs/pull/181>`_
376376
- Added ``attr.validators.and_()`` that composes multiple validators into one.

docs/api.rst

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
.. _api:
2-
31
API Reference
42
=============
53

64
.. currentmodule:: attr
75

8-
``attrs`` works by decorating a class using :func:`attr.s` and then optionally defining attributes on the class using :func:`attr.ib`.
6+
``attrs`` works by decorating a class using `attr.s` and then optionally defining attributes on the class using `attr.ib`.
97

108
.. note::
119

12-
When this documentation speaks about "``attrs`` attributes" it means those attributes that are defined using :func:`attr.ib` in the class body.
10+
When this documentation speaks about "``attrs`` attributes" it means those attributes that are defined using `attr.ib` in the class body.
1311

14-
What follows is the API explanation, if you'd like a more hands-on introduction, have a look at :doc:`examples`.
12+
What follows is the API explanation, if you'd like a more hands-on introduction, have a look at `examples`.
1513

1614

1715

@@ -64,7 +62,7 @@ Core
6462

6563
``attrs`` also comes with a serious business alias ``attr.attrib``.
6664

67-
The object returned by :func:`attr.ib` also allows for setting the default and the validator using decorators:
65+
The object returned by `attr.ib` also allows for setting the default and the validator using decorators:
6866

6967
.. doctest::
7068

@@ -90,7 +88,7 @@ Core
9088

9189
Instances of this class are frequently used for introspection purposes like:
9290

93-
- :func:`fields` returns a tuple of them.
91+
- `fields` returns a tuple of them.
9492
- Validators get them passed as the first argument.
9593

9694
.. warning::
@@ -148,6 +146,7 @@ Core
148146
.. autoexception:: attr.exceptions.NotAnAttrsClassError
149147
.. autoexception:: attr.exceptions.DefaultAlreadySetError
150148
.. autoexception:: attr.exceptions.UnannotatedAttributeError
149+
.. autoexception:: attr.exceptions.NotCallableError
151150

152151
For example::
153152

@@ -247,7 +246,7 @@ Helpers
247246

248247
.. autofunction:: attr.filters.exclude
249248

250-
See :ref:`asdict` for examples.
249+
See :func:`asdict` for examples.
251250

252251
.. autofunction:: attr.evolve
253252

@@ -357,7 +356,7 @@ Validators
357356

358357
.. autofunction:: attr.validators.and_
359358

360-
For convenience, it's also possible to pass a list to :func:`attr.ib`'s validator argument.
359+
For convenience, it's also possible to pass a list to `attr.ib`'s validator argument.
361360

362361
Thus the following two statements are equivalent::
363362

docs/backward-compatibility.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ Backward Compatibility
66
``attrs`` has a very strong backward compatibility policy that is inspired by the policy of the `Twisted framework <https://twistedmatrix.com/trac/wiki/CompatibilityPolicy>`_.
77

88
Put simply, you shouldn't ever be afraid to upgrade ``attrs`` if you're only using its public APIs.
9-
If there will ever be a need to break compatibility, it will be announced in the :doc:`changelog` and raise a ``DeprecationWarning`` for a year (if possible) before it's finally really broken.
9+
If there will ever be a need to break compatibility, it will be announced in the `changelog` and raise a ``DeprecationWarning`` for a year (if possible) before it's finally really broken.
1010

1111

1212
.. _exemption:
1313

1414
.. warning::
1515

16-
The structure of the :class:`attr.Attribute` class is exempt from this rule.
16+
The structure of the `attr.Attribute` class is exempt from this rule.
1717
It *will* change in the future, but since it should be considered read-only, that shouldn't matter.
1818

1919
However if you intend to build extensions on top of ``attrs`` you have to anticipate that.

docs/conf.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ def find_version(*file_paths):
3131

3232
# -- General configuration ------------------------------------------------
3333

34+
# In nitpick mode (-n), still ignore any of the following "broken" references
35+
# to non-types.
36+
nitpick_ignore = [
37+
("py:class", "Any value"),
38+
("py:class", "callable"),
39+
("py:class", "callables"),
40+
("py:class", "tuple of types"),
41+
]
42+
3443
# Add any Sphinx extension module names here, as strings. They can be
3544
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
3645
# ones.
@@ -68,6 +77,10 @@ def find_version(*file_paths):
6877
# directories to ignore when looking for source files.
6978
exclude_patterns = ["_build"]
7079

80+
# The reST default role (used for this markup: `text`) to use for all
81+
# documents.
82+
default_role = "any"
83+
7184
# If true, '()' will be appended to :func: etc. cross-reference text.
7285
add_function_parentheses = True
7386

@@ -154,7 +167,10 @@ def find_version(*file_paths):
154167
)
155168
]
156169

157-
intersphinx_mapping = {"https://docs.python.org/3": None}
170+
intersphinx_mapping = {
171+
"https://docs.python.org/3": None,
172+
"https://zopeinterface.readthedocs.io/en/latest/": None,
173+
}
158174

159175
# Allow non-local URIs so we can have images in CHANGELOG etc.
160176
suppress_warnings = ["image.nonlocal_uri"]

docs/examples.rst

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
.. _examples:
2-
31
``attrs`` by Example
42
====================
53

@@ -217,15 +215,15 @@ If you don't set ``kw_only=True``, then there's is no valid attribute ordering a
217215
Converting to Collections Types
218216
-------------------------------
219217

220-
When you have a class with data, it often is very convenient to transform that class into a :class:`dict` (for example if you want to serialize it to JSON):
218+
When you have a class with data, it often is very convenient to transform that class into a `dict` (for example if you want to serialize it to JSON):
221219

222220
.. doctest::
223221

224222
>>> attr.asdict(Coordinates(x=1, y=2))
225223
{'x': 1, 'y': 2}
226224

227225
Some fields cannot or should not be transformed.
228-
For that, :func:`attr.asdict` offers a callback that decides whether an attribute should be included:
226+
For that, `attr.asdict` offers a callback that decides whether an attribute should be included:
229227

230228
.. doctest::
231229

@@ -241,7 +239,7 @@ For that, :func:`attr.asdict` offers a callback that decides whether an attribut
241239
... filter=lambda attr, value: attr.name != "password")
242240
{'users': [{'email': '[email protected]'}, {'email': '[email protected]'}]}
243241

244-
For the common case where you want to :func:`include <attr.filters.include>` or :func:`exclude <attr.filters.exclude>` certain types or attributes, ``attrs`` ships with a few helpers:
242+
For the common case where you want to `include <attr.filters.include>` or `exclude <attr.filters.exclude>` certain types or attributes, ``attrs`` ships with a few helpers:
245243

246244
.. doctest::
247245

@@ -426,7 +424,7 @@ You can use a decorator:
426424
ValueError: value out of bounds
427425

428426

429-
``attrs`` ships with a bunch of validators, make sure to :ref:`check them out <api_validators>` before writing your own:
427+
``attrs`` ships with a bunch of validators, make sure to `check them out <api_validators>` before writing your own:
430428

431429
.. doctest::
432430

@@ -440,7 +438,7 @@ You can use a decorator:
440438
...
441439
TypeError: ("'x' must be <type 'int'> (got '42' that is a <type 'str'>).", Attribute(name='x', default=NOTHING, factory=NOTHING, validator=<instance_of validator for type <type 'int'>>, type=None, kw_only=False), <type 'int'>, '42')
442440

443-
Check out :ref:`validators` for more details.
441+
Check out `validators` for more details.
444442

445443

446444
Conversion
@@ -458,7 +456,7 @@ This can be useful for doing type-conversions on values that you don't want to f
458456
>>> o.x
459457
1
460458

461-
Check out :ref:`converters` for more details.
459+
Check out `converters` for more details.
462460

463461

464462
.. _metadata:
@@ -481,13 +479,13 @@ All ``attrs`` attributes may include arbitrary metadata in the form of a read-on
481479
Metadata is not used by ``attrs``, and is meant to enable rich functionality in third-party libraries.
482480
The metadata dictionary follows the normal dictionary rules: keys need to be hashable, and both keys and values are recommended to be immutable.
483481

484-
If you're the author of a third-party library with ``attrs`` integration, please see :ref:`Extending Metadata <extending_metadata>`.
482+
If you're the author of a third-party library with ``attrs`` integration, please see `Extending Metadata <extending_metadata>`.
485483

486484

487485
Types
488486
-----
489487

490-
``attrs`` also allows you to associate a type with an attribute using either the *type* argument to :func:`attr.ib` or -- as of Python 3.6 -- using `PEP 526 <https://www.python.org/dev/peps/pep-0526/>`_-annotations:
488+
``attrs`` also allows you to associate a type with an attribute using either the *type* argument to `attr.ib` or -- as of Python 3.6 -- using `PEP 526 <https://www.python.org/dev/peps/pep-0526/>`_-annotations:
491489

492490

493491
.. doctest::
@@ -501,7 +499,7 @@ Types
501499
>>> attr.fields(C).y.type
502500
<class 'int'>
503501

504-
If you don't mind annotating *all* attributes, you can even drop the :func:`attr.ib` and assign default values instead:
502+
If you don't mind annotating *all* attributes, you can even drop the `attr.ib` and assign default values instead:
505503

506504
.. doctest::
507505

@@ -572,11 +570,11 @@ If you'd like to enforce it, ``attrs`` will try to help:
572570
>>> i.x
573571
1
574572

575-
Please note that true immutability is impossible in Python but it will :ref:`get <how-frozen>` you 99% there.
573+
Please note that true immutability is impossible in Python but it will `get <how-frozen>` you 99% there.
576574
By themselves, immutable classes are useful for long-lived objects that should never change; like configurations for example.
577575

578576
In order to use them in regular program flow, you'll need a way to easily create new instances with changed attributes.
579-
In Clojure that function is called `assoc <https://clojuredocs.org/clojure.core/assoc>`_ and ``attrs`` shamelessly imitates it: :func:`attr.evolve`:
577+
In Clojure that function is called `assoc <https://clojuredocs.org/clojure.core/assoc>`_ and ``attrs`` shamelessly imitates it: `attr.evolve`:
580578

581579
.. doctest::
582580

@@ -598,7 +596,7 @@ Other Goodies
598596
-------------
599597

600598
Sometimes you may want to create a class programmatically.
601-
``attrs`` won't let you down and gives you :func:`attr.make_class` :
599+
``attrs`` won't let you down and gives you `attr.make_class` :
602600

603601
.. doctest::
604602

@@ -625,7 +623,7 @@ You can still have power over the attributes if you pass a dictionary of name: `
625623
>>> i.y
626624
[]
627625

628-
If you need to dynamically make a class with :func:`attr.make_class` and it needs to be a subclass of something else than ``object``, use the ``bases`` argument:
626+
If you need to dynamically make a class with `attr.make_class` and it needs to be a subclass of something else than ``object``, use the ``bases`` argument:
629627

630628
.. doctest::
631629

docs/extending.rst

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
.. _extending:
2-
31
Extending
42
=========
53

64
Each ``attrs``-decorated class has a ``__attrs_attrs__`` class attribute.
7-
It is a tuple of :class:`attr.Attribute` carrying meta-data about each attribute.
5+
It is a tuple of `attr.Attribute` carrying meta-data about each attribute.
86

97
So it is fairly simple to build your own decorators on top of ``attrs``:
108

@@ -23,7 +21,7 @@ So it is fairly simple to build your own decorators on top of ``attrs``:
2321

2422
.. warning::
2523

26-
The :func:`attr.s` decorator **must** be applied first because it puts ``__attrs_attrs__`` in place!
24+
The `attr.s` decorator **must** be applied first because it puts ``__attrs_attrs__`` in place!
2725
That means that is has to come *after* your decorator because::
2826

2927
@a
@@ -53,7 +51,7 @@ Types
5351
``attrs`` offers two ways of attaching type information to attributes:
5452

5553
- `PEP 526 <https://www.python.org/dev/peps/pep-0526/>`_ annotations on Python 3.6 and later,
56-
- and the *type* argument to :func:`attr.ib`.
54+
- and the *type* argument to `attr.ib`.
5755

5856
This information is available to you:
5957

docs/glossary.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ Glossary
3636
- Slotted classes can inherit from other classes just like non-slotted classes, but some of the benefits of slotted classes are lost if you do that.
3737
If you must inherit from other classes, try to inherit only from other slotted classes.
3838

39-
- Slotted classes must implement :meth:`__getstate__ <object.__getstate__>` and :meth:`__setstate__ <object.__setstate__>` to be serializable with :mod:`pickle` protocol 0 and 1.
39+
- Slotted classes must implement :meth:`__getstate__ <object.__getstate__>` and :meth:`__setstate__ <object.__setstate__>` to be serializable with `pickle` protocol 0 and 1.
4040
Therefore, ``attrs`` creates these methods automatically for ``slots=True`` classes (Python 2 uses protocol 0 by default).
4141

4242
.. note::
4343

4444
If the ``@attr.s(slots=True)`` decorated class already implements the :meth:`__getstate__ <object.__getstate__>` and :meth:`__setstate__ <object.__setstate__>` methods, they will be *overridden* by ``attrs`` autogenerated implementation.
4545

46-
Also, `think twice <https://www.youtube.com/watch?v=7KnfGDajDQw>`_ before using :mod:`pickle`.
46+
Also, `think twice <https://www.youtube.com/watch?v=7KnfGDajDQw>`_ before using `pickle`.
4747

4848
- Slotted classes are weak-referenceable by default.
4949
This can be disabled in CPython by passing ``weakref_slot=False`` to ``@attr.s`` [#pypyweakref]_.

docs/hashing.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ Hash Method Generation
1515
Setting ``hash`` yourself can have unexpected consequences so we recommend to tinker with it only if you know exactly what you're doing.
1616

1717
Under certain circumstances, it's necessary for objects to be *hashable*.
18-
For example if you want to put them into a :class:`set` or if you want to use them as keys in a :class:`dict`.
18+
For example if you want to put them into a `set` or if you want to use them as keys in a `dict`.
1919

2020
The *hash* of an object is an integer that represents the contents of an object.
21-
It can be obtained by calling :func:`hash` on an object and is implemented by writing a ``__hash__`` method for your class.
21+
It can be obtained by calling `hash` on an object and is implemented by writing a ``__hash__`` method for your class.
2222

2323
``attrs`` will happily write a ``__hash__`` method for you [#fn1]_, however it will *not* do so by default.
2424
Because according to the definition_ from the official Python docs, the returned hash has to fulfill certain constraints:
2525

2626
#. Two objects that are equal, **must** have the same hash.
2727
This means that if ``x == y``, it *must* follow that ``hash(x) == hash(y)``.
2828

29-
By default, Python classes are compared *and* hashed by their :func:`id`.
29+
By default, Python classes are compared *and* hashed by their `id`.
3030
That means that every instance of a class has a different hash, no matter what attributes it carries.
3131

3232
It follows that the moment you (or ``attrs``) change the way equality is handled by implementing ``__eq__`` which is based on attribute values, this constraint is broken.
@@ -65,7 +65,7 @@ For a more thorough explanation of this topic, please refer to this blog post: `
6565

6666
Hashing and Mutability
6767
----------------------
68-
Changing any field involved in hash code computation after the first call to `__hash__` (typically this would be after its insertion into a hash-based collection) can result in silent bugs.
68+
Changing any field involved in hash code computation after the first call to ``__hash__`` (typically this would be after its insertion into a hash-based collection) can result in silent bugs.
6969
Therefore, it is strongly recommended that hashable classes be ``frozen.``
7070
Beware, however, that this is not a complete guarantee of safety:
7171
if a field points to an object and that object is mutated, the hash code may change, but ``frozen`` will not protect you.

docs/how-does-it-work.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ No magic, no meta programming, no expensive introspection at runtime.
3939

4040
Everything until this point happens exactly *once* when the class is defined.
4141
As soon as a class is done, it's done.
42-
And it's just a regular Python class like any other, except for a single ``__attrs_attrs__`` attribute that can be used for introspection or for writing your own tools and decorators on top of ``attrs`` (like :func:`attr.asdict`).
42+
And it's just a regular Python class like any other, except for a single ``__attrs_attrs__`` attribute that can be used for introspection or for writing your own tools and decorators on top of ``attrs`` (like `attr.asdict`).
4343

4444
And once you start instantiating your classes, ``attrs`` is out of your way completely.
4545

@@ -51,7 +51,7 @@ This **static** approach was very much a design goal of ``attrs`` and what I str
5151
Immutability
5252
------------
5353

54-
In order to give you immutability, ``attrs`` will attach a ``__setattr__`` method to your class that raises a :exc:`attr.exceptions.FrozenInstanceError` whenever anyone tries to set an attribute.
54+
In order to give you immutability, ``attrs`` will attach a ``__setattr__`` method to your class that raises a `attr.exceptions.FrozenInstanceError` whenever anyone tries to set an attribute.
5555

5656
Depending on whether a class is a dict class or a slotted class, ``attrs`` uses a different technique to circumvent that limitation in the ``__init__`` method.
5757

0 commit comments

Comments
 (0)