Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,33 @@ c = C(4)
R.keys(a) # ['a']
R.keys(b) # ['a', 'b']
R.keys(c) # ['c'], because c does not call super().__init__()

# For normal dict
R.keys({'a': 1, 'b': 2}) # ['a', 'b']
```

- [x] keysIn

Different from `keys`, `keysIn` will return all attributes of the object, including super class attributes and class static variables.

```python
class A:
a_static = 1
def __init__(self):
self.a = 1
class B(A):
b_static = 2
def __init__(self, b):
super().__init__()
self.b = b

R.keysIn(A()) # ['a_static', 'a']
R.keysIn(B(2)) # ['a_static', 'a', 'b_static', 'b']

# For normal dict
R.keysIn({'a': 1, 'b': 2}) # ['a', 'b']
```

- [ ] keysIn
- [x] 0.1.4 last
- [x] 0.1.2 lastIndexOf
- [ ] length
Expand Down
1 change: 1 addition & 0 deletions ramda/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
from .join import join
from .juxt import juxt
from .keys import keys
from .keysIn import keysIn
from .last import last
from .lastIndexOf import lastIndexOf
from .lt import lt
Expand Down
5 changes: 2 additions & 3 deletions ramda/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ def inner_reduce(acc, key):
if isinstance(filterable, dict) or _has(filterable, 'get'):
if pred(filterable.get(key)):
acc[key] = filterable.get(key)
else:
elif not pred(getattr(filterable, key, None)):
# This is special, because we deepcopy the original object,
# so we delete attr from original object if not match
if not pred(getattr(filterable, key, None)):
delattr(acc, key)
delattr(acc, key)
return acc
return _reduce(inner_reduce, {} if isinstance(filterable, dict) or _has(filterable, 'get') else copy.deepcopy(filterable), keys(filterable))

Expand Down
3 changes: 3 additions & 0 deletions ramda/join.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
from .map import map


def join(separator, xs):
return separator.join(map(str, xs))
26 changes: 26 additions & 0 deletions ramda/keysIn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from .keys import keys
from .private._curry1 import _curry1


def static_keysIn(clazz):
ks = [v for v, m in vars(clazz).items() if not (v.startswith('_') or callable(m))]
for base in clazz.__bases__:
ks += static_keysIn(base)
return ks


def inner_keysIn(obj):
ks = []
primitives = (int, float, bool, str)
# ignore primitive types
if isinstance(obj, primitives):
return ks
# extract all static variables
ks += static_keysIn(obj.__class__)
# extract all instance variables
ks += keys(obj)

return ks


keysIn = _curry1(inner_keysIn)
2 changes: 1 addition & 1 deletion ramda/private/_Set.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class _Set(set):
def add(self, item):
if filter(equals(item), list(self.__iter__())):
if filter(equals(item), list(iter(self))):
return False
super().add(item)
return True
2 changes: 1 addition & 1 deletion ramda/private/_createReduce.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Iterable
from collections.abc import Iterable

from ._helper import getAttribute
from ._isArrayLike import _isArrayLike
Expand Down
6 changes: 1 addition & 5 deletions ramda/private/_equals.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ def _equals(a, b):
# Array-like
if len(a) != len(b):
return False
# pylint: disable=consider-using-enumerate
for i in range(len(a)):
if not _equals(a[i], b[i]):
return False
return True
return all(_equals(a[i], b[i]) for i in range(len(a)))
if _isFunction(getAttribute(a, 'equals')) and _isFunction(getAttribute(b, 'equals')):
# dispatch to objects' own equals method
return a.equals(b) and b.equals(a)
Expand Down
1 change: 0 additions & 1 deletion ramda/private/_xfBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def init(self):
def result(self, result):
return getAttribute(self.xf, '@@transducer/result')(result)

# pylint: disable=no-self-use
def step(self, result, _input):
raise Exception('Child class should implement this')

Expand Down
5 changes: 1 addition & 4 deletions ramda/where.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@


def inner_where(spec, testObj):
for prop in spec:
if _has(spec, prop) and not spec[prop](getAttribute(testObj, prop)):
return False
return True
return not any((_has(spec, prop) and not spec[prop](getAttribute(testObj, prop))) for prop in spec)


where = _curry2(inner_where)
59 changes: 59 additions & 0 deletions test/test_keysIn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

import unittest

import ramda as R

"""
https://github.com/ramda/ramda/blob/master/test/keysIn.js
"""


class TestKeysIn(unittest.TestCase):
def test_returns_an_array_of_the_given_dict_keys(self):
d = {'a': 100, 'b': [1, 2, 3], 'c': {'x': 200, 'y': 300}, 'd': 'D', 'e': None}
self.assertEqual(['a', 'b', 'c', 'd', 'e'], R.keysIn(d))

def test_returns_an_array_of_the_given_obj_keys(self):
class Obj:
def __init__(self, a, b, c, d, e):
self.a = a
self.b = b
self.c = c
self.d = d
self.e = e
obj = Obj(100, [1, 2, 3], {'x': 200, 'y': 300}, 'D', None)
self.assertEqual(['a', 'b', 'c', 'd', 'e'], R.keysIn(obj))

def test_returns_an_array_of_the_given_obj_with_parent_keys(self):
class Parent:
ps1 = 'parent static 1'
ps2 = 'parent static 2'

def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2

class Child(Parent):
cs1 = 'child static 1'
cs2 = 'child static 2'

def __init__(self, p1, p2, c1, c2):
super().__init__(p1, p2)
self.c1 = c1
self.c2 = c2

child = Child('p1', 'p2', 'c1', 'c2')
self.assertEqual(['cs1', 'cs2', 'ps1', 'ps2', 'p1', 'p2', 'c1', 'c2'], R.keysIn(child))

def test_works_for_primitives(self):
self.assertEqual([], R.keysIn(None))
self.assertEqual([], R.keysIn(0))
self.assertEqual([], R.keysIn(False))
self.assertEqual([], R.keysIn(True))
self.assertEqual([], R.keysIn(''))
self.assertEqual([], R.keysIn([]))
self.assertEqual([], R.keysIn({}))


if __name__ == '__main__':
unittest.main()