Projet

Général

Profil

0001-formdata-return-missing-boolean-value-as-False-not-N.patch

Frédéric Péters, 22 janvier 2021 12:55

Télécharger (5,49 ko)

Voir les différences:

Subject: [PATCH] formdata: return missing boolean value as False, not None
 (#50428)

 tests/test_formdata.py            |  8 ++++++--
 tests/test_workflows.py           |  9 +++++++++
 wcs/qommon/templatetags/qommon.py |  4 ++++
 wcs/variables.py                  | 24 ++++++++++++++++++++----
 4 files changed, 39 insertions(+), 6 deletions(-)
tests/test_formdata.py
591 591
    formdef.name = 'foobarlazy'
592 592
    formdef.fields = [
593 593
        fields.StringField(id='0', label='string', varname='foo_foo'),
594
        fields.BoolField(id='1', label='checkbox', varname='boolfield'),
595
        fields.BoolField(id='2', label='checkbox', varname='boolfield2'),
594
        fields.BoolField(id='1', label='checkbox', varname='boolfield', type='bool'),
595
        fields.BoolField(id='2', label='checkbox', varname='boolfield2', type='bool'),
596
        fields.BoolField(id='2b', label='checkbox', varname='boolfield3', type='bool'),
596 597
        fields.DateField(id='3', label='date', varname='datefield'),
597 598
        fields.ItemsField(id='4', label='items', items=['aa', 'ab', 'ac'], varname='itemsfield'),
598 599
        fields.FileField(id='5', label='file', varname='filefield'),
......
669 670
    assert lazy_formdata.var.foo_foo == 'bar'
670 671
    assert lazy_formdata.var.boolfield == 'False'
671 672
    assert bool(lazy_formdata.var.boolfield) is False
673
    assert lazy_formdata.var.boolfield.raw is False
672 674
    assert lazy_formdata.var.boolfield2 == 'True'
675
    assert lazy_formdata.var.boolfield2.raw is True
673 676
    assert bool(lazy_formdata.var.boolfield2) is True
677
    assert lazy_formdata.var.boolfield3.raw is False
674 678
    assert lazy_formdata.var.datefield.raw == time.strptime('2018-07-31', '%Y-%m-%d')
675 679
    assert lazy_formdata.var.datefield.tm_year == 2018
676 680
    assert lazy_formdata.var.datefield.tm_mon == 7
tests/test_workflows.py
2294 2294
        'bool': False,
2295 2295
    }
2296 2296

  
2297
    # check an empty boolean field is sent as False
2298
    del formdata.data['6']
2299
    with get_publisher().complex_data():
2300
        item.perform(formdata)
2301
    assert http_requests.get_last('url') == 'http://remote.example.net'
2302
    assert http_requests.get_last('method') == 'POST'
2303
    payload = json.loads(http_requests.get_last('body'))
2304
    assert payload['bool'] is False
2305

  
2297 2306
    # check it's possible to disable complex data support
2298 2307
    pub.load_site_options()
2299 2308
    pub.site_options.set('options', 'complex-data', 'false')
wcs/qommon/templatetags/qommon.py
216 216
def parse_decimal(value, do_raise=False):
217 217
    if hasattr(value, 'get_value'):
218 218
        value = value.get_value()  # unlazy
219
    if isinstance(value, bool):
220
        # treat all booleans as 0 (contrary to Python behaviour where
221
        # decimal(True) == 1).
222
        value = 0
219 223
    if isinstance(value, six.string_types):
220 224
        # replace , by . for French users comfort
221 225
        value = value.replace(',', '.')
wcs/variables.py
605 605
                raise
606 606
            maybe_varname = key.rsplit('_', 1)[0]
607 607
            field = self.varnames[maybe_varname]
608
            if key.endswith('_raw') and field.type == 'bool':
609
                # turn None into False so boolean fields are always a boolean.
610
                return bool(self._data.get(field.id))
611

  
608 612
            if self._data.get(field.id) in (None, True, False):
609 613
                # valid suffix and data of the correct type
610 614
                return self._data.get(field.id)
611 615
            raise KeyError(key)
612 616

  
613
        if self._data.get(field.id) is None:
614
            return None
617
        # let boolean pass through, to get None handled as False
618
        if field.type != 'bool':
619
            if self._data.get(field.id) is None:
620
                return None
615 621

  
616
        if str(field.id) not in self._data:
617
            raise KeyError(key)
622
            if str(field.id) not in self._data:
623
                raise KeyError(key)
618 624

  
619 625
        klass = LazyFieldVar
620 626
        if field.store_structured_value:
......
625 631
            'password': LazyFieldVarPassword,
626 632
            'file': LazyFieldVarFile,
627 633
            'block': LazyFieldVarBlock,
634
            'bool': LazyFieldVarBool,
628 635
        }.get(field.key, klass)
629 636

  
630 637
        return klass(**self.get_field_kwargs(field))
......
922 929
        return ['lat', 'lon']
923 930

  
924 931

  
932
class LazyFieldVarBool(LazyFieldVar):
933
    def get_value(self):
934
        return bool(self._data.get(self._field.id))
935

  
936
    @property
937
    def raw(self):
938
        return self.get_value()
939

  
940

  
925 941
class LazyFieldVarPassword(LazyFieldVar):
926 942
    def __getitem__(self, key):
927 943
        # get subpart (cleartext, md5, sha1) if it exists
928
-