Why not pyimport in the anonymous function; e.g., pmap(x -> pyimport("math").sin(x), a)? There are other ways to workaround this. But I don’t think customizing serialization is the right way to do it.
Python modules are cached so it’s a very cheap operation. I’d just use it untill it turned out to be a bottleneck after benchmarking and profiling. Having said that, there are other solutions:
@everywhere pysin(x) = math.sin(x) then pmap(pysin, a)
You can copy! the module math or the function math.sin to a constant as mentioned in PyCall README. This can be used as per-process memoization or in __init__.
If you are OK with Image().open(b) you should be OK with pyimport("PIL.Image").open(b) (performance-wise).
Your code with copy! didn’t work because you are not using memoization/caching pattern. You need to call copy! inside the function you passed to pmap, guarded by ispynull.
Performance-wise I’m okay with it because in my case, processing images are very slow operations. If this is the right way to do, then I will accept it because it requires minimum changes.