code: def search_objects(self, query):
          
          self._check_obj_properties(query, "query")
  
          # AND operator between results
          final_result = None
          for result in self._get_subset_matches(query):
              if final_result is None:
                  final_result = result
                  continue
  
              final_result = intersection(final_result, result)
  
          # if no result is found, `final_result` is None, and I want []
          if not final_result:
              return []
  
          return list(final_result)
docs: Return list of objects which match all properties that are set
          (``not None``) using AND operator to all of them.
  
          Example:
              result = storage_handler.search_objects(
                  DBPublication(isbn="azgabash")
              )
  
          Args:
              query (obj): Object implementing proper interface with some of the
                    properties set.
  
          Returns:
              list: List of matching objects or ``[]`` if no match was found.
  
          Raises:
              InvalidType: When the `query` doesn't implement required
                  properties.