Repository: apache/arrow
File: python/pyarrow/src/arrow/python/inference.cc (C++)

Code before:
  }

  Status VisitDict(PyObject* obj) {
    PyObject* key_obj;
    PyObject* value_obj;
    Py_ssize_t pos = 0;

    while (PyDict_Next(obj, &pos, &key_obj, &value_obj)) {
      std::string key;
      if (PyUnicode_Check(key_obj)) {
        RETURN_NOT_OK(internal::PyUnicode_AsStdString(key_obj, &key));
      } else if (PyBytes_Check(key_obj)) {
        key = internal::PyBytes_AsStdString(key_obj);
      } else {
        return Status::TypeError("Expected dict key of type str or bytes, got '",
                                 Py_TYPE(key_obj)->tp_name, "'");
      }
      // Get or create visitor for this key
      TypeInferrer* visitor;
      auto it = struct_field_index_.find(key);
      if (it == struct_field_index_.end()) {
        // New field - add to vector and index
        size_t new_index = struct_inferrers_.size();
        struct_inferrers_.emplace_back(
            key, TypeInferrer(pandas_null_sentinels_, validate_interval_, make_unions_));
        struct_field_index_.emplace(key, new_index);
        visitor = &struct_inferrers_.back().second;
      } else {
        // Existing field - retrieve from vector
        visitor = &struct_inferrers_[it->second].second;
      }

      // We ignore termination signals from child visitors for now
      //
      // TODO(wesm): keep track of whether type inference has terminated for
      // the child visitors to avoid doing unneeded work
      bool keep_going = true;
      RETURN_NOT_OK(visitor->Visit(value_obj, &keep_going));
    }

    // We do not terminate visiting dicts since we want the union of all
    // observed keys
    ++struct_count_;
    return Status::OK();
  }

  Status GetStructType(std::shared_ptr<DataType>* out) {
    std::vector<std::shared_ptr<Field>> fields;
    fields.reserve(struct_inferrers_.size());
    for (auto& it : struct_inferrers_) {
      std::shared_ptr<DataType> field_type;

Review comment (suggestion):
We can perhaps save a copy here, though probably not very important.
```suggestion
        struct_field_index_.emplace(std::move(key), new_index);
```

Code after:
  }

  Status VisitDict(PyObject* obj) {
    PyObject* key_obj;
    PyObject* value_obj;
    Py_ssize_t pos = 0;

    while (PyDict_Next(obj, &pos, &key_obj, &value_obj)) {
      std::string key;
      if (PyUnicode_Check(key_obj)) {
        RETURN_NOT_OK(internal::PyUnicode_AsStdString(key_obj, &key));
      } else if (PyBytes_Check(key_obj)) {
        key = internal::PyBytes_AsStdString(key_obj);
      } else {
        return Status::TypeError("Expected dict key of type str or bytes, got '",
                                 Py_TYPE(key_obj)->tp_name, "'");
      }
      // Get or create visitor for this key
      TypeInferrer* visitor;
      auto it = struct_field_index_.find(key);
      if (it == struct_field_index_.end()) {
        // New field - add to vector and index
        size_t new_index = struct_inferrers_.size();
        struct_inferrers_.emplace_back(
            key, TypeInferrer(pandas_null_sentinels_, validate_interval_, make_unions_));
        struct_field_index_.emplace(std::move(key), new_index);
        visitor = &struct_inferrers_.back().second;
      } else {
        // Existing field - retrieve from vector
        visitor = &struct_inferrers_[it->second].second;
      }

      // We ignore termination signals from child visitors for now
      //
      // TODO(wesm): keep track of whether type inference has terminated for
      // the child visitors to avoid doing unneeded work
      bool keep_going = true;
      RETURN_NOT_OK(visitor->Visit(value_obj, &keep_going));
    }

    // We do not terminate visiting dicts since we want the union of all
    // observed keys
    ++struct_count_;
    return Status::OK();
  }

  Status GetStructType(std::shared_ptr<DataType>* out) {
    std::vector<std::shared_ptr<Field>> fields;
    fields.reserve(struct_inferrers_.size());
    for (auto& it : struct_inferrers_) {
      std::shared_ptr<DataType> field_type;