def test_get_func_full_args_one_argument(self): self.assertEqual(inspect.get_func_full_args(Person.one_argument), [("something", )]) self.assertEqual( inspect.get_func_full_args(Person().one_argument), [("something", )], )
def test_get_func_full_args_all_arguments_classmethod(self): arguments = [ ("name", ), ("address", "home"), ("age", 25), ("*args", ), ("**kwargs", ), ] self.assertEqual(inspect.get_func_full_args(Person.cls_all_kinds), arguments) self.assertEqual(inspect.get_func_full_args(Person().cls_all_kinds), arguments)
def _load_perms_func(path): """ Load a function from its path as a string. """ if not path: return "Any", None, {} if callable(path): func = path elif isinstance(path, six.string_types): dot_pos = path.rfind('.') module, attr = path[:dot_pos], path[dot_pos + 1:] try: mod = import_module(module) except ImportError as err: raise ImproperlyConfigured('Error importing %s: "%s"' % (path, err)) except ValueError: raise ImproperlyConfigured('Error importing %s: ' % path) try: func = getattr(mod, attr) except AttributeError: raise ImproperlyConfigured('Module "%s" does not define a "%s"' % (module, attr)) else: raise ImproperlyConfigured( '%s is neither callable or a module path' % path) short_name = "" for line in func.__doc__.splitlines(): short_name = line.strip() if short_name: break if not short_name: raise ImproperlyConfigured( '%s should have at least a one-line documentation' % path) parms = {} for arg in inspect.get_func_full_args(func): if len(arg) > 1: parms.update({arg[0]: arg[1]}) return short_name, func, parms
def get_context_data(self, **kwargs): model_name = self.kwargs['model_name'] # Get the model class. try: app_config = apps.get_app_config(self.kwargs['app_label']) except LookupError: raise Http404(_("App %(app_label)r not found") % self.kwargs) try: model = app_config.get_model(model_name) except LookupError: raise Http404( _("Model %(model_name)r not found in app %(app_label)r") % self.kwargs) opts = model._meta title, body, metadata = utils.parse_docstring(model.__doc__) if title: title = utils.parse_rst(title, 'model', _('model:') + model_name) if body: body = utils.parse_rst(body, 'model', _('model:') + model_name) # Gather fields/field descriptions. fields = [] for field in opts.fields: # ForeignKey is a special case since the field will actually be a # descriptor that returns the other object if isinstance(field, models.ForeignKey): data_type = field.remote_field.model.__name__ app_label = field.remote_field.model._meta.app_label verbose = utils.parse_rst( (_("the related `%(app_label)s.%(data_type)s` object") % { 'app_label': app_label, 'data_type': data_type, }), 'model', _('model:') + data_type, ) else: data_type = get_readable_field_data_type(field) verbose = field.verbose_name fields.append({ 'name': field.name, 'data_type': data_type, 'verbose': verbose or '', 'help_text': field.help_text, }) # Gather many-to-many fields. for field in opts.many_to_many: data_type = field.remote_field.model.__name__ app_label = field.remote_field.model._meta.app_label verbose = _("related `%(app_label)s.%(object_name)s` objects") % { 'app_label': app_label, 'object_name': data_type, } fields.append({ 'name': "%s.all" % field.name, "data_type": 'List', 'verbose': utils.parse_rst( _("all %s") % verbose, 'model', _('model:') + opts.model_name), }) fields.append({ 'name': "%s.count" % field.name, 'data_type': 'Integer', 'verbose': utils.parse_rst( _("number of %s") % verbose, 'model', _('model:') + opts.model_name), }) methods = [] # Gather model methods. for func_name, func in model.__dict__.items(): if inspect.isfunction(func): try: for exclude in MODEL_METHODS_EXCLUDE: if func_name.startswith(exclude): raise StopIteration except StopIteration: continue verbose = func.__doc__ if verbose: verbose = utils.parse_rst(utils.trim_docstring(verbose), 'model', _('model:') + opts.model_name) # If a method has no arguments, show it as a 'field', otherwise # as a 'method with arguments'. if func_has_no_args(func) and not func_accepts_kwargs( func) and not func_accepts_var_args(func): fields.append({ 'name': func_name, 'data_type': get_return_data_type(func_name), 'verbose': verbose or '', }) else: arguments = get_func_full_args(func) # Join arguments with ', ' and in case of default value, # join it with '='. Use repr() so that strings will be # correctly displayed. print_arguments = ', '.join([ '='.join( list(arg_el[:1]) + [repr(el) for el in arg_el[1:]]) for arg_el in arguments ]) methods.append({ 'name': func_name, 'arguments': print_arguments, 'verbose': verbose or '', }) # Gather related objects for rel in opts.related_objects: verbose = _("related `%(app_label)s.%(object_name)s` objects") % { 'app_label': rel.related_model._meta.app_label, 'object_name': rel.related_model._meta.object_name, } accessor = rel.get_accessor_name() fields.append({ 'name': "%s.all" % accessor, 'data_type': 'List', 'verbose': utils.parse_rst( _("all %s") % verbose, 'model', _('model:') + opts.model_name), }) fields.append({ 'name': "%s.count" % accessor, 'data_type': 'Integer', 'verbose': utils.parse_rst( _("number of %s") % verbose, 'model', _('model:') + opts.model_name), }) kwargs.update({ 'name': '%s.%s' % (opts.app_label, opts.object_name), 'summary': title, 'description': body, 'fields': fields, 'methods': methods, }) return super(ModelDetailView, self).get_context_data(**kwargs)
def get_context_data(self, **kwargs): model_name = self.kwargs['model_name'] # Get the model class. try: app_config = apps.get_app_config(self.kwargs['app_label']) except LookupError: raise Http404(_("App %(app_label)r not found") % self.kwargs) try: model = app_config.get_model(model_name) except LookupError: raise Http404(_("Model %(model_name)r not found in app %(app_label)r") % self.kwargs) opts = model._meta title, body, metadata = utils.parse_docstring(model.__doc__) if title: title = utils.parse_rst(title, 'model', _('model:') + model_name) if body: body = utils.parse_rst(body, 'model', _('model:') + model_name) # Gather fields/field descriptions. fields = [] for field in opts.fields: # ForeignKey is a special case since the field will actually be a # descriptor that returns the other object if isinstance(field, models.ForeignKey): data_type = field.remote_field.model.__name__ app_label = field.remote_field.model._meta.app_label verbose = utils.parse_rst( (_("the related `%(app_label)s.%(data_type)s` object") % { 'app_label': app_label, 'data_type': data_type, }), 'model', _('model:') + data_type, ) else: data_type = get_readable_field_data_type(field) verbose = field.verbose_name fields.append({ 'name': field.name, 'data_type': data_type, 'verbose': verbose or '', 'help_text': field.help_text, }) # Gather many-to-many fields. for field in opts.many_to_many: data_type = field.remote_field.model.__name__ app_label = field.remote_field.model._meta.app_label verbose = _("related `%(app_label)s.%(object_name)s` objects") % { 'app_label': app_label, 'object_name': data_type, } fields.append({ 'name': "%s.all" % field.name, "data_type": 'List', 'verbose': utils.parse_rst(_("all %s") % verbose, 'model', _('model:') + opts.model_name), }) fields.append({ 'name': "%s.count" % field.name, 'data_type': 'Integer', 'verbose': utils.parse_rst(_("number of %s") % verbose, 'model', _('model:') + opts.model_name), }) methods = [] # Gather model methods. for func_name, func in model.__dict__.items(): if inspect.isfunction(func): try: for exclude in MODEL_METHODS_EXCLUDE: if func_name.startswith(exclude): raise StopIteration except StopIteration: continue verbose = func.__doc__ if verbose: verbose = utils.parse_rst(utils.trim_docstring(verbose), 'model', _('model:') + opts.model_name) # If a method has no arguments, show it as a 'field', otherwise # as a 'method with arguments'. if func_has_no_args(func) and not func_accepts_kwargs(func) and not func_accepts_var_args(func): fields.append({ 'name': func_name, 'data_type': get_return_data_type(func_name), 'verbose': verbose or '', }) else: arguments = get_func_full_args(func) # Join arguments with ', ' and in case of default value, # join it with '='. Use repr() so that strings will be # correctly displayed. print_arguments = ', '.join([ '='.join(list(arg_el[:1]) + [repr(el) for el in arg_el[1:]]) for arg_el in arguments ]) methods.append({ 'name': func_name, 'arguments': print_arguments, 'verbose': verbose or '', }) # Gather related objects for rel in opts.related_objects: verbose = _("related `%(app_label)s.%(object_name)s` objects") % { 'app_label': rel.related_model._meta.app_label, 'object_name': rel.related_model._meta.object_name, } accessor = rel.get_accessor_name() fields.append({ 'name': "%s.all" % accessor, 'data_type': 'List', 'verbose': utils.parse_rst(_("all %s") % verbose, 'model', _('model:') + opts.model_name), }) fields.append({ 'name': "%s.count" % accessor, 'data_type': 'Integer', 'verbose': utils.parse_rst(_("number of %s") % verbose, 'model', _('model:') + opts.model_name), }) kwargs.update({ 'name': '%s.%s' % (opts.app_label, opts.object_name), 'summary': title, 'description': body, 'fields': fields, 'methods': methods, }) return super().get_context_data(**kwargs)
def test_get_func_full_args_all_arguments(self): arguments = [('name',), ('address', 'home'), ('age', 25), ('*args',), ('**kwargs',)] self.assertEqual(inspect.get_func_full_args(Person.all_kinds), arguments)
def test_get_func_full_args_one_argument(self): self.assertEqual(inspect.get_func_full_args(Person.one_argument), [('something',)])
def test_get_func_full_args_no_arguments(self): self.assertEqual(inspect.get_func_full_args(Person.no_arguments), [])
def get_context_data(self, **kwargs): model_name = self.kwargs["model_name"] # Get the model class. try: app_config = apps.get_app_config(self.kwargs["app_label"]) except LookupError: raise Http404(_("App %(app_label)r not found") % self.kwargs) try: model = app_config.get_model(model_name) except LookupError: raise Http404( _("Model %(model_name)r not found in app %(app_label)r") % self.kwargs) opts = model._meta title, body, metadata = utils.parse_docstring(model.__doc__) title = title and utils.parse_rst(title, "model", _("model:") + model_name) body = body and utils.parse_rst(body, "model", _("model:") + model_name) # Gather fields/field descriptions. fields = [] for field in opts.fields: # ForeignKey is a special case since the field will actually be a # descriptor that returns the other object if isinstance(field, models.ForeignKey): data_type = field.remote_field.model.__name__ app_label = field.remote_field.model._meta.app_label verbose = utils.parse_rst( (_("the related `%(app_label)s.%(data_type)s` object") % { "app_label": app_label, "data_type": data_type, }), "model", _("model:") + data_type, ) else: data_type = get_readable_field_data_type(field) verbose = field.verbose_name fields.append({ "name": field.name, "data_type": data_type, "verbose": verbose or "", "help_text": field.help_text, }) # Gather many-to-many fields. for field in opts.many_to_many: data_type = field.remote_field.model.__name__ app_label = field.remote_field.model._meta.app_label verbose = _("related `%(app_label)s.%(object_name)s` objects") % { "app_label": app_label, "object_name": data_type, } fields.append({ "name": "%s.all" % field.name, "data_type": "List", "verbose": utils.parse_rst( _("all %s") % verbose, "model", _("model:") + opts.model_name), }) fields.append({ "name": "%s.count" % field.name, "data_type": "Integer", "verbose": utils.parse_rst( _("number of %s") % verbose, "model", _("model:") + opts.model_name, ), }) methods = [] # Gather model methods. for func_name, func in model.__dict__.items(): if inspect.isfunction(func) or isinstance( func, (cached_property, property)): try: for exclude in MODEL_METHODS_EXCLUDE: if func_name.startswith(exclude): raise StopIteration except StopIteration: continue verbose = func.__doc__ verbose = verbose and (utils.parse_rst( cleandoc(verbose), "model", _("model:") + opts.model_name)) # Show properties, cached_properties, and methods without # arguments as fields. Otherwise, show as a 'method with # arguments'. if isinstance(func, (cached_property, property)): fields.append({ "name": func_name, "data_type": get_return_data_type(func_name), "verbose": verbose or "", }) elif (method_has_no_args(func) and not func_accepts_kwargs(func) and not func_accepts_var_args(func)): fields.append({ "name": func_name, "data_type": get_return_data_type(func_name), "verbose": verbose or "", }) else: arguments = get_func_full_args(func) # Join arguments with ', ' and in case of default value, # join it with '='. Use repr() so that strings will be # correctly displayed. print_arguments = ", ".join([ "=".join([arg_el[0], *map(repr, arg_el[1:])]) for arg_el in arguments ]) methods.append({ "name": func_name, "arguments": print_arguments, "verbose": verbose or "", }) # Gather related objects for rel in opts.related_objects: verbose = _("related `%(app_label)s.%(object_name)s` objects") % { "app_label": rel.related_model._meta.app_label, "object_name": rel.related_model._meta.object_name, } accessor = rel.get_accessor_name() fields.append({ "name": "%s.all" % accessor, "data_type": "List", "verbose": utils.parse_rst( _("all %s") % verbose, "model", _("model:") + opts.model_name), }) fields.append({ "name": "%s.count" % accessor, "data_type": "Integer", "verbose": utils.parse_rst( _("number of %s") % verbose, "model", _("model:") + opts.model_name, ), }) return super().get_context_data( **{ **kwargs, "name": opts.label, "summary": title, "description": body, "fields": fields, "methods": methods, })
def test_get_func_full_args_all_arguments(self): arguments = [('name', ), ('address', 'home'), ('age', 25), ('*args', ), ('**kwargs', )] self.assertEqual(inspect.get_func_full_args(Person.all_kinds), arguments)
def test_get_func_full_args_all_arguments(self): arguments = [("name",), ("address", "home"), ("age", 25), ("*args",), ("**kwargs",)] self.assertEqual(inspect.get_func_full_args(Person.all_kinds), arguments)
import inspect