Repository: quantopian/zipline
File: zipline/data/data_portal.py (Python)

Code before:
        of the desired asset's field at either the given dt.

        Parameters
        ----------
        assets : Asset, ContinuousFuture, or iterable of same.
            The asset or assets whose data is desired.
        field : {'open', 'high', 'low', 'close', 'volume',
                 'price', 'last_traded'}
            The desired field of the asset.
        dt : pd.Timestamp
            The timestamp for the desired value.
        data_frequency : str
            The frequency of the data to query; i.e. whether the data is
            'daily' or 'minute' bars

        Returns
        -------
        value : float, int, or pd.Timestamp
            The spot value of ``field`` for ``asset`` The return type is based
            on the ``field`` requested. If the field is one of 'open', 'high',
            'low', 'close', or 'price', the value will be a float. If the
            ``field`` is 'volume' the value will be a int. If the ``field`` is
            'last_traded' the value will be a Timestamp.
        """
        assets_is_scalar = False
        if isinstance(assets, (Asset, ContinuousFuture, str)):
            assets_is_scalar = True
            assets = [assets]

        # If 'assets' was not one of the expected types then it should be an
        # iterable.
        try:
            iter(assets)
        except TypeError:
            raise TypeError(
                "Unexpected 'assets' value of type {}.".format(type(assets)),
            )

        spot_values = []

        for asset in assets:
            if self._is_extra_source(
                    asset, field, self._augmented_sources_map):
                spot_values.append(self._get_fetcher_value(asset, field, dt))
                continue

            if field not in BASE_FIELDS:
                raise KeyError("Invalid column: " + str(field))

            session_label = self.trading_calendar.minute_to_session_label(dt)


Review comment (suggestion):
Could we use `AssetConvertible` or `PricingDataAssociable` here instead, which each have the Python string types registered (and handles Python 2/3).
Checking for just `str` is not sufficient.

Code after:
        except KeyError:
            return np.NaN

    def get_spot_value(self, assets, field, dt, data_frequency):
        """
        Public API method that returns a scalar value representing the value
        of the desired asset's field at either the given dt.

        Parameters
        ----------
        assets : Asset, ContinuousFuture, or iterable of same.
            The asset or assets whose data is desired.
        field : {'open', 'high', 'low', 'close', 'volume',
                 'price', 'last_traded'}
            The desired field of the asset.
        dt : pd.Timestamp
            The timestamp for the desired value.
        data_frequency : str
            The frequency of the data to query; i.e. whether the data is
            'daily' or 'minute' bars

        Returns
        -------
        value : float, int, or pd.Timestamp
            The spot value of ``field`` for ``asset`` The return type is based
            on the ``field`` requested. If the field is one of 'open', 'high',
            'low', 'close', or 'price', the value will be a float. If the
            ``field`` is 'volume' the value will be a int. If the ``field`` is
            'last_traded' the value will be a Timestamp.
        """
        assets_is_scalar = False
        if isinstance(assets, (AssetConvertible, PricingDataAssociable)):
            assets_is_scalar = True
        else:
            # If 'assets' was not one of the expected types then it should be
            # an iterable.
            try:
                iter(assets)
            except TypeError:
                raise TypeError(
                    "Unexpected 'assets' value of type {}."
                    .format(type(assets))
                )

        session_label = self.trading_calendar.minute_to_session_label(dt)

        def get_single_asset_value(asset):
            if self._is_extra_source(
                    asset, field, self._augmented_sources_map):
                return self._get_fetcher_value(asset, field, dt)