Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable ruff rules #992

Merged
merged 15 commits into from
Jan 2, 2025
1 change: 1 addition & 0 deletions benchmarks/benchmarks/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Benchmark package."""
74 changes: 46 additions & 28 deletions numbergen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,24 +133,35 @@ def __abs__ (self): return UnaryOperator(self,operator.abs)
}

def pprint(x, *args, **kwargs):
"""Pretty-print the provided item, translating operators to their symbols"""
"""Pretty-print the provided item, translating operators to their symbols."""
return x.pprint(*args, **kwargs) if hasattr(x,'pprint') else operator_symbols.get(x, repr(x))


class BinaryOperator(NumberGenerator):
"""Applies any binary operator to NumberGenerators or numbers to yield a NumberGenerator."""
"""
Applies any binary operator to NumberGenerators or numbers to yield a NumberGenerator.

def __init__(self,lhs,rhs,operator,reverse=False,**args):
"""
Accepts two NumberGenerator operands, an operator, and
optional arguments to be provided to the operator when calling
it on the two operands.
"""
# Note that it's currently not possible to set
# parameters in the superclass when creating an instance,
# because **args is used by this class itself.
super().__init__()
Parameters
----------
lhs: NumberGenerator or Number
The left-hand side operand, which can be a NumberGenerator or a number.
rhs: NumberGenerator or Number
The right-hand side operand, which can be a NumberGenerator or a number.
operator : callable
The binary operator to apply to the operands.
reverse : bool, optional
If `True`, swaps the left and right operands. Defaults to `False`.
**args:
Optional keyword arguments to pass to the operator when it is called.

Notes
-----
It is currently not possible to set parameters in the superclass during
initialization because `**args` is used by this class itself.
"""

def __init__(self,lhs, rhs, operator, reverse=False, **args):
super().__init__()
if reverse:
self.lhs=rhs
self.rhs=lhs
Expand All @@ -171,17 +182,25 @@ def pprint(self, *args, **kwargs):


class UnaryOperator(NumberGenerator):
"""Applies any unary operator to a NumberGenerator to yield another NumberGenerator."""
"""
Applies any unary operator to a NumberGenerator to yield another NumberGenerator.

def __init__(self,operand,operator,**args):
"""
Accepts a NumberGenerator operand, an operator, and
optional arguments to be provided to the operator when calling
it on the operand.
"""
# Note that it's currently not possible to set
# parameters in the superclass when creating an instance,
# because **args is used by this class itself.
Parameters
----------
operand : NumberGenerator
The NumberGenerator to which the operator is applied.
operator : callable
The unary operator to apply to the operand.
**args:
Optional keyword arguments to pass to the operator when it is called.

Notes
-----
It is currently not possible to set parameters in the superclass during
initialization because `**args` is used by this class itself.
"""

def __init__(self, operand, operator, **args):
super().__init__()

self.operand=operand
Expand Down Expand Up @@ -237,23 +256,20 @@ def _rational(self, val):
numer, denom = frac.numerator, frac.denominator
return numer % I32, denom % I32


def __getstate__(self):
"""Avoid Hashlib.md5 TypeError in deepcopy (hashlib issue)"""
"""Avoid Hashlib.md5 TypeError in deepcopy (hashlib issue)."""
d = self.__dict__.copy()
d.pop('_digest')
d.pop('_hash_struct')
return d


def __setstate__(self, d):
self._digest = hashlib.md5()
name, input_count = d['name'], d['input_count']
self._digest.update(name.encode())
self._hash_struct = struct.Struct( "!" +" ".join(["I"] * (input_count * 2)))
self.__dict__.update(d)


def __call__(self, *vals):
"""
Given integer or rational inputs, generate a cross-platform,
Expand Down Expand Up @@ -330,7 +346,9 @@ class TimeAwareRandomState(TimeAware):

def _initialize_random_state(self, seed=None, shared=True, name=None):
"""
Initialization method to be called in the constructor of
Initialize the random state correctly.

Method to be called in the constructor of
subclasses to initialize the random state correctly.

If seed is None, there is no control over the random stream
Expand Down Expand Up @@ -427,7 +445,7 @@ class RandomDistribution(NumberGenerator, TimeAwareRandomState):

__abstract = True

def __init__(self,**params):
def __init__(self, **params):
"""
Initialize a new Random() instance and store the supplied
positional and keyword arguments.
Expand Down
62 changes: 52 additions & 10 deletions param/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,59 @@

"""
Param: A declarative framework for managing parameters and reactive programming in Python.

Param is a lightweight library for defining and managing user-modifiable parameters,
designed to simplify Python programs and enhance their readability, maintainability,
and robustness. In addition Param provides the `rx` framework for reactive programming.

Param is well-suited for use in scientific computing, data analysis tools,
graphical user interfaces (GUIs), and any Python application where well-defined,
validated parameters are needed.

Documentation
-------------
For detailed documentation, see https://param.holoviz.org/.

Examples
--------
Here is an example of using `param.Parameterized` to define a class with validated parameters:

>>> import param
>>> class MyClass(param.Parameterized):
... my_number = param.Number(default=1, bounds=(0, 10))
... my_list = param.List(default=[1, 2, 3], item_type=int)

>>> obj = MyClass()
>>> obj.my_number = 5 # Valid
>>> obj.my_number = 15 # Raises ValueError: must be in range (0, 10)

Here is an example of using `param.rx` to define a reactive expression:

>>> import param
>>> rx_value = param.rx([1,2,3])
>>> rx_value.rx.len()
3

Lets update the reactive value and check its length:

>>> rx_value.rx.value = [1,2,3,4]
>>> rx_value.rx.len()
4
"""
import os

from . import version # noqa: api import
from .depends import depends # noqa: api import
from .parameterized import ( # noqa: api import
from . import version
from .depends import depends
from .parameterized import (
Parameterized, Parameter, Skip, String, ParameterizedFunction,
ParamOverrides, Undefined, get_logger
)
from .parameterized import (batch_watch, output, script_repr, # noqa: api import
from .parameterized import (batch_watch, output, script_repr,
discard_events, edit_constant)
from .parameterized import shared_parameters # noqa: api import
from .parameterized import logging_level # noqa: api import
from .parameterized import DEBUG, VERBOSE, INFO, WARNING, ERROR, CRITICAL # noqa: api import
from .parameters import ( # noqa: api import
from .parameterized import shared_parameters
from .parameterized import logging_level
from .parameterized import DEBUG, VERBOSE, INFO, WARNING, ERROR, CRITICAL
from .parameters import (
guess_param_types,
param_union,
parameterized_class,
Expand Down Expand Up @@ -58,8 +100,8 @@
CalendarDateRange,
Event,
)
from .reactive import bind, rx # noqa: api import
from ._utils import ( # noqa: api import
from .reactive import bind, rx
from ._utils import (
produce_value,
as_unicode,
is_ordered_dict,
Expand Down
Loading
Loading