Code Monkey home page Code Monkey logo

lambdas's Introduction

lambdas logo


Build Status codecov Documentation Status Python Version wemake-python-styleguide Telegram chat


Write short and fully-typed lambdas where you need them.

Features

  • Allows to write lambdas as _
  • Fully typed with annotations and checked with mypy, PEP561 compatible
  • Has a bunch of helpers for better composition
  • Easy to start: has lots of docs, tests, and tutorials

Installation

pip install lambdas

You also need to configure mypy correctly and install our plugin:

# In setup.cfg or mypy.ini:
[mypy]
plugins =
  lambdas.contrib.mypy.lambdas_plugin

We recommend to use the same mypy settings we use.

Examples

Imagine that you need to sort an array of dictionaries like so:

>>> scores = [
...     {'name': 'Nikita', 'score': 2},
...     {'name': 'Oleg', 'score': 1},
...     {'name': 'Pavel', 'score': 4},
... ]

>>> print(sorted(scores, key=lambda item: item['score']))
[{'name': 'Oleg', 'score': 1}, {'name': 'Nikita', 'score': 2}, {'name': 'Pavel', 'score': 4}]

And it works perfectly fine. Except, that you have to do a lot of typing for such a simple operation.

That's where lambdas helper steps in:

>>> from lambdas import _

>>> scores = [
...     {'name': 'Nikita', 'score': 2},
...     {'name': 'Oleg', 'score': 1},
...     {'name': 'Pavel', 'score': 4},
... ]

>>> print(sorted(scores, key=_['score']))
[{'name': 'Oleg', 'score': 1}, {'name': 'Nikita', 'score': 2}, {'name': 'Pavel', 'score': 4}]

It might really save you a lot of effort, when you use a lot of lambda functions. Like when using returns library.

We can easily create math expressions:

>>> from lambdas import _

>>> math_expression = _ * 2 + 1
>>> print(math_expression(10))
21
>>> complex_math_expression = 50 / (_ ** 2) * 2
>>> print(complex_math_expression(5))
100.0

Work in progress:

  • _.method() is not supported yet for the same reason
  • TypedDicts are not tested with __getitem__
  • __getitem__ does not work with list and tuples (collections), only dicts (mappings)

For now you will have to use regular lamdbas in these cases.

lambdas's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar sobolevn avatar thepabloaguilar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

lambdas's Issues

Bug in the docs

>>> complex_math_expression = 50 / (_ ** 2) * 2
>>> print(complex_math_expression(5))
100.0

But:

>>> 50 / (5 ** 2) * 2
4.0

Not good :)

Convert all dunder functions to use the normal function signature

When we define a class like this:

def func():
    ...

class MyClass:
    my_func = lambda self, arg: arg

# or
class MyAnotherClass:
    my_func = func

The coverage plugin will consider the my_func as coveraged without any tests.
This behavior is expected because for it the my_func is an attribute!

I think it will be great use the normal signature, this will enforce we to make dummy tests to ensures the _ will work correctly.

Version conflict with returns 0.20.0

Bug report

Tried to create project with latest lambdas and returns to use them together.

What's wrong

pip fails to install my dependencies with the following error:

The conflict is caused by:
    returns 0.20.0 depends on typing-extensions<5.0 and >=4.0
    lambdas 0.1.0 depends on typing-extensions<4.0 and >=3.7

How is that should be

Latest lambdas should be installable together with latest returns.

I tried to install lambdas from master branch and everything resolves fine, because on master we have typing-extensions = ">=4.0,<5.0". Can we just release new version from master branch?

System information

  • pyhon version: 3.11.1
  • lambdas version: 0.1.0
  • returns version: 0.2.0

New release on pypi? (support for attrgetter)

Hello, could you publish a new release on pypi? I saw in the code that attribute access is supported, but the pypi release was made on the commit just before: c12d4ba so currently _.something raises AttributeError

Math operations

Hello, I'm opening this issue to discuss about Math operations. I've had and initial idea!

Create an class, MathOperations or something like, it'll store all operations to be executed when __call__ is called! So the math operations from _Callable will return that class.
I've made a simple test without the class:

>>> import operation
>>> from lambdas import _fmap

>>> # _ + 1 - 10
>>> operations = [_fmap(operator.add)(None, 1), _fmap(operator.sub)(None, 10)]
>>> first_operation, *rest_operations = operations
>>> reduce(lambda partial_result, operation: operation(partial_result), rest_operations, first_operation(1))
-8

I was worried about the operations order, but Python does it for us!

>>> # If we have this `_ + 1 * 2`, the operations list should be like below
>>> operations = [_fmap(operator.add)(None, 3)]

Python deals with the operations order, we just have to store them.

Question about using lambdas with returns.Maybe

First of all, thanks for creating this library! It's quite neat and I really enjoy the idea of lambdas (I wrote things in scala and using lambdas for Python development feels more natural to me).

I have a quick question about using lambdas with returns.Maybe. Pardon me if I did something wrong, but I'm not sure how to use lambdas' _ in a bind function of a Maybe instance. Below is an example:

from typing import Optional
from returns.maybe import Maybe, Nothing
from lambdas import _


class Test:
    a: Maybe[int]
    b: Maybe[int]

    def __init__(self, a: Optional[int] = None, b: Optional[int] = None) -> None:
        self.a = Maybe.from_value(a)
        self.b = Maybe.from_value(b)

    def get_a(self) -> Maybe[int]:
        return self.a

    def get_b(self) -> Maybe[int]:
        return self.b


def test_returns() -> None:
    print("haha")
    t = Test(13, None)
    value = (
        t.get_a()
        .bind(Maybe.from_value(_ ** 2 if _ > 12 else Nothing)) // Break
        .bind(Maybe.from_value(_ + 100)) // Break
    )
    print(value)
    print(t.get_b().bind(lambda x: x + 12))

if __name__ == "__main__":
    test_returns()

If I turn the two "Break" lines to using regular lambdas, the script executes as expected. Did I do something wrong here when using lambdas _ with Maybe.from_value?

Thanks!

When we can expect next release?

Your library seems to be very promising, but in my case I would benefit from it the most, if it would have __getattr__ implemented. When we can expect next release? As I can see, it is already implemented, but I guess there are some problems that stops you from releasing it?

Implements `_.method()`

I'm opening this issue to discuss the possible ways to implement _.method()

Currently, we have this implementation:

class _Callable(object):
    def __getattr__(
        self,
        key: str,
    ) -> Callable[[_LambdaDynamicProtocol[T1]], T1]:
        return operator.attrgetter(key)

The problem here is that we return the operator directly:

>>> from lambdas import _
>>> _.method
operator.attrgetter('method')
>>> _.method()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: attrgetter expected 1 arguments, got 0

My idea is to create an intermediated class like _MathExpression:

class Attr:  # Just ignore the name for now
    def __init__(self, attr: str) -> None:
        self._attrgetter = operator.attrgetter(attr)

    def __call__(self, *args, **kwargs) -> Any:
        if len(args) == 1:
            return self._attrgetter(args[0])
        return lambda obj: self._attrgetter(obj)(*args, **kwargs)

This implementation has a limitation, they won't work correctly if we try to call a method with one argument. This is hard because we don't know when the attribute is callable!

Prevent Python from treating _Callable an iterable

Problem

Due to lack of __iter__ implementation, Python is attempting to iterate over _Callable when possible. It's generally an undesired behavior, given the purposes of the _Callable class.

You can easily reproduce the issue:

[*__import__("lambdas")._]

Implementation

That should be a no-brainer to fix and write tests for.

class _Callable:
    __iter__ = None

Dependabot can't resolve your Python dependency files

Dependabot can't resolve your Python dependency files.

As a result, Dependabot couldn't update your dependencies.

The error Dependabot encountered was:

Creating virtualenv lambdas-KN7S6Y4v-py3.9 in /home/dependabot/.cache/pypoetry/virtualenvs
Updating dependencies
Resolving dependencies...

  PackageNotFound

  Package pytest-mypy-plugins (1.1.0) not found.

  at /usr/local/.pyenv/versions/3.9.0/lib/python3.9/site-packages/poetry/repositories/pool.py:144 in package
      140│                     self._packages.append(package)
      141│ 
      142│                     return package
      143│ 
    → 144│         raise PackageNotFound("Package {} ({}) not found.".format(name, version))
      145│ 
      146│     def find_packages(
      147│         self, dependency,
      148│     ):

If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.

View the update logs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.