diff --git a/CHANGELOG.md b/CHANGELOG.md
index af5fb3185bc3729f17d384c60fb0d12697332563..59656364974eb8f7d90b553a18dc0f9f816dd881 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1 +1,3 @@
 # v2.22.1
+
+* added length
\ No newline at end of file
diff --git a/docs/coding/sequences.rst b/docs/coding/sequences.rst
index b374ca6fb05adcfb334c0a254b28486d9167df61..777cd9ad5ac2fb75e715e31fc114174e33a76fb7 100644
--- a/docs/coding/sequences.rst
+++ b/docs/coding/sequences.rst
@@ -11,6 +11,11 @@ Rolling averages
 Standard routines
 =================
 
+length
+------
+
+.. autofunction:: satella.coding.length
+
 IteratorListAdapter
 -------------------
 
diff --git a/satella/__init__.py b/satella/__init__.py
index 15ce3dd0b43eccbfd64a839f84fc376faae078dd..dc7612af3e4095e0a534014b11383a174b4ac77f 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.22.1a1'
+__version__ = '2.22.1'
diff --git a/satella/coding/__init__.py b/satella/coding/__init__.py
index 612957d321d6b21dc52a7360b7a4219211612f49..72369906bb3573798f10f2a4e46f1d937e6bf79d 100644
--- a/satella/coding/__init__.py
+++ b/satella/coding/__init__.py
@@ -16,7 +16,7 @@ from .metaclasses import metaclass_maker, wrap_with, dont_wrap, wrap_property, D
 from .misc import update_if_not_none, update_key_if_none, update_attr_if_none, queue_iterator, \
     update_key_if_not_none, source_to_function, update_key_if_true, \
     get_arguments, call_with_arguments, chain_callables, Closeable, contains, \
-    enum_value
+    enum_value, length
 from .environment import Context
 from .overloading import overload, class_or_instancemethod
 from .recast_exceptions import rethrow_as, silence_excs, catch_exception, log_exceptions, \
@@ -25,7 +25,7 @@ from .expect_exception import expect_exception
 from .deep_compare import assert_equal, InequalityReason, Inequal
 
 __all__ = [
-    'EmptyContextManager', 'Context',
+    'EmptyContextManager', 'Context', 'length',
     'assert_equal', 'InequalityReason', 'Inequal',
     'Closeable', 'contains', 'enum_value', 'reraise_as',
     'expect_exception',
diff --git a/satella/coding/misc.py b/satella/coding/misc.py
index 5bb0092d383a9939f925df4d608355bf6145757a..da3a42d7dfe342923a40ba1e2a7978416fba723f 100644
--- a/satella/coding/misc.py
+++ b/satella/coding/misc.py
@@ -22,6 +22,19 @@ def enum_value(value):
     return value
 
 
+def length(lenable) -> int:
+    """
+    Return length of an item. If it is a generator, exhaust it and return it's length.
+    """
+    try:
+        return len(lenable)
+    except TypeError:
+        i = 0
+        for _ in lenable:
+            i += 1
+        return i
+
+
 def contains(needle, haystack) -> bool:
     """
     A syntactic sugar for the following:
diff --git a/tests/test_coding/test_misc.py b/tests/test_coding/test_misc.py
index 5826fbca5d159578521b1eb9061a1d14f866c9bb..05c89d34c29e81389a954aff4bb0dd769e2607d5 100644
--- a/tests/test_coding/test_misc.py
+++ b/tests/test_coding/test_misc.py
@@ -5,7 +5,7 @@ import unittest
 
 from satella.coding import update_key_if_not_none, overload, class_or_instancemethod, \
     update_key_if_true, get_arguments, call_with_arguments, chain_callables, Closeable, \
-    contains, enum_value, for_argument
+    contains, enum_value, for_argument, length
 from satella.coding.structures import HashableMixin, ComparableEnum
 from satella.coding.transforms import jsonify, intify
 
@@ -99,6 +99,11 @@ class TestCase(unittest.TestCase):
         self.assertRaises(ValueError, lambda: intify(object()))
         self.assertEqual(intify([1, 2, 3]), 3)
 
+    def test_length(self):
+        y = [1, 2, 3]
+        x = (z for z in y)
+        self.assertEqual(length(x, 3))
+
     def test_execute_with_locals(self):
         def fun(a, b, *args, c=None, **kwargs):
             if len(kwargs):
diff --git a/tests/test_coding/test_predicates.py b/tests/test_coding/test_predicates.py
index 9538a8a20396354b45c25602780b2b778355f8dc..4f3a7d05a68bb4c101b9fe7b0dca8ac02a737a0a 100644
--- a/tests/test_coding/test_predicates.py
+++ b/tests/test_coding/test_predicates.py
@@ -124,7 +124,7 @@ class TestPredicates(unittest.TestCase):
         self.assertFalse(p([2, 2]))
 
     def test_len(self):
-        p = x.length() == 2
+        p = x.len_able() == 2
         self.assertTrue(p([1, 2]))
         self.assertFalse(p([]))