For the glossary:
- distribution
In some operating systems, the kernel of the OS is produced by one organization but this is combined with other necessary tools by a second organization. This second organization is called a distribution.
- native string
Python2 and Python3 have different types for unadorned string literals and many strings operations. In Python2, these are byte strings. In Python3, these are text strings.
Note
In very old code, modules would specify that a parameter was a boolean by listing something like this in the argument_spec
:
- module = AnsibleModule(
- argument_spec=dict(
return_status=dict(choices=BOOLEANS),
),
)
This pattern is not very flexible and can cause issues in cornercases. It should no longer be used. Switch to using the type field instead:
module = AnsibleModule( argument_spec=dict( return_status=dict(type='bool'), ), )
Core team members, should we change get_all_subclasses() to return a set/frozenset? Right now, it returns a list and elements could be repeated
Core team members, do we want to change this API? Instead of returning an instantiated class, return the class and make the caller instantiate it. Doing that will mean we don't have to pass in *args
and **kwargs
.
These globals are not for use by other code. Documenting here for people who need to modify basic.py
.
Analogs to these are either in six or one of the ansible.module_utils.pycompatXY modules:
Deprecated New Way to Achieve this ---------- -----------------------imap ansible.module_utils.six.moves.map basestring ansible.module_utils.six.string_types or (ansible.module_utils.six.text_type, ansible.module_utils.six.binary_type) unicode ansible.module_utils.six.text_type or (ansible.module_utils._text.to_native, ansible.module_utils._text.to_text) [@]_ bytes ansible.module_utils.six.binary_type or (ansible.module_utils._text.to_bytes, ansible.module_utils._text.to_native) [@]_ iteritems ansible.module_utils.six.iteritems reduce ansible.module_utils.six.moves import reduce NUMBERTYPES ansible.module_utils.six.integer_types + (float,) [+]_ NoneType ansible.module_utils.pycompat27.NoneType ## Need to move Sequence ansible.module_utils.pycompat24.Sequence ## Need to move Mapping ansible.module_utils.pycompat24.Mapping ## Need to move SEQUENCETYPE ansible.module_utils.pycompat27.SEQUENCETYPE ## Need to move json ansible.module_utils.pycompat24.json ## Need to move literal_eval ansible.module_utils.pycompat24.literal_eval get_exception ansible.module_utils.pycompat24.get_exception
- if not isinstance(variable, basestring):
# Get the string representation of the object variable = str(variable)
- if not isinstance(variable, unicode):
# Make sure a string is unicode for the API we're calling variable = unicode(variable, 'utf-'8')
Those should be replaced with code like this:
if not isinstance(variable, (six.binary_type, six.text_type)): # Get the string representation of the object variable = to_native(variable, errors='surrogate_or_strict') if not isinstance(variable, six.text_type): # Make sure a string is the platform's text type (unicode on py2, str on py3) variable = to_text(variable, 'utf-8')
For converting between text and bytes use
ansible.module_utils._text.to_text
andansible.module_utils._text.to_bytes
:# Original: text_string = unicode("Toshio wrote this", encoding='utf-8') byte_string = bytes(u"Toshio wrote this", 'utf-8') # New: text_string = to_text("Toshio wrote this", errors='surrogate_or_strict') byte_string = to_bytes(u"Toshio wrote this", errors='surrogate_or_strict')
For converting between an unknown object and its string representation (for instance, for printing an informational error message), use the
nonstring
argument to to_text and `to_bytes`:# Original: text_msg = u'Error: Can not process: %s' % unicode({'An object': 'value'}, encoding='utf-8') byte_msg = 'Error: Can not process: %s' % bytes({'An object': 'value'}, 'utf-8') # New: text_msg = u'Error: Can not process: %s' % to_text({'An object': 'value'}, nonstring='simplerepr') byte_msg = to_bytes('Error: Can not process: %s' % to_native({'An object': 'value'}, nonstring='simplerepr')) # byte_msg is different because the original was not safe on python3
For testing whether a value is a text or byte string:
# Original: if isinstance('string', unicode): pass if isinstance('string', bytes): pass # New: if isinstance('string', text_type): pass if isinstance('string', binary_type): pass # Old code: from ansible.module_utils.basic import NUMBERTYPES if isinstance(obj, NUMBERTYPES): return str(obj) from ansible.module_utils.six import integer_types # New code: if isinstance(obj, integer_types + (float,)): return str(obj)
Move the deprecated values that belong in pycompatXY into those files.
Ansible Core Team -- do we want to make an ansible.module_utils.json with this and other json-related functions? (Or put this into a pycompat* as it's only for python-2.4 which doesn't have the stdlib json library)?
Rename these to have a leading underscore to mark them as private
If we switch to inline documentation, attributes are documented like this:
#: All the values that parameter parsing converts to True
BOOLEANS_TRUE = ['yes', 'on', '1', 'true', 'True', 1, True]
#: All the values that parameter parsing converts to False
BOOLEANS_FALSE = ['no', 'off', '0', 'false', 'False', 0, False]
This list of functions needs to be further documented
Move to _text
heading. Should we make text.converters
for what's there currently and text.formatters
for these?
Version 2 of AnsibleModule should contain functionality that sets up a Module similar to how GUI frameworks have an App
class that sets up an Application environment. Parameter parsing and registering how to exit from the Module seem like things which are AnsibleModule responsibilities.
- Entrypoint for current AnsibleModules
- Going to need a new AnsibleModule
- Going to split most methods out of it
- New focus should be
- parameter handling.
- return values?
- log_sanitization?
- Initialization is all about handling parameters
Same categories as for the functions. Many of these will need to be ported from being methods to being functions.
===> hashing
I've started some of this work which you can see at ansible/ansible@devel...sivel:categorization-of-basic
Some notes:
AnsibleModule
doesn't have the same signature, as it now expects to be passed a callable for the param validator which is it's own class, and instantiated separately.AnsibleModule
needing access to some internals, I've exposed those as attributes. This allows for a pluggable validator to be used, but we will only shipAnsibleParamsValidator
for now. Some sanity checks are needed.basic.py
and largely where they were methods, they are encapsulated in aDummyClass
right now, but that needs resolved.basic.py
, we should remove frombasic.py
and import from the new correct locations. Backwards compat in mind for what seems reasonable. I've tried to document someTODO
lines inbasic.py
and elsewhere that need remediated as a result of the splits, but not everywhere.