code: def getcomponents(self, product, force_refresh=False):
          
          proddict = self._lookup_product_in_cache(product)
          product_id = proddict.get("id", None)
  
          if (force_refresh or
              product_id is None or
              product_id not in self._cache.component_names):
              self.refresh_products(names=[product],
                                    include_fields=["name", "id"])
              proddict = self._lookup_product_in_cache(product)
              if "id" not in proddict:
                  raise BugzillaError("Product '%s' not found" % product)
              product_id = proddict["id"]
  
              opts = {'product_id': product_id, 'field': 'component'}
              names = self._proxy.Bug.legal_values(opts)["values"]
              self._cache.component_names[product_id] = names
  
          return self._cache.component_names[product_id]
docs: Return a list of component names for the passed product.
  
          This can be implemented with Product.get, but behind the
          scenes it uses Bug.legal_values. Reason being that on bugzilla
          instances with tons of components, like bugzilla.redhat.com
          Product=Fedora for example, there's a 10x speed difference
          even with properly limited Product.get calls.
  
          On first invocation the value is cached, and subsequent calls
          will return the cached data.
  
          :param force_refresh: Force refreshing the cache, and return
              the new data