# Copyright (C) 2018 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """This module has components that are used for testing Python Fire.""" from __future__ import absolute_import from __future__ import division from __future__ import print_function import collections import enum import functools import six if six.PY3: from fire import test_components_py3 as py3 # pylint: disable=unused-import,no-name-in-module,g-import-not-at-top def identity(arg1, arg2, arg3=10, arg4=20, *arg5, **arg6): # pylint: disable=keyword-arg-before-vararg return arg1, arg2, arg3, arg4, arg5, arg6 identity.__annotations__ = {'arg2': int, 'arg4': int} def multiplier_with_docstring(num, rate=2): """Multiplies num by rate. Args: num (int): the num you want to multiply rate (int): the rate for multiplication Returns: Multiplication of num by rate """ return num * rate def function_with_help(help=True): # pylint: disable=redefined-builtin return help class Empty(object): pass class OldStyleEmpty: # pylint: disable=old-style-class,no-init pass class WithInit(object): def __init__(self): pass class ErrorInConstructor(object): def __init__(self, value='value'): self.value = value raise ValueError('Error in constructor') class WithHelpArg(object): """Test class for testing when class has a help= arg.""" def __init__(self, help=True): # pylint: disable=redefined-builtin self.has_help = help self.dictionary = {'__help': 'help in a dict'} class NoDefaults(object): def double(self, count): return 2 * count def triple(self, count): return 3 * count class WithDefaults(object): """Class with functions that have default arguments.""" def double(self, count=0): """Returns the input multiplied by 2. Args: count: Input number that you want to double. Returns: A number that is the double of count. """ return 2 * count def triple(self, count=0): return 3 * count def text( self, string=('0001020304050607080910111213141516171819' '2021222324252627282930313233343536373839') ): return string class OldStyleWithDefaults: # pylint: disable=old-style-class,no-init def double(self, count=0): return 2 * count def triple(self, count=0): return 3 * count class MixedDefaults(object): def ten(self): return 10 def sum(self, alpha=0, beta=0): return alpha + 2 * beta def identity(self, alpha, beta='0'): return alpha, beta class SimilarArgNames(object): def identity(self, bool_one=False, bool_two=False): return bool_one, bool_two def identity2(self, a=None, alpha=None): return a, alpha class CapitalizedArgNames(object): def sum(self, Delta=1.0, Gamma=2.0): # pylint: disable=invalid-name return Delta + Gamma class Annotations(object): def double(self, count=0): return 2 * count def triple(self, count=0): return 3 * count double.__annotations__ = {'count': float} triple.__annotations__ = {'count': float} class TypedProperties(object): """Test class for testing Python Fire with properties of various types.""" def __init__(self): self.alpha = True self.beta = (1, 2, 3) self.charlie = WithDefaults() self.delta = { 'echo': 'E', 'nest': { 0: 'a', 1: 'b', }, } self.echo = ['alex', 'bethany'] self.fox = ('carry', 'divide') self.gamma = 'myexcitingstring' class VarArgs(object): """Test class for testing Python Fire with a property with varargs.""" def cumsums(self, *items): total = None sums = [] for item in items: if total is None: total = item else: total += item sums.append(total) return sums def varchars(self, alpha=0, beta=0, *chars): # pylint: disable=keyword-arg-before-vararg return alpha, beta, ''.join(chars) class Underscores(object): def __init__(self): self.underscore_example = 'fish fingers' def underscore_function(self, underscore_arg): return underscore_arg class BoolConverter(object): def as_bool(self, arg=False): return bool(arg) class ReturnsObj(object): def get_obj(self, *items): del items # Unused return BoolConverter() class NumberDefaults(object): def reciprocal(self, divisor=10.0): return 1.0 / divisor def integer_reciprocal(self, divisor=10): return 1.0 / divisor class InstanceVars(object): def __init__(self, arg1, arg2): self.arg1 = arg1 self.arg2 = arg2 def run(self, arg1, arg2): return (self.arg1, self.arg2, arg1, arg2) class Kwargs(object): def props(self, **kwargs): return kwargs def upper(self, **kwargs): return ' '.join(sorted(kwargs.keys())).upper() def run(self, positional, named=None, **kwargs): return (positional, named, kwargs) class ErrorRaiser(object): def fail(self): raise ValueError('This error is part of a test.') class NonComparable(object): def __eq__(self, other): raise ValueError('Instances of this class cannot be compared.') def __ne__(self, other): raise ValueError('Instances of this class cannot be compared.') class EmptyDictOutput(object): def totally_empty(self): return {} def nothing_printable(self): return {'__do_not_print_me': 1} class CircularReference(object): def create(self): x = {} x['y'] = x return x class OrderedDictionary(object): def empty(self): return collections.OrderedDict() def non_empty(self): ordered_dict = collections.OrderedDict() ordered_dict['A'] = 'A' ordered_dict[2] = 2 return ordered_dict class NamedTuple(object): """Functions returning named tuples used for testing.""" def point(self): """Point example straight from Python docs.""" # pylint: disable=invalid-name Point = collections.namedtuple('Point', ['x', 'y']) return Point(11, y=22) def matching_names(self): """Field name equals value.""" # pylint: disable=invalid-name Point = collections.namedtuple('Point', ['x', 'y']) return Point(x='x', y='y') class CallableWithPositionalArgs(object): """Test class for supporting callable.""" TEST = 1 def __call__(self, x, y): return x + y def fn(self, x): return x + 1 NamedTuplePoint = collections.namedtuple('NamedTuplePoint', ['x', 'y']) class SubPoint(NamedTuplePoint): """Used for verifying subclasses of namedtuples behave as intended.""" def coordinate_sum(self): return self.x + self.y class CallableWithKeywordArgument(object): """Test class for supporting callable.""" def __call__(self, **kwargs): for key, value in kwargs.items(): print('%s: %s' % (key, value)) def print_msg(self, msg): print(msg) CALLABLE_WITH_KEYWORD_ARGUMENT = CallableWithKeywordArgument() class ClassWithDocstring(object): """Test class for testing help text output. This is some detail description of this test class. """ def __init__(self, message='Hello!'): """Constructor of the test class. Constructs a new ClassWithDocstring object. Args: message: The default message to print. """ self.message = message def print_msg(self, msg=None): """Prints a message.""" if msg is None: msg = self.message print(msg) class ClassWithMultilineDocstring(object): """Test class for testing help text output with multiline docstring. This is a test class that has a long docstring description that spans across multiple lines for testing line breaking in help text. """ @staticmethod def example_generator(n): """Generators have a ``Yields`` section instead of a ``Returns`` section. Args: n (int): The upper limit of the range to generate, from 0 to `n` - 1. Yields: int: The next number in the range of 0 to `n` - 1. Examples: Examples should be written in doctest format, and should illustrate how to use the function. >>> print([i for i in example_generator(4)]) [0, 1, 2, 3] """ for i in range(n): yield i def simple_set(): return {1, 2, 'three'} def simple_frozenset(): return frozenset({1, 2, 'three'}) class Subdict(dict): """A subclass of dict, for testing purposes.""" # An example subdict. SUBDICT = Subdict({1: 2, 'red': 'blue'}) class Color(enum.Enum): RED = 1 GREEN = 2 BLUE = 3 class HasStaticAndClassMethods(object): """A class with a static method and a class method.""" CLASS_STATE = 1 def __init__(self, instance_state): self.instance_state = instance_state @staticmethod def static_fn(args): return args @classmethod def class_fn(cls, args): return args + cls.CLASS_STATE def function_with_varargs(arg1, arg2, arg3=1, *varargs): # pylint: disable=keyword-arg-before-vararg """Function with varargs. Args: arg1: Position arg docstring. arg2: Position arg docstring. arg3: Flags docstring. *varargs: Accepts unlimited positional args. Returns: The unlimited positional args. """ del arg1, arg2, arg3 # Unused. return varargs def function_with_keyword_arguments(arg1, arg2=3, **kwargs): del arg2 # Unused. return arg1, kwargs def fn_with_code_in_docstring(): """This has code in the docstring. Example: x = fn_with_code_in_docstring() indentation_matters = True Returns: True. """ return True class BinaryCanvas(object): """A canvas with which to make binary art, one bit at a time.""" def __init__(self, size=10): self.pixels = [[0] * size for _ in range(size)] self._size = size self._row = 0 # The row of the cursor. self._col = 0 # The column of the cursor. def __str__(self): return '\n'.join( ' '.join(str(pixel) for pixel in row) for row in self.pixels) def show(self): print(self) return self def move(self, row, col): self._row = row % self._size self._col = col % self._size return self def on(self): return self.set(1) def off(self): return self.set(0) def set(self, value): self.pixels[self._row][self._col] = value return self class DefaultMethod(object): def double(self, number): return 2 * number def __getattr__(self, name): def _missing(): return 'Undefined function' return _missing class InvalidProperty(object): def double(self, number): return 2 * number @property def prop(self): raise ValueError('test') def simple_decorator(f): @functools.wraps(f) def wrapper(*args, **kwargs): return f(*args, **kwargs) return wrapper @simple_decorator def decorated_method(name='World'): return 'Hello %s' % name # pylint: disable=g-doc-args,g-doc-return-or-yield def fn_with_kwarg(arg1, arg2, **kwargs): """Function with kwarg. :param arg1: Description of arg1. :param arg2: Description of arg2. :key arg3: Description of arg3. """ del arg1, arg2 return kwargs.get('arg3') def fn_with_kwarg_and_defaults(arg1, arg2, opt=True, **kwargs): """Function with kwarg and defaults. :param arg1: Description of arg1. :param arg2: Description of arg2. :key arg3: Description of arg3. """ del arg1, arg2, opt return kwargs.get('arg3') # pylint: enable=g-doc-args,g-doc-return-or-yield def fn_with_multiple_defaults(first='first', last='last', late='late'): """Function with kwarg and defaults. :key first: Description of first. :key last: Description of last. :key late: Description of late. """ del last, late return first