Пример #1
0
class GetPhaseHistory(_AbstractGameRequest):
    """ Game request to get a list of game phase data from game history for given phases interval.
        A phase can be either None, a phase name (string) or a phase index (integer).
        See :meth:`.Game.get_phase_history` about how phases are used to retrieve game phase data.

        :param from_phase: phase from which to look in game history
        :param to_phase: phase up to which to look in game history
        :type from_phase: str | int, optional
        :type to_phase: str | int, optional
        :return:

            - Server: DataGamePhases
            - Client: a list of :class:`.GamePhaseData` objects corresponding to game phases
              found between ``from_phase`` and ``to_phase`` in game history.
    """
    __slots__ = ['from_phase', 'to_phase']
    params = {
        strings.FROM_PHASE:
        parsing.OptionalValueType(parsing.SequenceOfPrimitivesType([str,
                                                                    int])),
        strings.TO_PHASE:
        parsing.OptionalValueType(parsing.SequenceOfPrimitivesType([str,
                                                                    int])),
    }
    phase_dependent = False

    def __init__(self, **kwargs):
        self.from_phase = ''
        self.to_phase = ''
        super(GetPhaseHistory, self).__init__(**kwargs)
Пример #2
0
class SetOrders(_AbstractGameRequest):
    """ Game request to set orders for a power.

        :param power_name: power name. If not given, request user must be a game player,
            and power is inferred from request game role.
        :param orders: list of power orders.
        :param wait: if provided, wait flag to set for this power.
        :type power_name: str, optional
        :type orders: list
        :type wait: bool, optional
        :return: None
    """
    __slots__ = ['power_name', 'orders', 'wait']
    params = {
        strings.POWER_NAME:
        parsing.OptionalValueType(str),  # required only for game master.
        strings.ORDERS: parsing.SequenceType(str),
        strings.WAIT: parsing.OptionalValueType(bool)
    }

    def __init__(self, **kwargs):
        self.power_name = None
        self.orders = None
        self.wait = None
        super(SetOrders, self).__init__(**kwargs)
Пример #3
0
class JoinPowers(_AbstractChannelRequest):
    """ Channel request to join many powers of a game with one request.

        This request is mostly identical to :class:`.JoinGame`, except that list of power names
        is mandatory. It's useful to allow the user to control many powers while still working
        with 1 client game instance.

        :param game_id: ID of game to join
        :param power_names: list of power names to join
        :param registration_password: password to join the game
        :type game_id: str
        :type power_names: list, optional
        :type registration_password: str, optionl
        :return: None. If request succeeds, then the user is registered as player for all
            given power names. The user can then simply join game to one of these powers (by sending
            a :class:`.JoinGame` request), and he will be able to manage all the powers through
            the client game returned by :class:`.JoinGame`.
    """
    __slots__ = ['game_id', 'power_names', 'registration_password']
    params = {
        strings.GAME_ID: str,
        strings.POWER_NAMES: parsing.SequenceType(str, sequence_builder=set),
        strings.REGISTRATION_PASSWORD: parsing.OptionalValueType(str)
    }

    def __init__(self, **kwargs):
        self.game_id = None
        self.power_names = None
        self.registration_password = None
        super(JoinPowers, self).__init__(**kwargs)
Пример #4
0
class SetDummyPowers(_AbstractGameRequest):
    """ SetDummyPowers request.
        Expected response: responses.Ok
        Expected response handler result: None
    """
    __slots__ = ['username', 'power_names']
    params = {
        strings.USERNAME: parsing.OptionalValueType(str),
        strings.POWER_NAMES:
        parsing.OptionalValueType(parsing.SequenceType(str)),
    }

    def __init__(self, **kwargs):
        self.username = None
        self.power_names = None
        super(SetDummyPowers, self).__init__(**kwargs)
Пример #5
0
class MyJsonable(Jsonable):
    """ Example of class derived from Jsonable. """
    __slots__ = ('field_a', 'field_b', 'field_c', 'field_d', 'field_e',
                 'field_f', 'field_g')

    model = {
        'field_a':
        bool,
        'field_b':
        str,
        'field_c':
        parsing.OptionalValueType(float),
        'field_d':
        parsing.DefaultValueType(str, 'super'),
        'field_e':
        parsing.SequenceType(int),
        'field_f':
        parsing.SequenceType(float, sequence_builder=SortedSet.builder(float)),
        'field_g':
        parsing.DefaultValueType(
            parsing.DictType(str, int, SortedDict.builder(str, int)),
            {'x': -1})
    }

    def __init__(self, **kwargs):
        """ Constructor """
        self.field_a = None
        self.field_b = None
        self.field_c = None
        self.field_d = None
        self.field_e = None
        self.field_f = None
        self.field_g = {}
        super(MyJsonable, self).__init__(**kwargs)
Пример #6
0
class TimeToDeadlineRequest(DaideRequest):
    """ Represents a TME DAIDE request. Sent by the client to request a TME message or to request it at a later time.

        Syntax: ::

            TME
            TME (seconds)
    """
    __slots__ = ['seconds']
    params = {
        strings.SECONDS: parsing.OptionalValueType(int)
    }

    def __init__(self, **kwargs):
        """ Constructor """
        self.seconds = None
        super(TimeToDeadlineRequest, self).__init__(seconds=0, **kwargs)

    def parse_bytes(self, daide_bytes):
        """ Builds the request from DAIDE bytes """
        super(TimeToDeadlineRequest, self).parse_bytes(daide_bytes)

        # Parsing
        lead_token, daide_bytes = parse_bytes(SingleToken, daide_bytes)
        seconds_group_bytes, daide_bytes = break_next_group(daide_bytes)
        assert str(lead_token) == 'TME', 'Expected TME request'

        # Seconds
        if seconds_group_bytes:
            seconds_group_bytes = strip_parentheses(seconds_group_bytes)
            seconds, daide_bytes = parse_bytes(Number, seconds_group_bytes)
        assert not daide_bytes, '%s bytes remaining. Request is malformed' % len(daide_bytes)

        # Setting properties
        self.seconds = None if not seconds_group_bytes else int(seconds)
Пример #7
0
class GamePhaseData(Jsonable):
    """ Small class to represent data for a game phase:
        phase name, state, orders, orders results and messages for this phase.
    """
    __slots__ = ['name', 'state', 'orders', 'results', 'messages']

    model = {
        strings.NAME:
        str,
        strings.STATE:
        dict,
        strings.ORDERS:
        parsing.DictType(str,
                         parsing.OptionalValueType(parsing.SequenceType(str))),
        strings.RESULTS:
        parsing.DictType(
            str,
            parsing.SequenceType(parsing.StringableType(
                common.StringableCode))),
        strings.MESSAGES:
        MESSAGES_TYPE,
    }

    def __init__(self, name, state, orders, results, messages):
        """ Constructor. """
        self.name = ''
        self.state = {}
        self.orders = {}
        self.results = {}
        self.messages = {}
        super(GamePhaseData, self).__init__(name=name,
                                            state=state,
                                            orders=orders,
                                            results=results,
                                            messages=messages)
Пример #8
0
class SetGrade(_AbstractChannelRequest):
    """ Channel request to modify the grade of a user.
        Require admin privileges to change admin grade, and at least game master privileges
        to change omniscient or moderator grade.

        :param grade: grade to update (``'omniscient'``, ``'admin'`` or ``'moderator'``)
        :param grade_update: how to make update (``'promote'`` or ``'demote'``)
        :param username: user for which the grade must be modified
        :param game_id: ID of game for which the grade must be modified.
            Required only for ``'moderator'`` and ``'omniscient'`` grade.
        :type grade: str
        :type grade_update: str
        :type username: str
        :type game_id: str, optional
        :return: None
    """
    __slots__ = ['grade', 'grade_update', 'username', 'game_id']
    params = {
        strings.GRADE: parsing.EnumerationType(strings.ALL_GRADES),
        strings.GRADE_UPDATE:
        parsing.EnumerationType(strings.ALL_GRADE_UPDATES),
        strings.USERNAME: str,
        strings.GAME_ID: parsing.OptionalValueType(str),
    }

    def __init__(self, **kwargs):
        self.grade = None
        self.grade_update = None
        self.username = None
        self.game_id = None
        super(SetGrade, self).__init__(**kwargs)
Пример #9
0
class JoinGame(_AbstractChannelRequest):
    """ JoinGame request.
        Expected response: responses.DataGame
        Expected response handler result: diplomacy.client.network_game.NetworkGame
    """
    __slots__ = ['game_id', 'power_name', 'registration_password']
    params = {
        strings.GAME_ID: str,
        strings.POWER_NAME: parsing.OptionalValueType(str),
        strings.REGISTRATION_PASSWORD: parsing.OptionalValueType(str)
    }

    def __init__(self, **kwargs):
        self.game_id = None
        self.power_name = None
        self.registration_password = None
        super(JoinGame, self).__init__(**kwargs)
Пример #10
0
class SetOrders(_AbstractGameRequest):
    """ SetOrders request.
        Expected response: responses.Ok
        Expected response handler result: None
    """
    __slots__ = ['power_name', 'orders', 'wait']
    params = {
        strings.POWER_NAME:
        parsing.OptionalValueType(str),  # required only for game master.
        strings.ORDERS: parsing.SequenceType(str),
        strings.WAIT: parsing.OptionalValueType(bool)
    }

    def __init__(self, **kwargs):
        self.power_name = None
        self.orders = None
        self.wait = None
        super(SetOrders, self).__init__(**kwargs)
Пример #11
0
class PowerOrdersUpdate(_GameNotification):
    """ Notification about a power order update. """
    __slots__ = ['orders']
    params = {
        strings.ORDERS: parsing.OptionalValueType(parsing.SequenceType(str)),
    }

    def __init__(self, **kwargs):
        self.orders = None  # type: set
        super(PowerOrdersUpdate, self).__init__(**kwargs)
Пример #12
0
class GetPhaseHistory(_AbstractGameRequest):
    """ Get a list of game phase data from game history for given phases interval.
        A phase can be either None, a phase name (string) or a phase index (integer).
        Expected response: responses.DataGamePhases
        Expected response handler result: [GamePhaseData objects]
    """
    __slots__ = ['from_phase', 'to_phase']
    params = {
        strings.FROM_PHASE:
        parsing.OptionalValueType(parsing.SequenceOfPrimitivesType([str,
                                                                    int])),
        strings.TO_PHASE:
        parsing.OptionalValueType(parsing.SequenceOfPrimitivesType([str,
                                                                    int])),
    }
    phase_dependent = False

    def __init__(self, **kwargs):
        self.from_phase = ''
        self.to_phase = ''
        super(GetPhaseHistory, self).__init__(**kwargs)
Пример #13
0
class SubmitOrdersRequest(DaideRequest):
    """ Represents a SUB DAIDE request. Sent by the client to submit orders.

        Syntax: ::

            SUB (order) (order) ...
            SUB (turn) (order) (order) ...

        order syntax: ::

            (unit) HLD                                       # Hold
            (unit) MTO province                              # Move to
            (unit) SUP (unit)                                # Support
            (unit) SUP (unit) MTO (prov_no_coast)            # Support to move
            (unit) CVY (unit) CTO province                   # Convoy
            (unit) CTO province VIA (sea_prov sea_prov ...)  # Convoy to via provinces
            (unit) RTO province                              # Retreat to
            (unit) DSB                                       # Disband (R phase)
            (unit) BLD                                       # Build
            (unit) REM                                       # Remove (A phase)
            (unit) WVE                                       # Waive
    """
    __slots__ = ['power_name', 'orders']
    params = {
        strings.POWER_NAME: parsing.OptionalValueType(str),
        strings.ORDERS: parsing.SequenceType(str)
    }

    def __init__(self, **kwargs):
        """ Constructor """
        self.power_name = None
        self.phase = ''
        self.orders = []
        super(SubmitOrdersRequest, self).__init__(power_name='', orders=[], **kwargs)

    def parse_bytes(self, daide_bytes):
        """ Builds the request from DAIDE bytes """
        super(SubmitOrdersRequest, self).parse_bytes(daide_bytes)
        orders = []

        # Parsing
        lead_token, daide_bytes = parse_bytes(SingleToken, daide_bytes)
        turn, daide_bytes = parse_bytes(Turn, daide_bytes, on_error='ignore')
        while daide_bytes:
            order, daide_bytes = parse_bytes(Order, daide_bytes)
            orders += [order]
        assert str(lead_token) == 'SUB', 'Expected SUB request'
        assert not daide_bytes, '%s bytes remaining. Request is malformed' % len(daide_bytes)

        # Setting properties
        self.phase = '' if not turn else str(turn)
        self.power_name = None if not orders or not orders[0].power_name else str(orders[0].power_name)
        self.orders = [str(order) for order in orders]
Пример #14
0
class JoinGame(_AbstractChannelRequest):
    """ Channel request to join a game.

        :param game_id: ID of game to join
        :param power_name: if provided, name of power to control. Otherwise,
            user wants to observe game without playing.
        :param registration_password: password to join game. If omitted while
            game requires a password, server will return an error.
        :type game_id: str
        :type power_name: str, optional
        :type registration_password: str, optional
        :return:

            - Server: :class:`.DataGame`
            - Client: a :class:`.NetworkGame` object representing the client game, which is either:

              - a power game (if power name was given), meaning that this network game allows user
                to play a power
              - an observer game, if power was not given and user does not have omniscient privileges
                for this game. Observer role allows user to watch game phases changes, orders submitted
                and orders results for each phase, but he can not see user messages and he can not
                send any request that requires game master privileges.
              - an omniscient game, if power was not given and user does have game master privileges.
                Omniscient role allows user to see everything in the game, including user messages.
                If user does only have omniscient privileges for this game, he can't do anything more,
                If he does have up to game master privileges, then he can also send requests that
                require game master privileges.
    """
    __slots__ = ['game_id', 'power_name', 'registration_password']
    params = {
        strings.GAME_ID: str,
        strings.POWER_NAME: parsing.OptionalValueType(str),
        strings.REGISTRATION_PASSWORD: parsing.OptionalValueType(str)
    }

    def __init__(self, **kwargs):
        self.game_id = None
        self.power_name = None
        self.registration_password = None
        super(JoinGame, self).__init__(**kwargs)
Пример #15
0
def test_optional_value_type():
    """ Test optional value type. """

    checker = parsing.OptionalValueType(bool)
    assert_raises(lambda ch=checker: ch.validate(1), exceptions.TypeException)
    assert_raises(lambda ch=checker: ch.validate(1.1),
                  exceptions.TypeException)
    assert_raises(lambda ch=checker: ch.validate(''), exceptions.TypeException)
    for value in (True, False, None):
        checker.validate(value)
        assert checker.to_type(value) is value
        assert checker.to_json(value) is value
    assert checker.update(None) is None
Пример #16
0
class ClearUnits(_AbstractGameRequest):
    """ ClearUnits request.
        Expected response: responses.Ok
        Expected response handler result: None
    """
    __slots__ = ['power_name']
    params = {
        strings.POWER_NAME: parsing.OptionalValueType(str),
    }

    def __init__(self, **kwargs):
        self.power_name = None  # type: str
        super(ClearUnits, self).__init__(**kwargs)
Пример #17
0
class SetDummyPowers(_AbstractGameRequest):
    """ Game request to set dummy powers. Require game master privileges.
        If given powers are controlled, related players are kicked
        and powers become dummy (uncontrolled).

        :param power_names: list of power names to set dummy. If not provided, will be all map power names.
        :param username: if provided, only power names controlled by this user will be set dummy.
        :type power_names: list, optional
        :type user_name: str, optional
        :return: None
    """
    __slots__ = ['username', 'power_names']
    params = {
        strings.USERNAME: parsing.OptionalValueType(str),
        strings.POWER_NAMES:
        parsing.OptionalValueType(parsing.SequenceType(str)),
    }

    def __init__(self, **kwargs):
        self.username = None
        self.power_names = None
        super(SetDummyPowers, self).__init__(**kwargs)
Пример #18
0
class ClearUnits(_AbstractGameRequest):
    """ Game request to clear units.

        :param power_name: if given, clear units for this power. Otherwise, clear units for all powers.
        :type power_name: str, optional
        :return: None
    """
    __slots__ = ['power_name']
    params = {
        strings.POWER_NAME: parsing.OptionalValueType(str),
    }

    def __init__(self, **kwargs):
        self.power_name = None  # type: str
        super(ClearUnits, self).__init__(**kwargs)
Пример #19
0
class PowersControllers(_GameNotification):
    """ Notification about current controller for each power in a game. """
    __slots__ = ['powers', 'timestamps']
    params = {
        # {power_name => controller_name}
        strings.POWERS:
        parsing.DictType(str, parsing.OptionalValueType(str)),
        # {power_name => controller timestamp}
        strings.TIMESTAMPS:
        parsing.DictType(str, int)
    }

    def __init__(self, **kwargs):
        self.powers = {}
        self.timestamps = {}
        super(PowersControllers, self).__init__(**kwargs)
Пример #20
0
class _GameNotification(_AbstractNotification):
    """ Game notification (intended to be sent to a game). """
    __slots__ = ['game_id', 'game_role', 'power_name']
    header = parsing.update_model(_AbstractNotification.header, {
        strings.GAME_ID: str,
        strings.GAME_ROLE: str,
        strings.POWER_NAME: parsing.OptionalValueType(str),
    })

    level = strings.GAME

    def __init__(self, **kwargs):
        self.game_id = None  # type: str
        self.game_role = None  # type: str
        self.power_name = None  # type: str
        super(_GameNotification, self).__init__(**kwargs)
Пример #21
0
class Vote(_AbstractGameRequest):
    """ Vote request.
        For powers only.
        Allow a power to vote about game draw for current phase.
        Expected response: responses.Ok
        Expected response handler result: None
    """
    __slots__ = ['power_name', 'vote']
    params = {
        strings.POWER_NAME: parsing.OptionalValueType(str),
        strings.VOTE: strings.ALL_VOTE_DECISIONS
    }

    def __init__(self, **kwargs):
        self.power_name = ''
        self.vote = ''
        super(Vote, self).__init__(**kwargs)
Пример #22
0
class IAmRequest(DaideRequest):
    """ Represents a IAM DAIDE request. Can be sent by the client at anytime to rejoin the game.
        Syntax:
            IAM (power) (passcode)
    """
    __slots__ = ['power_name', 'passcode']
    params = {
        strings.POWER_NAME: str,
        strings.PASSCODE: parsing.OptionalValueType(int)
    }

    def __init__(self, **kwargs):
        """ Constructor """
        self.power_name = ''
        self.passcode = 0
        super(IAmRequest, self).__init__(power_name='', passcode=0, **kwargs)

    def parse_bytes(self, daide_bytes):
        """ Builds the request from DAIDE bytes """
        super(IAmRequest, self).parse_bytes(daide_bytes)

        # Parsing
        lead_token, daide_bytes = parse_bytes(SingleToken, daide_bytes)
        assert str(lead_token) == 'IAM', 'Expected IAM request'

        # Power
        power_group_bytes, daide_bytes = break_next_group(daide_bytes)
        power_group_bytes = strip_parentheses(power_group_bytes)
        power, power_group_bytes = parse_bytes(Power, power_group_bytes)
        assert not power_group_bytes, '%s bytes remaining in power group. Request is malformed' % len(
            power_group_bytes)

        # Passcode
        passcode_group_bytes, daide_bytes = break_next_group(daide_bytes)
        passcode_group_bytes = strip_parentheses(passcode_group_bytes)
        passcode, passcode_group_bytes = parse_bytes(SingleToken,
                                                     passcode_group_bytes)
        assert not passcode_group_bytes, '%s bytes remaining in passcode group. Req. error' % len(
            passcode_group_bytes)
        assert not daide_bytes, '%s bytes remaining. Request is malformed' % len(
            daide_bytes)

        # Setting properties
        self.power_name = str(power)
        self.passcode = str(passcode)
Пример #23
0
class JoinPowers(_AbstractChannelRequest):
    """ JoinPowers request to join many powers of a game with one query.
        Useful to control many powers while still working only with 1 client game instance.
        Expected response: responses.Ok
        Expected response handler result: None
    """
    __slots__ = ['game_id', 'power_names', 'registration_password']
    params = {
        strings.GAME_ID: str,
        strings.POWER_NAMES: parsing.SequenceType(str, sequence_builder=set),
        strings.REGISTRATION_PASSWORD: parsing.OptionalValueType(str)
    }

    def __init__(self, **kwargs):
        self.game_id = None
        self.power_names = None
        self.registration_password = None
        super(JoinPowers, self).__init__(**kwargs)
Пример #24
0
class DaideUser(User):
    """ DAIDE user class """
    __slots__ = [
        'username', 'password_hash', 'client_name', 'client_version',
        'passcode'
    ]
    model = parsing.extend_model(
        User.model, {
            strings.CLIENT_NAME: str,
            strings.CLIENT_VERSION: str,
            strings.PASSCODE: parsing.OptionalValueType(int)
        })

    def __init__(self, **kwargs):
        self.client_name = ''
        self.client_version = ''
        self.passcode = 0
        super(DaideUser, self).__init__(**kwargs)
Пример #25
0
class Version1(Jsonable):
    """ A Jsonable with fields a, b, c, d.
        NB: To parse a dict from Version22 to Version1, modified fields a and c must be convertible in Version1.
        using ConverterType in Version1.
    """
    model = {
        'a': parsing.ConverterType(int, converter_to_int),
        'b': parsing.OptionalValueType(str),
        'c': parsing.ConverterType(float, converter_function=float),
        'd': parsing.DefaultValueType(bool, True),
    }

    def __init__(self, **kwargs):
        self.a = None
        self.b = None
        self.c = None
        self.d = None
        super(Version1, self).__init__(**kwargs)
Пример #26
0
class Version3(Jsonable):
    """ Version 1 with a modified, b removed, e added.
        To parse a dict between Version3 and Version1:
        - a must be convertible in both versions.
        - b must be optional in Version1.
        - e must be optional in Version3.
    """
    model = {
        'a': parsing.ConverterType(str, converter_function=str),
        'c': float,
        'd': bool,
        'e': parsing.OptionalValueType(parsing.SequenceType(int))
    }

    def __init__(self, **kwargs):
        self.a = None
        self.c = None
        self.d = None
        self.e = None
        super(Version3, self).__init__(**kwargs)
Пример #27
0
class SetGrade(_AbstractChannelRequest):
    """ SetGrade request.
        Expected response: responses.Ok
        Expected response handler result: None
    """
    __slots__ = ['grade', 'grade_update', 'username', 'game_id']
    params = {
        strings.GRADE: parsing.EnumerationType(strings.ALL_GRADES),
        strings.GRADE_UPDATE:
        parsing.EnumerationType(strings.ALL_GRADE_UPDATES),
        strings.USERNAME: str,
        strings.GAME_ID: parsing.OptionalValueType(str),
    }

    def __init__(self, **kwargs):
        self.grade = None
        self.grade_update = None
        self.username = None
        self.game_id = None
        super(SetGrade, self).__init__(**kwargs)
Пример #28
0
class PowersControllers(_GameNotification):
    """ Notification about current controller for each power in a game.

        Properties:

            - **powers**: A :class:`Dict` that maps a power_name to a controller_name :class:`str`.
            - **timestamps**: A :class:`Dict` that maps a power_name to timestamp where the controller took over.
    """
    __slots__ = ['powers', 'timestamps']
    params = {
        # {power_name => controller_name}
        strings.POWERS: parsing.DictType(str, parsing.OptionalValueType(str)),
        # {power_name => controller timestamp}
        strings.TIMESTAMPS: parsing.DictType(str, int)
    }

    def __init__(self, **kwargs):
        self.powers = {}
        self.timestamps = {}
        super(PowersControllers, self).__init__(**kwargs)
Пример #29
0
class SetWaitFlag(_AbstractGameRequest):
    """ Game request to set orders for a power.

        :param power_name: power name. If not given, request user must be a game player,
            and power if inferred from request game role.
        :param wait: wait flag to set.
        :type power_name: str, optional
        :type wait: bool
        :return: None
    """
    __slots__ = ['power_name', 'wait']
    params = {
        strings.POWER_NAME:
        parsing.OptionalValueType(str),  # required only for game master.
        strings.WAIT: bool
    }

    def __init__(self, **kwargs):
        self.power_name = None
        self.wait = None
        super(SetWaitFlag, self).__init__(**kwargs)
Пример #30
0
class Vote(_AbstractGameRequest):
    """ Game request to vote for draw decision.
        If number of pro-draw votes > number of con-draw votes for current phase,
        then server will automatically draw the game and send appropriate notifications.
        Votes are reset after a game processing.

        :param power_name: power name who wants to vote. If not provided, request user must be a game player,
            and power name will be inferred from request game role.
        :param vote: vote to set. Either ``'yes'`` (power votes for draw), ``'no'`` (power votes against draw),
            or ``'neutral'`` (power does not want to decide).
        :type power_name: str, optional
        :type vote: str
        :return: None
    """
    __slots__ = ['power_name', 'vote']
    params = {
        strings.POWER_NAME: parsing.OptionalValueType(str),
        strings.VOTE: strings.ALL_VOTE_DECISIONS
    }

    def __init__(self, **kwargs):
        self.power_name = ''
        self.vote = ''
        super(Vote, self).__init__(**kwargs)