diff --git a/cpp/include/cudf/binaryop.hpp b/cpp/include/cudf/binaryop.hpp index 6371cb6c82b..77d6a4d1e89 100644 --- a/cpp/include/cudf/binaryop.hpp +++ b/cpp/include/cudf/binaryop.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022, NVIDIA CORPORATION. + * Copyright (c) 2019-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -108,6 +108,7 @@ enum class binary_operator : int32_t { * @throw cudf::logic_error if @p output_type dtype isn't fixed-width * @throw cudf::logic_error if @p output_type dtype isn't boolean for comparison and logical * operations. + * @throw cudf::data_type_error if the operation is not supported for the types of @p lhs and @p rhs */ std::unique_ptr binary_operation( scalar const& lhs, @@ -136,6 +137,7 @@ std::unique_ptr binary_operation( * @throw cudf::logic_error if @p output_type dtype isn't fixed-width * @throw cudf::logic_error if @p output_type dtype isn't boolean for comparison and logical * operations. + * @throw cudf::data_type_error if the operation is not supported for the types of @p lhs and @p rhs */ std::unique_ptr binary_operation( column_view const& lhs, @@ -163,6 +165,7 @@ std::unique_ptr binary_operation( * @throw cudf::logic_error if @p output_type dtype isn't boolean for comparison and logical * operations. * @throw cudf::logic_error if @p output_type dtype isn't fixed-width + * @throw cudf::data_type_error if the operation is not supported for the types of @p lhs and @p rhs */ std::unique_ptr binary_operation( column_view const& lhs, diff --git a/cpp/include/cudf/concatenate.hpp b/cpp/include/cudf/concatenate.hpp index 1f8ce65ad93..b20c97b3c31 100644 --- a/cpp/include/cudf/concatenate.hpp +++ b/cpp/include/cudf/concatenate.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,8 +50,8 @@ rmm::device_buffer concatenate_masks( /** * @brief Concatenates multiple columns into a single column. * - * @throws cudf::logic_error - * If types of the input columns mismatch + * @throws cudf::logic_error If types of the input columns mismatch + * @throws std::overflow_error If the the total number of output rows exceeds cudf::size_type * * @param columns_to_concat host_span of column views to be concatenated into a single column * @param mr Device memory resource used to allocate the returned column's device memory @@ -80,8 +80,8 @@ std::unique_ptr concatenate( * column_view tc1 = (t->view()).column(1); //Contains {0,1,2,3,4,5,6,7} * ``` * - * @throws cudf::logic_error - * If number of columns mismatch + * @throws cudf::logic_error If number of columns mismatch + * @throws std::overflow_error If the the total number of output rows exceeds cudf::size_type * * @param tables_to_concat host_span of table views to be concatenated into a single table * @param mr Device memory resource used to allocate the returned table's device memory diff --git a/cpp/include/cudf/lists/combine.hpp b/cpp/include/cudf/lists/combine.hpp index 4f211e87cc7..531396e940e 100644 --- a/cpp/include/cudf/lists/combine.hpp +++ b/cpp/include/cudf/lists/combine.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. + * Copyright (c) 2021-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,10 +80,10 @@ std::unique_ptr concatenate_rows( * r is [ {1, 2, 3, 4, 5}, {6, 7, 8, 9} ] * @endcode * - * @throws cudf::logic_error if the input column is not at least two-level depth lists column (i.e., - * each row must be a list of list). + * @throws std::invalid_argument if the input column is not at least two-level depth lists column + * (i.e., each row must be a list of list). * @throws cudf::logic_error if the input lists column contains nested typed entries that are not - * lists. + * lists. * * @param input The lists column containing lists of list elements to concatenate. * @param null_policy The parameter to specify whether a null list element will be ignored from diff --git a/cpp/include/cudf/lists/contains.hpp b/cpp/include/cudf/lists/contains.hpp index d2b4d59dfba..a9f06bf399c 100644 --- a/cpp/include/cudf/lists/contains.hpp +++ b/cpp/include/cudf/lists/contains.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. + * Copyright (c) 2021-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -126,9 +126,7 @@ enum class duplicate_find_option : int32_t { * @param mr Device memory resource used to allocate the returned column's device memory. * @return std::unique_ptr INT32 column of `n` rows with the location of the `search_key` * - * @throw cudf::logic_error If `search_key` type does not match the element type in `lists` - * @throw cudf::logic_error If `search_key` is of a nested type, or `lists` contains nested - * elements (LIST, STRUCT) + * @throw cudf::data_type_error If `search_keys` type does not match the element type in `lists` */ std::unique_ptr index_of( cudf::lists_column_view const& lists, @@ -163,8 +161,7 @@ std::unique_ptr index_of( * @return std::unique_ptr INT32 column of `n` rows with the location of the `search_key` * * @throw cudf::logic_error If `search_keys` does not match `lists` in its number of rows - * @throw cudf::logic_error If `search_keys` type does not match the element type in `lists` - * @throw cudf::logic_error If `lists` or `search_keys` contains nested elements (LIST, STRUCT) + * @throw cudf::data_type_error If `search_keys` type does not match the element type in `lists` */ std::unique_ptr index_of( cudf::lists_column_view const& lists, diff --git a/cpp/include/cudf/lists/gather.hpp b/cpp/include/cudf/lists/gather.hpp index f91ce29a7cb..38bed9ede43 100644 --- a/cpp/include/cudf/lists/gather.hpp +++ b/cpp/include/cudf/lists/gather.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. + * Copyright (c) 2021-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ namespace lists { * @endcode * * @throws cudf::logic_error if `gather_map_list` size is not same as `source_column` size. - * @throws cudf::logic_error if gather_map contains null values. + * @throws std::invalid_argument if gather_map contains null values. * @throws cudf::logic_error if gather_map is not list column of an index type. * * If indices in `gather_map_list` are outside the range `[-n, n)`, where `n` is the number of diff --git a/cpp/include/cudf/strings/json.hpp b/cpp/include/cudf/strings/json.hpp index 11e8daa9855..8fabee6b9a5 100644 --- a/cpp/include/cudf/strings/json.hpp +++ b/cpp/include/cudf/strings/json.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. + * Copyright (c) 2021-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -160,6 +160,8 @@ class get_json_object_options { * @param options Options for controlling the behavior of the function * @param mr Resource for allocating device memory. * @return New strings column containing the retrieved json object strings + * + * @throw std::invalid_argument if provided an invalid operator or an empty name */ std::unique_ptr get_json_object( cudf::strings_column_view const& col, diff --git a/cpp/include/cudf/utilities/error.hpp b/cpp/include/cudf/utilities/error.hpp index 38ca0f2651e..f70ef4e5f07 100644 --- a/cpp/include/cudf/utilities/error.hpp +++ b/cpp/include/cudf/utilities/error.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022, NVIDIA CORPORATION. + * Copyright (c) 2019-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,6 +84,29 @@ struct cuda_error : public std::runtime_error { struct fatal_cuda_error : public cuda_error { using cuda_error::cuda_error; // Inherit constructors }; + +/** + * @brief Exception thrown when an operation is attempted on an unsupported dtype. + * + * This exception should be thrown when an operation is attempted on an + * unsupported data_type. This exception should not be thrown directly and is + * instead thrown by the CUDF_EXPECTS or CUDF_FAIL macros. + */ +struct data_type_error : public std::invalid_argument { + /** + * @brief Constructs a data_type_error with the error message. + * + * @param message Message to be associated with the exception + */ + data_type_error(char const* const message) : std::invalid_argument(message) {} + + /** + * @brief Construct a new data_type_error object with error message + * + * @param message Message to be associated with the exception + */ + data_type_error(std::string const& message) : std::invalid_argument(message) {} +}; /** @} */ } // namespace cudf diff --git a/cpp/src/binaryop/binaryop.cpp b/cpp/src/binaryop/binaryop.cpp index b23c1fc9fe1..f81f0dcc311 100644 --- a/cpp/src/binaryop/binaryop.cpp +++ b/cpp/src/binaryop/binaryop.cpp @@ -203,7 +203,7 @@ std::unique_ptr binary_operation(LhsType const& lhs, return cudf::binops::compiled::string_null_min_max(lhs, rhs, op, output_type, stream, mr); if (not cudf::binops::compiled::is_supported_operation(output_type, lhs.type(), rhs.type(), op)) - CUDF_FAIL("Unsupported operator for these types"); + CUDF_FAIL("Unsupported operator for these types", cudf::data_type_error); if (cudf::is_fixed_point(lhs.type()) or cudf::is_fixed_point(rhs.type())) { cudf::binops::compiled::fixed_point_binary_operation_validation( diff --git a/cpp/src/binaryop/compiled/equality_ops.cu b/cpp/src/binaryop/compiled/equality_ops.cu index 61f02252a26..041fca76494 100644 --- a/cpp/src/binaryop/compiled/equality_ops.cu +++ b/cpp/src/binaryop/compiled/equality_ops.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. + * Copyright (c) 2021-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,8 @@ void dispatch_equality_op(mutable_column_view& out, rmm::cuda_stream_view stream) { CUDF_EXPECTS(op == binary_operator::EQUAL || op == binary_operator::NOT_EQUAL, - "Unsupported operator for these types"); + "Unsupported operator for these types", + cudf::data_type_error); auto common_dtype = get_common_type(out.type(), lhs.type(), rhs.type()); auto outd = mutable_column_device_view::create(out, stream); auto lhsd = column_device_view::create(lhs, stream); diff --git a/cpp/src/binaryop/compiled/struct_binary_ops.cuh b/cpp/src/binaryop/compiled/struct_binary_ops.cuh index d167f0fe3c5..8418493318f 100644 --- a/cpp/src/binaryop/compiled/struct_binary_ops.cuh +++ b/cpp/src/binaryop/compiled/struct_binary_ops.cuh @@ -149,7 +149,8 @@ void apply_struct_equality_op(mutable_column_view& out, { CUDF_EXPECTS(op == binary_operator::EQUAL || op == binary_operator::NOT_EQUAL || op == binary_operator::NULL_EQUALS, - "Unsupported operator for these types"); + "Unsupported operator for these types", + cudf::data_type_error); auto tlhs = table_view{{lhs}}; auto trhs = table_view{{rhs}}; diff --git a/cpp/src/copying/concatenate.cu b/cpp/src/copying/concatenate.cu index 577d6427b19..5d36d70696c 100644 --- a/cpp/src/copying/concatenate.cu +++ b/cpp/src/copying/concatenate.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -228,7 +228,8 @@ std::unique_ptr fused_concatenate(host_span views, auto const output_size = std::get<3>(device_views); CUDF_EXPECTS(output_size <= static_cast(std::numeric_limits::max()), - "Total number of concatenated rows exceeds size_type range"); + "Total number of concatenated rows exceeds size_type range", + std::overflow_error); // Allocate output auto const policy = has_nulls ? mask_policy::ALWAYS : mask_policy::NEVER; @@ -398,7 +399,8 @@ void traverse_children::operator()(host_span(std::numeric_limits::max()), - "Total number of concatenated chars exceeds size_type range"); + "Total number of concatenated chars exceeds size_type range", + std::overflow_error); } template <> @@ -469,7 +471,8 @@ void bounds_and_type_check(host_span cols, rmm::cuda_stream_v }); // note: output text must include "exceeds size_type range" for python error handling CUDF_EXPECTS(total_row_count <= static_cast(std::numeric_limits::max()), - "Total number of concatenated rows exceeds size_type range"); + "Total number of concatenated rows exceeds size_type range", + std::overflow_error); // traverse children cudf::type_dispatcher(cols.front().type(), traverse_children{}, cols, stream); diff --git a/cpp/src/lists/combine/concatenate_list_elements.cu b/cpp/src/lists/combine/concatenate_list_elements.cu index 496d9ee670a..257b0aed82f 100644 --- a/cpp/src/lists/combine/concatenate_list_elements.cu +++ b/cpp/src/lists/combine/concatenate_list_elements.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. + * Copyright (c) 2021-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -257,11 +257,13 @@ std::unique_ptr concatenate_list_elements(column_view const& input, rmm::mr::device_memory_resource* mr) { auto type = input.type(); // Column that is lists of lists. - CUDF_EXPECTS(type.id() == type_id::LIST, "Input column must be a lists column."); + CUDF_EXPECTS( + type.id() == type_id::LIST, "Input column must be a lists column.", std::invalid_argument); auto col = lists_column_view(input).child(); // Rows, which are lists. type = col.type(); - CUDF_EXPECTS(type.id() == type_id::LIST, "Rows of the input column must be lists."); + CUDF_EXPECTS( + type.id() == type_id::LIST, "Rows of the input column must be lists.", std::invalid_argument); col = lists_column_view(col).child(); // The last level entries what we need to check. type = col.type(); diff --git a/cpp/src/lists/contains.cu b/cpp/src/lists/contains.cu index 05fe82d1713..a3293e36825 100644 --- a/cpp/src/lists/contains.cu +++ b/cpp/src/lists/contains.cu @@ -309,7 +309,8 @@ struct dispatch_index_of { auto const child = lists.child(); CUDF_EXPECTS(child.type() == search_keys.type(), - "Type/Scale of search key does not match list column element type."); + "Type/Scale of search key does not match list column element type.", + cudf::data_type_error); CUDF_EXPECTS(search_keys.type().id() != type_id::EMPTY, "Type cannot be empty."); auto constexpr search_key_is_scalar = std::is_same_v; diff --git a/cpp/src/lists/copying/segmented_gather.cu b/cpp/src/lists/copying/segmented_gather.cu index 2c12e09bcd9..79d33e7c17d 100644 --- a/cpp/src/lists/copying/segmented_gather.cu +++ b/cpp/src/lists/copying/segmented_gather.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ std::unique_ptr segmented_gather(lists_column_view const& value_column, { CUDF_EXPECTS(is_index_type(gather_map.child().type()), "Gather map should be list column of index type"); - CUDF_EXPECTS(!gather_map.has_nulls(), "Gather map contains nulls"); + CUDF_EXPECTS(!gather_map.has_nulls(), "Gather map contains nulls", std::invalid_argument); CUDF_EXPECTS(value_column.size() == gather_map.size(), "Gather map and list column should be same size"); diff --git a/cpp/src/strings/json/json_path.cu b/cpp/src/strings/json/json_path.cu index afe16518036..c6ea47ec0f3 100644 --- a/cpp/src/strings/json/json_path.cu +++ b/cpp/src/strings/json/json_path.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. + * Copyright (c) 2021-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -588,7 +588,7 @@ class path_state : private parser { return path_operator{path_operator_type::CHILD_WILDCARD}; } break; - default: CUDF_FAIL("Unrecognized JSONPath operator"); break; + default: CUDF_FAIL("Unrecognized JSONPath operator", std::invalid_argument); break; } return {path_operator_type::ERROR}; } @@ -624,7 +624,8 @@ class path_state : private parser { } // an empty name is not valid - CUDF_EXPECTS(name.size_bytes() > 0, "Invalid empty name in JSONPath query string"); + CUDF_EXPECTS( + name.size_bytes() > 0, "Invalid empty name in JSONPath query string", std::invalid_argument); return true; } diff --git a/cpp/tests/binaryop/binop-compiled-fixed_point-test.cpp b/cpp/tests/binaryop/binop-compiled-fixed_point-test.cpp index 8170fe4f490..bdd0003b86b 100644 --- a/cpp/tests/binaryop/binop-compiled-fixed_point-test.cpp +++ b/cpp/tests/binaryop/binop-compiled-fixed_point-test.cpp @@ -678,7 +678,7 @@ TYPED_TEST(FixedPointCompiledTest, FixedPointBinaryOpThrows) auto const col = fp_wrapper{{100, 300, 500, 700}, scale_type{-2}}; auto const non_bool_type = cudf::data_type{cudf::type_to_id(), -2}; EXPECT_THROW(cudf::binary_operation(col, col, cudf::binary_operator::LESS, non_bool_type), - cudf::logic_error); + cudf::data_type_error); } TYPED_TEST(FixedPointCompiledTest, FixedPointBinaryOpModSimple) diff --git a/cpp/tests/copying/concatenate_tests.cu b/cpp/tests/copying/concatenate_tests.cu index 79ec2293455..ca343b963d7 100644 --- a/cpp/tests/copying/concatenate_tests.cu +++ b/cpp/tests/copying/concatenate_tests.cu @@ -36,6 +36,7 @@ #include #include +#include #include template @@ -369,7 +370,7 @@ TEST_F(OverflowTest, OverflowTest) cudf::table_view tbl({*many_chars}); EXPECT_THROW(cudf::concatenate(std::vector({tbl, tbl, tbl, tbl, tbl, tbl})), - cudf::logic_error); + std::overflow_error); } // string column, overflow on chars @@ -384,7 +385,7 @@ TEST_F(OverflowTest, OverflowTest) cudf::table_view tbl({*col}); EXPECT_THROW(cudf::concatenate(std::vector({tbl, tbl, tbl, tbl, tbl, tbl})), - cudf::logic_error); + std::overflow_error); } // string column, overflow on offsets (rows) @@ -400,7 +401,7 @@ TEST_F(OverflowTest, OverflowTest) cudf::table_view tbl({*col}); EXPECT_THROW(cudf::concatenate(std::vector({tbl, tbl, tbl, tbl, tbl, tbl})), - cudf::logic_error); + std::overflow_error); } // list, structs too long @@ -425,7 +426,7 @@ TEST_F(OverflowTest, OverflowTest) cudf::table_view tbl({*col}); auto tables = std::vector({tbl, tbl, tbl, tbl, tbl, tbl, tbl, tbl, tbl, tbl, tbl, tbl}); - EXPECT_THROW(cudf::concatenate(tables), cudf::logic_error); + EXPECT_THROW(cudf::concatenate(tables), std::overflow_error); } // struct, list child too long @@ -450,7 +451,7 @@ TEST_F(OverflowTest, OverflowTest) cudf::table_view tbl({*col}); auto tables = std::vector({tbl, tbl, tbl, tbl, tbl, tbl, tbl, tbl, tbl, tbl, tbl, tbl}); - EXPECT_THROW(cudf::concatenate(tables), cudf::logic_error); + EXPECT_THROW(cudf::concatenate(tables), std::overflow_error); } } @@ -470,7 +471,8 @@ TEST_F(OverflowTest, Presliced) // 513 * 1024 * 1024, should fail cudf::table_view b({sliced[1]}); - EXPECT_THROW(cudf::concatenate(std::vector({b, b, b, b})), cudf::logic_error); + EXPECT_THROW(cudf::concatenate(std::vector({b, b, b, b})), + std::overflow_error); } // struct column @@ -490,7 +492,8 @@ TEST_F(OverflowTest, Presliced) // 513 * 1024 * 1024, should fail cudf::table_view b({sliced[1]}); - EXPECT_THROW(cudf::concatenate(std::vector({b, b, b, b})), cudf::logic_error); + EXPECT_THROW(cudf::concatenate(std::vector({b, b, b, b})), + std::overflow_error); } // strings, overflow on chars @@ -516,7 +519,8 @@ TEST_F(OverflowTest, Presliced) // (num_rows / 2) + 1 should fail cudf::table_view b({sliced[1]}); - EXPECT_THROW(cudf::concatenate(std::vector({b, b, b, b})), cudf::logic_error); + EXPECT_THROW(cudf::concatenate(std::vector({b, b, b, b})), + std::overflow_error); } // strings, overflow on offsets @@ -589,7 +593,7 @@ TEST_F(OverflowTest, Presliced) auto sliced = cudf::split(*col, {2}); cudf::table_view tbl({sliced[1]}); auto tables = std::vector({tbl, tbl, tbl, tbl}); - EXPECT_THROW(cudf::concatenate(tables), cudf::logic_error); + EXPECT_THROW(cudf::concatenate(tables), std::overflow_error); } // list, overflow on offsets @@ -674,7 +678,8 @@ TEST_F(OverflowTest, Presliced) cudf::concatenate(std::vector({a, a, a, a})); cudf::table_view b({sliced[1]}); - EXPECT_THROW(cudf::concatenate(std::vector({b, b, b, b})), cudf::logic_error); + EXPECT_THROW(cudf::concatenate(std::vector({b, b, b, b})), + std::overflow_error); } } diff --git a/cpp/tests/copying/segmented_gather_list_tests.cpp b/cpp/tests/copying/segmented_gather_list_tests.cpp index deeebc641c2..fc21af2087b 100644 --- a/cpp/tests/copying/segmented_gather_list_tests.cpp +++ b/cpp/tests/copying/segmented_gather_list_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. + * Copyright (c) 2020-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,8 @@ #include #include +#include + template class SegmentedGatherTest : public cudf::test::BaseFixture { }; @@ -611,7 +613,7 @@ TEST_F(SegmentedGatherTestFloat, Fails) // Nulls are not supported in the gather map. EXPECT_THROW(cudf::lists::segmented_gather(cudf::lists_column_view{list}, cudf::lists_column_view{nulls_map}), - cudf::logic_error); + std::invalid_argument); // Gather map and list column sizes must be the same. EXPECT_THROW(cudf::lists::segmented_gather(cudf::lists_column_view{list}, diff --git a/cpp/tests/lists/combine/concatenate_list_elements_tests.cpp b/cpp/tests/lists/combine/concatenate_list_elements_tests.cpp index ca25560141c..77e8f904d01 100644 --- a/cpp/tests/lists/combine/concatenate_list_elements_tests.cpp +++ b/cpp/tests/lists/combine/concatenate_list_elements_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,8 @@ #include +#include + using namespace cudf::test::iterators; namespace { @@ -47,13 +49,13 @@ TEST_F(ConcatenateListElementsTest, InvalidInput) // Input lists is not a 2-level depth lists column. { auto const col = IntCol{}; - EXPECT_THROW(cudf::lists::concatenate_list_elements(col), cudf::logic_error); + EXPECT_THROW(cudf::lists::concatenate_list_elements(col), std::invalid_argument); } // Input lists is not at least 2-level depth lists column. { auto const col = IntListsCol{1, 2, 3}; - EXPECT_THROW(cudf::lists::concatenate_list_elements(col), cudf::logic_error); + EXPECT_THROW(cudf::lists::concatenate_list_elements(col), std::invalid_argument); } } diff --git a/cpp/tests/lists/contains_tests.cpp b/cpp/tests/lists/contains_tests.cpp index 2139103500a..f592819dacb 100644 --- a/cpp/tests/lists/contains_tests.cpp +++ b/cpp/tests/lists/contains_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. + * Copyright (c) 2021-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -503,10 +503,11 @@ TEST_F(ContainsTest, ScalarTypeRelatedExceptions) {{1, 2, 3}, {4, 5, 6}}}.release(); auto skey = create_scalar_search_key(10); - EXPECT_THROW(cudf::lists::contains(list_of_lists->view(), *skey), cudf::logic_error); + EXPECT_THROW(cudf::lists::contains(list_of_lists->view(), *skey), cudf::data_type_error); EXPECT_THROW(cudf::lists::index_of(list_of_lists->view(), *skey, FIND_FIRST), - cudf::logic_error); - EXPECT_THROW(cudf::lists::index_of(list_of_lists->view(), *skey, FIND_LAST), cudf::logic_error); + cudf::data_type_error); + EXPECT_THROW(cudf::lists::index_of(list_of_lists->view(), *skey, FIND_LAST), + cudf::data_type_error); } { // Search key must match list elements in type. @@ -517,9 +518,11 @@ TEST_F(ContainsTest, ScalarTypeRelatedExceptions) } .release(); auto skey = create_scalar_search_key("Hello, World!"); - EXPECT_THROW(cudf::lists::contains(list_of_ints->view(), *skey), cudf::logic_error); - EXPECT_THROW(cudf::lists::index_of(list_of_ints->view(), *skey, FIND_FIRST), cudf::logic_error); - EXPECT_THROW(cudf::lists::index_of(list_of_ints->view(), *skey, FIND_LAST), cudf::logic_error); + EXPECT_THROW(cudf::lists::contains(list_of_ints->view(), *skey), cudf::data_type_error); + EXPECT_THROW(cudf::lists::index_of(list_of_ints->view(), *skey, FIND_FIRST), + cudf::data_type_error); + EXPECT_THROW(cudf::lists::index_of(list_of_ints->view(), *skey, FIND_LAST), + cudf::data_type_error); } } @@ -813,9 +816,11 @@ TEST_F(ContainsTest, VectorTypeRelatedExceptions) {{1, 2, 3}, {4, 5, 6}}}.release(); auto skey = cudf::test::fixed_width_column_wrapper{0, 1, 2}; - EXPECT_THROW(cudf::lists::contains(list_of_lists->view(), skey), cudf::logic_error); - EXPECT_THROW(cudf::lists::index_of(list_of_lists->view(), skey, FIND_FIRST), cudf::logic_error); - EXPECT_THROW(cudf::lists::index_of(list_of_lists->view(), skey, FIND_LAST), cudf::logic_error); + EXPECT_THROW(cudf::lists::contains(list_of_lists->view(), skey), cudf::data_type_error); + EXPECT_THROW(cudf::lists::index_of(list_of_lists->view(), skey, FIND_FIRST), + cudf::data_type_error); + EXPECT_THROW(cudf::lists::index_of(list_of_lists->view(), skey, FIND_LAST), + cudf::data_type_error); } { // Search key must match list elements in type. @@ -826,9 +831,11 @@ TEST_F(ContainsTest, VectorTypeRelatedExceptions) } .release(); auto skey = cudf::test::strings_column_wrapper{"Hello", "World"}; - EXPECT_THROW(cudf::lists::contains(list_of_ints->view(), skey), cudf::logic_error); - EXPECT_THROW(cudf::lists::index_of(list_of_ints->view(), skey, FIND_FIRST), cudf::logic_error); - EXPECT_THROW(cudf::lists::index_of(list_of_ints->view(), skey, FIND_LAST), cudf::logic_error); + EXPECT_THROW(cudf::lists::contains(list_of_ints->view(), skey), cudf::data_type_error); + EXPECT_THROW(cudf::lists::index_of(list_of_ints->view(), skey, FIND_FIRST), + cudf::data_type_error); + EXPECT_THROW(cudf::lists::index_of(list_of_ints->view(), skey, FIND_LAST), + cudf::data_type_error); } { // Search key column size must match lists column size. diff --git a/cpp/tests/strings/json_tests.cpp b/cpp/tests/strings/json_tests.cpp index 1924d809743..4a485de2f2a 100644 --- a/cpp/tests/strings/json_tests.cpp +++ b/cpp/tests/strings/json_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. + * Copyright (c) 2021-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,8 @@ #include #include +#include + // reference: https://jsonpath.herokuapp.com/ // clang-format off @@ -566,7 +568,7 @@ TEST_F(JsonPathTests, GetJsonObjectIllegalQuery) auto query = [&]() { auto result = cudf::strings::get_json_object(cudf::strings_column_view(input), json_path); }; - EXPECT_THROW(query(), cudf::logic_error); + EXPECT_THROW(query(), std::invalid_argument); } { @@ -575,7 +577,7 @@ TEST_F(JsonPathTests, GetJsonObjectIllegalQuery) auto query = [&]() { auto result = cudf::strings::get_json_object(cudf::strings_column_view(input), json_path); }; - EXPECT_THROW(query(), cudf::logic_error); + EXPECT_THROW(query(), std::invalid_argument); } { @@ -584,7 +586,7 @@ TEST_F(JsonPathTests, GetJsonObjectIllegalQuery) auto query = [&]() { auto result = cudf::strings::get_json_object(cudf::strings_column_view(input), json_path); }; - EXPECT_THROW(query(), cudf::logic_error); + EXPECT_THROW(query(), std::invalid_argument); } } diff --git a/docs/cudf/source/developer_guide/contributing_guide.md b/docs/cudf/source/developer_guide/contributing_guide.md index bb3479cf4c1..b5ea9519842 100644 --- a/docs/cudf/source/developer_guide/contributing_guide.md +++ b/docs/cudf/source/developer_guide/contributing_guide.md @@ -123,19 +123,13 @@ There is no need to mention when the argument will be supported in the future. ### Handling libcudf Exceptions -Currently libcudf raises `cudf::logic_error` and `cudf::cuda_error`. -These error types are mapped to `RuntimeError` in python. -Several APIs use the exception payload `what()` message to determine the exception type raised by libcudf. - -Determining error type based on exception payload is brittle since libcudf does not maintain API stability on exception messages. -This is a compromise due to libcudf only raising a limited number of error types. -Only adopt this strategy when necessary. - -The projected roadmap is to diversify the exception types raised by libcudf. Standard C++ natively supports various [exception types](https://en.cppreference.com/w/cpp/error/exception), which Cython maps to [these Python exception types](https://docs.cython.org/en/latest/src/userguide/wrapping_CPlusPlus.html#exceptions). -In the future, libcudf may employ custom C++ exception types. -If that occurs, this section will be updated to reflect how these may be mapped to desired Python exception types. +In addition to built-in exceptions, libcudf also raises a few additional types of exceptions. +cuDF extends Cython's default mapping to account for these exception types. +When a new libcudf exception type is added, a suitable except clause should be added to cuDF's +[exception handler](https://github.com/rapidsai/cudf/blob/main/python/cudf/cudf/_lib/cpp/exception_handler.hpp). +If no built-in Python exception seems like a good match, a new Python exception should be created. ### Raising warnings diff --git a/java/src/main/native/include/jni_utils.hpp b/java/src/main/native/include/jni_utils.hpp index 78239b86ae2..ee2325cc76f 100644 --- a/java/src/main/native/include/jni_utils.hpp +++ b/java/src/main/native/include/jni_utils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022, NVIDIA CORPORATION. + * Copyright (c) 2019-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ constexpr jint MINIMUM_JNI_VERSION = JNI_VERSION_1_6; constexpr char const *CUDA_ERROR_CLASS = "ai/rapids/cudf/CudaException"; constexpr char const *CUDA_FATAL_ERROR_CLASS = "ai/rapids/cudf/CudaFatalException"; constexpr char const *CUDF_ERROR_CLASS = "ai/rapids/cudf/CudfException"; +constexpr char const *CUDF_DTYPE_ERROR_CLASS = "ai/rapids/cudf/CudfException"; constexpr char const *INDEX_OOB_CLASS = "java/lang/ArrayIndexOutOfBoundsException"; constexpr char const *ILLEGAL_ARG_CLASS = "java/lang/IllegalArgumentException"; constexpr char const *NPE_CLASS = "java/lang/NullPointerException"; @@ -861,6 +862,9 @@ inline void jni_cuda_check(JNIEnv *const env, cudaError_t cuda_status) { catch (const cudf::cuda_error &e) { \ JNI_CHECK_CUDA_ERROR(env, cudf::jni::CUDA_ERROR_CLASS, e, ret_val); \ } \ + catch (const cudf::data_type_error &e) { \ + JNI_CHECK_THROW_NEW(env, cudf::jni::CUDF_DTYPE_ERROR_CLASS, e.what(), ret_val); \ + } \ catch (const std::exception &e) { \ /* Double check whether the thrown exception is unrecoverable CUDA error or not. */ \ /* Like cudf::detail::throw_cuda_error, it is nearly certain that a fatal error */ \ diff --git a/python/cudf/cudf/_lib/CMakeLists.txt b/python/cudf/cudf/_lib/CMakeLists.txt index 4b785563484..f7d4f12ad81 100644 --- a/python/cudf/cudf/_lib/CMakeLists.txt +++ b/python/cudf/cudf/_lib/CMakeLists.txt @@ -62,6 +62,11 @@ rapids_cython_create_modules( LINKED_LIBRARIES "${linked_libraries}" ASSOCIATED_TARGETS cudf ) +# All modules need to include the header containing the exception handler. +foreach(target IN LISTS RAPIDS_CYTHON_CREATED_TARGETS) + target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) +endforeach() + target_link_libraries(strings_udf cudf_strings_udf) # TODO: Finding NumPy currently requires finding Development due to a bug in CMake. This bug was diff --git a/python/cudf/cudf/_lib/cpp/copying.pxd b/python/cudf/cudf/_lib/cpp/copying.pxd index bc89d364004..09e8538ebb7 100644 --- a/python/cudf/cudf/_lib/cpp/copying.pxd +++ b/python/cudf/cudf/_lib/cpp/copying.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2022, NVIDIA CORPORATION. +# Copyright (c) 2020-2023, NVIDIA CORPORATION. from libc.stdint cimport int32_t, int64_t, uint8_t from libcpp cimport bool @@ -14,6 +14,7 @@ from cudf._lib.cpp.scalar.scalar cimport scalar from cudf._lib.cpp.table.table cimport table from cudf._lib.cpp.table.table_view cimport table_view from cudf._lib.cpp.types cimport size_type +from cudf._lib.exception_handler cimport cudf_exception_handler ctypedef const scalar constscalar @@ -32,7 +33,7 @@ cdef extern from "cudf/copying.hpp" namespace "cudf" nogil: const table_view& source_table, const column_view& gather_map, out_of_bounds_policy policy - ) except + + ) except +cudf_exception_handler cdef unique_ptr[column] shift( const column_view& input, diff --git a/python/cudf/cudf/_lib/cpp/lists/contains.pxd b/python/cudf/cudf/_lib/cpp/lists/contains.pxd index e3cb01721a0..e86c73deed2 100644 --- a/python/cudf/cudf/_lib/cpp/lists/contains.pxd +++ b/python/cudf/cudf/_lib/cpp/lists/contains.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2022, NVIDIA CORPORATION. +# Copyright (c) 2021-2023, NVIDIA CORPORATION. from libcpp.memory cimport unique_ptr @@ -6,20 +6,21 @@ from cudf._lib.cpp.column.column cimport column from cudf._lib.cpp.column.column_view cimport column_view from cudf._lib.cpp.lists.lists_column_view cimport lists_column_view from cudf._lib.cpp.scalar.scalar cimport scalar +from cudf._lib.exception_handler cimport cudf_exception_handler cdef extern from "cudf/lists/contains.hpp" namespace "cudf::lists" nogil: cdef unique_ptr[column] contains( lists_column_view lists, scalar search_key, - ) except + + ) except +cudf_exception_handler cdef unique_ptr[column] index_of( lists_column_view lists, scalar search_key, - ) except + + ) except +cudf_exception_handler cdef unique_ptr[column] index_of( lists_column_view lists, column_view search_keys, - ) except + + ) except +cudf_exception_handler diff --git a/python/cudf/cudf/_lib/exception_handler.hpp b/python/cudf/cudf/_lib/exception_handler.hpp new file mode 100644 index 00000000000..8daffddd7bd --- /dev/null +++ b/python/cudf/cudf/_lib/exception_handler.hpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +namespace cudf_python { +namespace exceptions { + +/** + * @brief Exception handler to map C++ exceptions to Python ones in Cython + * + * This exception handler extends the base exception handler provided by + * Cython (https://github.com/cython/cython/blob/master/Cython/Utility/CppSupport.cpp#L9). + * In addition to the exceptions that Cython itself supports, this file adds support + * for additional exceptions thrown by libcudf that need to be mapped to specific Python + * exceptions. + * + * Since this function interoperates with Python's exception state, it does not throw + * any C++ exceptions. + */ +void cudf_exception_handler() +{ + // Catch a handful of different errors here and turn them into the + // equivalent Python errors. + try { + if (PyErr_Occurred()) + ; // let the latest Python exn pass through and ignore the current one else + throw; + } catch (const std::bad_alloc& exn) { + PyErr_SetString(PyExc_MemoryError, exn.what()); + } catch (const std::bad_cast& exn) { + PyErr_SetString(PyExc_TypeError, exn.what()); + } catch (const std::domain_error& exn) { + PyErr_SetString(PyExc_ValueError, exn.what()); + } catch (const cudf::data_type_error& exn) { + // Have to catch data_type_error before invalid_argument because it is a subclass + PyErr_SetString(PyExc_TypeError, exn.what()); + } catch (const std::invalid_argument& exn) { + PyErr_SetString(PyExc_ValueError, exn.what()); + } catch (const std::ios_base::failure& exn) { + // Unfortunately, in standard C++ we have no way of distinguishing EOF + // from other errors here; be careful with the exception mask + PyErr_SetString(PyExc_IOError, exn.what()); + } catch (const std::out_of_range& exn) { + // Change out_of_range to IndexError + PyErr_SetString(PyExc_IndexError, exn.what()); + } catch (const std::overflow_error& exn) { + PyErr_SetString(PyExc_OverflowError, exn.what()); + } catch (const std::range_error& exn) { + PyErr_SetString(PyExc_ArithmeticError, exn.what()); + } catch (const std::underflow_error& exn) { + PyErr_SetString(PyExc_ArithmeticError, exn.what()); + // The below is the default catch-all case. + } catch (const std::exception& exn) { + PyErr_SetString(PyExc_RuntimeError, exn.what()); + } catch (...) { + PyErr_SetString(PyExc_RuntimeError, "Unknown exception"); + } +} + +} // namespace exceptions +} // namespace cudf_python diff --git a/python/cudf/cudf/_lib/exception_handler.pxd b/python/cudf/cudf/_lib/exception_handler.pxd new file mode 100644 index 00000000000..14ac3bb1d40 --- /dev/null +++ b/python/cudf/cudf/_lib/exception_handler.pxd @@ -0,0 +1,5 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. + + +cdef extern from "exception_handler.hpp" namespace "cudf_python::exceptions": + cdef void cudf_exception_handler() diff --git a/python/cudf/cudf/core/column/column.py b/python/cudf/cudf/core/column/column.py index fb1bcf6d673..b5f36aa3594 100644 --- a/python/cudf/cudf/core/column/column.py +++ b/python/cudf/cudf/core/column/column.py @@ -2587,19 +2587,10 @@ def concat_columns(objs: "MutableSequence[ColumnBase]") -> ColumnBase: f"size > {libcudf.MAX_COLUMN_SIZE_STR}" ) elif newsize == 0: - col = column_empty(0, head.dtype, masked=True) - else: - # Filter out inputs that have 0 length, then concatenate. - objs = [o for o in objs if len(o)] - try: - col = libcudf.concat.concat_columns(objs) - except RuntimeError as e: - if "exceeds size_type range" in str(e): - raise OverflowError( - "total size of output is too large for a cudf column" - ) from e - raise - return col + return column_empty(0, head.dtype, masked=True) + + # Filter out inputs that have 0 length, then concatenate. + return libcudf.concat.concat_columns([o for o in objs if len(o)]) def _proxy_cai_obj(cai, owner): diff --git a/python/cudf/cudf/core/column/decimal.py b/python/cudf/cudf/core/column/decimal.py index 157bc1f4291..96b8002e2a1 100644 --- a/python/cudf/cudf/core/column/decimal.py +++ b/python/cudf/cudf/core/column/decimal.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2022, NVIDIA CORPORATION. +# Copyright (c) 2021-2023, NVIDIA CORPORATION. import warnings from decimal import Decimal @@ -79,32 +79,26 @@ def _binaryop(self, other: ColumnBinaryOperand, op: str): # Binary Arithmetics between decimal columns. `Scale` and `precision` # are computed outside of libcudf - unsupported_msg = ( - f"{op} not supported for the following dtypes: " - f"{self.dtype}, {other.dtype}" - ) - try: - if op in {"__add__", "__sub__", "__mul__", "__div__"}: - output_type = _get_decimal_type(lhs.dtype, rhs.dtype, op) - result = libcudf.binaryop.binaryop(lhs, rhs, op, output_type) - # TODO: Why is this necessary? Why isn't the result's - # precision already set correctly based on output_type? - result.dtype.precision = output_type.precision - elif op in { - "__eq__", - "__ne__", - "__lt__", - "__gt__", - "__le__", - "__ge__", - }: - result = libcudf.binaryop.binaryop(lhs, rhs, op, bool) - else: - raise TypeError(unsupported_msg) - except RuntimeError as e: - if "Unsupported operator for these types" in str(e): - raise TypeError(unsupported_msg) from e - raise + if op in {"__add__", "__sub__", "__mul__", "__div__"}: + output_type = _get_decimal_type(lhs.dtype, rhs.dtype, op) + result = libcudf.binaryop.binaryop(lhs, rhs, op, output_type) + # TODO: Why is this necessary? Why isn't the result's + # precision already set correctly based on output_type? + result.dtype.precision = output_type.precision + elif op in { + "__eq__", + "__ne__", + "__lt__", + "__gt__", + "__le__", + "__ge__", + }: + result = libcudf.binaryop.binaryop(lhs, rhs, op, bool) + else: + raise TypeError( + f"{op} not supported for the following dtypes: " + f"{self.dtype}, {other.dtype}" + ) return result diff --git a/python/cudf/cudf/core/column/lists.py b/python/cudf/cudf/core/column/lists.py index 9b64f26f0fb..4eea64c00d3 100644 --- a/python/cudf/cudf/core/column/lists.py +++ b/python/cudf/cudf/core/column/lists.py @@ -406,19 +406,9 @@ def contains(self, search_key: ScalarLike) -> ParentType: Series([False, True, True]) dtype: bool """ - search_key = cudf.Scalar(search_key) - try: - res = self._return_or_inplace( - contains_scalar(self._column, search_key) - ) - except RuntimeError as e: - if ( - "Type/Scale of search key does not " - "match list column element type." in str(e) - ): - raise TypeError(str(e)) from e - raise - return res + return self._return_or_inplace( + contains_scalar(self._column, cudf.Scalar(search_key)) + ) def index(self, search_key: Union[ScalarLike, ColumnLike]) -> ParentType: """ @@ -465,23 +455,14 @@ def index(self, search_key: Union[ScalarLike, ColumnLike]) -> ParentType: dtype: int32 """ - try: - if is_scalar(search_key): - return self._return_or_inplace( - index_of_scalar(self._column, cudf.Scalar(search_key)) - ) - else: - return self._return_or_inplace( - index_of_column(self._column, as_column(search_key)) - ) - - except RuntimeError as e: - if ( - "Type/Scale of search key does not " - "match list column element type." in str(e) - ): - raise TypeError(str(e)) from e - raise + if is_scalar(search_key): + return self._return_or_inplace( + index_of_scalar(self._column, cudf.Scalar(search_key)) + ) + else: + return self._return_or_inplace( + index_of_column(self._column, as_column(search_key)) + ) @property def leaves(self) -> ParentType: @@ -577,16 +558,9 @@ def take(self, lists_indices: ColumnLike) -> ParentType: "lists_indices should be column of values of index types." ) - try: - res = self._return_or_inplace( - segmented_gather(self._column, lists_indices_col) - ) - except RuntimeError as e: - if "contains nulls" in str(e): - raise ValueError("lists_indices contains null.") from e - raise - else: - return res + return self._return_or_inplace( + segmented_gather(self._column, lists_indices_col) + ) def unique(self) -> ParentType: """ @@ -720,16 +694,9 @@ def concat(self, dropna=True) -> ParentType: 1 [6.0, nan, 7.0, 8.0, 9.0] dtype: list """ - try: - result = concatenate_list_elements(self._column, dropna=dropna) - except RuntimeError as e: - if "Rows of the input column must be lists." in str(e): - raise ValueError( - "list.concat() can only be called on " - "list columns with at least one level " - "of nesting" - ) - return self._return_or_inplace(result) + return self._return_or_inplace( + concatenate_list_elements(self._column, dropna=dropna) + ) def astype(self, dtype): """ diff --git a/python/cudf/cudf/core/column/string.py b/python/cudf/cudf/core/column/string.py index 8d6ffe48957..d5ef5fb5d11 100644 --- a/python/cudf/cudf/core/column/string.py +++ b/python/cudf/cudf/core/column/string.py @@ -2379,29 +2379,18 @@ def get_json_object( dtype: object """ - try: - options = libstrings.GetJsonObjectOptions( - allow_single_quotes=allow_single_quotes, - strip_quotes_from_single_strings=( - strip_quotes_from_single_strings - ), - missing_fields_as_nulls=missing_fields_as_nulls, - ) - res = self._return_or_inplace( - libstrings.get_json_object( - self._column, cudf.Scalar(json_path, "str"), options - ) - ) - except RuntimeError as e: - matches = ( - "Unrecognized JSONPath operator", - "Invalid empty name in JSONPath query string", + options = libstrings.GetJsonObjectOptions( + allow_single_quotes=allow_single_quotes, + strip_quotes_from_single_strings=( + strip_quotes_from_single_strings + ), + missing_fields_as_nulls=missing_fields_as_nulls, + ) + return self._return_or_inplace( + libstrings.get_json_object( + self._column, cudf.Scalar(json_path, "str"), options ) - if any(match in str(e) for match in matches): - raise ValueError("JSONPath value not found") from e - raise - else: - return res + ) def split( self, diff --git a/python/cudf/cudf/tests/test_column.py b/python/cudf/cudf/tests/test_column.py index 7d113bbb9e2..a15afa727c0 100644 --- a/python/cudf/cudf/tests/test_column.py +++ b/python/cudf/cudf/tests/test_column.py @@ -520,10 +520,7 @@ def test_concatenate_large_column_strings(): s_1 = cudf.Series(["very long string " * string_scale_f] * num_strings) s_2 = cudf.Series(["very long string " * string_scale_f] * num_strings) - with pytest.raises( - OverflowError, - match="total size of output is too large for a cudf column", - ): + with pytest.raises(OverflowError): cudf.concat([s_1, s_2])