Skip to content

Commit d67f69d

Browse files
authored
Docs edits (#706)
1 parent 1349008 commit d67f69d

File tree

3 files changed

+97
-64
lines changed

3 files changed

+97
-64
lines changed

docs/source/custom_resolvers.rst

+17-15
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ You can add additional interpolation types by registering custom resolvers with
2727
2828
Attempting to register the same resolver twice will raise a ``ValueError`` unless using ``replace=True``.
2929
30-
The example below creates a resolver that adds 10 to the given value.
30+
The example below creates a resolver that adds ``10`` to the given value.
3131
3232
.. doctest::
3333
@@ -36,9 +36,9 @@ The example below creates a resolver that adds 10 to the given value.
3636
>>> c.key
3737
1000
3838
39-
Custom resolvers support variadic argument lists in the form of a comma separated list of zero or more values.
40-
Whitespaces are stripped from both ends of each value ("foo,bar" is the same as "foo, bar ").
41-
You can use literal commas and spaces anywhere by escaping (:code:`\,` and :code:`\ `), or
39+
Custom resolvers support variadic argument lists in the form of a comma-separated list of zero or more values.
40+
In a variadic argument list, whitespace is stripped from the ends of each value ("foo,bar" gives the same result as "foo, bar ").
41+
You can use literal commas and spaces anywhere by escaping (``\,`` and :code:`\ `), or
4242
simply use quotes to bypass character limitations in strings.
4343

4444
.. doctest::
@@ -90,7 +90,7 @@ namespace, and to use interpolations in the name itself. The following example d
9090
By default a custom resolver is called on every access, but it is possible to cache its output
9191
by registering it with ``use_cache=True``.
9292
This may be useful either for performance reasons or to ensure the same value is always returned.
93-
Note that the cache is based on the string literals representing the resolver's inputs, and not
93+
Note that the cache is based on the string literals representing the resolver's inputs, not on
9494
the inputs themselves:
9595

9696
.. doctest::
@@ -121,14 +121,14 @@ the inputs themselves:
121121

122122
Custom interpolations can also receive the following special parameters:
123123

124-
- ``_parent_``: the parent node of an interpolation.
124+
- ``_parent_``: The parent node of an interpolation.
125125
- ``_root_``: The config root.
126126

127127
This can be achieved by adding the special parameters to the resolver signature.
128-
Note that special parameters must be defined as named keywords (after the `*`).
128+
Note that special parameters must be defined as named keywords (after the ``*``).
129129

130-
In the example below, we use ``_parent_`` to implement a sum function that defaults to 0 if the node does not exist.
131-
(In contrast to the sum we defined earlier where accessing an invalid key, e.g. ``"a_plus_z": ${sum:${a}, ${z}}`` would result in an error).
130+
In the example below, we use ``_parent_`` to implement a sum function that defaults to ``0`` if the node does not exist.
131+
This is in contrast to the sum we defined earlier where accessing an invalid key, e.g. ``"a_plus_z": ${sum:${a}, ${z}}``, would result in an error.
132132

133133
.. doctest::
134134

@@ -175,7 +175,8 @@ Input YAML file:
175175
'/home/omry'
176176

177177
You can specify a default value to use in case the environment variable is not set.
178-
In such a case, the default value is converted to a string using ``str(default)``, unless it is ``null`` (representing Python ``None``) - in which case ``None`` is returned.
178+
In such a case, the default value is converted to a string using ``str(default)``,
179+
unless it is ``null`` (representing Python ``None``) - in which case ``None`` is returned.
179180

180181
The following example falls back to default passwords when ``DB_PASSWORD`` is not defined:
181182

@@ -269,8 +270,8 @@ e.g. ``"true"``, ``"1"``, ``"1e-3"``, ``"{a: b}"``, ``"[a, b, c]"``.
269270

270271
Note that:
271272

272-
- In general input strings provided to ``oc.decode`` should be quoted, since only a subset of the characters is allowed in unquoted strings
273-
- ``None`` (written as ``null`` in the grammar) is the only valid non-string input to ``oc.decode`` (returning ``None`` in that case)
273+
- In general input strings provided to ``oc.decode`` should be quoted, since only a subset of the characters is allowed in unquoted strings.
274+
- ``None`` (written as ``null`` in the grammar) is the only valid non-string input to ``oc.decode`` (returning ``None`` in that case).
274275

275276
This resolver can be useful for instance to parse environment variables:
276277

@@ -366,9 +367,10 @@ Some config options that are stored as a ``DictConfig`` may sometimes be easier
366367
when we care only about the keys or the associated values.
367368

368369
The resolvers ``oc.dict.keys`` and ``oc.dict.values`` simplify such operations by offering an alternative
369-
view of a dictionary's keys or values as a list.
370-
They take as input a string that is the path to another config node (using the same syntax
371-
as interpolations) and return a ``ListConfig`` with its keys / values.
370+
view of a ``DictConfig``'s keys or values as a list,
371+
with behavior analogous to the ``dict.keys`` and ``dict.values`` methods in plain Python dictionaries.
372+
These resolvers take as input a string that is the path to another config node (using the same syntax
373+
as interpolations), and they return a ``ListConfig`` that contains keys or values of the node whose path was given.
372374

373375
.. doctest::
374376

docs/source/structured_config.rst

+51-23
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ Two types of structures classes that are supported: dataclasses and attr classes
2121
- `dataclasses <https://docs.python.org/3.7/library/dataclasses.html>`_ are standard as of Python 3.7 or newer and are available in Python 3.6 via the `dataclasses` pip package.
2222
- `attrs <https://github.com/python-attrs/attrs>`_ Offset slightly cleaner syntax in some cases but depends on the attrs pip package.
2323

24-
This documentation will use dataclasses, but you can use the annotation `@attr.s(auto_attribs=True)` from attrs instead of `@dataclass`.
24+
This documentation will use dataclasses, but you can use the annotation ``@attr.s(auto_attribs=True)`` from attrs instead of ``@dataclass``.
2525

26-
Basic usage involves passing in a structured config class or instance to OmegaConf.structured(), which will return an OmegaConf config that matches
27-
the values and types specified in the input. OmegaConf will validate modifications to the created config object at runtime against the schema specified
26+
Basic usage involves passing in a structured config class or instance to ``OmegaConf.structured()``, which will return an OmegaConf config that matches
27+
the values and types specified in the input. At runtine, OmegaConf will validate modifications to the created config object against the schema specified
2828
in the input class.
2929

3030
Simple types
@@ -52,7 +52,7 @@ The following class defines fields with all simple types:
5252
... height: Height = Height.SHORT
5353
... description: str = "text"
5454

55-
You can create a config based on the SimpleTypes class itself or instances of it.
55+
You can create a config based on the SimpleTypes class itself or an instance of it.
5656
Those would be equivalent by default, but the Object variant allows you to set the values of specific
5757
fields during construction.
5858

@@ -74,7 +74,7 @@ fields during construction.
7474
description: text
7575
<BLANKLINE>
7676

77-
The resulting object is a regular OmegaConf DictConfig, except it will utilize the type information in the input class/object
77+
The resulting object is a regular OmegaConf ``DictConfig``, except that it will utilize the type information in the input class/object
7878
and will validate the data at runtime.
7979
The resulting object and will also rejects attempts to access or set fields that are not already defined
8080
(similarly to configs with their to :ref:`struct-flag` set, but not recursive).
@@ -99,8 +99,8 @@ Python type annotation can be used by static type checkers like Mypy/Pyre or by
9999
>>> with raises(ValidationError):
100100
... conf.num = "foo"
101101

102-
This is duck-typing, the actual object type of `conf` is `DictConfig`. You can access the underlying
103-
type using `OmegaConf.get_type()`:
102+
This is duck-typing; the actual object type of ``conf`` is ``DictConfig``. You can access the underlying
103+
type using ``OmegaConf.get_type()``:
104104

105105
.. doctest::
106106

@@ -206,7 +206,8 @@ Python container types are fully supported in Structured configs.
206206

207207
Lists
208208
^^^^^
209-
Lists can hold any type supported by OmegaConf (int, float. bool, str, enum and Structured configs). Lists can be created from Lists and Tuples.
209+
Structured Config fields annotated with ``typing.List`` or ``typing.Tuple`` can hold any type
210+
supported by OmegaConf (``int``, ``float``. ``bool``, ``str``, ``Enum`` or Structured configs).
210211

211212
.. doctest::
212213

@@ -216,18 +217,19 @@ Lists can hold any type supported by OmegaConf (int, float. bool, str, enum and
216217
... name: str = MISSING
217218

218219
>>> @dataclass
219-
... class Lists:
220+
... class ListsExample:
220221
... # Typed list can hold Any, int, float, bool, str and Enums as well
221222
... # as arbitrary Structured configs
222223
... ints: List[int] = field(default_factory=lambda: [10, 20, 30])
223224
... bools: Tuple[bool, bool] = field(default_factory=lambda: (True, False))
224225
... users: List[User] = field(default_factory=lambda: [User(name="omry")])
225226

226227
OmegaConf verifies at runtime that your Lists contains only values of the correct type.
228+
In the example below, the OmegaConf object ``conf`` (which is actually an instance of ``DictConfig``) is duck-typed as ``ListExample``.
227229

228230
.. doctest::
229231

230-
>>> conf: Lists = OmegaConf.structured(Lists)
232+
>>> conf: ListsExample = OmegaConf.structured(ListsExample)
231233

232234
>>> # Okay, 10 is an int
233235
>>> conf.ints.append(10)
@@ -242,13 +244,40 @@ OmegaConf verifies at runtime that your Lists contains only values of the correc
242244

243245
Dictionaries
244246
^^^^^^^^^^^^
245-
Dictionaries are supported as well. Keys must be strings, ints or enums, and values can
246-
be any of any type supported by OmegaConf (Any, int, float, bool, str and Enums as well
247+
Dictionaries are supported via annotation of structured config fields with ``typing.Dict``.
248+
Keys must be typed as one of ``str``, ``int``, ``Enum``, ``float``, or ``bool``. Values can
249+
be any of the types supported by OmegaConf (``Any``, ``int``, ``float``, ``bool``, ``str`` and ``Enum`` as well
247250
as arbitrary Structured configs)
248251

252+
.. doctest::
253+
254+
>>> from typing import Dict
255+
>>> @dataclass
256+
... class DictExample:
257+
... # Typed dict keys are strings; values can be typed as Any, int, float, bool, str and Enums or
258+
... # arbitrary Structured configs
259+
... ints: Dict[str, int] = field(default_factory=lambda: {"a": 10, "b": 20, "c": 30})
260+
... bools: Dict[str, bool] = field(default_factory=lambda: {"Uno": True, "Zoro": False})
261+
... users: Dict[str, User] = field(default_factory=lambda: {"omry": User(name="omry")})
262+
263+
Like with Lists, the types of values contained in Dicts are verified at runtime.
264+
265+
.. doctest::
266+
267+
>>> conf: DictExample = OmegaConf.structured(DictExample)
268+
269+
>>> # Okay, correct type is assigned
270+
>>> conf.ints["d"] = 10
271+
>>> conf.bools["Dos"] = True
272+
>>> conf.users["James"] = User(name="Bond")
273+
274+
>>> # Not okay, 10 cannot be assigned to a User
275+
>>> with raises(ValidationError):
276+
... conf.users["Joe"] = 10
277+
249278
Misc
250279
----
251-
OmegaConf supports field modifiers such as MISSING and Optional.
280+
OmegaConf supports field modifiers such as ``MISSING`` and ``Optional``.
252281

253282
.. doctest::
254283

@@ -266,8 +295,8 @@ OmegaConf supports field modifiers such as MISSING and Optional.
266295
Mandatory missing values
267296
^^^^^^^^^^^^^^^^^^^^^^^^
268297

269-
Fields assigned the constant MISSING do not have a value and the value must be set prior to accessing the field
270-
Otherwise a MissingMandatoryValue exception is raised.
298+
Fields assigned the constant ``MISSING`` do not have a value and the value must be set prior to accessing the field.
299+
Otherwise a ``MissingMandatoryValue`` exception is raised.
271300

272301
.. doctest::
273302

@@ -294,8 +323,8 @@ Optional fields
294323
Interpolations
295324
^^^^^^^^^^^^^^
296325

297-
:ref:`interpolation` works normally with Structured configs but static type checkers may object to you assigning a string to another type.
298-
To work around it, use SI and II described below.
326+
:ref:`interpolation` works normally with Structured configs, but static type checkers may object to you assigning a string to another type.
327+
To work around this, use the special functions ``omegaconf.SI`` and ``omegaconf.II`` described below.
299328

300329
.. doctest::
301330

@@ -305,10 +334,10 @@ To work around it, use SI and II described below.
305334
... val: int = 100
306335
... # This will work, but static type checkers will complain
307336
... a: int = "${val}"
308-
... # This is identical to the above, but static type checkers
337+
... # This is equivalent to the above, but static type checkers
309338
... # will not complain
310339
... b: int = SI("${val}")
311-
... # This is a syntactic sugar, the input string is
340+
... # This is syntactic sugar; the input string is
312341
... # wrapped with ${} automatically.
313342
... c: int = II("val")
314343

@@ -354,7 +383,7 @@ Note however that this validation step is currently skipped for container node i
354383
Frozen
355384
^^^^^^
356385

357-
Frozen dataclasses and attr classes are supported via OmegaConf :ref:`read-only-flag`, which turns the entire config node and all if it's child nodes read-only.
386+
Frozen dataclasses and attr classes are supported via OmegaConf :ref:`read-only-flag`, which makes the entire config node and all if it's child nodes read-only.
358387

359388
.. doctest::
360389

@@ -367,7 +396,7 @@ Frozen dataclasses and attr classes are supported via OmegaConf :ref:`read-only-
367396
>>> with raises(ReadonlyConfigError):
368397
... conf.x = 20
369398

370-
Read-only flag is recursive:
399+
The read-only flag is recursive:
371400

372401
.. doctest::
373402

@@ -406,7 +435,7 @@ A Schema for the above config can be defined like this.
406435
... users: List[int] = field(default_factory=list)
407436

408437

409-
I intentionally made an error in the type of the users list (List[int] should be List[str]).
438+
I intentionally made an error in the type of the users list (``List[int]`` should be ``List[str]``).
410439
This will cause a validation error when merging the config from the file with that from the scheme.
411440

412441
.. doctest::
@@ -416,4 +445,3 @@ This will cause a validation error when merging the config from the file with th
416445
>>> with raises(ValidationError):
417446
... OmegaConf.merge(schema, conf)
418447

419-

0 commit comments

Comments
 (0)