`vtkCommunicator.MarshalDataObject` mutates locale unexpectedly

This seems like a bug, since I would expect locale not to be mutated when calling vtk code like this:

import locale
import vtk

l = locale.getlocale()
e = locale.getencoding()
print(f"Locale before: {l}, Encoding: {e}")

vtk.vtkCommunicator.MarshalDataObject(vtk.vtkPolyData(), vtk.vtkCharArray())

l = locale.getlocale()
e = locale.getencoding()
print(f"Locale after: {l}, Encoding: {e}")
Locale before: ('en_US', 'UTF-8'), Encoding: UTF-8
Locale after: (None, None), Encoding: US-ASCII

This mutation has implications for python users, since vtk.vtkCommunicator.MarshalDataObject is called when pickling vtk objects:

This is even more confusing when users aren’t even pickling objects themselves, e.g. pickling is used by copy.deepcopy, resulting in locale being unexpectedly mutated with this code:

import copy
import vtk

poly = vtk.vtkPolyData()
poly_copy = copy.deepcopy(poly)

Is this normal/expected? Should this be tracked as an issue in GitLab?

@jaswantp

@ben.boeckel i do not know about the vtkCommunicator.MarshalDataObject method. The marshalling that we worked on is different.

The marshalling is using a generic data object writer to serialize the vtk object:

Using this info, we can reproduce the bug by simply saving the mesh to file, e.g. with vtkPolyDataWriter:

import locale
import vtk

l = locale.getlocale()
e = locale.getencoding()
print(f"Locale before: {l}, Encoding: {e}")

poly = vtk.vtkPolyData()
writer = vtk.vtkPolyDataWriter()
writer.SetFileName("poly.vtk")
writer.SetInputData(poly)
writer.Write()

l = locale.getlocale()
e = locale.getencoding()
print(f"Locale after: {l}, Encoding: {e}")

So it’s not specific to pickling or marshalling, but is related to the IO or writer modules.

and if we comment out writer.Write(), then the locale is not mutated. So this mutation is caused by the Write method somehow.

Perhaps this is the culprit?

Yes, that looks to be the culprit. We should convert to using stream object locale APIs instead of messing with the global state.

We should convert to using stream object locale APIs instead of messing with the global state.

Sounds like this should be tracked in GitLab then as a bug-fix / maintenance item?

Here’s the original MR: https://gitlab.kitware.com/vtk/vtk/-/merge_requests/5080
The locale is supposed to be restored here:

But it appears no tests were added with the MR to ensure this actually works.

Even with restoration, any multi-threading will see the locale switch on it suddenly. Yes, please open an issue for it.

https://gitlab.kitware.com/vtk/vtk/-/issues/19928