Skip to content

Commit

Permalink
another change to attempt to fix 3.8
Browse files Browse the repository at this point in the history
  • Loading branch information
barrust committed Dec 27, 2024
1 parent 676a85e commit e27020a
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 2 additions & 0 deletions probables/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""pyprobables module"""

from __future__ import annotations

from probables.blooms import (
BloomFilter,
BloomFilterOnDisk,
Expand Down
52 changes: 27 additions & 25 deletions probables/blooms/bloom.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
URL: https://github.com/barrust/bloom
"""

from __future__ import annotations

import math
import os
from array import array
Expand Down Expand Up @@ -68,11 +70,11 @@ class BloomFilter:

def __init__(
self,
est_elements: Union[int, None] = None,
false_positive_rate: Union[float, None] = None,
filepath: Union[str, Path, None] = None,
hex_string: Union[str, None] = None,
hash_function: Union[HashFuncT, None] = None,
est_elements: int | None = None,
false_positive_rate: float | None = None,
filepath: str | Path | None = None,
hex_string: str | None = None,
hash_function: HashFuncT | None = None,
):
# set some things up
self._on_disk = False
Expand Down Expand Up @@ -110,7 +112,7 @@ def _load_init(self, filepath, hash_function, hex_string, est_elements, false_po
_FPR_STRUCT = Struct("f")
_IMPT_STRUCT = Struct("B")

def __contains__(self, key: KeyT) -> Union[int, bool]:
def __contains__(self, key: KeyT) -> int | bool:
"""setup the `in` keyword"""
return self.check(key)

Expand Down Expand Up @@ -220,7 +222,7 @@ def clear(self) -> None:
for idx in range(self._bloom_length):
self._bloom[idx] = 0

def hashes(self, key: KeyT, depth: Union[int, None] = None) -> HashResultsT:
def hashes(self, key: KeyT, depth: int | None = None) -> HashResultsT:
"""Return the hashes based on the provided key
Args:
Expand Down Expand Up @@ -284,7 +286,7 @@ def export_hex(self) -> str:
bytes_string = hexlify(bytearray(self._bloom[: self.bloom_length])) + hexlify(footer_bytes)
return str(bytes_string, "utf-8")

def export(self, file: Union[Path, str, IOBase, mmap]) -> None:
def export(self, file: Path | str | IOBase | mmap) -> None:
"""Export the Bloom Filter to disk
Args:
Expand All @@ -303,7 +305,7 @@ def export(self, file: Union[Path, str, IOBase, mmap]) -> None:
)
)

def export_c_header(self, filename: Union[str, Path]) -> None:
def export_c_header(self, filename: str | Path) -> None:
"""Export the Bloom Filter to disk as a C header file.
Args:
Expand All @@ -322,7 +324,7 @@ def export_c_header(self, filename: Union[str, Path]) -> None:
print("const unsigned char bloom[] = {", *data, "};", sep="\n", file=file)

@classmethod
def frombytes(cls, b: ByteString, hash_function: Union[HashFuncT, None] = None) -> "BloomFilter":
def frombytes(cls, b: ByteString, hash_function: HashFuncT | None = None) -> BloomFilter:
"""
Args:
b (ByteString): The bytes to load as a Bloom Filter
Expand Down Expand Up @@ -368,7 +370,7 @@ def current_false_positive_rate(self) -> float:
exp = math.exp(dbl)
return math.pow((1 - exp), self.number_hashes)

def intersection(self, second: SimpleBloomT) -> Union[SimpleBloomT, None]:
def intersection(self, second: SimpleBloomT) -> SimpleBloomT | None:
"""Return a new Bloom Filter that contains the intersection of the
two
Expand Down Expand Up @@ -399,7 +401,7 @@ def intersection(self, second: SimpleBloomT) -> Union[SimpleBloomT, None]:
res.elements_added = res.estimate_elements()
return res

def union(self, second: SimpleBloomT) -> Union["BloomFilter", None]:
def union(self, second: SimpleBloomT) -> BloomFilter | None:
"""Return a new Bloom Filter that contains the union of the two
Args:
Expand Down Expand Up @@ -429,7 +431,7 @@ def union(self, second: SimpleBloomT) -> Union["BloomFilter", None]:
res.elements_added = res.estimate_elements()
return res

def jaccard_index(self, second: SimpleBloomT) -> Union[float, None]:
def jaccard_index(self, second: SimpleBloomT) -> float | None:
"""Calculate the jaccard similarity score between two Bloom Filters
Args:
Expand Down Expand Up @@ -491,7 +493,7 @@ def _set_values(
fpr: float,
n_hashes: int,
n_bits: int,
hash_func: Union[HashFuncT, None],
hash_func: HashFuncT | None,
) -> None:
self._est_elements = est_els
self._fpr = fpr
Expand All @@ -504,7 +506,7 @@ def _set_values(
self._number_hashes = n_hashes
self._num_bits = n_bits

def _load_hex(self, hex_string: str, hash_function: Union[HashFuncT, None] = None) -> None:
def _load_hex(self, hex_string: str, hash_function: HashFuncT | None = None) -> None:
"""placeholder for loading from hex string"""
offset = self._FOOTER_STRUCT_BE.size * 2
est_els, els_added, fpr, n_hashes, n_bits = self._parse_footer(
Expand All @@ -516,8 +518,8 @@ def _load_hex(self, hex_string: str, hash_function: Union[HashFuncT, None] = Non

def _load(
self,
file: Union[Path, str, IOBase, mmap, ByteString],
hash_function: Union[HashFuncT, None] = None,
file: Path | str | IOBase | mmap | ByteString,
hash_function: HashFuncT | None = None,
) -> None:
"""load the Bloom Filter from file or bytes"""
if not isinstance(file, (IOBase, mmap, bytes, bytearray, memoryview)):
Expand Down Expand Up @@ -597,11 +599,11 @@ class BloomFilterOnDisk(BloomFilter):

def __init__(
self,
filepath: Union[str, Path],
est_elements: Union[int, None] = None,
false_positive_rate: Union[float, None] = None,
hex_string: Union[str, None] = None,
hash_function: Union[HashFuncT, None] = None,
filepath: str | Path,
est_elements: int | None = None,
false_positive_rate: float | None = None,
hex_string: str | None = None,
hash_function: HashFuncT | None = None,
) -> None:
# set some things up
self._filepath = resolve_path(filepath)
Expand Down Expand Up @@ -644,7 +646,7 @@ def close(self) -> None:
self.__file_pointer.close()
self.__file_pointer = None

def export(self, file: Union[str, Path]) -> None: # type: ignore
def export(self, file: str | Path) -> None: # type: ignore
"""Export to disk if a different location
Args:
Expand All @@ -656,7 +658,7 @@ def export(self, file: Union[str, Path]) -> None: # type: ignore
copyfile(self._filepath.name, str(file))
# otherwise, nothing to do!

def _load(self, file: Union[str, Path], hash_function: Union[HashFuncT, None] = None): # type: ignore
def _load(self, file: str | Path, hash_function: HashFuncT | None = None): # type: ignore
"""load the Bloom Filter on disk"""
# read the file, set the optimal params
# mmap everything
Expand All @@ -678,7 +680,7 @@ def add_alt(self, hashes: HashResultsT) -> None:
self.__update()

@classmethod
def frombytes(cls, b: ByteString, hash_function: Union[HashFuncT, None] = None) -> "BloomFilterOnDisk":
def frombytes(cls, b: ByteString, hash_function: HashFuncT | None = None) -> BloomFilterOnDisk:
"""
Raises: NotSupportedError
"""
Expand Down
32 changes: 17 additions & 15 deletions probables/blooms/countingbloom.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
""" CountingBloomFilter, python implementation
License: MIT
Author: Tyler Barrus ([email protected])
URL: https://github.com/barrust/counting_bloom
"""CountingBloomFilter, python implementation
License: MIT
Author: Tyler Barrus ([email protected])
URL: https://github.com/barrust/counting_bloom
"""

from __future__ import annotations

from array import array
from collections.abc import ByteString
from pathlib import Path
from struct import Struct
from typing import Union

from probables.blooms.bloom import BloomFilter
from probables.constants import UINT32_T_MAX, UINT64_T_MAX
Expand All @@ -18,7 +20,7 @@
MISMATCH_MSG = "The parameter second must be of type CountingBloomFilter"


def _verify_not_type_mismatch(second: "CountingBloomFilter") -> bool:
def _verify_not_type_mismatch(second: CountingBloomFilter) -> bool:
"""verify that there is not a type mismatch"""
return isinstance(second, (CountingBloomFilter))

Expand Down Expand Up @@ -47,11 +49,11 @@ class CountingBloomFilter(BloomFilter):

def __init__(
self,
est_elements: Union[int, None] = None,
false_positive_rate: Union[float, None] = None,
filepath: Union[str, Path, None] = None,
hex_string: Union[str, None] = None,
hash_function: Union[HashFuncT, None] = None,
est_elements: int | None = None,
false_positive_rate: float | None = None,
filepath: str | Path | None = None,
hex_string: str | None = None,
hash_function: HashFuncT | None = None,
) -> None:
"""setup the basic values needed"""
self._filepath = None
Expand Down Expand Up @@ -80,7 +82,7 @@ def _load_init(self, filepath, hash_function, hex_string, est_elements, false_po
_IMPT_STRUCT = Struct("I")

@classmethod
def frombytes(cls, b: ByteString, hash_function: Union[HashFuncT, None] = None) -> "CountingBloomFilter":
def frombytes(cls, b: ByteString, hash_function: HashFuncT | None = None) -> CountingBloomFilter:
"""
Args:
b (ByteString): the bytes to load as a Counting Bloom Filter
Expand Down Expand Up @@ -207,7 +209,7 @@ def remove_alt(self, hashes: HashResultsT, num_els: int = 1) -> int:
self.elements_added -= to_remove
return min_val - to_remove

def intersection(self, second: "CountingBloomFilter") -> Union["CountingBloomFilter", None]: # type: ignore
def intersection(self, second: CountingBloomFilter) -> CountingBloomFilter | None: # type: ignore
"""Take the intersection of two Counting Bloom Filters
Args:
Expand Down Expand Up @@ -240,7 +242,7 @@ def intersection(self, second: "CountingBloomFilter") -> Union["CountingBloomFil
res.elements_added = res.estimate_elements()
return res

def jaccard_index(self, second: "CountingBloomFilter") -> Union[float, None]: # type:ignore
def jaccard_index(self, second: CountingBloomFilter) -> float | None: # type:ignore
"""Take the Jaccard Index of two Counting Bloom Filters
Args:
Expand Down Expand Up @@ -270,7 +272,7 @@ def jaccard_index(self, second: "CountingBloomFilter") -> Union[float, None]: #
return 1.0
return count_inter / count_union

def union(self, second: "CountingBloomFilter") -> Union["CountingBloomFilter", None]: # type:ignore
def union(self, second: CountingBloomFilter) -> CountingBloomFilter | None: # type:ignore
"""Return a new Countiong Bloom Filter that contains the union of
the two
Expand Down
29 changes: 15 additions & 14 deletions probables/blooms/expandingbloom.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
URL: https://github.com/barrust/pyprobables
"""

from __future__ import annotations

from array import array
from collections.abc import ByteString
from io import BytesIO, IOBase
from mmap import mmap
from pathlib import Path
from struct import Struct
from typing import Union

from probables.blooms.bloom import BloomFilter
from probables.exceptions import RotatingBloomFilterError
Expand Down Expand Up @@ -46,10 +47,10 @@ class ExpandingBloomFilter:

def __init__(
self,
est_elements: Union[int, None] = None,
false_positive_rate: Union[float, None] = None,
filepath: Union[str, Path, None] = None,
hash_function: Union[HashFuncT, None] = None,
est_elements: int | None = None,
false_positive_rate: float | None = None,
filepath: str | Path | None = None,
hash_function: HashFuncT | None = None,
):
"""initialize"""
self._blooms = [] # type: ignore
Expand All @@ -74,7 +75,7 @@ def __init__(
_BLOOM_ELEMENT_SIZE = Struct("B").size

@classmethod
def frombytes(cls, b: ByteString, hash_function: Union[HashFuncT, None] = None) -> "ExpandingBloomFilter":
def frombytes(cls, b: ByteString, hash_function: HashFuncT | None = None) -> ExpandingBloomFilter:
"""
Args:
b (ByteString): The bytes to load as a Expanding Bloom Filter
Expand Down Expand Up @@ -184,7 +185,7 @@ def __check_for_growth(self):
if self._blooms[-1].elements_added >= self.__est_elements:
self.__add_bloom_filter()

def export(self, file: Union[Path, str, IOBase, mmap]) -> None:
def export(self, file: Path | str | IOBase | mmap) -> None:
"""Export an expanding Bloom Filter, or subclass, to disk
Args:
Expand All @@ -208,7 +209,7 @@ def export(self, file: Union[Path, str, IOBase, mmap]) -> None:
)
)

def __load(self, file: Union[Path, str, IOBase, mmap]):
def __load(self, file: Path | str | IOBase | mmap):
"""load a file"""
if not isinstance(file, (IOBase, mmap)):
file = resolve_path(file)
Expand Down Expand Up @@ -273,11 +274,11 @@ class RotatingBloomFilter(ExpandingBloomFilter):

def __init__(
self,
est_elements: Union[int, None] = None,
false_positive_rate: Union[float, None] = None,
est_elements: int | None = None,
false_positive_rate: float | None = None,
max_queue_size: int = 10,
filepath: Union[str, Path, None] = None,
hash_function: Union[HashFuncT, None] = None,
filepath: str | Path | None = None,
hash_function: HashFuncT | None = None,
) -> None:
"""initialize"""
super().__init__(
Expand All @@ -290,8 +291,8 @@ def __init__(

@classmethod
def frombytes( # type:ignore
cls, b: ByteString, max_queue_size: int, hash_function: Union[HashFuncT, None] = None
) -> "RotatingBloomFilter":
cls, b: ByteString, max_queue_size: int, hash_function: HashFuncT | None = None
) -> RotatingBloomFilter:
"""
Args:
b (ByteString): The bytes to load as a Expanding Bloom Filter
Expand Down
Loading

0 comments on commit e27020a

Please sign in to comment.