It’s just an follow-up. I recently encounter the similar situation. The workaround solution that I did is to use the str() to cast the torch.dtype into a C++ string, and in the python end write a wrapper around it:
Here is the C++ part:
torch::Tensor func1(const vector<int64_t> &shape, const std::string &dtype){
   // convert the string -> torch::ScalarType here. 
   auto options = torch.TensorOptions();
   if(dtype=="torch.float32"){
       options.dtype(torch::kFloat32);
   } // ... extend this

   return torch::Tensor(shape,options);

}


Here is the pybind wrapper part :
PYBIND11_MODULE(cytnx,m){
    m.def("c_func1",&func1);
}

Here is the python module in the directory structure:
cytnx/
|- __ init __.py
|- [the dynamic linking file compiled from pybind]
Inside __ init __.py:
from .cytnx import *

## this is the API expose to user
def func1(shape, dtype):
     # calling the wrapper from pybind
     return c_func1(shape,str(dtype),str(device))

I would hope there will be a direct support over this in the future