summaryrefslogtreecommitdiff
path: root/src/lxml/html
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2020-08-12 08:14:00 +0200
committerStefan Behnel <stefan_ml@behnel.de>2020-08-12 08:14:00 +0200
commit0b23ce6b61047303b1c9dc93a56bdaa6ba703793 (patch)
treef2f812cae6a34a3728d3722f6ee809523b77e3ef /src/lxml/html
parentfcf0efcbb256d48b75cc6c4d0766d1643c6086ea (diff)
downloadpython-lxml-0b23ce6b61047303b1c9dc93a56bdaa6ba703793.tar.gz
html: Add InputGetter.items() method and make .keys() return the field names in document order.
Diffstat (limited to 'src/lxml/html')
-rw-r--r--src/lxml/html/__init__.py39
-rw-r--r--src/lxml/html/tests/test_forms.txt16
2 files changed, 47 insertions, 8 deletions
diff --git a/src/lxml/html/__init__.py b/src/lxml/html/__init__.py
index 6649268b..2139c75a 100644
--- a/src/lxml/html/__init__.py
+++ b/src/lxml/html/__init__.py
@@ -1176,7 +1176,8 @@ class InputGetter(object):
``form.inputs['field_name']``. If there are a set of checkboxes
with the same name, they are returned as a list (a `CheckboxGroup`
which also allows value setting). Radio inputs are handled
- similarly.
+ similarly. Use ``.keys()`` and ``.items()`` to process all fields
+ in this way.
You can also iterate over this to get all input elements. This
won't return the same thing as if you get all the names, as
@@ -1195,7 +1196,7 @@ class InputGetter(object):
## a dictionary-like object or list-like object
def __getitem__(self, name):
- fields = [field for field in self if field.get('name') == name]
+ fields = [field for field in self if field.name == name]
if not fields:
raise KeyError("No input element with the name %r" % name)
@@ -1214,17 +1215,39 @@ class InputGetter(object):
def __contains__(self, name):
for field in self:
- if field.get('name') == name:
+ if field.name == name:
return True
return False
def keys(self):
- names = set()
+ """
+ Returns all unique field names, in document order.
+
+ :return: A list of all unique field names.
+ """
+ names = []
+ seen = {None}
+ for el in self:
+ name = el.name
+ if name not in seen:
+ names.append(name)
+ seen.add(name)
+ return names
+
+ def items(self):
+ """
+ Returns all fields with their names, similar to dict.items().
+
+ :return: A list of (name, field) tuples.
+ """
+ items = []
+ seen = set()
for el in self:
- names.add(el.name)
- if None in names:
- names.remove(None)
- return list(names)
+ name = el.name
+ if name not in seen:
+ seen.add(name)
+ items.append((name, self[name]))
+ return items
def __iter__(self):
return self.form.iter('select', 'input', 'textarea')
diff --git a/src/lxml/html/tests/test_forms.txt b/src/lxml/html/tests/test_forms.txt
index c173f837..5d7d5139 100644
--- a/src/lxml/html/tests/test_forms.txt
+++ b/src/lxml/html/tests/test_forms.txt
@@ -49,8 +49,20 @@ u'http://example.org/form.html'
u'http://example.org/test'
>>> f.method
'GET'
+
>>> f.inputs # doctest:+NOPARSE_MARKUP
<InputGetter for form 0>
+>>> len(f.inputs)
+20
+>>> len(list(f.inputs))
+20
+>>> len(f.inputs.keys())
+15
+>>> len(f.inputs.items())
+15
+>>> len([f.inputs[name] for name in f.inputs.keys()])
+15
+
>>> hidden = f.inputs['hidden_field']
>>> hidden.checkable
False
@@ -162,6 +174,8 @@ hidden_field=new+value&text_field=text_value&single_checkbox=on&single_checkbox2
>>> fields = f.fields
>>> fields # doctest:+NOPARSE_MARKUP
<FieldsDict for form 0>
+>>> len(fields)
+20
>>> for name, value in sorted(fields.items()):
... print('%s: %r' % (name, value))
check_group: <CheckboxValues {'1', '2', '3'} for checkboxes name='check_group'>
@@ -195,6 +209,8 @@ textarea_field: 'some text'
<Element form at ...>
>>> tree.forms[0].fields # doctest: +NOPARSE_MARKUP
<FieldsDict for form 0>
+>>> len(tree.forms[0].fields)
+2
>>> list(tree.forms[0].fields.keys())
['foo']
>>> list(tree.forms[0].fields.items())