Пример #1
0
    def __getattribute__(self, attr_name):
        """Patch the default __getattribute__ call to be better for us.

        Rather than *only* looking at the __dict__ of the object do determine
        attribute resolution, improve so that:

            * Attributes are looked at in the underlying ``rally_data`` stored
              against the object.

                * If found in this data and it is a dictionary, load a new
                  python object up with the data.
                * Otherwise, just return the data.

            * If not found there, attributes are looked at in
              ``sub_objects_dynamic_loader``. This is a dictionary of
              ``property_name`` to ``rally_data`` key. If ``attr_name`` exists
              in this mapping, the corresponding data is dynamically loaded and
              returned.
            * If neither of these yield results, return the standard object
              __getattribute__ result.
        """
        # Filter out the attributes we require to make decisions in this
        # method. Otherwise, we'll get "Maximum recursion depth" errors.
        if attr_name in ['rally_data', 'sub_objects_dynamic_loader',
                         '_full_sub_objects']:
            return object.__getattribute__(self, attr_name)

        rally_data = object.__getattribute__(self, 'rally_data')
        if attr_name in rally_data:
            rally_item = rally_data[attr_name]
            if isinstance(rally_item, dict) and '_ref' in rally_item:
                rally_name = rally_item['_type']
                object_class = API_OBJECT_TYPES.get(rally_name, BaseRallyModel)
                try:
                    return object_class.create_from_ref(rally_item['_ref'])
                except ReferenceNotFoundException:
                    return None
            else:
                return rally_item
        else:
            # If it is not in the rally data, let's check if we're trying to
            # access an auto-loading attribute.
            if attr_name in self.sub_objects_dynamic_loader:

                if attr_name not in self._full_sub_objects:
                    rally_data_equivalent = \
                                    self.sub_objects_dynamic_loader[attr_name]
                    self._full_sub_objects[attr_name] = []
                    for skeleton in self.rally_data.get(rally_data_equivalent,
                                                        []):
                        rally_name = skeleton['_type']
                        object_class = API_OBJECT_TYPES.get(rally_name,
                                                            BaseRallyModel)
                        self._full_sub_objects[attr_name].append(
                                    object_class.create_from_ref(
                                                             skeleton['_ref']))
                return self._full_sub_objects[attr_name]
            return object.__getattribute__(self, attr_name)
Пример #2
0
    def __getattribute__(self, attr_name):
        """Patch the default __getattribute__ call to be better for us.

        Rather than *only* looking at the __dict__ of the object do determine
        attribute resolution, improve so that:

            * Attributes are looked at in the underlying ``rally_data`` stored
              against the object.

                * If found in this data and it is a dictionary, load a new
                  python object up with the data.
                * Otherwise, just return the data.

            * If not found there, attributes are looked at in
              ``sub_objects_dynamic_loader``. This is a dictionary of
              ``property_name`` to ``rally_data`` key. If ``attr_name`` exists
              in this mapping, the corresponding data is dynamically loaded and
              returned.
            * If neither of these yield results, return the standard object
              __getattribute__ result.
        """
        # Filter out the attributes we require to make decisions in this
        # method. Otherwise, we'll get "Maximum recursion depth" errors.
        if attr_name in [
                'rally_data', 'sub_objects_dynamic_loader', '_full_sub_objects'
        ]:
            return object.__getattribute__(self, attr_name)

        rally_data = object.__getattribute__(self, 'rally_data')
        if attr_name in rally_data:
            rally_item = rally_data[attr_name]
            if isinstance(rally_item, dict) and '_ref' in rally_item:
                rally_name = rally_item['_type']
                object_class = API_OBJECT_TYPES.get(rally_name, BaseRallyModel)
                try:
                    return object_class.create_from_ref(rally_item['_ref'])
                except ReferenceNotFoundException:
                    return None
            else:
                return rally_item
        else:
            # If it is not in the rally data, let's check if we're trying to
            # access an auto-loading attribute.
            if attr_name in self.sub_objects_dynamic_loader:

                if attr_name not in self._full_sub_objects:
                    rally_data_equivalent = \
                                    self.sub_objects_dynamic_loader[attr_name]
                    self._full_sub_objects[attr_name] = []
                    for skeleton in self.rally_data.get(
                            rally_data_equivalent, []):
                        rally_name = skeleton['_type']
                        object_class = API_OBJECT_TYPES.get(
                            rally_name, BaseRallyModel)
                        self._full_sub_objects[attr_name].append(
                            object_class.create_from_ref(skeleton['_ref']))
                return self._full_sub_objects[attr_name]
            return object.__getattribute__(self, attr_name)
Пример #3
0
    def convert_from_query_result(cls, results, full_objects=False):
        """Convert a set of Rally results into python objects.

        :param results:
            An iterable of results from the Rally API.

        :param full_objects:
            Boolean. If ``True``, ``results`` is assumed to contain full
            objects as returned by the API when ``fetch=True`` is included in
            the URL. If ``False``, the full object data is fetched using
            :py:meth:`~pyrally.models.BaseRallyModel.create_from_ref`.

        :returns:
            A list of full :py:class:`~pyrally.models.BaseRallyModel`
            inheriting python objects.
        """
        converted_results = []
        for result in results:
            object_class = API_OBJECT_TYPES.get(result['_type'],
                                                BaseRallyModel)
            if full_objects:
                new_obj = object_class(result)
            else:
                new_obj = object_class.create_from_ref(result['_ref'])
            converted_results.append(new_obj)
        return converted_results
Пример #4
0
    def convert_from_query_result(cls, results, full_objects=False):
        """Convert a set of Rally results into python objects.

        :param results:
            An iterable of results from the Rally API.

        :param full_objects:
            Boolean. If ``True``, ``results`` is assumed to contain full
            objects as returned by the API when ``fetch=True`` is included in
            the URL. If ``False``, the full object data is fetched using
            :py:meth:`~pyrally.models.BaseRallyModel.create_from_ref`.

        :returns:
            A list of full :py:class:`~pyrally.models.BaseRallyModel`
            inheriting python objects.
        """
        converted_results = []
        for result in results:
            object_class = API_OBJECT_TYPES.get(result['_type'],
                                                BaseRallyModel)
            if full_objects:
                new_obj = object_class(result)
            else:
                new_obj = object_class.create_from_ref(result['_ref'])
            converted_results.append(new_obj)
        return converted_results