docs: def _populate_from_list_blobs(self, creds, options, dry_run):
          # type: (SourcePath, StorageCredentials, Any, bool) -> StorageEntity
          """Internal generator for Azure remote blobs
          :param SourcePath self: this
          :param StorageCredentials creds: storage creds
          :param object options: download or synccopy options
          :param bool dry_run: dry run
          :rtype: StorageEntity
          :return: Azure storage entity object
          """
          is_synccopy = isinstance(options, blobxfer.models.options.SyncCopy)
          for _path in self._paths:
              rpath = str(_path)
              sa = creds.get_storage_account(self.lookup_storage_account(rpath))
              # ensure at least read permissions
              if not sa.can_read_object:
                  raise RuntimeError(
                      'unable to populate sources for remote path {} as '
                      'credential for storage account {} does not permit read '
                      'access'.format(rpath, sa.name))
              cont, dir = blobxfer.util.explode_azure_path(rpath)
              if sa.can_list_container_objects:
                  for blob in blobxfer.operations.azure.blob.list_blobs(
                          sa.block_blob_client, cont, dir, options.mode,
                          options.recursive):
                      # check for virtual directory placeholder
                      if not is_synccopy:
                          try:
                              if (blob.metadata[
                                      _METADATA_VIRTUAL_DIRECTORY] == 'true'):
                                  continue
                          except KeyError:
                              pass
                      if not self._inclusion_check(blob.name):
                          if dry_run:
                              logger.info(
                                  '[DRY RUN] skipping due to filters: '
                                  '{}/{}'.format(cont, blob.name))
                          continue
                      for ase in self._handle_vectored_io_stripe(
                              creds, options, is_synccopy, sa, blob,
                              False, cont):
                          if ase is None:
                              continue
                          yield ase
              else:
                  blob = blobxfer.operations.azure.blob.get_blob_properties(
                      sa.block_blob_client, cont, dir, options.mode)
                  if blob is None:
                      logger.error(
                          'blob {} not found in storage account {}'.format(
                              rpath, sa.name))
                      return
                  if not self._inclusion_check(blob.name):
                      if dry_run:
                          logger.info(
                              '[DRY RUN] skipping due to filters: {}/{}'.format(
                                  cont, blob.name))
                      return
                  for ase in self._handle_vectored_io_stripe(
                          creds, options, is_synccopy, sa, blob, False, cont):
                      if ase is None:
                          continue
                      yield ase