| 378 | }; |
| 379 | |
| 380 | class TypeInferrer { |
| 381 | // A type inference visitor for Python values |
| 382 | public: |
| 383 | // \param validate_interval the number of elements to observe before checking |
| 384 | // whether the data is mixed type or has other problems. This helps avoid |
| 385 | // excess computation for each element while also making sure we "bail out" |
| 386 | // early with long sequences that may have problems up front |
| 387 | // \param make_unions permit mixed-type data by creating union types (not yet |
| 388 | // implemented) |
| 389 | explicit TypeInferrer(bool pandas_null_sentinels = false, |
| 390 | int64_t validate_interval = 100, bool make_unions = false) |
| 391 | : pandas_null_sentinels_(pandas_null_sentinels), |
| 392 | validate_interval_(validate_interval), |
| 393 | make_unions_(make_unions), |
| 394 | total_count_(0), |
| 395 | none_count_(0), |
| 396 | bool_count_(0), |
| 397 | int_count_(0), |
| 398 | date_count_(0), |
| 399 | time_count_(0), |
| 400 | timestamp_micro_count_(0), |
| 401 | duration_count_(0), |
| 402 | float_count_(0), |
| 403 | binary_count_(0), |
| 404 | unicode_count_(0), |
| 405 | decimal_count_(0), |
| 406 | list_count_(0), |
| 407 | struct_count_(0), |
| 408 | arrow_scalar_count_(0), |
| 409 | numpy_dtype_count_(0), |
| 410 | interval_count_(0), |
| 411 | uuid_count_(0), |
| 412 | max_decimal_metadata_(std::numeric_limits<int32_t>::min(), |
| 413 | std::numeric_limits<int32_t>::min()), |
| 414 | decimal_type_() { |
| 415 | ARROW_CHECK_OK(internal::ImportDecimalType(&decimal_type_)); |
| 416 | ARROW_CHECK_OK(ImportPresentIntervalTypes(&interval_types_)); |
| 417 | } |
| 418 | |
| 419 | /// \param[in] obj a Python object in the sequence |
| 420 | /// \param[out] keep_going if sufficient information has been gathered to |
| 421 | /// attempt to begin converting the sequence, *keep_going will be set to true |
| 422 | /// to signal to the calling visitor loop to terminate |
| 423 | Status Visit(PyObject* obj, bool* keep_going) { |
| 424 | ++total_count_; |
| 425 | |
| 426 | if (obj == Py_None || (pandas_null_sentinels_ && internal::PandasObjectIsNull(obj))) { |
| 427 | ++none_count_; |
| 428 | } else if (PyBool_Check(obj)) { |
| 429 | ++bool_count_; |
| 430 | *keep_going = make_unions_; |
| 431 | } else if (PyFloat_Check(obj)) { |
| 432 | ++float_count_; |
| 433 | *keep_going = make_unions_; |
| 434 | } else if (internal::IsPyInteger(obj)) { |
| 435 | ++int_count_; |
| 436 | } else if (PyDateTime_Check(obj)) { |
| 437 | // infer timezone from the first encountered datetime object |