22``web_poet.fields`` is a module with helpers for putting extraction logic
33into separate Page Object methods / properties.
44"""
5+ from __future__ import annotations
6+
57import inspect
68from contextlib import suppress
79from functools import update_wrapper , wraps
1012import attrs
1113from itemadapter import ItemAdapter
1214
15+ import web_poet
1316from web_poet .utils import cached_method , ensure_awaitable
1417
1518_FIELDS_INFO_ATTRIBUTE_READ = "_web_poet_fields_info"
@@ -226,28 +229,30 @@ def _without_unsupported_field_names(
226229
227230@attrs .define
228231class SelectFields :
229- """This is used as a dependency in :class:`web_poet.pages. ItemPage` to
230- control which fields to populate its returned item class.
232+ """This is used as a dependency in :class:`~. ItemPage` to control which
233+ fields to populate its returned item class.
231234
232- You can use this to enable some fields that were disabled by the
233- ``@field(disabled=True)`` decorator.
235+ You can also use this to enable some fields that were disabled by default
236+ via the ``@field(disabled=True)`` decorator.
234237
235238 Some usage examples:
236239
237- * ``SelectFields({"name": True})`` - select one specific field
238- * ``SelectFields({"*": True})`` - select all fields
239- * ``SelectFields({"*": False, "name": True})`` - unselect all fields
240- except one
240+ * ``SelectFields({"name": True})`` — select one field
241+ * ``SelectFields({"name": False})`` — unselect one field
242+ * ``SelectFields({"*": True})`` — select all fields
243+ * ``SelectFields({"*": True, "name": False})`` — select all fields but one
244+ * ``SelectFields({"*": False, "name": True})`` — unselect all fields but one
241245
242246 """
243247
244- #: Fields that the page object would use to populate its item class. It's a
245- #: mapping of field names to boolean values to where ``True`` would indicate
246- #: it being included in ``.to_item()`` calls.
248+ #: Fields that the page object would use to populate the
249+ #: :meth:`~.Returns.item_cls` it returns. It's a mapping of field names to
250+ #: boolean values where ``True`` would indicate it being included when using
251+ #: :meth:`~.ItemPage.to_item()` and :func:`~.item_from_select_fields`.
247252 fields : Mapping [str , bool ] = attrs .field (converter = lambda x : x or {})
248253
249254
250- def _validate_select_fields (page ) -> None :
255+ def _validate_select_fields (page : web_poet . ItemPage ) -> None :
251256 fields = page .select_fields .fields
252257
253258 if fields is None or len (fields ) == 0 :
@@ -279,26 +284,14 @@ def _validate_select_fields(page) -> None:
279284 )
280285
281286
282- async def item_from_select_fields (page ) -> Any :
283- """Return an item from the given page object instance.
284-
285- When passing a page object that uses at the ``@field`` decorator, it's the
286- same as calling the original :meth:`web_poet.pages.ItemPage.to_item` method
287- of :class:`web_poet.pages.ItemPage`.
288-
289- When passing a page object that *doesn't* use any ``@field`` decorators at
290- all and instead populates its item class by overriding the
291- :meth:`web_poet.pages.ItemPage.to_item` method, it would essentially call
292- the overridden ``.to_item()`` method and drop any fields specified in the
293- :class:`web_poet.fields.SelectFields` instance.
294-
295- .. warning::
287+ async def item_from_select_fields (page : web_poet .ItemPage ) -> Any :
288+ """Returns an item produced by the given page object instance.
296289
297- However, when passing a page object that partially uses the ``@field` `
298- decorator where some fields are populated in an overridden
299- :meth:`web_poet.pages.ItemPage.to_item` method, the page object should
300- make sure that :meth:`web_poet.pages. ItemPage.fields_to_ignore`
301- is taken into account when populating the fields .
290+ This ensures that the fields specified inside the :class:`~.SelectFields `
291+ instance are taken into account alongside any fields that are disabled by
292+ default (i.e. ``@field(disabled=True)``. This is done by calling the
293+ :meth:`~. ItemPage.to_item` method and simply dropping any field that should
294+ not be included .
302295 """
303296
304297 _validate_select_fields (page )
@@ -314,4 +307,4 @@ async def item_from_select_fields(page) -> Any:
314307 ):
315308 continue
316309 kwargs [k ] = v
317- return item . __class__ (** kwargs )
310+ return page . item_cls (** kwargs )
0 commit comments