Repository: apache/arrow-rs
Pull request #6769 (2024-11-21 13:44:54)

Allow NullBuffer construction directly from array 
# Which issue does this PR close?

none

# Rationale for this change
 
For convenience and API compatibility with Buffer.


# What changes are included in this PR?

- Allow `NullBuffer::from(array)`
- Migrate code to use `Buffer::from(array)` where it results in shorter code

# Are there any user-facing changes?

yes, new `NullBuffer::from` variant


Patch:
diff --git a/README.md b/README.md
index 98c0a6615..3b16629d6 100644
--- a/README.md
+++ b/README.md
@@ -67,11 +67,11 @@ Planned Release Schedule
 
 | Approximate Date | Version  | Notes                                   |
 | ---------------- | -------- | --------------------------------------- |
-| Sep 2024         | `53.0.0` | Major, potentially breaking API changes |
-| Oct 2024         | `53.1.0` | Minor, NO breaking API changes          |
-| Oct 2024         | `53.2.0` | Minor, NO breaking API changes          |
 | Nov 2024         | `53.3.0` | Minor, NO breaking API changes          |
 | Dec 2024         | `54.0.0` | Major, potentially breaking API changes |
+| Jan 2025         | `54.1.0` | Minor, NO breaking API changes          |
+| Feb 2025         | `54.2.0` | Minor, NO breaking API changes          |
+| Mar 2025         | `55.0.0` | Major, potentially breaking API changes |
 
 [this ticket]: https://github.com/apache/arrow-rs/issues/5368
 [semantic versioning]: https://semver.org/
diff --git a/arrow-arith/LICENSE.txt b/arrow-arith/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-arith/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-arith/NOTICE.txt b/arrow-arith/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-arith/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-array/LICENSE.txt b/arrow-array/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-array/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-array/NOTICE.txt b/arrow-array/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-array/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-array/src/array/binary_array.rs b/arrow-array/src/array/binary_array.rs
index 8f8a39b20..401a60d4d 100644
--- a/arrow-array/src/array/binary_array.rs
+++ b/arrow-array/src/array/binary_array.rs
@@ -358,7 +358,7 @@ mod tests {
         let values = b"helloparquet";
         let child_data = ArrayData::builder(DataType::UInt8)
             .len(12)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(values))
             .build()
             .unwrap();
         let offsets = [0, 5, 5, 12].map(|n| O::from_usize(n).unwrap());
@@ -415,7 +415,7 @@ mod tests {
         let child_data = ArrayData::builder(DataType::UInt8)
             .len(15)
             .offset(5)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(values))
             .build()
             .unwrap();
 
@@ -460,7 +460,7 @@ mod tests {
         let values = b"HelloArrow";
         let child_data = ArrayData::builder(DataType::UInt8)
             .len(10)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(values))
             .null_bit_buffer(Some(Buffer::from_slice_ref([0b1010101010])))
             .build()
             .unwrap();
diff --git a/arrow-array/src/array/fixed_size_binary_array.rs b/arrow-array/src/array/fixed_size_binary_array.rs
index 8f1489ee4..83de50fd9 100644
--- a/arrow-array/src/array/fixed_size_binary_array.rs
+++ b/arrow-array/src/array/fixed_size_binary_array.rs
@@ -662,7 +662,7 @@ mod tests {
 
         let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
             .len(3)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(&values))
             .build()
             .unwrap();
         let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
@@ -691,7 +691,7 @@ mod tests {
         let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
             .len(2)
             .offset(1)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(&values))
             .build()
             .unwrap();
         let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
@@ -798,7 +798,7 @@ mod tests {
 
         let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
             .len(3)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(&values))
             .build()
             .unwrap();
         let arr = FixedSizeBinaryArray::from(array_data);
diff --git a/arrow-array/src/array/primitive_array.rs b/arrow-array/src/array/primitive_array.rs
index 7b0d6c5ca..22768cfa5 100644
--- a/arrow-array/src/array/primitive_array.rs
+++ b/arrow-array/src/array/primitive_array.rs
@@ -2296,7 +2296,7 @@ mod tests {
         ];
         let array_data = ArrayData::builder(DataType::Decimal128(38, 6))
             .len(2)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(&values))
             .build()
             .unwrap();
         let decimal_array = Decimal128Array::from(array_data);
diff --git a/arrow-array/src/array/string_array.rs b/arrow-array/src/array/string_array.rs
index 25581cfaa..d7011e397 100644
--- a/arrow-array/src/array/string_array.rs
+++ b/arrow-array/src/array/string_array.rs
@@ -382,7 +382,7 @@ mod tests {
         let child_data = ArrayData::builder(DataType::UInt8)
             .len(15)
             .offset(5)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(values))
             .build()
             .unwrap();
 
@@ -427,7 +427,7 @@ mod tests {
         let values = b"HelloArrow";
         let child_data = ArrayData::builder(DataType::UInt8)
             .len(10)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(values))
             .null_bit_buffer(Some(Buffer::from_slice_ref([0b1010101010])))
             .build()
             .unwrap();
@@ -469,7 +469,7 @@ mod tests {
         let values = b"HelloArrow";
         let child_data = ArrayData::builder(DataType::UInt16)
             .len(5)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(values))
             .build()
             .unwrap();
 
diff --git a/arrow-avro/LICENSE.txt b/arrow-avro/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-avro/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-avro/NOTICE.txt b/arrow-avro/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-avro/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-buffer/LICENSE.txt b/arrow-buffer/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-buffer/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-buffer/NOTICE.txt b/arrow-buffer/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-buffer/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-buffer/src/buffer/null.rs b/arrow-buffer/src/buffer/null.rs
index c79aef398..e9f383ca2 100644
--- a/arrow-buffer/src/buffer/null.rs
+++ b/arrow-buffer/src/buffer/null.rs
@@ -235,6 +235,12 @@ impl From<&[bool]> for NullBuffer {
     }
 }
 
+impl<const N: usize> From<&[bool; N]> for NullBuffer {
+    fn from(value: &[bool; N]) -> Self {
+        value[..].into()
+    }
+}
+
 impl From<Vec<bool>> for NullBuffer {
     fn from(value: Vec<bool>) -> Self {
         BooleanBuffer::from(value).into()
diff --git a/arrow-cast/LICENSE.txt b/arrow-cast/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-cast/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-cast/NOTICE.txt b/arrow-cast/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-cast/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-csv/LICENSE.txt b/arrow-csv/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-csv/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-csv/NOTICE.txt b/arrow-csv/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-csv/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-data/LICENSE.txt b/arrow-data/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-data/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-data/NOTICE.txt b/arrow-data/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-data/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-flight/LICENSE.txt b/arrow-flight/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-flight/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-flight/NOTICE.txt b/arrow-flight/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-flight/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-flight/src/utils.rs b/arrow-flight/src/utils.rs
index f6129ddfe..c3a2e0d0b 100644
--- a/arrow-flight/src/utils.rs
+++ b/arrow-flight/src/utils.rs
@@ -17,8 +17,7 @@
 
 //! Utilities to assist with reading and writing Arrow data as Flight messages
 
-use crate::{FlightData, IpcMessage, SchemaAsIpc, SchemaResult};
-use bytes::Bytes;
+use crate::{FlightData, SchemaAsIpc};
 use std::collections::HashMap;
 use std::sync::Arc;
 
@@ -104,41 +103,6 @@ pub fn flight_data_to_arrow_batch(
         })?
 }
 
-/// Convert a `Schema` to `SchemaResult` by converting to an IPC message
-#[deprecated(
-    since = "4.4.0",
-    note = "Use From trait, e.g.: SchemaAsIpc::new(schema, options).try_into()"
-)]
-pub fn flight_schema_from_arrow_schema(
-    schema: &Schema,
-    options: &IpcWriteOptions,
-) -> Result<SchemaResult, ArrowError> {
-    SchemaAsIpc::new(schema, options).try_into()
-}
-
-/// Convert a `Schema` to `FlightData` by converting to an IPC message
-#[deprecated(
-    since = "4.4.0",
-    note = "Use From trait, e.g.: SchemaAsIpc::new(schema, options).into()"
-)]
-pub fn flight_data_from_arrow_schema(schema: &Schema, options: &IpcWriteOptions) -> FlightData {
-    SchemaAsIpc::new(schema, options).into()
-}
-
-/// Convert a `Schema` to bytes in the format expected in `FlightInfo.schema`
-#[deprecated(
-    since = "4.4.0",
-    note = "Use TryFrom trait, e.g.: SchemaAsIpc::new(schema, options).try_into()"
-)]
-pub fn ipc_message_from_arrow_schema(
-    schema: &Schema,
-    options: &IpcWriteOptions,
-) -> Result<Bytes, ArrowError> {
-    let message = SchemaAsIpc::new(schema, options).try_into()?;
-    let IpcMessage(vals) = message;
-    Ok(vals)
-}
-
 /// Convert `RecordBatch`es to wire protocol `FlightData`s
 pub fn batches_to_flight_data(
     schema: &Schema,
diff --git a/arrow-ipc/LICENSE.txt b/arrow-ipc/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-ipc/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-ipc/NOTICE.txt b/arrow-ipc/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-ipc/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-ipc/src/reader.rs b/arrow-ipc/src/reader.rs
index dcded3288..0aea191a6 100644
--- a/arrow-ipc/src/reader.rs
+++ b/arrow-ipc/src/reader.rs
@@ -1778,7 +1778,7 @@ mod tests {
 
     #[test]
     fn test_roundtrip_struct_empty_fields() {
-        let nulls = NullBuffer::from(&[true, true, false][..]);
+        let nulls = NullBuffer::from(&[true, true, false]);
         let rb = RecordBatch::try_from_iter([(
             "",
             Arc::new(StructArray::new_empty_fields(nulls.len(), Some(nulls))) as _,
diff --git a/arrow-json/LICENSE.txt b/arrow-json/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-json/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-json/NOTICE.txt b/arrow-json/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-json/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-ord/LICENSE.txt b/arrow-ord/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-ord/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-ord/NOTICE.txt b/arrow-ord/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-ord/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-row/LICENSE.txt b/arrow-row/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-row/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-row/NOTICE.txt b/arrow-row/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-row/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-schema/LICENSE.txt b/arrow-schema/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-schema/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-schema/NOTICE.txt b/arrow-schema/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-schema/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-select/LICENSE.txt b/arrow-select/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-select/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-select/NOTICE.txt b/arrow-select/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-select/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-select/src/filter.rs b/arrow-select/src/filter.rs
index bc19a5f7a..a59d87aa8 100644
--- a/arrow-select/src/filter.rs
+++ b/arrow-select/src/filter.rs
@@ -517,14 +517,14 @@ fn filter_bits(buffer: &BooleanBuffer, predicate: &FilterPredicate) -> Buffer {
             unsafe { MutableBuffer::from_trusted_len_iter_bool(bits).into() }
         }
         IterationStrategy::SlicesIterator => {
-            let mut builder = BooleanBufferBuilder::new(bit_util::ceil(predicate.count, 8));
+            let mut builder = BooleanBufferBuilder::new(predicate.count);
             for (start, end) in SlicesIterator::new(&predicate.filter) {
                 builder.append_packed_range(start + offset..end + offset, src)
             }
             builder.into()
         }
         IterationStrategy::Slices(slices) => {
-            let mut builder = BooleanBufferBuilder::new(bit_util::ceil(predicate.count, 8));
+            let mut builder = BooleanBufferBuilder::new(predicate.count);
             for (start, end) in slices {
                 builder.append_packed_range(*start + offset..*end + offset, src)
             }
diff --git a/arrow-string/LICENSE.txt b/arrow-string/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-string/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-string/NOTICE.txt b/arrow-string/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-string/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-string/src/substring.rs b/arrow-string/src/substring.rs
index bfdafb790..fa6a47147 100644
--- a/arrow-string/src/substring.rs
+++ b/arrow-string/src/substring.rs
@@ -636,7 +636,7 @@ mod tests {
 
         let data = ArrayData::builder(DataType::FixedSizeBinary(5))
             .len(2)
-            .add_buffer(Buffer::from(&values[..]))
+            .add_buffer(Buffer::from(&values))
             .offset(1)
             .null_bit_buffer(Some(Buffer::from(bits_v)))
             .build()
diff --git a/arrow/Cargo.toml b/arrow/Cargo.toml
index a0fd96415..732819cf0 100644
--- a/arrow/Cargo.toml
+++ b/arrow/Cargo.toml
@@ -54,7 +54,7 @@ arrow-select = { workspace = true }
 arrow-string = { workspace = true }
 
 rand = { version = "0.8", default-features = false, features = ["std", "std_rng"], optional = true }
-pyo3 = { version = "0.22.2", default-features = false, optional = true }
+pyo3 = { version = "0.23", default-features = false, optional = true }
 
 chrono = { workspace = true, optional = true }
 
diff --git a/arrow/LICENSE.txt b/arrow/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow/NOTICE.txt b/arrow/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow/examples/builders.rs b/arrow/examples/builders.rs
index 5c8cd51c5..bd0575bb5 100644
--- a/arrow/examples/builders.rs
+++ b/arrow/examples/builders.rs
@@ -76,7 +76,7 @@ fn main() {
     let array_data = ArrayData::builder(DataType::Utf8)
         .len(3)
         .add_buffer(Buffer::from(offsets.to_byte_slice()))
-        .add_buffer(Buffer::from(&values[..]))
+        .add_buffer(Buffer::from(&values))
         .null_bit_buffer(Some(Buffer::from([0b00000101])))
         .build()
         .unwrap();
diff --git a/arrow/src/pyarrow.rs b/arrow/src/pyarrow.rs
index 6effe1c03..4ccbd0541 100644
--- a/arrow/src/pyarrow.rs
+++ b/arrow/src/pyarrow.rs
@@ -111,7 +111,7 @@ impl<T: ToPyArrow> IntoPyArrow for T {
 }
 
 fn validate_class(expected: &str, value: &Bound<PyAny>) -> PyResult<()> {
-    let pyarrow = PyModule::import_bound(value.py(), "pyarrow")?;
+    let pyarrow = PyModule::import(value.py(), "pyarrow")?;
     let class = pyarrow.getattr(expected)?;
     if !value.is_instance(&class)? {
         let expected_module = class.getattr("__module__")?.extract::<PyBackedStr>()?;
@@ -177,7 +177,7 @@ impl ToPyArrow for DataType {
     fn to_pyarrow(&self, py: Python) -> PyResult<PyObject> {
         let c_schema = FFI_ArrowSchema::try_from(self).map_err(to_py_err)?;
         let c_schema_ptr = &c_schema as *const FFI_ArrowSchema;
-        let module = py.import_bound("pyarrow")?;
+        let module = py.import("pyarrow")?;
         let class = module.getattr("DataType")?;
         let dtype = class.call_method1("_import_from_c", (c_schema_ptr as Py_uintptr_t,))?;
         Ok(dtype.into())
@@ -213,7 +213,7 @@ impl ToPyArrow for Field {
     fn to_pyarrow(&self, py: Python) -> PyResult<PyObject> {
         let c_schema = FFI_ArrowSchema::try_from(self).map_err(to_py_err)?;
         let c_schema_ptr = &c_schema as *const FFI_ArrowSchema;
-        let module = py.import_bound("pyarrow")?;
+        let module = py.import("pyarrow")?;
         let class = module.getattr("Field")?;
         let dtype = class.call_method1("_import_from_c", (c_schema_ptr as Py_uintptr_t,))?;
         Ok(dtype.into())
@@ -249,7 +249,7 @@ impl ToPyArrow for Schema {
     fn to_pyarrow(&self, py: Python) -> PyResult<PyObject> {
         let c_schema = FFI_ArrowSchema::try_from(self).map_err(to_py_err)?;
         let c_schema_ptr = &c_schema as *const FFI_ArrowSchema;
-        let module = py.import_bound("pyarrow")?;
+        let module = py.import("pyarrow")?;
         let class = module.getattr("Schema")?;
         let schema = class.call_method1("_import_from_c", (c_schema_ptr as Py_uintptr_t,))?;
         Ok(schema.into())
@@ -309,7 +309,7 @@ impl ToPyArrow for ArrayData {
         let array = FFI_ArrowArray::new(self);
         let schema = FFI_ArrowSchema::try_from(self.data_type()).map_err(to_py_err)?;
 
-        let module = py.import_bound("pyarrow")?;
+        let module = py.import("pyarrow")?;
         let class = module.getattr("Array")?;
         let array = class.call_method1(
             "_import_from_c",
@@ -318,7 +318,7 @@ impl ToPyArrow for ArrayData {
                 addr_of!(schema) as Py_uintptr_t,
             ),
         )?;
-        Ok(array.to_object(py))
+        Ok(array.unbind())
     }
 }
 
@@ -335,7 +335,7 @@ impl<T: ToPyArrow> ToPyArrow for Vec<T> {
             .iter()
             .map(|v| v.to_pyarrow(py))
             .collect::<PyResult<Vec<_>>>()?;
-        Ok(values.to_object(py))
+        Ok(PyList::new(py, values)?.unbind().into())
     }
 }
 
@@ -451,7 +451,7 @@ impl FromPyArrow for ArrowArrayStreamReader {
         // make the conversion through PyArrow's private API
         // this changes the pointer's memory and is thus unsafe.
         // In particular, `_export_to_c` can go out of bounds
-        let args = PyTuple::new_bound(value.py(), [stream_ptr as Py_uintptr_t]);
+        let args = PyTuple::new(value.py(), [stream_ptr as Py_uintptr_t])?;
         value.call_method1("_export_to_c", args)?;
 
         let stream_reader = ArrowArrayStreamReader::try_new(stream)
@@ -469,9 +469,9 @@ impl IntoPyArrow for Box<dyn RecordBatchReader + Send> {
         let mut stream = FFI_ArrowArrayStream::new(self);
 
         let stream_ptr = (&mut stream) as *mut FFI_ArrowArrayStream;
-        let module = py.import_bound("pyarrow")?;
+        let module = py.import("pyarrow")?;
         let class = module.getattr("RecordBatchReader")?;
-        let args = PyTuple::new_bound(py, [stream_ptr as Py_uintptr_t]);
+        let args = PyTuple::new(py, [stream_ptr as Py_uintptr_t])?;
         let reader = class.call_method1("_import_from_c", args)?;
 
         Ok(PyObject::from(reader))
@@ -500,11 +500,17 @@ impl<'source, T: FromPyArrow> FromPyObject<'source> for PyArrowType<T> {
     }
 }
 
-impl<T: IntoPyArrow> IntoPy<PyObject> for PyArrowType<T> {
-    fn into_py(self, py: Python) -> PyObject {
+impl<'py, T: IntoPyArrow> IntoPyObject<'py> for PyArrowType<T> {
+    type Target = PyAny;
+
+    type Output = Bound<'py, Self::Target>;
+
+    type Error = PyErr;
+
+    fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, PyErr> {
         match self.0.into_pyarrow(py) {
-            Ok(obj) => obj,
-            Err(err) => err.to_object(py),
+            Ok(obj) => Result::Ok(obj.into_bound(py)),
+            Err(err) => Result::Err(err),
         }
     }
 }
diff --git a/parquet/LICENSE.txt b/parquet/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/parquet/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/parquet/NOTICE.txt b/parquet/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/parquet/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/parquet/src/arrow/buffer/view_buffer.rs b/parquet/src/arrow/buffer/view_buffer.rs
index 2256f4877..fd7d6c213 100644
--- a/parquet/src/arrow/buffer/view_buffer.rs
+++ b/parquet/src/arrow/buffer/view_buffer.rs
@@ -130,7 +130,7 @@ mod tests {
     #[test]
     fn test_view_buffer_append_view() {
         let mut buffer = ViewBuffer::default();
-        let string_buffer = Buffer::from(&b"0123456789long string to test string view"[..]);
+        let string_buffer = Buffer::from(b"0123456789long string to test string view");
         let block_id = buffer.append_block(string_buffer);
 
         unsafe {
@@ -157,7 +157,7 @@ mod tests {
     #[test]
     fn test_view_buffer_pad_null() {
         let mut buffer = ViewBuffer::default();
-        let string_buffer = Buffer::from(&b"0123456789long string to test string view"[..]);
+        let string_buffer = Buffer::from(b"0123456789long string to test string view");
         let block_id = buffer.append_block(string_buffer);
 
         unsafe {
diff --git a/parquet_derive/LICENSE.txt b/parquet_derive/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/parquet_derive/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/parquet_derive/NOTICE.txt b/parquet_derive/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/parquet_derive/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file


Test patch:
diff --git a/arrow-integration-test/LICENSE.txt b/arrow-integration-test/LICENSE.txt
new file mode 120000
index 000000000..4ab43736a
--- /dev/null
+++ b/arrow-integration-test/LICENSE.txt
@@ -0,0 +1,1 @@
+../LICENSE.txt
\ No newline at end of file
diff --git a/arrow-integration-test/NOTICE.txt b/arrow-integration-test/NOTICE.txt
new file mode 120000
index 000000000..eb9f24e04
--- /dev/null
+++ b/arrow-integration-test/NOTICE.txt
@@ -0,0 +1,1 @@
+../NOTICE.txt
\ No newline at end of file
diff --git a/arrow-pyarrow-integration-testing/Cargo.toml b/arrow-pyarrow-integration-testing/Cargo.toml
index 0834f2d13..03d08df30 100644
--- a/arrow-pyarrow-integration-testing/Cargo.toml
+++ b/arrow-pyarrow-integration-testing/Cargo.toml
@@ -34,4 +34,4 @@ crate-type = ["cdylib"]
 
 [dependencies]
 arrow = { path = "../arrow", features = ["pyarrow"] }
-pyo3 = { version = "0.22", features = ["extension-module"] }
+pyo3 = { version = "0.23", features = ["extension-module"] }
diff --git a/arrow-pyarrow-integration-testing/src/lib.rs b/arrow-pyarrow-integration-testing/src/lib.rs
index e12c1389e..d4908fff0 100644
--- a/arrow-pyarrow-integration-testing/src/lib.rs
+++ b/arrow-pyarrow-integration-testing/src/lib.rs
@@ -43,7 +43,7 @@ fn to_py_err(err: ArrowError) -> PyErr {
 #[pyfunction]
 fn double(array: &Bound<PyAny>, py: Python) -> PyResult<PyObject> {
     // import
-    let array = make_array(ArrayData::from_pyarrow_bound(&array)?);
+    let array = make_array(ArrayData::from_pyarrow_bound(array)?);
 
     // perform some operation
     let array = array
diff --git a/arrow/tests/array_cast.rs b/arrow/tests/array_cast.rs
index 8f86cbeab..c5311bd8c 100644
--- a/arrow/tests/array_cast.rs
+++ b/arrow/tests/array_cast.rs
@@ -325,11 +325,11 @@ fn make_fixed_size_list_array() -> FixedSizeListArray {
 }
 
 fn make_fixed_size_binary_array() -> FixedSizeBinaryArray {
-    let values: [u8; 15] = *b"hellotherearrow";
+    let values: &[u8; 15] = b"hellotherearrow";
 
     let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
         .len(3)
-        .add_buffer(Buffer::from(&values[..]))
+        .add_buffer(Buffer::from(values))
         .build()
         .unwrap();
     FixedSizeBinaryArray::from(array_data)