How does Blender know which faces and edges to automatically select when doing a multi-vert selection?
Flushing select mode.

Recommend naming a bmesh representation of a mesh bm and reserve mesh or me for a mesh.  

bpy.ops.mesh operators manipulate the mesh.  A bound bmesh, ie from_edit_mesh is still not the mesh.  An edit mode mesh is what we don't have a handle on via python.  Can set me.vertices properties in edit mode, but will have no effect on the "special" edit mode instance of the mesh. 

Flushing selection, or updating the bmesh will ensure the mesh used by the operator has the changes. Put it in a fit context to be operated on  

If the intention is using bound bmesh to select the geometry required by  bpy.ops.mesh operator, flush the selection before the operator call. 

As mentioned in prior answer, the results of your script will change depending on selection mode. It is part of the context bpy.ops.mesh operators use. This sets it to all.

&gt;&gt;&gt; C.tool_settings.mesh_select_mode = (True, True, True)



Result of running the script in prior question in only vert, only edge, and only face selection modes.  No prior selections

Will also get the desired result if we select face in face selection mode, then switch to vert select mode and run script.  The simplest fix of all to use bpy.ops.mesh with face selection from verts selection is to set one or both of faces and edges to True. 

In the bmesh docs


  Selection / Flushing
  
  As mentioned above, it is possible to create an invalid selection
  state (by selecting a state and then de-selecting one of its
  vertices’s for example), mostly the best way to solve this is to flush
  the selection after performing a series of edits. this validates the
  selection state.


In Keeping a Correct State it states that vertices belonging to edge are selected when edge selected. Similarly for edges, (and hence verts) of a face. 

It does not mention the converse is true.  Selecting verts selects their edges and / or faces. (Speculatively This works from the UI since it has a handle on "special edit mode mesh" ie select 4 verts in UI, vert select only,  then on running script to check,  face is selected)

To set a face to selected, makes sense to select the sub-elements.  Work like an update method. Face sets edges, edges set verts.  To conversely select a vert then check all its linked edges and faces, and set to selected would fire off our update reelecting the selected.  Or similarly as a property getter  checking all the selection of sub-elements, could prove expensive. 

Instead select_flush is used to sanitize state.

Akin to setting the context tool select mode calling bm.select_flush_mode() will flush the states according to those set in bmesh.select_mode.

Test scripts. both designed to select face and extrude even in select only vertex mode. context.tool_settings.mesh_select_mode = (True, False, False), 

Selects verts,  flushes mode, extrudes face.

import bpy 
import bmesh
context = bpy.context
me = context.object.data
bmesh.select_mode = {'VERT', 'EDGE', 'FACE'}
bm = bmesh.from_edit_mesh(me)
for v in bm.verts:
    v.select = v.co.z &gt; 0
# flush the selection
bm.select_flush_mode()    

bpy.ops.mesh.extrude_region_move(
        TRANSFORM_OT_translate={"value" : (0, 0, 2)}
        )


If we use faces can  skip the flush call and select the faces  based on the vert selection

    for f in bm.faces:
        f.select = all(v.select for v in f.verts) 


but, IMO if you are going to extrude regions, generally only want faces, not edges or verts, so rather than diddle around with vertex selection, select faces instead (and vertex edge selection is done for us)  The so called brute force approach

    for f in bm.faces:
        f.select = all(v.co.z &gt; 0 for v in f.verts) 


Test script.

import bpy 
import bmesh


context = bpy.context
me = context.object.data
bm = bmesh.from_edit_mesh(me)  

for f in bm.faces:
    f.select = all(v.co.z &gt; 0 for v in f.verts) 

bpy.ops.mesh.extrude_region_move(
        TRANSFORM_OT_translate={"value" : (0, 0, 2)})


As mentioned in prior answer, recommend using bmesh.ops operators over bpy.ops.mesh...  The geometry is passed to the operator, rather than manipulating context and selection.  

Leave selection to the user, or a selection operator.

Can use the tag property

for v i bm.verts:
    v.tag = some_long_winded_test_bool_func

for f in bm.faces:
    f.select = all(v.tag for v in f.verts)


to avoid calculating per vert per face, and verts not part of a face.