Source code for pyardrone.at.parameters

import enum
import functools
import json
import io
import operator

from pyardrone.utils import repack_to_int


[docs]class Parameter: ''' Base class of all at command parameters. :param description: description of the parameter, stored in __doc__ :param default: default value of the parameter ''' def __init__(self, description='', default=None, name=None, index=None): self.__doc__ = description self._default = default self._name = name self._index = index def __repr__(self): if self._name is not None: return '<{self.__class__.__name__}:{self._name}>'.format(self=self) else: return super().__repr__() def __get__(self, obj, type=None): if obj is None: return self else: return obj[self._index] def __set__(self, obj, value): raise AttributeError( '{} of {} not settable, please use {}._replace'.format( self._name, obj, obj.__class__.__name__)) @staticmethod
[docs] def _check(value): ''' Checks the value on :py:class:`~pyardrone.at.base.ATCommand`\ 's init. Subclasses can optionally define this method, the default implementation is a no-op. :raises TypeError: If the value is of the wrong type. :raises ValueError: If the value is not valid. '''
@staticmethod
[docs] def _pack(value): ''' Packs the value. Subclasses should define this method. :rtype: bytes ''' raise NotImplementedError
[docs]class Int32(Parameter): ''' Parameter class of a 32-bit integer. ''' @staticmethod def _check(value): if int.bit_length(value) > 32: raise ValueError( 'value {} should be less than 4 bytes'.format(value) ) @staticmethod def _pack(value): return str(int(value)).encode() def __setattr__(self, name, value): super().__setattr__(name, value) if name == '_name' and hasattr(self, '_flags'): self._flags.__name__ = value
[docs] def _set_flags(self, **flags): ''' Set the flags of this argument. Example: ``int_param._set_flags(a=1, b=2, c=4, d=8)`` ''' self._flags = enum.IntEnum('_flags', flags) self.__dict__.update(self._flags.__members__) self._patch_flag_doc()
def _patch_flag_doc(self): patch = io.StringIO() patch.write('\n\n:Flags:\n') for key, value in sorted( self._flags.__members__.items(), key=operator.itemgetter(1) ): patch.write(' * ``{}`` = *{:d}*\n'.format( key, value)) self.__doc__ = self.__doc__.rstrip() + patch.getvalue()
[docs]class Float(Parameter): 'Parameter class of a float' __slots__ = () @staticmethod def _check(value): float(value) @staticmethod def _pack(value): return str(repack_to_int(value)).encode()
[docs]class String(Parameter): 'Parameter class of a string' __slots__ = () @staticmethod def _check(value): if not isinstance(value, (str, bytes, float, int, bool)): raise TypeError( '{} is of type {}, which is unsupported'.format( value, type(value) ) ) @functools.singledispatch
[docs] def _pack(value): ''' packing rule: =========== ============ Value Packes into =========== ============ ``True`` ``b'TRUE'`` ``False`` ``b'FALSE'`` ``65535`` ``b'65535'`` ``0.32`` ``b'0.32'`` ``'hello'`` ``b'hello'`` =========== ============ ''' return json.dumps(str(value)).encode()
@_pack.register(bool) def _pack_bool(value): return b'"TRUE"' if value else b'"FALSE"' @_pack.register(bytes) def _pack_bytes(value): return json.dumps(value.decode()).encode() _pack = staticmethod(_pack)