Skip to content

Commit

Permalink
added is_array()
Browse files Browse the repository at this point in the history
  • Loading branch information
Ken Kundert authored and Ken Kundert committed Feb 16, 2025
1 parent f7ab858 commit 745b33e
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 10 deletions.
2 changes: 2 additions & 0 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ Inform Utilities

.. autofunction:: inform.is_iterable

.. autofunction:: inform.is_array

.. autofunction:: inform.is_mapping

.. autofunction:: inform.is_str
Expand Down
2 changes: 2 additions & 0 deletions doc/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Latest development release
| Version: 1.33
| Released: 2024-12-11
- Added :func:`is_array`.


1.33 (2024-12-11)
-----------------
Expand Down
47 changes: 43 additions & 4 deletions doc/user.rst
Original file line number Diff line number Diff line change
Expand Up @@ -797,17 +797,25 @@ You can specify the output stream when creating an informant. If you do not,
then the stream uses is under the control of *Inform's* *stream_policy*
argument.

If *stream_policy* is set to 'termination', then all messages are sent to the
If *stream_policy* is set to 'termination' then all messages are sent to the
standard output except the final termination message, which is set to standard
error. This is suitable for programs whose output largely consists of status
messages rather than data, and so would be unlikely to be used in a pipeline.

If *stream_policy* is 'header'. then all messages with headers (those messages
If *stream_policy* is 'header' then all messages with headers (those messages
produced from informants with *severity*) are sent to the standard error stream
and all other messages are sent to the standard output. This is more suitable
for programs whose output largely consists of data and so would likely be used
in a pipeline.

If *stream_policy* is 'errors' then all error messages are sent to the standard
error stream and all other messages are sent to the standard output. This is
also commonly used for programs that act s filters.

If *stream_policy* is 'all' stderr is used for all informants that do not
explicitly set their stream. By default, no informants explicitly set their
stream, but your can create new informants and explicitly set the stream.

It is also possible for *stream_policy* to be a function that takes three
arguments, the informant and the standard output and error streams. It should
return the desired stream.
Expand Down Expand Up @@ -1534,6 +1542,37 @@ is_iterable
True
.. _is_array desc:

is_array
""""""""

.. py:function:: is_array(obj)
:noindex:

:func:`is_array` returns *True* if its argument is a list or a tuple. This
includes other list-like objects.

.. code-block:: python
>>> from inform import is_array
>>> is_array('') # string
False
>>> is_array([]) # list
True
>>> is_array(()) # tuple
True
>>> is_array({}) # dictionary
False
>>> is_array(set()) # set
False
.. _is_mapping desc:

is_mapping
Expand All @@ -1542,8 +1581,8 @@ is_mapping
.. py:function:: is_mapping(obj)
:noindex:

:func:`is_collection` returns *True* if its argument is a mapping. This
includes dictionary and other dictionary-like objects.
:func:`is_mapping` returns *True* if its argument is a mapping. This includes
dictionary and other dictionary-like objects.

.. code-block:: python
Expand Down
2 changes: 1 addition & 1 deletion inform/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .inform import (
# inform utility functions and classes
cull, indent, is_collection, is_iterable, is_mapping, is_str, join,
cull, indent, is_collection, is_iterable, is_array, is_mapping, is_str, join,
Color, Info, LoggingCache,

# user utility functions and classes
Expand Down
32 changes: 32 additions & 0 deletions inform/inform.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,41 @@ def is_collection(obj):
>>> is_collection({}) # dictionary
True
>>> is_collection(set()) # set
True
"""
return is_iterable(obj) and not is_str(obj)

# is_array {{{2
def is_array(obj):
"""Identifies objects that are is_array (tuples and arrays).
Returns *True* if argument is a sequence (tuple or list).
**Example**::
>>> from inform import is_array
>>> is_array('') # string
False
>>> is_array([]) # list
True
>>> is_array(()) # tuple
True
>>> is_array({}) # dictionary
False
>>> is_array(set()) # set
False
"""
from collections.abc import Sequence
return isinstance(obj, Sequence) and not is_str(obj)


# is_mapping {{{2
def is_mapping(obj):
"""Identifies objects that are mappings (are dictionary like).
Expand Down
1 change: 1 addition & 0 deletions inform/inform.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def is_str(arg: Any) -> bool: ...
def is_iterable(obj: Any) -> bool: ...
def is_collection(obj: Any) -> bool: ...
def is_mapping(obj: Any) -> bool: ...
def is_array(obj: Any) -> bool: ...

class Color:
enable: bool
Expand Down
19 changes: 15 additions & 4 deletions tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
from inform import (
Color, Error, Info, LoggingCache, columns, conjoin, did_you_mean, comment,
cull, dedent, display, done, error, fatal, fmt, full_stop, indent, Inform,
is_collection, is_iterable, is_mapping, is_str, join, get_prog_name,
get_informer, narrate, os_error, output, plural, render, terminate,
title_case, tree, truth, warn, ddd, ppp, sss, vvv, ProgressBar, parse_range,
format_range
is_collection, is_iterable, is_mapping, is_array, is_str, join,
get_prog_name, get_informer, narrate, os_error, output, plural, render,
terminate, title_case, tree, truth, warn, ddd, ppp, sss, vvv, ProgressBar,
parse_range, format_range
)
from textwrap import dedent as tw_dedent
import sys
Expand Down Expand Up @@ -795,20 +795,31 @@ def test_is_iterable():
assert is_iterable([]) == True
assert is_iterable(()) == True
assert is_iterable({}) == True
assert is_iterable(set()) == True

def test_is_collection():
assert is_collection(0) == False
assert is_collection('') == False
assert is_collection([]) == True
assert is_collection(()) == True
assert is_collection({}) == True
assert is_collection(set()) == True

def test_is_mapping():
assert is_mapping(0) == False
assert is_mapping('') == False
assert is_mapping([]) == False
assert is_mapping(()) == False
assert is_mapping({}) == True
assert is_mapping(set()) == False

def test_is_array():
assert is_array(0) == False
assert is_array('') == False
assert is_array([]) == True
assert is_array(()) == True
assert is_array({}) == False
assert is_array(set()) == False

def test_color():
assert Color('white', scheme='dark')('') == ''
Expand Down
2 changes: 1 addition & 1 deletion tests/test_zdoctests.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_inform():
return

rv = doctest.testfile('../inform/inform.py', optionflags=doctest.ELLIPSIS)
assert rv.attempted == 173
assert rv.attempted == 181
assert rv.failed == 0

def test_manual():
Expand Down

0 comments on commit 745b33e

Please sign in to comment.