For signature like Tensor.reshape(*shape), this function can handle these cases: 1. parse positional arguments only case, like Tensor.reshape(1, 2) 2. parse keyword arguments only case, like Tensor.reshape(shape=(1, 2)) 3. raise Error for multiple arguments case, like Tensor.reshape(1, shape=(1, )) 4. return empty tuple for empty arguments, like Tensor.reshape()
| 39 | // 3. raise Error for multiple arguments case, like Tensor.reshape(1, shape=(1, )) |
| 40 | // 4. return empty tuple for empty arguments, like Tensor.reshape() |
| 41 | PyObject* PyParseArgs(PyObject* args, PyObject* kwargs, const char* func_name, |
| 42 | const std::string& param_name) { |
| 43 | PyObject* args_obj = NULL; |
| 44 | // Tensor.reshape(shape=(1, 2)), get (1, 2) for kwargs["shape"] |
| 45 | if (kwargs != NULL) { |
| 46 | PyObject* key = nullptr; |
| 47 | PyObject* value = nullptr; |
| 48 | Py_ssize_t pos = 0; |
| 49 | while (PyDict_Next(kwargs, &pos, &key, &value)) { |
| 50 | CHECK_OR_THROW(args_obj == NULL) |
| 51 | << Error::TypeError() << func_name << "() got multiple values for argument '" |
| 52 | << param_name << "' or get invalid argument"; |
| 53 | CHECK_EQ_OR_THROW(PyUnpack_String(key), param_name) |
| 54 | << Error::TypeError() << func_name << "() got an unexpected keyword argument " |
| 55 | << PyUnpack_String(key); |
| 56 | args_obj = value; |
| 57 | } |
| 58 | } |
| 59 | if (PyTuple_GET_SIZE(args) != 0) { |
| 60 | CHECK_OR_THROW(args_obj == NULL) |
| 61 | << Error::TypeError() << func_name << "() got multiple values for argument '" << param_name |
| 62 | << "' or get invalid argument"; |
| 63 | if (PyTuple_Size(args) == 1 && functional::PyShapeSequenceCheck(args)) { |
| 64 | args_obj = PyTuple_GET_ITEM(args, 0); |
| 65 | } else { |
| 66 | args_obj = args; |
| 67 | } |
| 68 | }; |
| 69 | if (args_obj == NULL) { args_obj = args; } |
| 70 | return args_obj; |
| 71 | } |
| 72 | |
| 73 | } // namespace one |
| 74 | } // namespace oneflow |
no test coverage detected