def _get_class_variables(self) -> OrderedDict: """Returns an OrderedDict mapping class variables names to their additional information.""" class_variable_names = self._get_class_dict().keys( ) | self._get_annotations().keys() try: class_variables = self._get_from_self_and_super( extract_func=lambda super_class: get_class_variables( super_class), dict_type=OrderedDict) # Handle edge-case of source code modification while code is running variables_to_add = class_variable_names - class_variables.keys() variables_to_remove = class_variables.keys() - class_variable_names for variable in variables_to_add: class_variables[variable] = {'comment': ''} for variable in variables_to_remove: class_variables.pop(variable) # Exception if inspect.getsource fails to extract the source code except Exception: class_variables = OrderedDict() for variable in class_variable_names: class_variables[variable] = {'comment': ''} return class_variables
def test_commented_variables(self): class CommentedVariable: """Comment """ arg_1: str # Arg 1 comment # Hello def func(self): pass arg_2: int = 3 # Arg 2 comment arg_3: Dict[str, int] # noqa E203,E262 Poorly formatted comment """More comment""" class_variables = OrderedDict() class_variables['arg_1'] = {'comment': 'Arg 1 comment'} class_variables['arg_2'] = {'comment': 'Arg 2 comment'} class_variables['arg_3'] = { 'comment': 'noqa E203,E262 Poorly formatted comment More comment' } self.assertEqual(get_class_variables(CommentedVariable), class_variables)
def test_one_variable(self): class OneVariable: arg = 2 class_variables = OrderedDict() class_variables['arg'] = {'comment': ''} self.assertEqual(get_class_variables(OneVariable), class_variables)
def test_single_quote_multiline(self): class SingleQuoteMultiline: bar: int = 0 '''biz baz''' class_variables = OrderedDict() class_variables['bar'] = {'comment': 'biz baz'} self.assertEqual(get_class_variables(SingleQuoteMultiline), class_variables)
def test_typed_variables(self): class TypedVariable: arg_1: str arg_2: int = 3 class_variables = OrderedDict() class_variables['arg_1'] = {'comment': ''} class_variables['arg_2'] = {'comment': ''} self.assertEqual(get_class_variables(TypedVariable), class_variables)
def test_multiple_variable(self): class MultiVariable: arg_1 = 2 arg_2 = 3 class_variables = OrderedDict() class_variables['arg_1'] = {'comment': ''} class_variables['arg_2'] = {'comment': ''} self.assertEqual(get_class_variables(MultiVariable), class_variables)
def test_dataclass(self): @class_decorator class DataclassColumn: arg: int = 5 class_variables = OrderedDict() class_variables['arg'] = {'comment': ''} self.assertEqual(get_class_variables(DataclassColumn), class_variables)
def test_functions_with_docs_multiline(self): class FunctionsWithDocs: i: int = 0 def f(self): """Function""" a: str = 'hello' """with docs""" class_variables = OrderedDict() class_variables['i'] = {'comment': ''} self.assertEqual(get_class_variables(FunctionsWithDocs), class_variables)
def _get_class_variables(self) -> OrderedDict: """Returns an OrderedDict mapping class variables names to their additional information.""" try: class_variables = self._get_from_self_and_super( extract_func=lambda super_class: get_class_variables( super_class), dict_type=OrderedDict) # Exception if inspect.getsource fails to extract the source code except Exception: class_variables = OrderedDict() for variable in self._get_class_dict().keys(): class_variables[variable] = {'comment': ''} return class_variables
def test_separated_variables(self): class SeparatedVariable: """Comment """ arg_1: str # Hello def func(self): pass arg_2: int = 3 """More comment""" class_variables = OrderedDict() class_variables['arg_1'] = {'comment': ''} class_variables['arg_2'] = {'comment': 'More comment'} self.assertEqual(get_class_variables(SeparatedVariable), class_variables)
def test_bad_spacing_multiline(self): class TrickyMultiline: """ This is really difficult so so very difficult """ foo: str = 'my' # Header line """ Footer T A P multi line!! """ class_variables = OrderedDict() comment = 'Header line Footer\nT\n A\n P\n\n multi\n line!!' class_variables['foo'] = {'comment': comment} self.assertEqual(get_class_variables(TrickyMultiline), class_variables)
def test_no_variables(self): class NoVariables: pass self.assertEqual(get_class_variables(NoVariables), OrderedDict())
def _get_class_variables(self) -> OrderedDict: """Returns an OrderedDict mapping class variables names to their additional information.""" return self._get_from_self_and_super( extract_func=lambda super_class: get_class_variables(super_class), dict_type=OrderedDict)