The normal_update methods of BMVert, BMEdge, BMFace, and BMesh are not clear on some behaviors. These behaviors are listed below and are included in this diff.
Calling normal_update on a BMVert that has no adjoining faces (is_wire is True) will set the vert's normal to a zero vector. While this is not an unreasonable result, this can be unexpected and cause confusion. Also, normal_update for a vert does not update the normals of adjoining faces.
Calling normal_update on a BMEdge first calls normal_update on any adjoining faces, then calls normal_update on the two edge verts. An edge has no normal, yet it seemingly has a way to update it? Also, the vert normal will be a zero vector if the vert is_wire is True (see prev note).
Calling normal_update on a BMFace does not update the normals of face verts.
Finally, calling normal_update on BMesh will call normal_update on all faces and verts. (see note on vert normal when is_wire is True.
note: the normal_update for BMVert could include details on how the normal is computed (based on normals of adjoining faces).