We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bool values get flipped when converting Arrow table to DataFrame
Using the latest version:
`vaex==2.6.1`

Just realised that when converting an Arrow table to a DataFrame, bool columns get flipped and converted to integers:

```python
import vaex
from pyarrow import feather

bool_array = [False, True, True, False]
pdf = pd.DataFrame({"col1": bool_array})
pdf.to_feather("test_data.feather")
arrow_table = feather.read_table("test_data.feather")
vaex.from_arrow_table(arrow_table)
```

```
#  | col1
-- | --
0  | 1
1  | 0
2  | 0
3  | 1
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `packages/vaex-arrow/vaex_arrow/convert.py`
Content:
```
1 """Convert between arrow and vaex/numpy columns/arrays without doing memory copies."""
2 import pyarrow
3 import numpy as np
4 from vaex.column import ColumnStringArrow
5 
6 def arrow_array_from_numpy_array(array):
7     dtype = array.dtype
8     mask = None
9     if np.ma.isMaskedArray(array):
10         mask = array.mask
11         # arrow 0.16 behaves weird in this case https://github.com/vaexio/vaex/pull/639
12         if mask is np.False_:
13             mask = None
14         elif mask is np.True_:
15             raise ValueError('not sure what pyarrow does with mask=True')
16         array = array.data
17     if dtype.kind == 'S':
18         type = pyarrow.binary(dtype.itemsize)
19         arrow_array = pyarrow.array(array, type, mask=mask)
20     else:
21         if not dtype.isnative:
22             array = array.astype(dtype.newbyteorder('='))
23         arrow_array = pyarrow.Array.from_pandas(array, mask=mask)
24     return arrow_array
25 
26 from vaex.dataframe import Column
27 
28 
29 def column_from_arrow_array(arrow_array):
30     arrow_type = arrow_array.type
31     buffers = arrow_array.buffers()
32     if len(buffers) == 2:
33         return numpy_array_from_arrow_array(arrow_array)
34     elif len(buffers) == 3 and  isinstance(arrow_array.type, type(pyarrow.string())):
35         bitmap_buffer, offsets, string_bytes = arrow_array.buffers()
36         if arrow_array.null_count == 0:
37             null_bitmap = None  # we drop any null_bitmap when there are no null counts
38         else:
39             null_bitmap = np.frombuffer(bitmap_buffer, 'uint8', len(bitmap_buffer))
40         offsets = np.frombuffer(offsets, np.int32, len(offsets)//4)
41         if string_bytes is None:
42             string_bytes = np.array([], dtype='S1')
43         else:
44             string_bytes = np.frombuffer(string_bytes, 'S1', len(string_bytes))
45         column = ColumnStringArrow(offsets, string_bytes, len(arrow_array), null_bitmap=null_bitmap)
46         return column
47     else:
48         raise TypeError('type unsupported: %r' % arrow_type)
49 
50 
51 def numpy_array_from_arrow_array(arrow_array):
52     arrow_type = arrow_array.type
53     buffers = arrow_array.buffers()
54     assert len(buffers) == 2
55     bitmap_buffer, data_buffer = buffers
56     if isinstance(arrow_type, type(pyarrow.binary(1))):  # todo, is there a better way to typecheck?
57         # mimics python/pyarrow/array.pxi::Array::to_numpy
58         assert len(buffers) == 2
59         dtype = "S" + str(arrow_type.byte_width)
60         # arrow seems to do padding, check if it is all ok
61         expected_length = arrow_type.byte_width * len(arrow_array)
62         actual_length = len(buffers[-1])
63         if actual_length < expected_length:
64             raise ValueError('buffer is smaller (%d) than expected (%d)' % (actual_length, expected_length))
65         array = np.frombuffer(buffers[-1], dtype, len(arrow_array))# TODO: deal with offset ? [arrow_array.offset:arrow_array.offset + len(arrow_array)]
66     else:
67         dtype = arrow_array.type.to_pandas_dtype()
68     if np.bool_ == dtype:
69         # TODO: this will also be a copy, we probably want to support bitmasks as well
70         bitmap = np.frombuffer(data_buffer, np.uint8, len(data_buffer))
71         array = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))
72     else:
73         array = np.frombuffer(data_buffer, dtype, len(arrow_array))
74 
75     if bitmap_buffer is not None:
76         bitmap = np.frombuffer(bitmap_buffer, np.uint8, len(bitmap_buffer))
77         mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))
78         array = np.ma.MaskedArray(array, mask=mask)
79     return array
80 
81 def numpy_mask_from_arrow_mask(bitmap, length):
82     # arrow uses a bitmap https://github.com/apache/arrow/blob/master/format/Layout.md
83     # we do have to change the ordering of the bits
84     return 1-np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length]
85 
86 
87 
88 def arrow_table_from_vaex_df(ds, column_names=None, selection=None, strings=True, virtual=False):
89     """Implementation of Dataset.to_arrow_table"""
90     names = []
91     arrays = []
92     for name, array in ds.to_items(column_names=column_names, selection=selection, strings=strings, virtual=virtual):
93         names.append(name)
94         arrays.append(arrow_array_from_numpy_array(array))
95     return pyarrow.Table.from_arrays(arrays, names)
96 
97 def vaex_df_from_arrow_table(table):
98     from .dataset import DatasetArrow
99     return DatasetArrow(table=table)
100
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/packages/vaex-arrow/vaex_arrow/convert.py b/packages/vaex-arrow/vaex_arrow/convert.py
--- a/packages/vaex-arrow/vaex_arrow/convert.py
+++ b/packages/vaex-arrow/vaex_arrow/convert.py
@@ -53,6 +53,7 @@
     buffers = arrow_array.buffers()
     assert len(buffers) == 2
     bitmap_buffer, data_buffer = buffers
+    offset = arrow_array.offset
     if isinstance(arrow_type, type(pyarrow.binary(1))):  # todo, is there a better way to typecheck?
         # mimics python/pyarrow/array.pxi::Array::to_numpy
         assert len(buffers) == 2
@@ -68,13 +69,13 @@
     if np.bool_ == dtype:
         # TODO: this will also be a copy, we probably want to support bitmasks as well
         bitmap = np.frombuffer(data_buffer, np.uint8, len(data_buffer))
-        array = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))
+        array = numpy_bool_from_arrow_bitmap(bitmap, len(arrow_array) + offset)[offset:]
     else:
-        array = np.frombuffer(data_buffer, dtype, len(arrow_array))
+        array = np.frombuffer(data_buffer, dtype, len(arrow_array) + offset)[offset:]
 
     if bitmap_buffer is not None:
         bitmap = np.frombuffer(bitmap_buffer, np.uint8, len(bitmap_buffer))
-        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))
+        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array) + offset)[offset:]
         array = np.ma.MaskedArray(array, mask=mask)
     return array
 
@@ -83,7 +84,10 @@
     # we do have to change the ordering of the bits
     return 1-np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length]
 
-
+def numpy_bool_from_arrow_bitmap(bitmap, length):
+    # arrow uses a bitmap https://github.com/apache/arrow/blob/master/format/Layout.md
+    # we do have to change the ordering of the bits
+    return np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length].view(np.bool_)
 
 def arrow_table_from_vaex_df(ds, column_names=None, selection=None, strings=True, virtual=False):
     """Implementation of Dataset.to_arrow_table"""

{"golden_diff": "diff --git a/packages/vaex-arrow/vaex_arrow/convert.py b/packages/vaex-arrow/vaex_arrow/convert.py\n--- a/packages/vaex-arrow/vaex_arrow/convert.py\n+++ b/packages/vaex-arrow/vaex_arrow/convert.py\n@@ -53,6 +53,7 @@\n     buffers = arrow_array.buffers()\n     assert len(buffers) == 2\n     bitmap_buffer, data_buffer = buffers\n+    offset = arrow_array.offset\n     if isinstance(arrow_type, type(pyarrow.binary(1))):  # todo, is there a better way to typecheck?\n         # mimics python/pyarrow/array.pxi::Array::to_numpy\n         assert len(buffers) == 2\n@@ -68,13 +69,13 @@\n     if np.bool_ == dtype:\n         # TODO: this will also be a copy, we probably want to support bitmasks as well\n         bitmap = np.frombuffer(data_buffer, np.uint8, len(data_buffer))\n-        array = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))\n+        array = numpy_bool_from_arrow_bitmap(bitmap, len(arrow_array) + offset)[offset:]\n     else:\n-        array = np.frombuffer(data_buffer, dtype, len(arrow_array))\n+        array = np.frombuffer(data_buffer, dtype, len(arrow_array) + offset)[offset:]\n \n     if bitmap_buffer is not None:\n         bitmap = np.frombuffer(bitmap_buffer, np.uint8, len(bitmap_buffer))\n-        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))\n+        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array) + offset)[offset:]\n         array = np.ma.MaskedArray(array, mask=mask)\n     return array\n \n@@ -83,7 +84,10 @@\n     # we do have to change the ordering of the bits\n     return 1-np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length]\n \n-\n+def numpy_bool_from_arrow_bitmap(bitmap, length):\n+    # arrow uses a bitmap https://github.com/apache/arrow/blob/master/format/Layout.md\n+    # we do have to change the ordering of the bits\n+    return np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length].view(np.bool_)\n \n def arrow_table_from_vaex_df(ds, column_names=None, selection=None, strings=True, virtual=False):\n     \"\"\"Implementation of Dataset.to_arrow_table\"\"\"\n", "issue": "Bool values get flipped when converting Arrow table to DataFrame\nUsing the latest version:\r\n`vaex==2.6.1`\r\n\r\nJust realised that when converting an Arrow table to a DataFrame, bool columns get flipped and converted to integers:\r\n\r\n```python\r\nimport vaex\r\nfrom pyarrow import feather\r\n\r\nbool_array = [False, True, True, False]\r\npdf = pd.DataFrame({\"col1\": bool_array})\r\npdf.to_feather(\"test_data.feather\")\r\narrow_table = feather.read_table(\"test_data.feather\")\r\nvaex.from_arrow_table(arrow_table)\r\n```\r\n\r\n```\r\n#  | col1\r\n-- | --\r\n0  | 1\r\n1  | 0\r\n2  | 0\r\n3  | 1\r\n```\n", "before_files": [{"content": "\"\"\"Convert between arrow and vaex/numpy columns/arrays without doing memory copies.\"\"\"\nimport pyarrow\nimport numpy as np\nfrom vaex.column import ColumnStringArrow\n\ndef arrow_array_from_numpy_array(array):\n    dtype = array.dtype\n    mask = None\n    if np.ma.isMaskedArray(array):\n        mask = array.mask\n        # arrow 0.16 behaves weird in this case https://github.com/vaexio/vaex/pull/639\n        if mask is np.False_:\n            mask = None\n        elif mask is np.True_:\n            raise ValueError('not sure what pyarrow does with mask=True')\n        array = array.data\n    if dtype.kind == 'S':\n        type = pyarrow.binary(dtype.itemsize)\n        arrow_array = pyarrow.array(array, type, mask=mask)\n    else:\n        if not dtype.isnative:\n            array = array.astype(dtype.newbyteorder('='))\n        arrow_array = pyarrow.Array.from_pandas(array, mask=mask)\n    return arrow_array\n\nfrom vaex.dataframe import Column\n\n\ndef column_from_arrow_array(arrow_array):\n    arrow_type = arrow_array.type\n    buffers = arrow_array.buffers()\n    if len(buffers) == 2:\n        return numpy_array_from_arrow_array(arrow_array)\n    elif len(buffers) == 3 and  isinstance(arrow_array.type, type(pyarrow.string())):\n        bitmap_buffer, offsets, string_bytes = arrow_array.buffers()\n        if arrow_array.null_count == 0:\n            null_bitmap = None  # we drop any null_bitmap when there are no null counts\n        else:\n            null_bitmap = np.frombuffer(bitmap_buffer, 'uint8', len(bitmap_buffer))\n        offsets = np.frombuffer(offsets, np.int32, len(offsets)//4)\n        if string_bytes is None:\n            string_bytes = np.array([], dtype='S1')\n        else:\n            string_bytes = np.frombuffer(string_bytes, 'S1', len(string_bytes))\n        column = ColumnStringArrow(offsets, string_bytes, len(arrow_array), null_bitmap=null_bitmap)\n        return column\n    else:\n        raise TypeError('type unsupported: %r' % arrow_type)\n\n\ndef numpy_array_from_arrow_array(arrow_array):\n    arrow_type = arrow_array.type\n    buffers = arrow_array.buffers()\n    assert len(buffers) == 2\n    bitmap_buffer, data_buffer = buffers\n    if isinstance(arrow_type, type(pyarrow.binary(1))):  # todo, is there a better way to typecheck?\n        # mimics python/pyarrow/array.pxi::Array::to_numpy\n        assert len(buffers) == 2\n        dtype = \"S\" + str(arrow_type.byte_width)\n        # arrow seems to do padding, check if it is all ok\n        expected_length = arrow_type.byte_width * len(arrow_array)\n        actual_length = len(buffers[-1])\n        if actual_length < expected_length:\n            raise ValueError('buffer is smaller (%d) than expected (%d)' % (actual_length, expected_length))\n        array = np.frombuffer(buffers[-1], dtype, len(arrow_array))# TODO: deal with offset ? [arrow_array.offset:arrow_array.offset + len(arrow_array)]\n    else:\n        dtype = arrow_array.type.to_pandas_dtype()\n    if np.bool_ == dtype:\n        # TODO: this will also be a copy, we probably want to support bitmasks as well\n        bitmap = np.frombuffer(data_buffer, np.uint8, len(data_buffer))\n        array = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))\n    else:\n        array = np.frombuffer(data_buffer, dtype, len(arrow_array))\n\n    if bitmap_buffer is not None:\n        bitmap = np.frombuffer(bitmap_buffer, np.uint8, len(bitmap_buffer))\n        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))\n        array = np.ma.MaskedArray(array, mask=mask)\n    return array\n\ndef numpy_mask_from_arrow_mask(bitmap, length):\n    # arrow uses a bitmap https://github.com/apache/arrow/blob/master/format/Layout.md\n    # we do have to change the ordering of the bits\n    return 1-np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length]\n\n\n\ndef arrow_table_from_vaex_df(ds, column_names=None, selection=None, strings=True, virtual=False):\n    \"\"\"Implementation of Dataset.to_arrow_table\"\"\"\n    names = []\n    arrays = []\n    for name, array in ds.to_items(column_names=column_names, selection=selection, strings=strings, virtual=virtual):\n        names.append(name)\n        arrays.append(arrow_array_from_numpy_array(array))\n    return pyarrow.Table.from_arrays(arrays, names)\n\ndef vaex_df_from_arrow_table(table):\n    from .dataset import DatasetArrow\n    return DatasetArrow(table=table)\n", "path": "packages/vaex-arrow/vaex_arrow/convert.py"}], "after_files": [{"content": "\"\"\"Convert between arrow and vaex/numpy columns/arrays without doing memory copies.\"\"\"\nimport pyarrow\nimport numpy as np\nfrom vaex.column import ColumnStringArrow\n\ndef arrow_array_from_numpy_array(array):\n    dtype = array.dtype\n    mask = None\n    if np.ma.isMaskedArray(array):\n        mask = array.mask\n        # arrow 0.16 behaves weird in this case https://github.com/vaexio/vaex/pull/639\n        if mask is np.False_:\n            mask = None\n        elif mask is np.True_:\n            raise ValueError('not sure what pyarrow does with mask=True')\n        array = array.data\n    if dtype.kind == 'S':\n        type = pyarrow.binary(dtype.itemsize)\n        arrow_array = pyarrow.array(array, type, mask=mask)\n    else:\n        if not dtype.isnative:\n            array = array.astype(dtype.newbyteorder('='))\n        arrow_array = pyarrow.Array.from_pandas(array, mask=mask)\n    return arrow_array\n\nfrom vaex.dataframe import Column\n\n\ndef column_from_arrow_array(arrow_array):\n    arrow_type = arrow_array.type\n    buffers = arrow_array.buffers()\n    if len(buffers) == 2:\n        return numpy_array_from_arrow_array(arrow_array)\n    elif len(buffers) == 3 and  isinstance(arrow_array.type, type(pyarrow.string())):\n        bitmap_buffer, offsets, string_bytes = arrow_array.buffers()\n        if arrow_array.null_count == 0:\n            null_bitmap = None  # we drop any null_bitmap when there are no null counts\n        else:\n            null_bitmap = np.frombuffer(bitmap_buffer, 'uint8', len(bitmap_buffer))\n        offsets = np.frombuffer(offsets, np.int32, len(offsets)//4)\n        if string_bytes is None:\n            string_bytes = np.array([], dtype='S1')\n        else:\n            string_bytes = np.frombuffer(string_bytes, 'S1', len(string_bytes))\n        column = ColumnStringArrow(offsets, string_bytes, len(arrow_array), null_bitmap=null_bitmap)\n        return column\n    else:\n        raise TypeError('type unsupported: %r' % arrow_type)\n\n\ndef numpy_array_from_arrow_array(arrow_array):\n    arrow_type = arrow_array.type\n    buffers = arrow_array.buffers()\n    assert len(buffers) == 2\n    bitmap_buffer, data_buffer = buffers\n    offset = arrow_array.offset\n    if isinstance(arrow_type, type(pyarrow.binary(1))):  # todo, is there a better way to typecheck?\n        # mimics python/pyarrow/array.pxi::Array::to_numpy\n        assert len(buffers) == 2\n        dtype = \"S\" + str(arrow_type.byte_width)\n        # arrow seems to do padding, check if it is all ok\n        expected_length = arrow_type.byte_width * len(arrow_array)\n        actual_length = len(buffers[-1])\n        if actual_length < expected_length:\n            raise ValueError('buffer is smaller (%d) than expected (%d)' % (actual_length, expected_length))\n        array = np.frombuffer(buffers[-1], dtype, len(arrow_array))# TODO: deal with offset ? [arrow_array.offset:arrow_array.offset + len(arrow_array)]\n    else:\n        dtype = arrow_array.type.to_pandas_dtype()\n    if np.bool_ == dtype:\n        # TODO: this will also be a copy, we probably want to support bitmasks as well\n        bitmap = np.frombuffer(data_buffer, np.uint8, len(data_buffer))\n        array = numpy_bool_from_arrow_bitmap(bitmap, len(arrow_array) + offset)[offset:]\n    else:\n        array = np.frombuffer(data_buffer, dtype, len(arrow_array) + offset)[offset:]\n\n    if bitmap_buffer is not None:\n        bitmap = np.frombuffer(bitmap_buffer, np.uint8, len(bitmap_buffer))\n        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array) + offset)[offset:]\n        array = np.ma.MaskedArray(array, mask=mask)\n    return array\n\ndef numpy_mask_from_arrow_mask(bitmap, length):\n    # arrow uses a bitmap https://github.com/apache/arrow/blob/master/format/Layout.md\n    # we do have to change the ordering of the bits\n    return 1-np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length]\n\ndef numpy_bool_from_arrow_bitmap(bitmap, length):\n    # arrow uses a bitmap https://github.com/apache/arrow/blob/master/format/Layout.md\n    # we do have to change the ordering of the bits\n    return np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length].view(np.bool_)\n\ndef arrow_table_from_vaex_df(ds, column_names=None, selection=None, strings=True, virtual=False):\n    \"\"\"Implementation of Dataset.to_arrow_table\"\"\"\n    names = []\n    arrays = []\n    for name, array in ds.to_items(column_names=column_names, selection=selection, strings=strings, virtual=virtual):\n        names.append(name)\n        arrays.append(arrow_array_from_numpy_array(array))\n    return pyarrow.Table.from_arrays(arrays, names)\n\ndef vaex_df_from_arrow_table(table):\n    from .dataset import DatasetArrow\n    return DatasetArrow(table=table)\n", "path": "packages/vaex-arrow/vaex_arrow/convert.py"}]}