diff --git a/docs/mypy.md b/docs/mypy.md index e4b8b8f596..3d73148c73 100644 --- a/docs/mypy.md +++ b/docs/mypy.md @@ -158,3 +158,8 @@ to annotate strings in Zulip's code. We follow the style of doing of doing `import six` and using `six.text_type` for annotation, because `text_type` is used so extensively for type annotations that we don't need to be that verbose. + +Sometimes you'll find that you have to convert strings from one type to +another. `zerver/lib/str_utils.py` has utility functions to help with that. +It also has documentation (in docstrings) which explains the right way +to use them. diff --git a/zerver/lib/str_utils.py b/zerver/lib/str_utils.py index dc465d585a..d62434877b 100644 --- a/zerver/lib/str_utils.py +++ b/zerver/lib/str_utils.py @@ -1,3 +1,35 @@ +""" +String Utilities: + +This module helps in converting strings from one type to another. + +Currently we have strings of 3 semantic types: + +1. text strings: These strings are used to represent all textual data, + like people's names, stream names, content of messages, etc. + These strings can contain non-ASCII characters, so its type should be + six.text_type (which is `str` in python 3 and `unicode` in python 2). + +2. binary strings: These strings are used to represent binary data. + This should be of type six.binary_type (which is `bytes` in python 3 + and `str` in python 2). + +3. native strings: These strings are for internal use only. Strings of + this type are not meant to be stored in database, displayed to end + users, etc. Things like exception names, parameter names, attribute + names, etc should be native strings. These strings should only + contain ASCII characters and they should have type `str`. + +There are 3 utility functions provided for converting strings from one type +to another - force_text, force_bytes, force_str + +Interconversion between text strings and binary strings can be done by +using encode and decode appropriately or by using the utility functions +force_text and force_bytes. + +It is recommended to use the utility functions for other string conversions. +""" + import six from six import text_type, binary_type from typing import Any, Mapping, Union, TypeVar @@ -7,6 +39,7 @@ NonBinaryStr = TypeVar('NonBinaryStr', str, text_type) def force_text(s): # type: (Union[text_type, binary_type]) -> text_type + """converts a string to a text string""" if isinstance(s, text_type): return s elif isinstance(s, binary_type): @@ -16,6 +49,7 @@ def force_text(s): def force_bytes(s): # type: (Union[text_type, binary_type]) -> binary_type + """converts a string to binary string""" if isinstance(s, binary_type): return s elif isinstance(s, text_type): @@ -25,6 +59,7 @@ def force_bytes(s): def force_str(s): # type: (Union[text_type, binary_type]) -> str + """converts a string to a native string""" if isinstance(s, str): return s elif isinstance(s, text_type):