{
    "file_diffs": [
        {
            "old_file_content": "# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-\n# vi: set ft=python sts=4 ts=4 sw=4 et:\n### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##\n#\n#   See COPYING file distributed along with the datalad package for the\n#   copyright and license terms.\n#\n### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##g\n\"\"\"Parameter representation\"\"\"\n\n__docformat__ = 'restructuredtext'\n\nimport re\nimport textwrap\nfrom .constraints import expand_contraint_spec\n\n_whitespace_re = re.compile('\\n\\s+|^\\s+')\n\n\nclass Parameter(object):\n    \"\"\"This class shall serve as a representation of a parameter.\n    \"\"\"\n\n    def __init__(self, constraints=None, doc=None, args=None, **kwargs):\n        \"\"\"Add contraints (validator) specifications and a docstring for\n        a parameter.\n\n        Parameters\n        ----------\n        constraints : callable\n          A functor that takes any input value, performs checks or type\n          conversions and finally returns a value that is appropriate for a\n          parameter or raises an exception. This will also be used to set up\n          the ``type`` functionality of argparse.add_argument.\n        doc : str\n          Documentation about the purpose of this parameter.\n        args : tuple or None\n          Any additional positional args for argparser.add_argument. This is\n          most useful for assigned multiple alternative argument names or\n          create positional arguments.\n        **kwargs :\n          Any additional keyword args for argparser.add_argument.\n\n        Examples\n        --------\n        Ensure a parameter is a float\n        >>> from datalad.support.param import Parameter\n        >>> from datalad.support.constraints import (EnsureFloat, EnsureRange,\n        ...                              AltConstraints, Constraints)\n        >>> C = Parameter(constraints=EnsureFloat())\n\n        Ensure a parameter is of type float or None:\n        >>> C = Parameter(constraints=AltConstraints(EnsureFloat(), None))\n\n        Ensure a parameter is None or of type float and lies in the inclusive\n        range (7.0,44.0):\n        >>> C = Parameter(\n        ...         AltConstraints(\n        ...             Constraints(EnsureFloat(),\n        ...                         EnsureRange(min=7.0,max=44.0)),\n        ...             None))\n        \"\"\"\n        self.constraints = expand_contraint_spec(constraints)\n        self._doc = doc\n        self.cmd_args = args\n        self.cmd_kwargs = kwargs\n\n    def get_autodoc(self, name, indent=\"  \", width=70, default=None, has_default=False):\n        \"\"\"Docstring for the parameter to be used in lists of parameters\n\n        Returns\n        -------\n        string or list of strings (if indent is None)\n        \"\"\"\n        paramsdoc = '%s' % name\n        sdoc = None\n        if self.constraints is not None:\n            sdoc = self.constraints.short_description()\n        elif 'action' in self.cmd_kwargs \\\n                and self.cmd_kwargs['action'] in (\"store_true\", \"store_false\"):\n            sdoc = 'bool'\n        if not sdoc is None:\n            if sdoc[0] == '(' and sdoc[-1] == ')':\n                sdoc = sdoc[1:-1]\n            paramsdoc += \" : %s\" % sdoc\n            if has_default:\n                paramsdoc += \", optional\"\n        paramsdoc = [paramsdoc]\n\n        doc = self._doc\n        if doc is None:\n            doc = ''\n        doc.strip()\n        if len(doc) and not doc.endswith('.'):\n            doc += '.'\n        if self.constraints is not None:\n            cdoc = self.constraints.long_description()\n            if cdoc[0] == '(' and cdoc[-1] == ')':\n                cdoc = cdoc[1:-1]\n            addinfo = ''\n            if 'nargs' in self.cmd_kwargs \\\n                    and not self.cmd_kwargs['nargs'] == '?':\n                addinfo = 'list expected, each '\n            doc += ' Constraints: %s%s.' % (addinfo, cdoc)\n        if has_default:\n            doc += \" [Default: %r]\" % (default,)\n        # Explicitly deal with multiple spaces, for some reason\n        # replace_whitespace is non-effective\n        doc = _whitespace_re.sub(' ', doc)\n        paramsdoc += [indent + x\n                      for x in textwrap.wrap(doc, width=width - len(indent),\n                                             replace_whitespace=True)]\n        return '\\n'.join(paramsdoc)\n",
            "new_file_content": "# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-\n# vi: set ft=python sts=4 ts=4 sw=4 et:\n### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##\n#\n#   See COPYING file distributed along with the datalad package for the\n#   copyright and license terms.\n#\n### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##g\n\"\"\"Parameter representation\"\"\"\n\n__docformat__ = 'restructuredtext'\n\nimport re\nimport textwrap\nimport argparse\nfrom inspect import getargspec\n\nfrom .constraints import expand_contraint_spec\n\n_whitespace_re = re.compile('\\n\\s+|^\\s+')\n\n\nclass Parameter(object):\n    \"\"\"This class shall serve as a representation of a parameter.\n    \"\"\"\n\n    # Known keyword arguments which we want to allow to pass over into\n    # argparser.add_argument . Mentioned explicitly, since otherwise\n    # are not verified while working in Python-only API\n    _KNOWN_ARGS = getargspec(argparse.Action.__init__)[0] + ['action']\n\n    def __init__(self, constraints=None, doc=None, args=None, **kwargs):\n        \"\"\"Add contraints (validator) specifications and a docstring for\n        a parameter.\n\n        Parameters\n        ----------\n        constraints : callable\n          A functor that takes any input value, performs checks or type\n          conversions and finally returns a value that is appropriate for a\n          parameter or raises an exception. This will also be used to set up\n          the ``type`` functionality of argparse.add_argument.\n        doc : str\n          Documentation about the purpose of this parameter.\n        args : tuple or None\n          Any additional positional args for argparser.add_argument. This is\n          most useful for assigned multiple alternative argument names or\n          create positional arguments.\n        **kwargs :\n          Any additional keyword args for argparser.add_argument.\n\n        Examples\n        --------\n        Ensure a parameter is a float\n        >>> from datalad.support.param import Parameter\n        >>> from datalad.support.constraints import (EnsureFloat, EnsureRange,\n        ...                              AltConstraints, Constraints)\n        >>> C = Parameter(constraints=EnsureFloat())\n\n        Ensure a parameter is of type float or None:\n        >>> C = Parameter(constraints=AltConstraints(EnsureFloat(), None))\n\n        Ensure a parameter is None or of type float and lies in the inclusive\n        range (7.0,44.0):\n        >>> C = Parameter(\n        ...         AltConstraints(\n        ...             Constraints(EnsureFloat(),\n        ...                         EnsureRange(min=7.0, max=44.0)),\n        ...             None))\n        \"\"\"\n        self.constraints = expand_contraint_spec(constraints)\n        self._doc = doc\n        self.cmd_args = args\n\n        # Verify that no mistyped kwargs present\n        unknown_args = set(kwargs).difference(self._KNOWN_ARGS)\n        if unknown_args:\n            raise ValueError(\n                \"Detected unknown argument(s) for the Parameter: %s.  Known are: %s\"\n                % (', '.join(unknown_args), ', '.join(self._KNOWN_ARGS))\n            )\n        self.cmd_kwargs = kwargs\n\n    def get_autodoc(self, name, indent=\"  \", width=70, default=None, has_default=False):\n        \"\"\"Docstring for the parameter to be used in lists of parameters\n\n        Returns\n        -------\n        string or list of strings (if indent is None)\n        \"\"\"\n        paramsdoc = '%s' % name\n        sdoc = None\n        if self.constraints is not None:\n            sdoc = self.constraints.short_description()\n        elif 'action' in self.cmd_kwargs \\\n                and self.cmd_kwargs['action'] in (\"store_true\", \"store_false\"):\n            sdoc = 'bool'\n        if not sdoc is None:\n            if sdoc[0] == '(' and sdoc[-1] == ')':\n                sdoc = sdoc[1:-1]\n            paramsdoc += \" : %s\" % sdoc\n            if has_default:\n                paramsdoc += \", optional\"\n        paramsdoc = [paramsdoc]\n\n        doc = self._doc\n        if doc is None:\n            doc = ''\n        doc.strip()\n        if len(doc) and not doc.endswith('.'):\n            doc += '.'\n        if self.constraints is not None:\n            cdoc = self.constraints.long_description()\n            if cdoc[0] == '(' and cdoc[-1] == ')':\n                cdoc = cdoc[1:-1]\n            addinfo = ''\n            if 'nargs' in self.cmd_kwargs \\\n                    and not self.cmd_kwargs['nargs'] == '?':\n                addinfo = 'list expected, each '\n            doc += ' Constraints: %s%s.' % (addinfo, cdoc)\n        if has_default:\n            doc += \" [Default: %r]\" % (default,)\n        # Explicitly deal with multiple spaces, for some reason\n        # replace_whitespace is non-effective\n        doc = _whitespace_re.sub(' ', doc)\n        paramsdoc += [indent + x\n                      for x in textwrap.wrap(doc, width=width - len(indent),\n                                             replace_whitespace=True)]\n        return '\\n'.join(paramsdoc)\n",
            "header": {
                "file": {
                    "path": "datalad/support/param.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "da0080533",
                "new_commit_hash": "abdd725d4",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/datalad/support/param.py"
            },
            "plus_file": {
                "path": "b/datalad/support/param.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 12,
                            "length": 6
                        },
                        "new_range": {
                            "start": 12,
                            "length": 9
                        },
                        "section": "__docformat__ = 'restructuredtext'"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "import re",
                                "type": "context"
                            },
                            {
                                "content": "import textwrap",
                                "type": "context"
                            },
                            {
                                "content": "import argparse",
                                "type": "added"
                            },
                            {
                                "content": "from inspect import getargspec",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "from .constraints import expand_contraint_spec",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "_whitespace_re = re.compile('\\n\\s+|^\\s+')",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "datalad/support/param.py",
                            "type": "statement",
                            "name": "",
                            "content": "from inspect import getargspec",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 16,
                            "end_lineno": 16,
                            "parent": null
                        },
                        {
                            "file_name": "datalad/support/param.py",
                            "type": "import",
                            "name": "argparse",
                            "content": "import argparse",
                            "ast_type_str": "Import",
                            "start_lineno": 15,
                            "end_lineno": 15,
                            "parent": null
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 21,
                            "length": 6
                        },
                        "new_range": {
                            "start": 24,
                            "length": 11
                        },
                        "section": "class Parameter(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    \"\"\"This class shall serve as a representation of a parameter.",
                                "type": "context"
                            },
                            {
                                "content": "    \"\"\"",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    # Known keyword arguments which we want to allow to pass over into",
                                "type": "added"
                            },
                            {
                                "content": "    # argparser.add_argument . Mentioned explicitly, since otherwise",
                                "type": "added"
                            },
                            {
                                "content": "    # are not verified while working in Python-only API",
                                "type": "added"
                            },
                            {
                                "content": "    _KNOWN_ARGS = getargspec(argparse.Action.__init__)[0] + ['action']",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def __init__(self, constraints=None, doc=None, args=None, **kwargs):",
                                "type": "context"
                            },
                            {
                                "content": "        \"\"\"Add contraints (validator) specifications and a docstring for",
                                "type": "context"
                            },
                            {
                                "content": "        a parameter.",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "datalad/support/param.py",
                            "type": "class",
                            "name": "Parameter",
                            "content": "class Parameter(object):\n    \"\"\"This class shall serve as a representation of a parameter.\n    \"\"\"\n\n    # Known keyword arguments which we want to allow to pass over into\n    # argparser.add_argument . Mentioned explicitly, since otherwise\n    # are not verified while working in Python-only API\n    _KNOWN_ARGS = getargspec(argparse.Action.__init__)[0] + ['action']\n\n    def __init__(self, constraints=None, doc=None, args=None, **kwargs):\n        \"\"\"Add contraints (validator) specifications and a docstring for\n        a parameter.\n\n        Parameters\n        ----------\n        constraints : callable\n          A functor that takes any input value, performs checks or type\n          conversions and finally returns a value that is appropriate for a\n          parameter or raises an exception. This will also be used to set up\n          the ``type`` functionality of argparse.add_argument.\n        doc : str\n          Documentation about the purpose of this parameter.\n        args : tuple or None\n          Any additional positional args for argparser.add_argument. This is\n          most useful for assigned multiple alternative argument names or\n          create positional arguments.\n        **kwargs :\n          Any additional keyword args for argparser.add_argument.\n\n        Examples\n        --------\n        Ensure a parameter is a float\n        >>> from datalad.support.param import Parameter\n        >>> from datalad.support.constraints import (EnsureFloat, EnsureRange,\n        ...                              AltConstraints, Constraints)\n        >>> C = Parameter(constraints=EnsureFloat())\n\n        Ensure a parameter is of type float or None:\n        >>> C = Parameter(constraints=AltConstraints(EnsureFloat(), None))\n\n        Ensure a parameter is None or of type float and lies in the inclusive\n        range (7.0,44.0):\n        >>> C = Parameter(\n        ...         AltConstraints(\n        ...             Constraints(EnsureFloat(),\n        ...                         EnsureRange(min=7.0, max=44.0)),\n        ...             None))\n        \"\"\"\n        self.constraints = expand_contraint_spec(constraints)\n        self._doc = doc\n        self.cmd_args = args\n\n        # Verify that no mistyped kwargs present\n        unknown_args = set(kwargs).difference(self._KNOWN_ARGS)\n        if unknown_args:\n            raise ValueError(\n                \"Detected unknown argument(s) for the Parameter: %s.  Known are: %s\"\n                % (', '.join(unknown_args), ', '.join(self._KNOWN_ARGS))\n            )\n        self.cmd_kwargs = kwargs\n\n    def get_autodoc(self, name, indent=\"  \", width=70, default=None, has_default=False):\n        \"\"\"Docstring for the parameter to be used in lists of parameters\n\n        Returns\n        -------\n        string or list of strings (if indent is None)\n        \"\"\"\n        paramsdoc = '%s' % name\n        sdoc = None\n        if self.constraints is not None:\n            sdoc = self.constraints.short_description()\n        elif 'action' in self.cmd_kwargs \\\n                and self.cmd_kwargs['action'] in (\"store_true\", \"store_false\"):\n            sdoc = 'bool'\n        if not sdoc is None:\n            if sdoc[0] == '(' and sdoc[-1] == ')':\n                sdoc = sdoc[1:-1]\n            paramsdoc += \" : %s\" % sdoc\n            if has_default:\n                paramsdoc += \", optional\"\n        paramsdoc = [paramsdoc]\n\n        doc = self._doc\n        if doc is None:\n            doc = ''\n        doc.strip()\n        if len(doc) and not doc.endswith('.'):\n            doc += '.'\n        if self.constraints is not None:\n            cdoc = self.constraints.long_description()\n            if cdoc[0] == '(' and cdoc[-1] == ')':\n                cdoc = cdoc[1:-1]\n            addinfo = ''\n            if 'nargs' in self.cmd_kwargs \\\n                    and not self.cmd_kwargs['nargs'] == '?':\n                addinfo = 'list expected, each '\n            doc += ' Constraints: %s%s.' % (addinfo, cdoc)\n        if has_default:\n            doc += \" [Default: %r]\" % (default,)\n        # Explicitly deal with multiple spaces, for some reason\n        # replace_whitespace is non-effective\n        doc = _whitespace_re.sub(' ', doc)\n        paramsdoc += [indent + x\n                      for x in textwrap.wrap(doc, width=width - len(indent),\n                                             replace_whitespace=True)]\n        return '\\n'.join(paramsdoc)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 23,
                            "end_lineno": 129,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 57,
                            "length": 12
                        },
                        "new_range": {
                            "start": 65,
                            "length": 20
                        },
                        "section": "class Parameter(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        >>> C = Parameter(",
                                "type": "context"
                            },
                            {
                                "content": "        ...         AltConstraints(",
                                "type": "context"
                            },
                            {
                                "content": "        ...             Constraints(EnsureFloat(),",
                                "type": "context"
                            },
                            {
                                "content": "        ...                         EnsureRange(min=7.0,max=44.0)),",
                                "type": "deleted"
                            },
                            {
                                "content": "        ...                         EnsureRange(min=7.0, max=44.0)),",
                                "type": "added"
                            },
                            {
                                "content": "        ...             None))",
                                "type": "context"
                            },
                            {
                                "content": "        \"\"\"",
                                "type": "context"
                            },
                            {
                                "content": "        self.constraints = expand_contraint_spec(constraints)",
                                "type": "context"
                            },
                            {
                                "content": "        self._doc = doc",
                                "type": "context"
                            },
                            {
                                "content": "        self.cmd_args = args",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        # Verify that no mistyped kwargs present",
                                "type": "added"
                            },
                            {
                                "content": "        unknown_args = set(kwargs).difference(self._KNOWN_ARGS)",
                                "type": "added"
                            },
                            {
                                "content": "        if unknown_args:",
                                "type": "added"
                            },
                            {
                                "content": "            raise ValueError(",
                                "type": "added"
                            },
                            {
                                "content": "                \"Detected unknown argument(s) for the Parameter: %s.  Known are: %s\"",
                                "type": "added"
                            },
                            {
                                "content": "                % (', '.join(unknown_args), ', '.join(self._KNOWN_ARGS))",
                                "type": "added"
                            },
                            {
                                "content": "            )",
                                "type": "added"
                            },
                            {
                                "content": "        self.cmd_kwargs = kwargs",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def get_autodoc(self, name, indent=\"  \", width=70, default=None, has_default=False):",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "datalad/support/param.py",
                            "type": "class",
                            "name": "Parameter",
                            "content": "class Parameter(object):\n    \"\"\"This class shall serve as a representation of a parameter.\n    \"\"\"\n\n    def __init__(self, constraints=None, doc=None, args=None, **kwargs):\n        \"\"\"Add contraints (validator) specifications and a docstring for\n        a parameter.\n\n        Parameters\n        ----------\n        constraints : callable\n          A functor that takes any input value, performs checks or type\n          conversions and finally returns a value that is appropriate for a\n          parameter or raises an exception. This will also be used to set up\n          the ``type`` functionality of argparse.add_argument.\n        doc : str\n          Documentation about the purpose of this parameter.\n        args : tuple or None\n          Any additional positional args for argparser.add_argument. This is\n          most useful for assigned multiple alternative argument names or\n          create positional arguments.\n        **kwargs :\n          Any additional keyword args for argparser.add_argument.\n\n        Examples\n        --------\n        Ensure a parameter is a float\n        >>> from datalad.support.param import Parameter\n        >>> from datalad.support.constraints import (EnsureFloat, EnsureRange,\n        ...                              AltConstraints, Constraints)\n        >>> C = Parameter(constraints=EnsureFloat())\n\n        Ensure a parameter is of type float or None:\n        >>> C = Parameter(constraints=AltConstraints(EnsureFloat(), None))\n\n        Ensure a parameter is None or of type float and lies in the inclusive\n        range (7.0,44.0):\n        >>> C = Parameter(\n        ...         AltConstraints(\n        ...             Constraints(EnsureFloat(),\n        ...                         EnsureRange(min=7.0,max=44.0)),\n        ...             None))\n        \"\"\"\n        self.constraints = expand_contraint_spec(constraints)\n        self._doc = doc\n        self.cmd_args = args\n        self.cmd_kwargs = kwargs\n\n    def get_autodoc(self, name, indent=\"  \", width=70, default=None, has_default=False):\n        \"\"\"Docstring for the parameter to be used in lists of parameters\n\n        Returns\n        -------\n        string or list of strings (if indent is None)\n        \"\"\"\n        paramsdoc = '%s' % name\n        sdoc = None\n        if self.constraints is not None:\n            sdoc = self.constraints.short_description()\n        elif 'action' in self.cmd_kwargs \\\n                and self.cmd_kwargs['action'] in (\"store_true\", \"store_false\"):\n            sdoc = 'bool'\n        if not sdoc is None:\n            if sdoc[0] == '(' and sdoc[-1] == ')':\n                sdoc = sdoc[1:-1]\n            paramsdoc += \" : %s\" % sdoc\n            if has_default:\n                paramsdoc += \", optional\"\n        paramsdoc = [paramsdoc]\n\n        doc = self._doc\n        if doc is None:\n            doc = ''\n        doc.strip()\n        if len(doc) and not doc.endswith('.'):\n            doc += '.'\n        if self.constraints is not None:\n            cdoc = self.constraints.long_description()\n            if cdoc[0] == '(' and cdoc[-1] == ')':\n                cdoc = cdoc[1:-1]\n            addinfo = ''\n            if 'nargs' in self.cmd_kwargs \\\n                    and not self.cmd_kwargs['nargs'] == '?':\n                addinfo = 'list expected, each '\n            doc += ' Constraints: %s%s.' % (addinfo, cdoc)\n        if has_default:\n            doc += \" [Default: %r]\" % (default,)\n        # Explicitly deal with multiple spaces, for some reason\n        # replace_whitespace is non-effective\n        doc = _whitespace_re.sub(' ', doc)\n        paramsdoc += [indent + x\n                      for x in textwrap.wrap(doc, width=width - len(indent),\n                                             replace_whitespace=True)]\n        return '\\n'.join(paramsdoc)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 20,
                            "end_lineno": 113,
                            "parent": null
                        },
                        {
                            "file_name": "datalad/support/param.py",
                            "type": "method",
                            "name": "Parameter.__init__",
                            "content": "class Parameter(object):\n    \"\"\"This class shall serve as a representation of a parameter.\n    \"\"\"\n\n    def __init__(self, constraints=None, doc=None, args=None, **kwargs):\n        \"\"\"Add contraints (validator) specifications and a docstring for\n        a parameter.\n\n        Parameters\n        ----------\n        constraints : callable\n          A functor that takes any input value, performs checks or type\n          conversions and finally returns a value that is appropriate for a\n          parameter or raises an exception. This will also be used to set up\n          the ``type`` functionality of argparse.add_argument.\n        doc : str\n          Documentation about the purpose of this parameter.\n        args : tuple or None\n          Any additional positional args for argparser.add_argument. This is\n          most useful for assigned multiple alternative argument names or\n          create positional arguments.\n        **kwargs :\n          Any additional keyword args for argparser.add_argument.\n\n        Examples\n        --------\n        Ensure a parameter is a float\n        >>> from datalad.support.param import Parameter\n        >>> from datalad.support.constraints import (EnsureFloat, EnsureRange,\n        ...                              AltConstraints, Constraints)\n        >>> C = Parameter(constraints=EnsureFloat())\n\n        Ensure a parameter is of type float or None:\n        >>> C = Parameter(constraints=AltConstraints(EnsureFloat(), None))\n\n        Ensure a parameter is None or of type float and lies in the inclusive\n        range (7.0,44.0):\n        >>> C = Parameter(\n        ...         AltConstraints(\n        ...             Constraints(EnsureFloat(),\n        ...                         EnsureRange(min=7.0,max=44.0)),\n        ...             None))\n        \"\"\"\n        self.constraints = expand_contraint_spec(constraints)\n        self._doc = doc\n        self.cmd_args = args\n        self.cmd_kwargs = kwargs\n\n    def get_autodoc(self, name, indent=\"  \", width=70, default=None, has_default=False):\n        \"\"\"Docstring for the parameter to be used in lists of parameters\n\n        Returns\n        -------\n        string or list of strings (if indent is None)\n        \"\"\"\n        paramsdoc = '%s' % name\n        sdoc = None\n        if self.constraints is not None:\n            sdoc = self.constraints.short_description()\n        elif 'action' in self.cmd_kwargs \\\n                and self.cmd_kwargs['action'] in (\"store_true\", \"store_false\"):\n            sdoc = 'bool'\n        if not sdoc is None:\n            if sdoc[0] == '(' and sdoc[-1] == ')':\n                sdoc = sdoc[1:-1]\n            paramsdoc += \" : %s\" % sdoc\n            if has_default:\n                paramsdoc += \", optional\"\n        paramsdoc = [paramsdoc]\n\n        doc = self._doc\n        if doc is None:\n            doc = ''\n        doc.strip()\n        if len(doc) and not doc.endswith('.'):\n            doc += '.'\n        if self.constraints is not None:\n            cdoc = self.constraints.long_description()\n            if cdoc[0] == '(' and cdoc[-1] == ')':\n                cdoc = cdoc[1:-1]\n            addinfo = ''\n            if 'nargs' in self.cmd_kwargs \\\n                    and not self.cmd_kwargs['nargs'] == '?':\n                addinfo = 'list expected, each '\n            doc += ' Constraints: %s%s.' % (addinfo, cdoc)\n        if has_default:\n            doc += \" [Default: %r]\" % (default,)\n        # Explicitly deal with multiple spaces, for some reason\n        # replace_whitespace is non-effective\n        doc = _whitespace_re.sub(' ', doc)\n        paramsdoc += [indent + x\n                      for x in textwrap.wrap(doc, width=width - len(indent),\n                                             replace_whitespace=True)]\n        return '\\n'.join(paramsdoc)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 24,
                            "end_lineno": 66,
                            "parent": {
                                "file_name": "datalad/support/param.py",
                                "type": "class",
                                "name": "Parameter",
                                "content": "class Parameter(object):\n    \"\"\"This class shall serve as a representation of a parameter.\n    \"\"\"\n\n    def __init__(self, constraints=None, doc=None, args=None, **kwargs):\n        \"\"\"Add contraints (validator) specifications and a docstring for\n        a parameter.\n\n        Parameters\n        ----------\n        constraints : callable\n          A functor that takes any input value, performs checks or type\n          conversions and finally returns a value that is appropriate for a\n          parameter or raises an exception. This will also be used to set up\n          the ``type`` functionality of argparse.add_argument.\n        doc : str\n          Documentation about the purpose of this parameter.\n        args : tuple or None\n          Any additional positional args for argparser.add_argument. This is\n          most useful for assigned multiple alternative argument names or\n          create positional arguments.\n        **kwargs :\n          Any additional keyword args for argparser.add_argument.\n\n        Examples\n        --------\n        Ensure a parameter is a float\n        >>> from datalad.support.param import Parameter\n        >>> from datalad.support.constraints import (EnsureFloat, EnsureRange,\n        ...                              AltConstraints, Constraints)\n        >>> C = Parameter(constraints=EnsureFloat())\n\n        Ensure a parameter is of type float or None:\n        >>> C = Parameter(constraints=AltConstraints(EnsureFloat(), None))\n\n        Ensure a parameter is None or of type float and lies in the inclusive\n        range (7.0,44.0):\n        >>> C = Parameter(\n        ...         AltConstraints(\n        ...             Constraints(EnsureFloat(),\n        ...                         EnsureRange(min=7.0,max=44.0)),\n        ...             None))\n        \"\"\"\n        self.constraints = expand_contraint_spec(constraints)\n        self._doc = doc\n        self.cmd_args = args\n        self.cmd_kwargs = kwargs\n\n    def get_autodoc(self, name, indent=\"  \", width=70, default=None, has_default=False):\n        \"\"\"Docstring for the parameter to be used in lists of parameters\n\n        Returns\n        -------\n        string or list of strings (if indent is None)\n        \"\"\"\n        paramsdoc = '%s' % name\n        sdoc = None\n        if self.constraints is not None:\n            sdoc = self.constraints.short_description()\n        elif 'action' in self.cmd_kwargs \\\n                and self.cmd_kwargs['action'] in (\"store_true\", \"store_false\"):\n            sdoc = 'bool'\n        if not sdoc is None:\n            if sdoc[0] == '(' and sdoc[-1] == ')':\n                sdoc = sdoc[1:-1]\n            paramsdoc += \" : %s\" % sdoc\n            if has_default:\n                paramsdoc += \", optional\"\n        paramsdoc = [paramsdoc]\n\n        doc = self._doc\n        if doc is None:\n            doc = ''\n        doc.strip()\n        if len(doc) and not doc.endswith('.'):\n            doc += '.'\n        if self.constraints is not None:\n            cdoc = self.constraints.long_description()\n            if cdoc[0] == '(' and cdoc[-1] == ')':\n                cdoc = cdoc[1:-1]\n            addinfo = ''\n            if 'nargs' in self.cmd_kwargs \\\n                    and not self.cmd_kwargs['nargs'] == '?':\n                addinfo = 'list expected, each '\n            doc += ' Constraints: %s%s.' % (addinfo, cdoc)\n        if has_default:\n            doc += \" [Default: %r]\" % (default,)\n        # Explicitly deal with multiple spaces, for some reason\n        # replace_whitespace is non-effective\n        doc = _whitespace_re.sub(' ', doc)\n        paramsdoc += [indent + x\n                      for x in textwrap.wrap(doc, width=width - len(indent),\n                                             replace_whitespace=True)]\n        return '\\n'.join(paramsdoc)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 20,
                                "end_lineno": 113,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "# emacs: -*- mode: python-mode; py-indent-offset: 4; tab-width: 4; indent-tabs-mode: nil -*-\n# ex: set sts=4 ts=4 sw=4 noet:\n# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##\n#\n#   See COPYING file distributed along with the datalad package for the\n#   copyright and license terms.\n#\n# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##\n\"\"\"Test command call wrapper\n\"\"\"\n\nimport re\nfrom nose.tools import assert_is, assert_equal, assert_raises, assert_true\n\nfrom ..support.param import Parameter\nfrom ..support import constraints as cnstr\nfrom ..interface.base import Interface, get_api_name, get_cmdline_command_name\n\nfrom ..utils import swallow_outputs\nfrom .utils import assert_re_in\n\n\nclass Demo(Interface):\n    \"\"\"I am a demo\"\"\"\n    _params_ = dict(\n\n        demoposarg=Parameter(\n            doc=\"demoposdoc\",\n            constraints=cnstr.EnsureInt(),\n            nargs=2),\n\n        demooptposarg1=Parameter(\n            args=('demooptposarg1',),\n            doc=\"demooptposdoc1\",\n            constraints=cnstr.EnsureInt(),\n            nargs='?'),\n\n        demooptposarg2=Parameter(\n            args=('demooptposarg2',),\n            doc=\"demooptposdoc2\",\n            constraints=cnstr.EnsureInt(),\n            nargs='?'),\n\n        demoarg=Parameter(\n            doc=\"demodoc\",\n            constraints=cnstr.EnsureInt()))\n\n    def __call__(self, demoposarg, demooptposarg1=99, demooptposarg2=999, demoarg=100):\n        return demoarg\n\n\ndef test_param():\n    # having a parametr with no information is fine\n    # it doesn't need a name, because it comes from the signatur\n    # of the actual implementation that is described\n    p = Parameter()\n    pname = 'testname'\n    # minimal docstring\n    assert_equal(pname, p.get_autodoc('testname'))\n    doc = 'somedoc'\n    p = Parameter(doc=doc)\n    assert_equal('%s\\n  %s.' % (pname, doc), p.get_autodoc('testname'))\n    # constraints\n    p = Parameter(doc=doc, constraints=cnstr.EnsureInt() | cnstr.EnsureStr())\n    autodoc = p.get_autodoc('testname')\n    assert_true(\"convertible to type 'int'\" in autodoc)\n    assert_true('must be a string' in autodoc)\n    assert_true('int or str' in autodoc)\n\n\ndef test_interface():\n    di = Demo()\n\n    import argparse\n    parser = argparse.ArgumentParser()\n\n    di.setup_parser(parser)\n    with swallow_outputs() as cmo:\n        assert_equal(parser.print_help(), None)\n        assert(cmo.out)\n        assert_equal(cmo.err, '')\n    args = parser.parse_args(['42', '11', '1', '2', '--demoarg', '23'])\n    assert_is(args.demoarg, 23)\n    assert_equal(args.demoposarg, [42, 11])\n    assert_equal(args.demooptposarg1, 1)\n    assert_equal(args.demooptposarg2, 2)\n\n    # wrong type\n    with swallow_outputs() as cmo:\n        assert_raises(SystemExit, parser.parse_args, ['--demoarg', 'abc'])\n        # that is what we dump upon folks atm. TODO: improve reporting of illspecified options\n        assert_re_in(\".*invalid constraint:int value:.*\",\n                     cmo.err, re.DOTALL)\n\n    # missing argument to option\n    with swallow_outputs() as cmo:\n        assert_raises(SystemExit, parser.parse_args, ['--demoarg'])\n        assert_re_in(\".*--demoarg: expected one argument\", cmo.err, re.DOTALL)\n\n    # missing positional argument\n    with swallow_outputs() as cmo:\n        assert_raises(SystemExit, parser.parse_args, [''])\n        # PY2|PY3\n        assert_re_in(\".*error: (too few arguments|the following arguments are required: demoposarg)\",\n                     cmo.err, re.DOTALL)\n\n\ndef test_name_generation():\n    assert_equal(\n        get_api_name((\"some.module\", \"SomeClass\")),\n        'module')\n    assert_equal(\n        get_api_name((\"some.module\", \"SomeClass\", \"cmdline-override\")),\n        'module')\n    assert_equal(\n        get_api_name((\"some.module\",\n                      \"SomeClass\",\n                      \"cmdline_override\",\n                      \"api_override-dont-touch\")),\n        \"api_override-dont-touch\")\n    assert_equal(\n        get_cmdline_command_name((\"some.module_something\", \"SomeClass\")),\n        \"module-something\")\n    assert_equal(\n        get_cmdline_command_name((\n            \"some.module_something\",\n            \"SomeClass\",\n            \"override\")),\n        \"override\")\n    assert_equal(\n        get_cmdline_command_name((\n            \"some.module_something\",\n            \"SomeClass\",\n            \"override\",\n            \"api_ignore\")),\n        \"override\")\n",
            "new_file_content": "# emacs: -*- mode: python-mode; py-indent-offset: 4; tab-width: 4; indent-tabs-mode: nil -*-\n# ex: set sts=4 ts=4 sw=4 noet:\n# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##\n#\n#   See COPYING file distributed along with the datalad package for the\n#   copyright and license terms.\n#\n# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##\n\"\"\"Test command call wrapper\n\"\"\"\n\nimport re\nfrom nose.tools import assert_is, assert_equal, assert_raises, assert_true\n\nfrom ..support.param import Parameter\nfrom ..support import constraints as cnstr\nfrom ..interface.base import Interface, get_api_name, get_cmdline_command_name\n\nfrom ..utils import swallow_outputs\nfrom .utils import assert_re_in\nfrom .utils import assert_in\n\n\nclass Demo(Interface):\n    \"\"\"I am a demo\"\"\"\n    _params_ = dict(\n\n        demoposarg=Parameter(\n            doc=\"demoposdoc\",\n            constraints=cnstr.EnsureInt(),\n            nargs=2),\n\n        demooptposarg1=Parameter(\n            args=('demooptposarg1',),\n            doc=\"demooptposdoc1\",\n            constraints=cnstr.EnsureInt(),\n            nargs='?'),\n\n        demooptposarg2=Parameter(\n            args=('demooptposarg2',),\n            doc=\"demooptposdoc2\",\n            constraints=cnstr.EnsureInt(),\n            nargs='?'),\n\n        demoarg=Parameter(\n            doc=\"demodoc\",\n            constraints=cnstr.EnsureInt()))\n\n    def __call__(self, demoposarg, demooptposarg1=99, demooptposarg2=999, demoarg=100):\n        return demoarg\n\n\ndef test_param():\n    # having a parametr with no information is fine\n    # it doesn't need a name, because it comes from the signatur\n    # of the actual implementation that is described\n    p = Parameter()\n    pname = 'testname'\n    # minimal docstring\n    assert_equal(pname, p.get_autodoc('testname'))\n    doc = 'somedoc'\n    p = Parameter(doc=doc)\n    assert_equal('%s\\n  %s.' % (pname, doc), p.get_autodoc('testname'))\n    # constraints\n    p = Parameter(doc=doc, constraints=cnstr.EnsureInt() | cnstr.EnsureStr())\n    autodoc = p.get_autodoc('testname')\n    assert_true(\"convertible to type 'int'\" in autodoc)\n    assert_true('must be a string' in autodoc)\n    assert_true('int or str' in autodoc)\n\n    with assert_raises(ValueError) as cmr:\n        Parameter(unknown_arg=123)\n    assert_in('Detected unknown argument(s) for the Parameter: unknown_arg',\n              str(cmr.exception))\n\n\ndef test_interface():\n    di = Demo()\n\n    import argparse\n    parser = argparse.ArgumentParser()\n\n    di.setup_parser(parser)\n    with swallow_outputs() as cmo:\n        assert_equal(parser.print_help(), None)\n        assert(cmo.out)\n        assert_equal(cmo.err, '')\n    args = parser.parse_args(['42', '11', '1', '2', '--demoarg', '23'])\n    assert_is(args.demoarg, 23)\n    assert_equal(args.demoposarg, [42, 11])\n    assert_equal(args.demooptposarg1, 1)\n    assert_equal(args.demooptposarg2, 2)\n\n    # wrong type\n    with swallow_outputs() as cmo:\n        assert_raises(SystemExit, parser.parse_args, ['--demoarg', 'abc'])\n        # that is what we dump upon folks atm. TODO: improve reporting of illspecified options\n        assert_re_in(\".*invalid constraint:int value:.*\",\n                     cmo.err, re.DOTALL)\n\n    # missing argument to option\n    with swallow_outputs() as cmo:\n        assert_raises(SystemExit, parser.parse_args, ['--demoarg'])\n        assert_re_in(\".*--demoarg: expected one argument\", cmo.err, re.DOTALL)\n\n    # missing positional argument\n    with swallow_outputs() as cmo:\n        assert_raises(SystemExit, parser.parse_args, [''])\n        # PY2|PY3\n        assert_re_in(\".*error: (too few arguments|the following arguments are required: demoposarg)\",\n                     cmo.err, re.DOTALL)\n\n\ndef test_name_generation():\n    assert_equal(\n        get_api_name((\"some.module\", \"SomeClass\")),\n        'module')\n    assert_equal(\n        get_api_name((\"some.module\", \"SomeClass\", \"cmdline-override\")),\n        'module')\n    assert_equal(\n        get_api_name((\"some.module\",\n                      \"SomeClass\",\n                      \"cmdline_override\",\n                      \"api_override-dont-touch\")),\n        \"api_override-dont-touch\")\n    assert_equal(\n        get_cmdline_command_name((\"some.module_something\", \"SomeClass\")),\n        \"module-something\")\n    assert_equal(\n        get_cmdline_command_name((\n            \"some.module_something\",\n            \"SomeClass\",\n            \"override\")),\n        \"override\")\n    assert_equal(\n        get_cmdline_command_name((\n            \"some.module_something\",\n            \"SomeClass\",\n            \"override\",\n            \"api_ignore\")),\n        \"override\")\n",
            "header": {
                "file": {
                    "path": "datalad/tests/test_interface.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "a3d42dd8d",
                "new_commit_hash": "a3cf55edd",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/datalad/tests/test_interface.py"
            },
            "plus_file": {
                "path": "b/datalad/tests/test_interface.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 18,
                            "length": 6
                        },
                        "new_range": {
                            "start": 18,
                            "length": 7
                        },
                        "section": "from ..interface.base import Interface, get_api_name, get_cmdline_command_name"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "from ..utils import swallow_outputs",
                                "type": "context"
                            },
                            {
                                "content": "from .utils import assert_re_in",
                                "type": "context"
                            },
                            {
                                "content": "from .utils import assert_in",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "class Demo(Interface):",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "datalad/tests/test_interface.py",
                            "type": "statement",
                            "name": "",
                            "content": "from .utils import assert_in",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 21,
                            "end_lineno": 21,
                            "parent": null
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 67,
                            "length": 6
                        },
                        "new_range": {
                            "start": 68,
                            "length": 11
                        },
                        "section": "def test_param():"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    assert_true('must be a string' in autodoc)",
                                "type": "context"
                            },
                            {
                                "content": "    assert_true('int or str' in autodoc)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    with assert_raises(ValueError) as cmr:",
                                "type": "added"
                            },
                            {
                                "content": "        Parameter(unknown_arg=123)",
                                "type": "added"
                            },
                            {
                                "content": "    assert_in('Detected unknown argument(s) for the Parameter: unknown_arg',",
                                "type": "added"
                            },
                            {
                                "content": "              str(cmr.exception))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "def test_interface():",
                                "type": "context"
                            },
                            {
                                "content": "    di = Demo()",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "datalad/tests/test_interface.py",
                            "type": "function",
                            "name": "test_param",
                            "content": "def test_param():\n    # having a parametr with no information is fine\n    # it doesn't need a name, because it comes from the signatur\n    # of the actual implementation that is described\n    p = Parameter()\n    pname = 'testname'\n    # minimal docstring\n    assert_equal(pname, p.get_autodoc('testname'))\n    doc = 'somedoc'\n    p = Parameter(doc=doc)\n    assert_equal('%s\\n  %s.' % (pname, doc), p.get_autodoc('testname'))\n    # constraints\n    p = Parameter(doc=doc, constraints=cnstr.EnsureInt() | cnstr.EnsureStr())\n    autodoc = p.get_autodoc('testname')\n    assert_true(\"convertible to type 'int'\" in autodoc)\n    assert_true('must be a string' in autodoc)\n    assert_true('int or str' in autodoc)\n\n    with assert_raises(ValueError) as cmr:\n        Parameter(unknown_arg=123)\n    assert_in('Detected unknown argument(s) for the Parameter: unknown_arg',\n              str(cmr.exception))",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 53,
                            "end_lineno": 74,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "8567dc58f2cf43018a56ed7264929241dfe09dfb^",
    "new_commit_hash": "8567dc58f2cf43018a56ed7264929241dfe09dfb",
    "commit_message": "Merge pull request #621 from yarikoptic/enh-check-params\n\nENH: catch misspecified parameter early",
    "commit_date": "2016-07-08T07:23:26+02:00",
    "metadata": {}
}
{
    "repo_name": "datalad",
    "new_commit_hash": "8567dc58f2cf43018a56ed7264929241dfe09dfb",
    "test_file_codes": [
        "# emacs: -*- mode: python-mode; py-indent-offset: 4; tab-width: 4; indent-tabs-mode: nil -*-\n# ex: set sts=4 ts=4 sw=4 noet:\n# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##\n#\n#   See COPYING file distributed along with the datalad package for the\n#   copyright and license terms.\n#\n# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##\n\"\"\"Test command call wrapper\n\"\"\"\n\nimport re\nfrom nose.tools import assert_is, assert_equal, assert_raises, assert_true\n\nfrom datalad.support.param import Parameter\nfrom datalad.support import constraints as cnstr\nfrom datalad.interface.base import Interface, get_api_name, get_cmdline_command_name\n\nfrom datalad.utils import swallow_outputs\nfrom datalad.tests.utils import assert_re_in\nfrom datalad.tests.utils import assert_in\n\n\nclass Demo(Interface):\n    \"\"\"I am a demo\"\"\"\n    _params_ = dict(\n\n        demoposarg=Parameter(\n            doc=\"demoposdoc\",\n            constraints=cnstr.EnsureInt(),\n            nargs=2),\n\n        demooptposarg1=Parameter(\n            args=('demooptposarg1',),\n            doc=\"demooptposdoc1\",\n            constraints=cnstr.EnsureInt(),\n            nargs='?'),\n\n        demooptposarg2=Parameter(\n            args=('demooptposarg2',),\n            doc=\"demooptposdoc2\",\n            constraints=cnstr.EnsureInt(),\n            nargs='?'),\n\n        demoarg=Parameter(\n            doc=\"demodoc\",\n            constraints=cnstr.EnsureInt()))\n\n    def __call__(self, demoposarg, demooptposarg1=99, demooptposarg2=999, demoarg=100):\n        return demoarg\n\n\ndef test_param():\n    # having a parametr with no information is fine\n    # it doesn't need a name, because it comes from the signatur\n    # of the actual implementation that is described\n    p = Parameter()\n    pname = 'testname'\n    # minimal docstring\n    assert_equal(pname, p.get_autodoc('testname'))\n    doc = 'somedoc'\n    p = Parameter(doc=doc)\n    assert_equal('%s\\n  %s.' % (pname, doc), p.get_autodoc('testname'))\n    # constraints\n    p = Parameter(doc=doc, constraints=cnstr.EnsureInt() | cnstr.EnsureStr())\n    autodoc = p.get_autodoc('testname')\n    assert_true(\"convertible to type 'int'\" in autodoc)\n    assert_true('must be a string' in autodoc)\n    assert_true('int or str' in autodoc)\n\n    with assert_raises(ValueError) as cmr:\n        Parameter(unknown_arg=123)\n    assert_in('Detected unknown argument(s) for the Parameter: unknown_arg',\n              str(cmr.exception))\n\n\ndef test_interface():\n    di = Demo()\n\n    import argparse\n    parser = argparse.ArgumentParser()\n\n    di.setup_parser(parser)\n    with swallow_outputs() as cmo:\n        assert_equal(parser.print_help(), None)\n        assert(cmo.out)\n        assert_equal(cmo.err, '')\n    args = parser.parse_args(['42', '11', '1', '2', '--demoarg', '23'])\n    assert_is(args.demoarg, 23)\n    assert_equal(args.demoposarg, [42, 11])\n    assert_equal(args.demooptposarg1, 1)\n    assert_equal(args.demooptposarg2, 2)\n\n    # wrong type\n    with swallow_outputs() as cmo:\n        assert_raises(SystemExit, parser.parse_args, ['--demoarg', 'abc'])\n        # that is what we dump upon folks atm. TODO: improve reporting of illspecified options\n        assert_re_in(\".*invalid constraint:int value:.*\",\n                     cmo.err, re.DOTALL)\n\n    # missing argument to option\n    with swallow_outputs() as cmo:\n        assert_raises(SystemExit, parser.parse_args, ['--demoarg'])\n        assert_re_in(\".*--demoarg: expected one argument\", cmo.err, re.DOTALL)\n\n    # missing positional argument\n    with swallow_outputs() as cmo:\n        assert_raises(SystemExit, parser.parse_args, [''])\n        # PY2|PY3\n        assert_re_in(\".*error: (too few arguments|the following arguments are required: demoposarg)\",\n                     cmo.err, re.DOTALL)\n\n\ndef test_name_generation():\n    assert_equal(\n        get_api_name((\"some.module\", \"SomeClass\")),\n        'module')\n    assert_equal(\n        get_api_name((\"some.module\", \"SomeClass\", \"cmdline-override\")),\n        'module')\n    assert_equal(\n        get_api_name((\"some.module\",\n                      \"SomeClass\",\n                      \"cmdline_override\",\n                      \"api_override-dont-touch\")),\n        \"api_override-dont-touch\")\n    assert_equal(\n        get_cmdline_command_name((\"some.module_something\", \"SomeClass\")),\n        \"module-something\")\n    assert_equal(\n        get_cmdline_command_name((\n            \"some.module_something\",\n            \"SomeClass\",\n            \"override\")),\n        \"override\")\n    assert_equal(\n        get_cmdline_command_name((\n            \"some.module_something\",\n            \"SomeClass\",\n            \"override\",\n            \"api_ignore\")),\n        \"override\")\n",
        "import pytest\nimport tempfile\nimport os\n\n\n@pytest.fixture\ndef path():\n    with tempfile.TemporaryDirectory() as tmpdir:\n        yield tmpdir\n\n\n@pytest.fixture(autouse=True)\ndef setup_git_config():\n    with tempfile.TemporaryDirectory() as home:\n        old_home = os.environ.get(\"HOME\")\n        os.environ[\"HOME\"] = home\n        os.system('git config --global user.name \"DataLad Tester\"')\n        os.system('git config --global user.email \"test@example.com\"')\n        yield\n        if old_home:\n            os.environ[\"HOME\"] = old_home\n"
    ],
    "test_file_names": [
        "test_1.py",
        "conftest.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "Starting Datalad installation attempts...\nVerifying installation...\n❌ Verification failed\nPython 3.9 installation failed, trying Python 3.7...\nVerifying installation...\nDatalad version: 0.2.3.dev57\n✅ Installation successful!\nSuccessfully installed Datalad using Python 3.7\n",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 25 packages in 122ms\nInstalled 25 packages in 4.57s\n + coverage==7.6.10\n + docopt==0.6.2\n + exceptiongroup==1.2.2\n + grabbit==0.2.6\n + importlib-resources==6.4.5\n + iniconfig==2.0.0\n + nibabel==5.3.2\n + num2words==0.5.14\n + numpy==2.0.2\n + packaging==24.2\n + pandas==2.2.3\n + patsy==1.0.1\n + pluggy==1.5.0\n + pybids==0.6.5\n + pytest==8.3.4\n + pytest-cov==6.0.0\n + python-dateutil==2.9.0.post0\n + pytz==2024.2\n + scipy==1.13.1\n + setuptools==75.6.0\n + six==1.17.0\n + tomli==2.2.1\n + typing-extensions==4.12.2\n + tzdata==2024.2\n + zipp==3.21.0\nerror: The build backend returned an error\n  Caused by: Call to `setuptools.build_meta:__legacy__.build_editable` failed (exit status: 1)\n\n[stderr]\nTraceback (most recent call last):\n  File \"<string>\", line 14, in <module>\n  File \"/home/gcpuser/.cache/uv/builds-v0/.tmp6IWXBH/lib/python3.9/site-packages/setuptools/build_meta.py\", line 483, in get_requires_for_build_editable\n    return self.get_requires_for_build_wheel(config_settings)\n  File \"/home/gcpuser/.cache/uv/builds-v0/.tmp6IWXBH/lib/python3.9/site-packages/setuptools/build_meta.py\", line 334, in get_requires_for_build_wheel\n    return self._get_build_requires(config_settings, requirements=[])\n  File \"/home/gcpuser/.cache/uv/builds-v0/.tmp6IWXBH/lib/python3.9/site-packages/setuptools/build_meta.py\", line 304, in _get_build_requires\n    self.run_setup()\n  File \"/home/gcpuser/.cache/uv/builds-v0/.tmp6IWXBH/lib/python3.9/site-packages/setuptools/build_meta.py\", line 522, in run_setup\n    super().run_setup(setup_script=setup_script)\n  File \"/home/gcpuser/.cache/uv/builds-v0/.tmp6IWXBH/lib/python3.9/site-packages/setuptools/build_meta.py\", line 320, in run_setup\n    exec(code, locals())\n  File \"<string>\", line 39, in <module>\nAttributeError: module 'platform' has no attribute 'dist'\n\nhint: This usually indicates a problem with the package or the build environment.\nerror: The build backend returned an error\n  Caused by: Call to `setuptools.build_meta:__legacy__.build_editable` failed (exit status: 1)\n\n[stderr]\nTraceback (most recent call last):\n  File \"<string>\", line 14, in <module>\n  File \"/home/gcpuser/.cache/uv/builds-v0/.tmpDtMSDM/lib/python3.9/site-packages/setuptools/build_meta.py\", line 483, in get_requires_for_build_editable\n    return self.get_requires_for_build_wheel(config_settings)\n  File \"/home/gcpuser/.cache/uv/builds-v0/.tmpDtMSDM/lib/python3.9/site-packages/setuptools/build_meta.py\", line 334, in get_requires_for_build_wheel\n    return self._get_build_requires(config_settings, requirements=[])\n  File \"/home/gcpuser/.cache/uv/builds-v0/.tmpDtMSDM/lib/python3.9/site-packages/setuptools/build_meta.py\", line 304, in _get_build_requires\n    self.run_setup()\n  File \"/home/gcpuser/.cache/uv/builds-v0/.tmpDtMSDM/lib/python3.9/site-packages/setuptools/build_meta.py\", line 522, in run_setup\n    super().run_setup(setup_script=setup_script)\n  File \"/home/gcpuser/.cache/uv/builds-v0/.tmpDtMSDM/lib/python3.9/site-packages/setuptools/build_meta.py\", line 320, in run_setup\n    exec(code, locals())\n  File \"<string>\", line 39, in <module>\nAttributeError: module 'platform' has no attribute 'dist'\n\nhint: This usually indicates a problem with the package or the build environment.\nTraceback (most recent call last):\n  File \"<string>\", line 1, in <module>\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/datalad_8567dc58f2cf43018a56ed7264929241dfe09dfb/datalad/__init__.py\", line 20, in <module>\n    from .config import ConfigManager\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/datalad_8567dc58f2cf43018a56ed7264929241dfe09dfb/datalad/config.py\", line 17, in <module>\n    from appdirs import AppDirs\nModuleNotFoundError: No module named 'appdirs'\nUsing CPython 3.7.9\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 26 packages in 360ms\nInstalled 26 packages in 5.30s\n + bids==0.0\n + coverage==7.2.7\n + docopt==0.6.2\n + exceptiongroup==1.2.2\n + fasteners==0.19\n + grabbit==0.2.6\n + importlib-metadata==6.7.0\n + iniconfig==2.0.0\n + nibabel==4.0.2\n + num2words==0.5.14\n + numpy==1.21.6\n + packaging==24.0\n + pandas==1.3.5\n + patsy==1.0.1\n + pluggy==1.2.0\n + pybids==0.6.5\n + pytest==7.4.4\n + pytest-cov==4.1.0\n + python-dateutil==2.9.0.post0\n + pytz==2024.2\n + scipy==1.7.3\n + setuptools==68.0.0\n + six==1.17.0\n + tomli==2.0.1\n + typing-extensions==4.7.1\n + zipp==3.15.0\nResolved 67 packages in 2.45s\nPrepared 1 package in 2.34s\nInstalled 61 packages in 84ms\n + appdirs==1.4.4\n + attrs==24.2.0\n + automat==22.10.0\n + beautifulsoup4==4.12.3\n + boto==2.49.0\n + certifi==2024.12.14\n + cffi==1.15.1\n + charset-normalizer==3.4.1\n + constantly==15.1.0\n + cryptography==44.0.0\n + cssselect==1.2.0\n + datalad==0.2.3 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/datalad_8567dc58f2cf43018a56ed7264929241dfe09dfb)\n + filelock==3.12.2\n + gitdb==4.0.12\n + gitpython==3.1.44\n + httpretty==1.1.4\n + humanize==4.6.0\n + hyperlink==21.0.0\n + idna==3.10\n + importlib-resources==5.12.0\n + incremental==22.10.0\n + itemadapter==0.8.0\n + itemloaders==1.1.0\n + jaraco-classes==3.2.3\n + jeepney==0.8.0\n + jmespath==1.0.1\n + keyring==24.1.1\n + keyrings-alt==4.2.0\n + lxml==5.3.0\n + mock==5.1.0\n + more-itertools==9.1.0\n + msgpack-python==0.5.6\n + multidict==6.0.5\n + nose==1.3.7\n + parsel==1.8.1\n + patool==1.12\n + protego==0.3.0\n + pyasn1==0.5.1\n + pyasn1-modules==0.3.0\n + pycparser==2.21\n + pydispatcher==2.0.7\n + pyopenssl==24.3.0\n + pyyaml==6.0.1\n + queuelib==1.6.2\n + requests==2.31.0\n + requests-file==2.1.0\n + scrapy==2.9.0\n + secretstorage==3.3.3\n + service-identity==21.1.0\n + smmap==5.0.2\n + soupsieve==2.4.1\n + testtools==2.7.1\n + tldextract==4.0.0\n + tqdm==4.67.1\n + twisted==23.8.0\n + urllib3==2.0.7\n + vcrpy==4.3.0\n + w3lib==2.1.2\n + wrapt==1.16.0\n + yarl==1.9.4\n + zope-interface==6.4.post2\nAudited 1 package in 4ms\n/home/gcpuser/buckets/local_repoeval_bucket/repos/datalad_8567dc58f2cf43018a56ed7264929241dfe09dfb/.venv/lib/python3.7/site-packages/urllib3/__init__.py:38: NotOpenSSLWarning: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 3.1.4'. See: https://github.com/urllib3/urllib3/issues/3020\n  exceptions.NotOpenSSLWarning,\n",
    "new_commit_res_code": 0,
    "new_commit_res_stdout": "============================= test session starts ==============================\nplatform linux -- Python 3.7.9, pytest-7.4.4, pluggy-1.2.0\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/datalad_8567dc58f2cf43018a56ed7264929241dfe09dfb\nplugins: cov-4.1.0\ncollected 3 items\n\nr2e_tests/test_1.py ...                                                  [100%]\n\n==================================== PASSES ====================================\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::test_param\nPASSED r2e_tests/test_1.py::test_interface\nPASSED r2e_tests/test_1.py::test_name_generation\n============================== 3 passed in 0.97s ===============================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts ==============================\nplatform linux -- Python 3.7.9, pytest-7.4.4, pluggy-1.2.0\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/datalad_8567dc58f2cf43018a56ed7264929241dfe09dfb\nplugins: cov-4.1.0\ncollected 3 items\n\nr2e_tests/test_1.py F..                                                  [100%]\n\n=================================== FAILURES ===================================\n__________________________________ test_param __________________________________\n\n    def test_param():\n        # having a parametr with no information is fine\n        # it doesn't need a name, because it comes from the signatur\n        # of the actual implementation that is described\n        p = Parameter()\n        pname = 'testname'\n        # minimal docstring\n        assert_equal(pname, p.get_autodoc('testname'))\n        doc = 'somedoc'\n        p = Parameter(doc=doc)\n        assert_equal('%s\\n  %s.' % (pname, doc), p.get_autodoc('testname'))\n        # constraints\n        p = Parameter(doc=doc, constraints=cnstr.EnsureInt() | cnstr.EnsureStr())\n        autodoc = p.get_autodoc('testname')\n        assert_true(\"convertible to type 'int'\" in autodoc)\n        assert_true('must be a string' in autodoc)\n        assert_true('int or str' in autodoc)\n    \n        with assert_raises(ValueError) as cmr:\n>           Parameter(unknown_arg=123)\n\nr2e_tests/test_1.py:72: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n../../../../.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib/python3.7/unittest/case.py:203: in __exit__\n    self._raiseFailure(\"{} not raised\".format(exc_name))\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <unittest.case._AssertRaisesContext object at 0x74b7a1950c10>\nstandardMsg = 'ValueError not raised'\n\n    def _raiseFailure(self, standardMsg):\n        msg = self.test_case._formatMessage(self.msg, standardMsg)\n>       raise self.test_case.failureException(msg)\nE       AssertionError: ValueError not raised\n\n../../../../.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib/python3.7/unittest/case.py:135: AssertionError\n==================================== PASSES ====================================\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::test_interface\nPASSED r2e_tests/test_1.py::test_name_generation\nFAILED r2e_tests/test_1.py::test_param - AssertionError: ValueError not raised\n========================= 1 failed, 2 passed in 0.82s ==========================\n",
    "old_commit_res_stderr": ""
}
datalad/support/param.py datalad/tests/test_interface.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title**: Parameter Class Fails to Validate Unknown Keyword Arguments

**Description**:
When initializing a `Parameter` with an unrecognized keyword argument, the system does not raise an error. This allows misspelled or unintended parameters to be passed silently, potentially leading to unexpected behavior later in the application.

**Example Code**:
```python
p = Parameter(unknown_arg=123)
```

**Expected Behavior**:
Initializing a `Parameter` with an unknown keyword argument should raise a `ValueError` that clearly indicates which arguments are unrecognized.

**Actual Behavior**:
No exception is raised when an unknown keyword argument is provided, which can result in overlooked bugs due to parameter misspecification.

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### datalad/support/param.py
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
#
#   See COPYING file distributed along with the datalad package for the
#   copyright and license terms.
#
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##g
"""Parameter representation"""

__docformat__ = 'restructuredtext'

import re
import textwrap
from .constraints import expand_contraint_spec

_whitespace_re = re.compile('\n\s+|^\s+')


class Parameter(object):
    """This class shall serve as a representation of a parameter.
    """

    def __init__(self, constraints=None, doc=None, args=None, **kwargs):
        """Add contraints (validator) specifications and a docstring for
        a parameter.

        Parameters
        ----------
        constraints : callable
          A functor that takes any input value, performs checks or type
          conversions and finally returns a value that is appropriate for a
          parameter or raises an exception. This will also be used to set up
          the ``type`` functionality of argparse.add_argument.
        doc : str
          Documentation about the purpose of this parameter.
        args : tuple or None
          Any additional positional args for argparser.add_argument. This is
          most useful for assigned multiple alternative argument names or
          create positional arguments.
        **kwargs :
          Any additional keyword args for argparser.add_argument.

        Examples
        --------
        Ensure a parameter is a float
        >>> from datalad.support.param import Parameter
        >>> from datalad.support.constraints import (EnsureFloat, EnsureRange,
        ...                              AltConstraints, Constraints)
        >>> C = Parameter(constraints=EnsureFloat())

        Ensure a parameter is of type float or None:
        >>> C = Parameter(constraints=AltConstraints(EnsureFloat(), None))

        Ensure a parameter is None or of type float and lies in the inclusive
        range (7.0,44.0):
        >>> C = Parameter(
        ...         AltConstraints(
        ...             Constraints(EnsureFloat(),
        ...                         EnsureRange(min=7.0,max=44.0)),
        ...             None))
        """
        self.constraints = expand_contraint_spec(constraints)
        self._doc = doc
        self.cmd_args = args
        self.cmd_kwargs = kwargs

    def get_autodoc(self, name, indent="  ", width=70, default=None, has_default=False):
        """Docstring for the parameter to be used in lists of parameters

        Returns
        -------
        string or list of strings (if indent is None)
        """
        paramsdoc = '%s' % name
        sdoc = None
        if self.constraints is not None:
            sdoc = self.constraints.short_description()
        elif 'action' in self.cmd_kwargs \
                and self.cmd_kwargs['action'] in ("store_true", "store_false"):
            sdoc = 'bool'
        if not sdoc is None:
            if sdoc[0] == '(' and sdoc[-1] == ')':
                sdoc = sdoc[1:-1]
            paramsdoc += " : %s" % sdoc
            if has_default:
                paramsdoc += ", optional"
        paramsdoc = [paramsdoc]

        doc = self._doc
        if doc is None:
            doc = ''
        doc.strip()
        if len(doc) and not doc.endswith('.'):
            doc += '.'
        if self.constraints is not None:
            cdoc = self.constraints.long_description()
            if cdoc[0] == '(' and cdoc[-1] == ')':
                cdoc = cdoc[1:-1]
            addinfo = ''
            if 'nargs' in self.cmd_kwargs \
                    and not self.cmd_kwargs['nargs'] == '?':
                addinfo = 'list expected, each '
            doc += ' Constraints: %s%s.' % (addinfo, cdoc)
        if has_default:
            doc += " [Default: %r]" % (default,)
        # Explicitly deal with multiple spaces, for some reason
        # replace_whitespace is non-effective
        doc = _whitespace_re.sub(' ', doc)
        paramsdoc += [indent + x
                      for x in textwrap.wrap(doc, width=width - len(indent),
                                             replace_whitespace=True)]
        return '\n'.join(paramsdoc)

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]
**Title**: Parameter Class Fails to Validate Unknown Keyword Arguments

**Description**:
When initializing a `Parameter` with an unrecognized keyword argument, the system does not raise an error. This allows misspelled or unintended parameters to be passed silently, potentially leading to unexpected behavior later in the application.

**Example Code**:
```python
p = Parameter(unknown_arg=123)
```

**Expected Behavior**:
Initializing a `Parameter` with an unknown keyword argument should raise a `ValueError` that clearly indicates which arguments are unrecognized.

**Actual Behavior**:
No exception is raised when an unknown keyword argument is provided, which can result in overlooked bugs due to parameter misspecification.

[/ISSUE]
{
    "test_param": "PASSED",
    "test_interface": "PASSED",
    "test_name_generation": "PASSED"
}
diff --git a/datalad/support/param.py b/datalad/support/param.py
index da0080533..abdd725d4 100644
--- a/datalad/support/param.py
+++ b/datalad/support/param.py
@@ -12,6 +12,9 @@ __docformat__ = 'restructuredtext'
 
 import re
 import textwrap
+import argparse
+from inspect import getargspec
+
 from .constraints import expand_contraint_spec
 
 _whitespace_re = re.compile('\n\s+|^\s+')
@@ -21,6 +24,11 @@ class Parameter(object):
     """This class shall serve as a representation of a parameter.
     """
 
+    # Known keyword arguments which we want to allow to pass over into
+    # argparser.add_argument . Mentioned explicitly, since otherwise
+    # are not verified while working in Python-only API
+    _KNOWN_ARGS = getargspec(argparse.Action.__init__)[0] + ['action']
+
     def __init__(self, constraints=None, doc=None, args=None, **kwargs):
         """Add contraints (validator) specifications and a docstring for
         a parameter.
@@ -57,12 +65,20 @@ class Parameter(object):
         >>> C = Parameter(
         ...         AltConstraints(
         ...             Constraints(EnsureFloat(),
-        ...                         EnsureRange(min=7.0,max=44.0)),
+        ...                         EnsureRange(min=7.0, max=44.0)),
         ...             None))
         """
         self.constraints = expand_contraint_spec(constraints)
         self._doc = doc
         self.cmd_args = args
+
+        # Verify that no mistyped kwargs present
+        unknown_args = set(kwargs).difference(self._KNOWN_ARGS)
+        if unknown_args:
+            raise ValueError(
+                "Detected unknown argument(s) for the Parameter: %s.  Known are: %s"
+                % (', '.join(unknown_args), ', '.join(self._KNOWN_ARGS))
+            )
         self.cmd_kwargs = kwargs
 
     def get_autodoc(self, name, indent="  ", width=70, default=None, has_default=False):

{"datalad/support/param.py": "# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-\n# vi: set ft=python sts=4 ts=4 sw=4 et:\n### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##\n#\n#   See COPYING file distributed along with the datalad package for the\n#   copyright and license terms.\n#\n### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##g\n\"\"\"Parameter representation\"\"\"\n\n__docformat__ = 'restructuredtext'\n\nimport re\nimport textwrap\nfrom .constraints import expand_contraint_spec\n\n_whitespace_re = re.compile('\\n\\s+|^\\s+')\n\n\nclass Parameter(object):\n    \"\"\"This class shall serve as a representation of a parameter.\n    \"\"\"\n\n    def __init__(self, constraints=None, doc=None, args=None, **kwargs):\n        \"\"\"Add contraints (validator) specifications and a docstring for\n        a parameter.\n\n        Parameters\n        ----------\n        constraints : callable\n          A functor that takes any input value, performs checks or type\n          conversions and finally returns a value that is appropriate for a\n          parameter or raises an exception. This will also be used to set up\n          the ``type`` functionality of argparse.add_argument.\n        doc : str\n          Documentation about the purpose of this parameter.\n        args : tuple or None\n          Any additional positional args for argparser.add_argument. This is\n          most useful for assigned multiple alternative argument names or\n          create positional arguments.\n        **kwargs :\n          Any additional keyword args for argparser.add_argument.\n\n        Examples\n        --------\n        Ensure a parameter is a float\n        >>> from datalad.support.param import Parameter\n        >>> from datalad.support.constraints import (EnsureFloat, EnsureRange,\n        ...                              AltConstraints, Constraints)\n        >>> C = Parameter(constraints=EnsureFloat())\n\n        Ensure a parameter is of type float or None:\n        >>> C = Parameter(constraints=AltConstraints(EnsureFloat(), None))\n\n        Ensure a parameter is None or of type float and lies in the inclusive\n        range (7.0,44.0):\n        >>> C = Parameter(\n        ...         AltConstraints(\n        ...             Constraints(EnsureFloat(),\n        ...                         EnsureRange(min=7.0,max=44.0)),\n        ...             None))\n        \"\"\"\n        self.constraints = expand_contraint_spec(constraints)\n        self._doc = doc\n        self.cmd_args = args\n        self.cmd_kwargs = kwargs\n\n    def get_autodoc(self, name, indent=\"  \", width=70, default=None, has_default=False):\n        \"\"\"Docstring for the parameter to be used in lists of parameters\n\n        Returns\n        -------\n        string or list of strings (if indent is None)\n        \"\"\"\n        paramsdoc = '%s' % name\n        sdoc = None\n        if self.constraints is not None:\n            sdoc = self.constraints.short_description()\n        elif 'action' in self.cmd_kwargs \\\n                and self.cmd_kwargs['action'] in (\"store_true\", \"store_false\"):\n            sdoc = 'bool'\n        if not sdoc is None:\n            if sdoc[0] == '(' and sdoc[-1] == ')':\n                sdoc = sdoc[1:-1]\n            paramsdoc += \" : %s\" % sdoc\n            if has_default:\n                paramsdoc += \", optional\"\n        paramsdoc = [paramsdoc]\n\n        doc = self._doc\n        if doc is None:\n            doc = ''\n        doc.strip()\n        if len(doc) and not doc.endswith('.'):\n            doc += '.'\n        if self.constraints is not None:\n            cdoc = self.constraints.long_description()\n            if cdoc[0] == '(' and cdoc[-1] == ')':\n                cdoc = cdoc[1:-1]\n            addinfo = ''\n            if 'nargs' in self.cmd_kwargs \\\n                    and not self.cmd_kwargs['nargs'] == '?':\n                addinfo = 'list expected, each '\n            doc += ' Constraints: %s%s.' % (addinfo, cdoc)\n        if has_default:\n            doc += \" [Default: %r]\" % (default,)\n        # Explicitly deal with multiple spaces, for some reason\n        # replace_whitespace is non-effective\n        doc = _whitespace_re.sub(' ', doc)\n        paramsdoc += [indent + x\n                      for x in textwrap.wrap(doc, width=width - len(indent),\n                                             replace_whitespace=True)]\n        return '\\n'.join(paramsdoc)\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title**: Parameter Class Fails to Validate Unknown Keyword Arguments

**Description**:
When initializing a `Parameter` with an unrecognized keyword argument, the system does not raise an error. This allows misspelled or unintended parameters to be passed silently, potentially leading to unexpected behavior later in the application.

**Example Code**:
```python
p = Parameter(unknown_arg=123)
```

**Expected Behavior**:
Initializing a `Parameter` with an unknown keyword argument should raise a `ValueError` that clearly indicates which arguments are unrecognized.

**Actual Behavior**:
No exception is raised when an unknown keyword argument is provided, which can result in overlooked bugs due to parameter misspecification.

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### datalad/support/param.py
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
#
#   See COPYING file distributed along with the datalad package for the
#   copyright and license terms.
#
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##g
"""Parameter representation"""

__docformat__ = 'restructuredtext'

import re
import textwrap
from .constraints import expand_contraint_spec

_whitespace_re = re.compile('\n\s+|^\s+')


class Parameter(object):
    """This class shall serve as a representation of a parameter.
    """

    def __init__(self, constraints=None, doc=None, args=None, **kwargs):
        """Add contraints (validator) specifications and a docstring for
        a parameter.

        Parameters
        ----------
        constraints : callable
          A functor that takes any input value, performs checks or type
          conversions and finally returns a value that is appropriate for a
          parameter or raises an exception. This will also be used to set up
          the ``type`` functionality of argparse.add_argument.
        doc : str
          Documentation about the purpose of this parameter.
        args : tuple or None
          Any additional positional args for argparser.add_argument. This is
          most useful for assigned multiple alternative argument names or
          create positional arguments.
        **kwargs :
          Any additional keyword args for argparser.add_argument.

        Examples
        --------
        Ensure a parameter is a float
        >>> from datalad.support.param import Parameter
        >>> from datalad.support.constraints import (EnsureFloat, EnsureRange,
        ...                              AltConstraints, Constraints)
        >>> C = Parameter(constraints=EnsureFloat())

        Ensure a parameter is of type float or None:
        >>> C = Parameter(constraints=AltConstraints(EnsureFloat(), None))

        Ensure a parameter is None or of type float and lies in the inclusive
        range (7.0,44.0):
        >>> C = Parameter(
        ...         AltConstraints(
        ...             Constraints(EnsureFloat(),
        ...                         EnsureRange(min=7.0,max=44.0)),
        ...             None))
        """
        self.constraints = expand_contraint_spec(constraints)
        self._doc = doc
        self.cmd_args = args
        self.cmd_kwargs = kwargs

    def get_autodoc(self, name, indent="  ", width=70, default=None, has_default=False):
        """Docstring for the parameter to be used in lists of parameters

        Returns
        -------
        string or list of strings (if indent is None)
        """
        paramsdoc = '%s' % name
        sdoc = None
        if self.constraints is not None:
            sdoc = self.constraints.short_description()
        elif 'action' in self.cmd_kwargs \
                and self.cmd_kwargs['action'] in ("store_true", "store_false"):
            sdoc = 'bool'
        if not sdoc is None:
            if sdoc[0] == '(' and sdoc[-1] == ')':
                sdoc = sdoc[1:-1]
            paramsdoc += " : %s" % sdoc
            if has_default:
                paramsdoc += ", optional"
        paramsdoc = [paramsdoc]

        doc = self._doc
        if doc is None:
            doc = ''
        doc.strip()
        if len(doc) and not doc.endswith('.'):
            doc += '.'
        if self.constraints is not None:
            cdoc = self.constraints.long_description()
            if cdoc[0] == '(' and cdoc[-1] == ')':
                cdoc = cdoc[1:-1]
            addinfo = ''
            if 'nargs' in self.cmd_kwargs \
                    and not self.cmd_kwargs['nargs'] == '?':
                addinfo = 'list expected, each '
            doc += ' Constraints: %s%s.' % (addinfo, cdoc)
        if has_default:
            doc += " [Default: %r]" % (default,)
        # Explicitly deal with multiple spaces, for some reason
        # replace_whitespace is non-effective
        doc = _whitespace_re.sub(' ', doc)
        paramsdoc += [indent + x
                      for x in textwrap.wrap(doc, width=width - len(indent),
                                             replace_whitespace=True)]
        return '\n'.join(paramsdoc)

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user