Skip to content

Commit 5d9753a

Browse files
raratiruhynek
andauthored
Slightly refined documentation while reading it (#1106)
* Fixed typos in why.md * Rephrased introductory sentences * Update init.md * Update docs/init.md * Update docs/init.md * Update docs/init.md --------- Co-authored-by: Hynek Schlawack <[email protected]>
1 parent f7f0bf4 commit 5d9753a

File tree

2 files changed

+12
-11
lines changed

2 files changed

+12
-11
lines changed

docs/init.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,12 @@ Traceback (most recent call last):
213213
ValueError: 'x' has to be smaller than 'y'!
214214
```
215215

216-
This example also shows of some syntactic sugar for using the {obj}`attrs.validators.and_` validator: if you pass a list, all validators have to pass.
216+
This example demonstrates a convenience shortcut:
217+
Passing a list of validators directly is equivalent to passing them wrapped in the {obj}`attrs.validators.and_` validator and all validators must pass.
217218

218219
*attrs* won't intercept your changes to those attributes but you can always call {func}`attrs.validate` on any instance to verify that it's still valid:
219-
When using {func}`attrs.define` or [`attrs.frozen`](attrs.frozen), *attrs* will run the validators even when setting the attribute.
220+
221+
When using {func}`attrs.define` or [`attrs.frozen`](attrs.frozen), however, *attrs* will run the validators even when setting the attribute.
220222

221223
```{doctest}
222224
>>> i = C(4, 5)
@@ -241,7 +243,7 @@ TypeError: ("'x' must be <type 'int'> (got '42' that is a <type 'str'>).", Attri
241243
```
242244

243245
Of course you can mix and match the two approaches at your convenience.
244-
If you define validators both ways for an attribute, they are both ran:
246+
If you use both ways to define validators for an attribute, they are both ran:
245247

246248
```{doctest}
247249
>>> @define
@@ -263,7 +265,7 @@ Traceback (most recent call last):
263265
ValueError: value out of bounds
264266
```
265267

266-
And finally you can disable validators globally:
268+
Finally, validators can be globally disabled:
267269

268270
```{doctest}
269271
>>> attrs.validators.set_disabled(True)
@@ -276,7 +278,7 @@ Traceback (most recent call last):
276278
TypeError: ("'x' must be <class 'int'> (got '128' that is a <class 'str'>).", Attribute(name='x', default=NOTHING, validator=[<instance_of validator for type <class 'int'>>, <function fits_byte at 0x10fd7a0d0>], repr=True, cmp=True, hash=True, init=True, metadata=mappingproxy({}), type=None, converter=None), <class 'int'>, '128')
277279
```
278280

279-
You can achieve the same by using the context manager:
281+
... or within a context manager:
280282

281283
```{doctest}
282284
>>> with attrs.validators.disabled():
@@ -292,8 +294,7 @@ TypeError: ("'x' must be <class 'int'> (got '128' that is a <class 'str'>).", At
292294

293295
## Converters
294296

295-
Finally, sometimes you may want to normalize the values coming in.
296-
For that *attrs* comes with converters.
297+
Sometimes, it is necessary to normalize the values coming in, therefore *attrs* comes with converters.
297298

298299
Attributes can have a `converter` function specified, which will be called with the attribute's passed-in value to get a new value to use.
299300
This can be useful for doing type-conversions on values that you don't want to force your callers to do.
@@ -350,10 +351,10 @@ A converter will override an explicit type annotation or `type` argument.
350351

351352
## Hooking Yourself Into Initialization
352353

353-
Generally speaking, the moment you think that you need finer control over how your class is instantiated than what *attrs* offers, it's usually best to use a {obj}`classmethod` factory or to apply the [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern).
354+
Generally speaking, the moment you realize the need of finer control than what *attrs* offers – over how a class is instantiated, it's usually best to use a {obj}`classmethod` factory or to apply the [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern).
354355

355356
However, sometimes you need to do that one quick thing before or after your class is initialized.
356-
And for that *attrs* offers three means:
357+
For that purpose, *attrs* offers the following options:
357358

358359
- `__attrs_pre_init__` is automatically detected and run *before* *attrs* starts initializing.
359360
This is useful if you need to inject a call to `super().__init__()`.

docs/why.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ is roughly
269269
ArtisanalClass(a=1, b=2)
270270
```
271271

272-
which is quite a mouthful and it doesn't even use any of *attrs*'s more advanced features like validators or defaults values.
272+
which is quite a mouthful and it doesn't even use any of *attrs*'s more advanced features like validators or default values.
273273
Also: no tests whatsoever.
274274
And who will guarantee you, that you don't accidentally flip the `<` in your tenth implementation of `__gt__`?
275275

@@ -293,5 +293,5 @@ If you don't care and like typing, we're not gonna stop you.
293293

294294
However it takes a lot of bias and determined rationalization to claim that *attrs* raises the mental burden on a project given how difficult it is to find the important bits in a hand-written class and how annoying it is to ensure you've copy-pasted your code correctly over all your classes.
295295

296-
In any case, if you ever get sick of the repetitiveness and drowning important code in a sea of boilerplate, *attrs* will be waiting for you.
296+
In any case, if you ever get sick of the repetitiveness and the drowning of important code in a sea of boilerplate, *attrs* will be waiting for you.
297297
:::

0 commit comments

Comments
 (0)