noirbizarre / flask-restplus

Fully featured framework for fast, easy and documented API development with Flask
http://flask-restplus.readthedocs.org
Other
2.73k stars 507 forks source link

get_parent does not work as exptected #645

Open lvqier opened 5 years ago

lvqier commented 5 years ago
  1. Parent is an empty dict:

    >>> from flask_restplus import Namespace
    >>> ns = Namespace('sample')
    >>> a = ns.model('A', {})
    >>> b = ns.inherit('B', a, {})
    >>> b.get_parent('A')
    Traceback (most recent call last):
    File "<console>", line 1, in <module>
    File "/opt/sample/.tox/dev/lib/python3.5/site-packages/flask_restplus/model.py", line 67, in get_parent
    raise ValueError('Parent ' + name + ' not found')
    ValueError: Parent A not found
    >>> from flask_restplus import fields
    >>> a = ns.model('A', {'a': fields.Integer()})
    >>> b = ns.inherit('B', a, {})
    >>> b.get_parent('A')
    Model([('a', <flask_restplus.fields.Integer object at 0x7fe9c2ba1550>)])
  2. Model has multiple parents

    >>> from flask_restplus import fields
    >>> ns = Namespace('sample')
    >>> a = ns.model('A', {'a': fields.Integer()})
    >>> b = ns.inherit('B', a, {})
    >>> b.get_parent('A')
    Model([('a', <flask_restplus.fields.Integer object at 0x7fe9c2ba1550>)])
    >>> c = ns.model('C', {'c': fields.Integer()})
    >>> b = ns.inherit('B', c, a, {})
    >>> b.get_parent('A')
    Traceback (most recent call last):
    File "<console>", line 1, in <module>
    File "/opt/zjxta/.tox/dev/lib/python3.5/site-packages/flask_restplus/model.py", line 64, in get_parent
    found = parent.get_parent(name)
    File "/opt/zjxta/.tox/dev/lib/python3.5/site-packages/flask_restplus/model.py", line 67, in get_parent
    raise ValueError('Parent ' + name + ' not found')
    ValueError: Parent A not found
arabidopsis commented 5 years ago

because the check in model.get_parent is just if found but models are instances of dictionaries... and a dictionary without elements is 'falsy'. So A is not found because it is falsy. The get_parent method should really be something like

    def get_parent(self, name):
        if self.name == name:
            return self
        else:
            for parent in self.__parents__:
                try:
                    return parent.get_parent(name)
                except ValueError:
                  pass
        raise ValueError("Parent " + name + " not found")