Thanks to visit codestin.com
Credit goes to github.com

Skip to content

BUG: truthiness of strings is arbitrary, context-dependent, and inconsistent #9875

Closed
@eric-wieser

Description

@eric-wieser

The following table shows the extents of the problem

x : str
sc = np.str_(x)
arr = np.array(x, np.str_)
x bool(x) bool(sc) bool(arr[()]) bool(arr) sc.astype(bool)
'' False False False False ValueError
'\0' True True False False ValueError
' ' True True True False ValueError
' \0' True True True False ValueError
'0' True True True True False
'1' True True True True True
'\0 ' True True True True ValueError
' \0 ' True True True True ValueError
def call_or_exc(f):
    try:
        return f()
    except Exception as e:
        return e

def truthiness(x):
    x_arr = np.array(x)
    x_sc = np.unicode_(x)
    x_sc2 = x_arr[()]
    return bool(x), bool(x_sc), bool(x_sc2), bool(x_arr), call_or_exc(lambda: x_sc.astype(bool))

def fmt(x):
    if isinstance(x, str): return repr(x).replace(r'\x00', r'\0')
    if isinstance(x, Exception): return type(x).__name__
    return repr(x)

print(' | '.join("`{}`".format(x) for x in ['x', 'bool(x)', 'bool(sc)', 'bool(arr[()])', 'bool(arr)', 'sc.astype(bool)']))
print(' | '.join(['--'] * 6))
for val in ['', '\0', ' ', ' \0', '0', '1', '\0 ', ' \0 ']:
   print(' | '.join("`{}`".format(fmt(x)) for x in (val,)+truthiness(val)))
Generated with...

The differences come down to:

  • bool(arr[()]) - indexing string arrays causes trailing nulls to be truncated. This is unavoidable.
  • bool(arr) - has special handling to treat spaces as falsy. This seems unpythonic, since that's not how str.__bool__ behaves - are we stuck with it
  • arr.astype(bool) - treated as arr.astype(int).astype(bool), which seems bizarre

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions