Skip to content

Commit

Permalink
pyupgrade, typing
Browse files Browse the repository at this point in the history
  • Loading branch information
artemisart committed Jan 22, 2024
1 parent 64dfef7 commit 12c38d0
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 93 deletions.
1 change: 0 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
#
# ScalaFunctional documentation build configuration file, created by
# sphinx-quickstart on Wed Mar 11 23:00:20 2015.
Expand Down
6 changes: 3 additions & 3 deletions functional/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from functional.util import compose, parallelize


class ExecutionStrategies(object):
class ExecutionStrategies:
"""
Enum like object listing the types of execution strategies.
"""
Expand All @@ -11,7 +11,7 @@ class ExecutionStrategies(object):
PARALLEL = 1


class ExecutionEngine(object):
class ExecutionEngine:
"""
Class to perform serial execution of a Sequence evaluation.
"""
Expand Down Expand Up @@ -43,7 +43,7 @@ def __init__(self, processes=None, partition_size=None):
Set the number of processes for parallel execution.
:param processes: Number of parallel Processes
"""
super(ParallelExecutionEngine, self).__init__()
super().__init__()
self.processes = processes
self.partition_size = partition_size

Expand Down
31 changes: 16 additions & 15 deletions functional/io.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import gzip
import lzma
import builtins
import bz2
import gzip
import io
import builtins

from typing import Optional, Generic, TypeVar, Any
import lzma
from os import PathLike
from typing import Any, Optional, TypeAlias

# from typeshed
StrOrBytesPath: TypeAlias = str | bytes | PathLike[str] | PathLike[bytes]
FileDescriptorOrPath: TypeAlias = int | StrOrBytesPath

WRITE_MODE = "wt"

_FileConv_co = TypeVar("_FileConv_co", covariant=True)


class ReusableFile(Generic[_FileConv_co]):
class ReusableFile:
"""
Class which emulates the builtin file except that calling iter() on it will return separate
iterators on different file handlers (which are automatically closed when iteration stops). This
Expand All @@ -23,7 +24,7 @@ class ReusableFile(Generic[_FileConv_co]):
# pylint: disable=too-many-instance-attributes
def __init__(
self,
path: str,
path: FileDescriptorOrPath,
delimiter: Optional[str] = None,
mode: str = "r",
buffering: int = -1,
Expand Down Expand Up @@ -95,7 +96,7 @@ def __init__(
errors: Optional[str] = None,
newline: Optional[str] = None,
):
super(CompressedFile, self).__init__(
super().__init__(
path,
delimiter=delimiter,
mode=mode,
Expand Down Expand Up @@ -126,7 +127,7 @@ def __init__(
errors: Optional[str] = None,
newline: Optional[str] = None,
):
super(GZFile, self).__init__(
super().__init__(
path,
delimiter=delimiter,
mode=mode,
Expand Down Expand Up @@ -181,7 +182,7 @@ def __init__(
errors: Optional[str] = None,
newline: Optional[str] = None,
):
super(BZ2File, self).__init__(
super().__init__(
path,
delimiter=delimiter,
mode=mode,
Expand Down Expand Up @@ -234,7 +235,7 @@ def __init__(
filters=None,
format=None,
):
super(XZFile, self).__init__(
super().__init__(
path,
delimiter=delimiter,
mode=mode,
Expand Down Expand Up @@ -278,7 +279,7 @@ def read(self):
return file_content.read()


COMPRESSION_CLASSES = [GZFile, BZ2File, XZFile]
COMPRESSION_CLASSES: list[type[CompressedFile]] = [GZFile, BZ2File, XZFile]
N_COMPRESSION_CHECK_BYTES = max(len(cls.magic_bytes) for cls in COMPRESSION_CLASSES) # type: ignore


Expand All @@ -288,7 +289,7 @@ def get_read_function(filename: str, disable_compression: bool):
with open(filename, "rb") as f:
start_bytes = f.read(N_COMPRESSION_CHECK_BYTES)
for cls in COMPRESSION_CLASSES:
if cls.is_compressed(start_bytes): # type: ignore
if cls.is_compressed(start_bytes):
return cls
return ReusableFile

Expand Down
13 changes: 10 additions & 3 deletions functional/lineage.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
from __future__ import annotations

from typing import Optional
from functional.execution import ExecutionEngine
from functional.transformations import CACHE_T


class Lineage(object):
class Lineage:
"""
Class for tracking the lineage of transformations, and applying them to a given sequence.
"""

def __init__(self, prior_lineage=None, engine=None):
def __init__(
self,
prior_lineage: Optional[Lineage] = None,
engine: Optional[ExecutionEngine] = None,
):
"""
Construct an empty lineage if prior_lineage is None or if its not use it as the list of
current transformations
Expand All @@ -16,7 +23,7 @@ def __init__(self, prior_lineage=None, engine=None):
:return: new Lineage object
"""
self.transformations = (
[] if prior_lineage is None else list(prior_lineage.transformations)
[] if prior_lineage is None else prior_lineage.transformations
)
self.engine = (
(engine or ExecutionEngine())
Expand Down
87 changes: 41 additions & 46 deletions functional/pipeline.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,49 @@
"""
The pipeline module contains the transformations and actions API of PyFunctional
"""
from operator import mul, add
import collections
from functools import reduce, wraps, partial

import json
import csv
import sqlite3
import json
import re

import sqlite3
from collections.abc import Iterable
from typing import List, Optional, Tuple, Union
from functools import partial, reduce, wraps
from operator import add, mul
from typing import Any, Callable, Generic, Optional, TypeVar, Union, reveal_type

from tabulate import tabulate

from functional.execution import ExecutionEngine
from functional import transformations
from functional.execution import ExecutionEngine, ExecutionStrategies
from functional.io import WRITE_MODE, universal_write_open
from functional.lineage import Lineage
from functional.util import (
default_value,
identity,
is_iterable,
is_primitive,
is_namedtuple,
is_primitive,
is_tabulatable,
identity,
default_value,
)
from functional.io import WRITE_MODE, universal_write_open
from functional import transformations
from functional.execution import ExecutionStrategies

T = TypeVar('T')


class Sequence(object):
class Sequence(Generic[T]):
"""
Sequence is a wrapper around any type of sequence which provides access to common
functional transformations and reductions in a data pipeline style
"""

engine: ExecutionEngine
_max_repr_items: Optional[int]
_base_sequence: Iterable[T]
_lineage: Lineage
no_wrap: Optional[bool]

def __init__(
self,
sequence: Iterable,
sequence: Iterable[T],
transform=None,
engine: Optional[ExecutionEngine] = None,
max_repr_items: Optional[int] = None,
Expand All @@ -62,7 +67,7 @@ def __init__(
self._max_repr_items: Optional[int] = (
max_repr_items or sequence._max_repr_items
)
self._base_sequence: Union[Iterable, List, Tuple] = sequence._base_sequence
self._base_sequence: Union[Iterable, list, tuple] = sequence._base_sequence
self._lineage: Lineage = Lineage(
prior_lineage=sequence._lineage, engine=engine
)
Expand Down Expand Up @@ -432,7 +437,7 @@ def drop_while(self, func):
"""
return self._transform(transformations.drop_while_t(func))

def take(self, n):
def take(self, n: int):
"""
Take the first n elements of the sequence.
Expand Down Expand Up @@ -963,7 +968,7 @@ def reduce(self, func, *initial):
:param initial: single optional argument acting as initial value
:return: reduced value using func
"""
if len(initial) == 0:
if not initial:
return _wrap(reduce(func, self))
elif len(initial) == 1:
return _wrap(reduce(func, self, initial[0]))
Expand All @@ -987,7 +992,7 @@ def accumulate(self, func=add):
"""
return self._transform(transformations.accumulate_t(func))

def make_string(self, separator):
def make_string(self, separator: str) -> str:
"""
Concatenate the elements of the sequence into a string separated by separator.
Expand Down Expand Up @@ -1016,20 +1021,10 @@ def product(self, projection=None):
:return: product of elements in sequence
"""
if self.empty():
if projection:
return projection(1)
else:
return 1
return projection(1) if projection else 1
if self.size() == 1:
if projection:
return projection(self.first())
else:
return self.first()

if projection:
return self.map(projection).reduce(mul)
else:
return self.reduce(mul)
return projection(self.first()) if projection else self.first()
return (self.map(projection) if projection else self).reduce(mul)

def sum(self, projection=None):
"""
Expand All @@ -1044,10 +1039,7 @@ def sum(self, projection=None):
:param projection: function to project on the sequence before taking the sum
:return: sum of elements in sequence
"""
if projection:
return sum(self.map(projection))
else:
return sum(self)
return sum(self.map(projection) if projection else self)

def average(self, projection=None):
"""
Expand All @@ -1062,10 +1054,7 @@ def average(self, projection=None):
:return: average of elements in the sequence
"""
length = self.size()
if projection:
return sum(self.map(projection)) / length
else:
return sum(self) / length
return sum(self.map(projection) if projection else self) / length

def aggregate(self, *args):
"""
Expand Down Expand Up @@ -1377,7 +1366,7 @@ def slice(self, start, until):
"""
return self._transform(transformations.slice_t(start, until))

def to_list(self, n=None):
def to_list(self, n: Optional[int] = None) -> list[T]:
"""
Converts sequence to list of elements.
Expand All @@ -1399,7 +1388,7 @@ def to_list(self, n=None):
else:
return self.cache().take(n).list()

def list(self, n=None):
def list(self, n: Optional[int] = None) -> list[T]:
"""
Converts sequence to list of elements.
Expand All @@ -1417,7 +1406,7 @@ def list(self, n=None):
"""
return self.to_list(n=n)

def to_set(self):
def to_set(self) -> set[T]:
"""
Converts sequence to a set of elements.
Expand All @@ -1434,7 +1423,7 @@ def to_set(self):
"""
return set(self.sequence)

def set(self):
def set(self) -> set[T]:
"""
Converts sequence to a set of elements.
Expand Down Expand Up @@ -1828,7 +1817,13 @@ def _wrap(value):
return value


def extend(func=None, aslist=False, final=False, name=None, parallel=False):
def extend(
func: Optional[Callable[[Any], Any]] = None,
aslist: bool = False,
final: bool = False,
name: str = '',
parallel: bool = False,
):
"""
Function decorator for adding new methods to the Sequence class.
Expand Down
6 changes: 2 additions & 4 deletions functional/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from functional.io import get_read_function


class Stream(object):
class Stream:
"""
Represents and implements a stream which separates the responsibilities of Sequence and
ExecutionEngine.
Expand Down Expand Up @@ -318,9 +318,7 @@ def __init__(
:param disable_compression: Disable file compression detection
:param no_wrap: default value of no_wrap for functions like first() or last()
"""
super(ParallelStream, self).__init__(
disable_compression=disable_compression, no_wrap=no_wrap
)
super().__init__(disable_compression=disable_compression, no_wrap=no_wrap)
self.processes = processes
self.partition_size = partition_size

Expand Down
4 changes: 2 additions & 2 deletions functional/test/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ def test_wrap(self):
self.assert_not_type(_wrap(Data(1, 2)))

def test_wrap_objects(self):
class A(object):
class A:
a = 1

l = [A(), A(), A()]
Expand Down Expand Up @@ -1031,7 +1031,7 @@ def test_tabulate(self):
sequence = seq(1, 2, 3)
self.assertEqual(sequence.tabulate(), None)

class NotTabulatable(object):
class NotTabulatable:
pass

sequence = seq(NotTabulatable(), NotTabulatable(), NotTabulatable())
Expand Down
Loading

0 comments on commit 12c38d0

Please sign in to comment.