{"record":{"id":"37b6ae2a22313df0","repo":"D4Vinci/Scrapling","slug":"callable-filter-function-must-have-at-least-one-ar","errorCode":null,"errorMessage":"Callable filter function must have at least one argument to take `Selector` objects.","messagePattern":"Callable filter function must have at least one argument to take `Selector` objects\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"scrapling/parser.py","lineNumber":743,"sourceCode":"                if not all(map(lambda x: isinstance(x, str), arg)):\n                    raise TypeError(\"Nested Iterables are not accepted, only iterables of tag names are accepted\")\n                tags.update(set(arg))\n\n            elif isinstance(arg, dict):\n                if not all([(isinstance(k, str) and isinstance(v, str)) for k, v in arg.items()]):\n                    raise TypeError(\n                        \"Nested dictionaries are not accepted, only string keys and string values are accepted\"\n                    )\n                attributes.update(arg)\n\n            elif isinstance(arg, re_Pattern):\n                patterns.add(arg)\n\n            elif callable(arg):\n                if len(signature(arg).parameters) > 0:\n                    functions.append(arg)\n                else:\n                    raise TypeError(\n                        \"Callable filter function must have at least one argument to take `Selector` objects.\"\n                    )\n\n            else:\n                raise TypeError(f'Argument with type \"{type(arg)}\" is not accepted, please read the docs.')\n\n        if not all([(isinstance(k, str) and isinstance(v, str)) for k, v in kwargs.items()]):\n            raise TypeError(\"Only string values are accepted for arguments\")\n\n        for attribute_name, value in kwargs.items():\n            # Only replace names for kwargs, replacing them in dictionaries doesn't make sense\n            attribute_name = _whitelisted.get(attribute_name, attribute_name)\n            attributes[attribute_name] = value\n\n        # It's easier and faster to build a selector than traversing the tree\n        tags = tags or set(\"*\")\n        for tag in tags:\n            selector = tag","sourceCodeStart":725,"sourceCodeEnd":761,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/parser.py#L725-L761","documentation":"A callable passed to find_all() takes zero parameters, so it cannot receive the Selector objects it is supposed to filter. scrapling inspects the callable's signature with inspect.signature and requires at least one positional parameter.","triggerScenarios":"find_all(lambda: True) or find_all(some_zero_arg_function). Lambdas with one arg like lambda s: s.attrib.get('x') are fine.","commonSituations":"Refactoring a filter from a constant-returning helper; passing a functools.partial that consumed all positional arguments; passing a class's __init__-less instance method bound with no free parameters left.","solutions":["Add the element parameter to the callable: def keep(s): return s.attrib.get('data-ok') == '1'.","If using functools.partial, ensure at least one positional slot remains free for the Selector.","Note that builtins with optional-only args may also trip the signature check — wrap them in a lambda taking one argument."],"exampleFix":"# before\nselector.find_all(lambda: True)  # TypeError\n\n# after\nselector.find_all(lambda s: True)","handlingStrategy":"validation","validationCode":"from inspect import signature\n\ndef takes_at_least_one_arg(fn) -> bool:\n    try:\n        return len(signature(fn).parameters) > 0\n    except (TypeError, ValueError):\n        return False\n\nassert takes_at_least_one_arg(my_filter), 'filter must accept a Selector argument'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Write filter callables as lambda s: ... from the start so the parameter is never forgotten.","With functools.partial, leave at least one positional parameter unfilled for the Selector."],"tags":["find-all","callable","validation","signature"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}