1616_FIELDS_INFO_ATTRIBUTE_WRITE = "_web_poet_fields_info_temp"
1717
1818
19+ def _fields_template ():
20+ return {"enabled" : {}, "disabled" : {}}
21+
22+
1923@attrs .define
2024class FieldInfo :
2125 """Information about a field"""
@@ -29,6 +33,9 @@ class FieldInfo:
2933 #: field processors
3034 out : Optional [List [Callable ]] = None
3135
36+ #: when set to ``True``, the field is not populated on ``.to_item()`` calls.
37+ disabled : bool = False
38+
3239
3340class FieldsMixin :
3441 """A mixin which is required for a class to support fields"""
@@ -39,11 +46,24 @@ def __init_subclass__(cls, **kwargs):
3946 # between subclasses, i.e. a decorator in a subclass doesn't affect
4047 # the base class. This is done by making decorator write to a
4148 # temporary location, and then merging it all on subclass creation.
42- this_class_fields = getattr (cls , _FIELDS_INFO_ATTRIBUTE_WRITE , {})
43- base_class_fields = getattr (cls , _FIELDS_INFO_ATTRIBUTE_READ , {})
49+ this_class_fields = getattr (
50+ cls , _FIELDS_INFO_ATTRIBUTE_WRITE , _fields_template ()
51+ )
52+ base_class_fields = getattr (
53+ cls , _FIELDS_INFO_ATTRIBUTE_READ , _fields_template ()
54+ )
4455 if base_class_fields or this_class_fields :
45- fields = {** base_class_fields , ** this_class_fields }
46- setattr (cls , _FIELDS_INFO_ATTRIBUTE_READ , fields )
56+ enabled = {** base_class_fields ["enabled" ], ** this_class_fields ["enabled" ]}
57+ disabled = {** this_class_fields ["disabled" ]}
58+ for name , info in this_class_fields ["disabled" ].items ():
59+ if name in enabled :
60+ del enabled [name ]
61+ disabled [name ] = info
62+ setattr (
63+ cls ,
64+ _FIELDS_INFO_ATTRIBUTE_READ ,
65+ {"enabled" : enabled , "disabled" : disabled },
66+ )
4767 with suppress (AttributeError ):
4868 delattr (cls , _FIELDS_INFO_ATTRIBUTE_WRITE )
4969
@@ -54,6 +74,7 @@ def field(
5474 cached : bool = False ,
5575 meta : Optional [dict ] = None ,
5676 out : Optional [List [Callable ]] = None ,
77+ disabled : bool = False ,
5778):
5879 """
5980 Page Object method decorated with ``@field`` decorator becomes a property,
@@ -85,10 +106,11 @@ def __init__(self, method):
85106
86107 def __set_name__ (self , owner , name ):
87108 if not hasattr (owner , _FIELDS_INFO_ATTRIBUTE_WRITE ):
88- setattr (owner , _FIELDS_INFO_ATTRIBUTE_WRITE , {} )
109+ setattr (owner , _FIELDS_INFO_ATTRIBUTE_WRITE , _fields_template () )
89110
90- field_info = FieldInfo (name = name , meta = meta , out = out )
91- getattr (owner , _FIELDS_INFO_ATTRIBUTE_WRITE )[name ] = field_info
111+ field_info = FieldInfo (name = name , meta = meta , out = out , disabled = disabled )
112+ switch = "disabled" if disabled else "enabled"
113+ getattr (owner , _FIELDS_INFO_ATTRIBUTE_WRITE )[switch ][name ] = field_info
92114
93115 def __get__ (self , instance , owner = None ):
94116 return self .unbound_method (instance )
@@ -125,12 +147,20 @@ def processed(*args, **kwargs):
125147 return _field
126148
127149
128- def get_fields_dict (cls_or_instance ) -> Dict [str , FieldInfo ]:
150+ def get_fields_dict (
151+ cls_or_instance , include_disabled : bool = False
152+ ) -> Dict [str , FieldInfo ]:
129153 """Return a dictionary with information about the fields defined
130154 for the class: keys are field names, and values are
131155 :class:`web_poet.fields.FieldInfo` instances.
132156 """
133- return getattr (cls_or_instance , _FIELDS_INFO_ATTRIBUTE_READ , {})
157+ fields_info = getattr (
158+ cls_or_instance , _FIELDS_INFO_ATTRIBUTE_READ , _fields_template ()
159+ )
160+ fields_dict = fields_info ["enabled" ]
161+ if include_disabled :
162+ fields_dict .update (fields_info ["disabled" ])
163+ return fields_dict
134164
135165
136166T = TypeVar ("T" )
0 commit comments