Issue 22184: Early detection and reporting of missing lru_cache parameters
diff --git a/Lib/functools.py b/Lib/functools.py
index b8463ad..24fdb16 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -392,6 +392,12 @@
     # The internals of the lru_cache are encapsulated for thread safety and
     # to allow the implementation to change (including a possible C version).
 
+    # Early detection of an erroneous call to @lru_cache without any arguments
+    # resulting in the inner function being passed to maxsize instead of an
+    # integer or None.
+    if maxsize is not None and not isinstance(maxsize, int):
+        raise TypeError('Expected maxsize to be an integer or None')
+
     # Constants shared by all lru cache instances:
     sentinel = object()          # unique object used to signal cache misses
     make_key = _make_key         # build a key from the function arguments
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 75ae7f3..a7e5c7e 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -1070,6 +1070,13 @@
         self.assertEqual(test_func(DoubleEq(2)),    # Trigger a re-entrant __eq__ call
                          DoubleEq(2))               # Verify the correct return value
 
+    def test_early_detection_of_bad_call(self):
+        # Issue #22184
+        with self.assertRaises(TypeError):
+            @functools.lru_cache
+            def f():
+                pass
+
 
 class TestSingleDispatch(unittest.TestCase):
     def test_simple_overloads(self):