autouse=True,             scope="function",             # Use a unique name to speed up lookup.            name=f"xunit_setup_method_fixture_{self.obj.__qualname__}",            name=f"_xunit_setup_method_fixture_{self.obj.__qualname__}",         )         def xunit_setup_method_fixture(self, request) -> Generator[None, None, None]:             method = request.functiondiff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py-- a/src/_pytest/unittest.py++ b/src/_pytest/unittest.py


scope=scope,         autouse=True,         # Use a unique name to speed up lookup.        name=f"unittest_{setup_name}_fixture_{obj.__qualname__}",        name=f"_unittest_{setup_name}_fixture_{obj.__qualname__}",     )     def fixture(self, request: FixtureRequest) -> Generator[None, None, None]:         if _is_skipped(self):


return not (actual == self)      def _approx_scalar(self, x) -> "ApproxScalar":<ins>        if isinstance(x, Decimal):            return ApproxDecimal(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok)</ins>         return ApproxScalar(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok)      def _yield_comparisons(self, actual):


"#configuring-hook-specs-impls-using-markers", ) MARKED_FIXTURE = PytestRemovedIn8Warning(    "Marks applied to fixtures have no effect\n"    "See docs: https://docs.pytest.org/en/stable/deprecations.html#applying-a-mark-to-a-fixture-function") # You want to make some `__init__` or function "private". # #   def my_private_function(some, args):diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py-- a/src/_pytest/fixtures.py++ b/src/_pytest/fixtures.py


from _pytest.config import Config from _pytest.config.argparsing import Parser from _pytest.deprecated import check_ispytest<ins>from _pytest.deprecated import MARKED_FIXTURE</ins> from _pytest.deprecated import YIELD_FIXTURE from _pytest.mark import Mark from _pytest.mark import ParameterSet


"fixture is being applied more than once to the same function"             )         if hasattr(function, "pytestmark"):            warnings.warn(MARKED_FIXTURE, stacklevel=2)         function = wrap_function_to_error_out_if_called_directly(function, self)          name = self.name or function.__name__diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py-- a/src/_pytest/mark/structures.py++ b/src/_pytest/mark/structures.py


from ..compat import NotSetType from _pytest.config import Config from _pytest.deprecated import check_ispytest<ins>from _pytest.deprecated import MARKED_FIXTURE</ins> from _pytest.outcomes import fail from _pytest.warning_types import PytestUnknownMarkWarning


This is used to implement the Mark declarations/decorators correctly.     """     assert isinstance(mark, Mark), mark<ins>    from ..fixtures import getfixturemarker    if getfixturemarker(obj) is not None:        warnings.warn(MARKED_FIXTURE, stacklevel=2)</ins>     # Always reassign name to avoid updating pytestmark in a reference that     # was only borrowed.     obj.pytestmark = [*get_unpacked_marks(obj, consider_mro=False), mark]


@classmethod     def from_config(cls, config: Config) -> "Session":        session: Session = cls._create(config)        session: Session = cls._create(config=config)         return session      def __repr__(self) -> str:diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py-- a/src/_pytest/nodes.py++ b/src/_pytest/nodes.py


import os import warningsfrom inspect import signature from pathlib import Path from typing import Any from typing import Callablefrom typing import cast from typing import Iterable from typing import Iterator from typing import List


from _pytest.pathlib import absolutepath from _pytest.pathlib import commonpath from _pytest.store import Store<ins>from _pytest.warning_types import PytestWarning</ins>  if TYPE_CHECKING:     # Imported here due to circular import.


fail(msg, pytrace=False)      def _create(self, *k, **kw):        return super().__call__(*k, **kw)        try:            return super().__call__(*k, **kw)        except TypeError:            sig = signature(getattr(self, "__init__"))            known_kw = {k: v for k, v in kw.items() if k in sig.parameters}            from .warning_types import PytestDeprecationWarning            warnings.warn(                PytestDeprecationWarning(                    f"{self} is not using a cooperative constructor and only takes {set(known_kw)}"                )            )            return super().__call__(*k, **known_kw)   class Node(metaclass=NodeMeta):


class FSCollector(Collector):     def __init__(         self,        fspath: Optional[LEGACY_PATH],        path: Optional[Path],        parent=None,        fspath: Optional[LEGACY_PATH] = None,        path_or_parent: Optional[Union[Path, Node]] = None,        path: Optional[Path] = None,        name: Optional[str] = None,        parent: Optional[Node] = None,         config: Optional[Config] = None,         session: Optional["Session"] = None,         nodeid: Optional[str] = None,     ) -> None:        if path_or_parent:            if isinstance(path_or_parent, Node):                assert parent is None                parent = cast(FSCollector, path_or_parent)            elif isinstance(path_or_parent, Path):                assert path is None                path = path_or_parent         path, fspath = _imply_path(path, fspath=fspath)        name = path.name        if parent is not None and parent.path != path:            try:                rel = path.relative_to(parent.path)            except ValueError:                pass            else:                name = str(rel)            name = name.replace(os.sep, SEP)        if name is None:            name = path.name            if parent is not None and parent.path != path:                try:                    rel = path.relative_to(parent.path)                except ValueError:                    pass                else:                    name = str(rel)                name = name.replace(os.sep, SEP)         self.path = path         session = session or parent.session        if session is None:            assert parent is not None            session = parent.session          if nodeid is None:             try:


nodeid = nodeid.replace(os.sep, SEP)          super().__init__(            name, parent, config, session, nodeid=nodeid, fspath=fspath, path=path            name=name,            parent=parent,            config=config,            session=session,            nodeid=nodeid,            path=path,         )      @classmethod


nextitem = None <ins>    def __init_subclass__(cls) -> None:        problems = ", ".join(            base.__name__ for base in cls.__bases__ if issubclass(base, Collector)        )        if problems:            warnings.warn(                f"{cls.__name__} is an Item subclass and should not be a collector, "                f"however its bases {problems} are collectors.\n"                "Please split the Collectors and the Item into separate node types.\n"                "Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n"                "example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/",                PytestWarning,            )</ins>     def __init__(         self,         name,


config: Optional[Config] = None,         session: Optional["Session"] = None,         nodeid: Optional[str] = None,        **kw,     ) -> None:        super().__init__(name, parent, config, session, nodeid=nodeid)        super().__init__(            name=name,            parent=parent,            config=config,            session=session,            nodeid=nodeid,            **kw,        )         self._report_sections: List[Tuple[str, str, str]] = []          #: A list of tuples (name, value) that holds user defined properties


return path.joinpath(".lock")  <del>def ensure_reset_dir(path: Path) -> None:    """Ensure the given path is an empty directory."""    if path.exists():        rm_rf(path)    path.mkdir()</del> def on_rm_rf_error(func, path: str, exc, *, start_path: Path) -> bool:     """Handle known read-only errors during rmtree.


pass  def make_numbered_dir(root: Path, prefix: str) -> Path:def make_numbered_dir(root: Path, prefix: str, mode: int = 0o700) -> Path:     """Create a directory with an increased number as suffix for the given prefix."""     for i in range(10):         # try up to 10 times to create the folder


new_number = max_existing + 1         new_path = root.joinpath(f"{prefix}{new_number}")         try:            new_path.mkdir()            new_path.mkdir(mode=mode)         except Exception:             pass         else:


def make_numbered_dir_with_cleanup(    root: Path, prefix: str, keep: int, lock_timeout: float    root: Path,    prefix: str,    keep: int,    lock_timeout: float,    mode: int, ) -> Path:     """Create a numbered dir with a cleanup lock and remove old ones."""     e = None     for i in range(10):         try:            p = make_numbered_dir(root, prefix)            p = make_numbered_dir(root, prefix, mode)             lock_path = create_cleanup_lock(p)             register_cleanup_lock_removal(lock_path)         except Exception as exc:diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py-- a/src/_pytest/pytester.py++ b/src/_pytest/pytester.py


:py:class:`Pytester.TimeoutExpired`.         """         __tracebackhide__ = True        p = make_numbered_dir(root=self.path, prefix="runpytest-")        p = make_numbered_dir(root=self.path, prefix="runpytest-", mode=0o700)         args = ("--basetemp=%s" % p,) + args         plugins = [x for x in self.plugins if isinstance(x, str)]         if plugins:


The pexpect child is returned.         """         basetemp = self.path / "temp-pexpect"        basetemp.mkdir()        basetemp.mkdir(mode=0o700)         invoke = " ".join(map(str, self._getpytestargs()))         cmd = f"{invoke} --basetemp={basetemp} {string}"         return self.spawn(cmd, expect_timeout=expect_timeout)diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py-- a/src/_pytest/tmpdir.py++ b/src/_pytest/tmpdir.py


import attr from .pathlib import ensure_reset_dir from .pathlib import LOCK_TIMEOUT from .pathlib import make_numbered_dir from .pathlib import make_numbered_dir_with_cleanupfrom .pathlib import rm_rf from _pytest.compat import final from _pytest.compat import LEGACY_PATH from _pytest.compat import legacy_path


basename = self._ensure_relative_to_basetemp(basename)         if not numbered:             p = self.getbasetemp().joinpath(basename)            p.mkdir()            p.mkdir(mode=0o700)         else:            p = make_numbered_dir(root=self.getbasetemp(), prefix=basename)            p = make_numbered_dir(root=self.getbasetemp(), prefix=basename, mode=0o700)             self._trace("mktemp", p)         return p      def getbasetemp(self) -> Path:        """Return base temporary directory."""        """Return the base temporary directory, creating it if needed."""         if self._basetemp is not None:             return self._basetemp          if self._given_basetemp is not None:             basetemp = self._given_basetemp            ensure_reset_dir(basetemp)            if basetemp.exists():                rm_rf(basetemp)            basetemp.mkdir(mode=0o700)             basetemp = basetemp.resolve()         else:             from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT")


# make_numbered_dir() call             rootdir = temproot.joinpath(f"pytest-of-{user}")             try:                rootdir.mkdir(exist_ok=True)                rootdir.mkdir(mode=0o700, exist_ok=True)             except OSError:                 # getuser() likely returned illegal characters for the platform, use unknown back off mechanism                 rootdir = temproot.joinpath("pytest-of-unknown")                rootdir.mkdir(exist_ok=True)                rootdir.mkdir(mode=0o700, exist_ok=True)            # Because we use exist_ok=True with a predictable name, make sure            # we are the owners, to prevent any funny business (on unix, where            # temproot is usually shared).            # Also, to keep things private, fixup any world-readable temp            # rootdir's permissions. Historically 0o755 was used, so we can't            # just error out on this, at least for a while.            if hasattr(os, "getuid"):                rootdir_stat = rootdir.stat()                uid = os.getuid()                # getuid shouldn't fail, but cpython defines such a case.                # Let's hope for the best.                if uid != -1:                    if rootdir_stat.st_uid != uid:                        raise OSError(                            f"The temporary directory {rootdir} is not owned by the current user. "                            "Fix this and try again."                        )                    if (rootdir_stat.st_mode & 0o077) != 0:                        os.chmod(rootdir, rootdir_stat.st_mode & ~0o077)             basetemp = make_numbered_dir_with_cleanup(                prefix="pytest-", root=rootdir, keep=3, lock_timeout=LOCK_TIMEOUT                prefix="pytest-",                root=rootdir,                keep=3,                lock_timeout=LOCK_TIMEOUT,                mode=0o700,             )         assert basetemp is not None, basetemp        self._basetemp = t = basetemp        self._trace("new basetemp", t)        return t        self._basetemp = basetemp        self._trace("new basetemp", basetemp)        return basetemp   @final


logging.DEBUG: {"purple"},         logging.NOTSET: set(),     }    LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-.]?\d*s)")    LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-.]?\d*(?:\.\d+)?s)")      def __init__(self, terminalwriter: TerminalWriter, *args, **kwargs) -> None:         super().__init__(*args, **kwargs)


def _find_lineno(self, obj, source_lines):                 """Doctest code does not take into account `@property`, this                is a hackish way to fix it.                is a hackish way to fix it. https://bugs.python.org/issue17446                 https://bugs.python.org/issue17446                Wrapped Doctests will need to be unwrapped so the correct                line number is returned. This will be reported upstream. #8796                 """                 if isinstance(obj, property):                     obj = getattr(obj, "fget", obj)                if hasattr(obj, "__wrapped__"):                    # Get the main obj in case of it being wrapped                    obj = inspect.unwrap(obj)                 # Type ignored because this is a private function.                 return doctest.DocTestFinder._find_lineno(  # type: ignore                     self,


if e.allow_module_level:                 raise             raise self.CollectError(<del>                "Using pytest.skip outside of a test is not allowed. "                "To decorate a test function, use the @pytest.mark.skip "                "or @pytest.mark.skipif decorators instead, and to skip a "                "module use `pytestmark = pytest.mark.{skip,skipif}."</del><ins>                "Using pytest.skip outside of a test will skip the entire module. "                "If that's your intention, pass `allow_module_level=True`. "                "If you want to skip a specific test or an entire class, "                "use the @pytest.mark.skip or @pytest.mark.skipif decorators."</ins>             ) from e         self.config.pluginmanager.consider_module(mod)         return mod


errors: int = 0,         xpassed: int = 0,         xfailed: int = 0,<ins>        warnings: int = 0,</ins>     ) -> None:         """Assert that the specified outcomes appear with the respective         numbers (0 means it didn't occur) in the text output from a test run."""


errors=errors,             xpassed=xpassed,             xfailed=xfailed,            warnings=warnings,         )  diff --git a/src/_pytest/pytester_assertions.py b/src/_pytest/pytester_assertions.py-- a/src/_pytest/pytester_assertions.py++ b/src/_pytest/pytester_assertions.py


errors: int = 0,     xpassed: int = 0,     xfailed: int = 0,<ins>    warnings: int = 0,</ins> ) -> None:     """Assert that the specified outcomes appear with the respective     numbers (0 means it didn't occur) in the text output from a test run."""


"errors": outcomes.get("errors", 0),         "xpassed": outcomes.get("xpassed", 0),         "xfailed": outcomes.get("xfailed", 0),<ins>        "warnings": outcomes.get("warnings", 0),</ins>     }     expected = {         "passed": passed,


"errors": errors,         "xpassed": xpassed,         "xfailed": xfailed,<ins>        "warnings": warnings,</ins>     }     assert obtained == expected


expr:       and_expr ('or' and_expr)* and_expr:   not_expr ('and' not_expr)* not_expr:   'not' not_expr | '(' expr ')' | identident:      (\w|:|\+|-|\.|\[|\])+ident:      (\w|:|\+|-|\.|\[|\]|\\)+  The semantics are:


yield Token(TokenType.RPAREN, ")", pos)                 pos += 1             else:                match = re.match(r"(:?\w|:|\+|-|\.|\[|\])+", input[pos:])                match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\)+", input[pos:])                 if match:                     value = match.group(0)                     if value == "or":


action="store_true",         default=False,         dest="stepwise_skip",        help="ignore the first failing test but stop on the next failing test",        help="ignore the first failing test but stop on the next failing test.\n"        "implicitly enables --stepwise.",     )   @pytest.hookimpl def pytest_configure(config: Config) -> None:    # We should always have a cache as cache provider plugin uses tryfirst=True    if config.option.stepwise_skip:        # allow --stepwise-skip to work on it's own merits.        config.option.stepwise = True     if config.getoption("stepwise"):         config.pluginmanager.register(StepwisePlugin(config), "stepwiseplugin")


"See "             "https://docs.pytest.org/en/stable/deprecations.html#node-construction-changed-to-node-from-parent"             " for more details."        ).format(name=self.__name__)        ).format(name=f"{self.__module__}.{self.__name__}")         fail(msg, pytrace=False)      def _create(self, *k, **kw):


xpassed: int = 0,         xfailed: int = 0,         warnings: int = 0,<ins>        deselected: int = 0,</ins>     ) -> None:         """Assert that the specified outcomes appear with the respective         numbers (0 means it didn't occur) in the text output from a test run."""


xpassed=xpassed,             xfailed=xfailed,             warnings=warnings,            deselected=deselected,         )  diff --git a/src/_pytest/pytester_assertions.py b/src/_pytest/pytester_assertions.py-- a/src/_pytest/pytester_assertions.py++ b/src/_pytest/pytester_assertions.py


xpassed: int = 0,     xfailed: int = 0,     warnings: int = 0,<ins>    deselected: int = 0,</ins> ) -> None:     """Assert that the specified outcomes appear with the respective     numbers (0 means it didn't occur) in the text output from a test run."""


"xpassed": outcomes.get("xpassed", 0),         "xfailed": outcomes.get("xfailed", 0),         "warnings": outcomes.get("warnings", 0),<ins>        "deselected": outcomes.get("deselected", 0),</ins>     }     expected = {         "passed": passed,


"xpassed": xpassed,         "xfailed": xfailed,         "warnings": warnings,<ins>        "deselected": deselected,</ins>     }     assert obtained == expected


expr:       and_expr ('or' and_expr)* and_expr:   not_expr ('and' not_expr)* not_expr:   'not' not_expr | '(' expr ')' | identident:      (\w|:|\+|-|\.|\[|\]|\\)+ident:      (\w|:|\+|-|\.|\[|\]|\\|/)+  The semantics are:


yield Token(TokenType.RPAREN, ")", pos)                 pos += 1             else:                match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\)+", input[pos:])                match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\|/)+", input[pos:])                 if match:                     value = match.group(0)                     if value == "or":


nodeid: Optional[str] = None,         **kw,     ) -> None:        # The first two arguments are intentionally passed positionally,        # to keep plugins who define a node type which inherits from        # (pytest.Item, pytest.File) working (see issue #8435).        # They can be made kwargs when the deprecation above is done.         super().__init__(            name=name,            parent=parent,            name,            parent,             config=config,             session=session,             nodeid=nodeid,


values: List[int] = []     for x in ast.walk(node):         if isinstance(x, (ast.stmt, ast.ExceptHandler)):<ins>            # Before Python 3.8, the lineno of a decorated class or function pointed at the decorator.            # Since Python 3.8, the lineno points to the class/def, so need to include the decorators.            if isinstance(x, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):                for d in x.decorator_list:                    values.append(d.lineno - 1)</ins>             values.append(x.lineno - 1)             for name in ("finalbody", "orelse"):                 val: Optional[List[ast.stmt]] = getattr(x, name, None)


errors: int = 0,         xpassed: int = 0,         xfailed: int = 0,        warnings: int = 0,        deselected: int = 0,        warnings: Optional[int] = None,        deselected: Optional[int] = None,     ) -> None:        """Assert that the specified outcomes appear with the respective        numbers (0 means it didn't occur) in the text output from a test run."""        """        Assert that the specified outcomes appear with the respective        numbers (0 means it didn't occur) in the text output from a test run.        ``warnings`` and ``deselected`` are only checked if not None.        """         __tracebackhide__ = True         from _pytest.pytester_assertions import assert_outcomes diff --git a/src/_pytest/pytester_assertions.py b/src/_pytest/pytester_assertions.py-- a/src/_pytest/pytester_assertions.py++ b/src/_pytest/pytester_assertions.py


# hence cannot be subject to assertion rewriting, which requires a # module to not be already imported. from typing import Dict<ins>from typing import Optional</ins> from typing import Sequence from typing import Tuple from typing import Union


errors: int = 0,     xpassed: int = 0,     xfailed: int = 0,    warnings: int = 0,    deselected: int = 0,    warnings: Optional[int] = None,    deselected: Optional[int] = None, ) -> None:     """Assert that the specified outcomes appear with the respective     numbers (0 means it didn't occur) in the text output from a test run."""


"errors": outcomes.get("errors", 0),         "xpassed": outcomes.get("xpassed", 0),         "xfailed": outcomes.get("xfailed", 0),<del>        "warnings": outcomes.get("warnings", 0),        "deselected": outcomes.get("deselected", 0),</del>     }     expected = {         "passed": passed,


"errors": errors,         "xpassed": xpassed,         "xfailed": xfailed,        "warnings": warnings,        "deselected": deselected,     }    if warnings is not None:        obtained["warnings"] = outcomes.get("warnings", 0)        expected["warnings"] = warnings    if deselected is not None:        obtained["deselected"] = outcomes.get("deselected", 0)        expected["deselected"] = deselected     assert obtained == expected


_excinfo: Optional[List[_pytest._code.ExceptionInfo[BaseException]]] = None     _testcase: Optional["unittest.TestCase"] = None <ins>    def _getobj(self):        assert self.parent is not None        # Unlike a regular Function in a Class, where `item.obj` returns        # a *bound* method (attached to an instance), TestCaseFunction's        # `obj` returns an *unbound* method (not attached to an instance).        # This inconsistency is probably not desirable, but needs some        # consideration before changing.        return getattr(self.parent.obj, self.originalname)  # type: ignore[attr-defined]</ins>     def setup(self) -> None:         # A bound method to be called during teardown() if set (see 'runtest()').         self._explicit_tearDown: Optional[Callable[[], None]] = None


nextitem = None <del>    def __init_subclass__(cls) -> None:        problems = ", ".join(            base.__name__ for base in cls.__bases__ if issubclass(base, Collector)        )        if problems:            warnings.warn(                f"{cls.__name__} is an Item subclass and should not be a collector, "                f"however its bases {problems} are collectors.\n"                "Please split the Collectors and the Item into separate node types.\n"                "Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n"                "example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/",                PytestWarning,            )</del>     def __init__(         self,         name,


#: for this test.         self.user_properties: List[Tuple[str, object]] = [] <ins>        self._check_item_and_collector_diamond_inheritance()    def _check_item_and_collector_diamond_inheritance(self) -> None:        """        Check if the current type inherits from both File and Collector        at the same time, emitting a warning accordingly (#8447).        """        cls = type(self)        # We inject an attribute in the type to avoid issuing this warning        # for the same class more than once, which is not helpful.        # It is a hack, but was deemed acceptable in order to avoid        # flooding the user in the common case.        attr_name = "_pytest_diamond_inheritance_warning_shown"        if getattr(cls, attr_name, False):            return        setattr(cls, attr_name, True)        problems = ", ".join(            base.__name__ for base in cls.__bases__ if issubclass(base, Collector)        )        if problems:            warnings.warn(                f"{cls.__name__} is an Item subclass and should not be a collector, "                f"however its bases {problems} are collectors.\n"                "Please split the Collectors and the Item into separate node types.\n"                "Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n"                "example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/",                PytestWarning,            )</ins>     def runtest(self) -> None:         """Run the test case for this item.


module_parts = module_name.split(".")     while module_name:         if module_name not in modules:            module = ModuleType(                module_name,                doc="Empty module created by pytest's importmode=importlib.",            )            modules[module_name] = module            try:                # If sys.meta_path is empty, calling import_module will issue                # a warning and raise ModuleNotFoundError. To avoid the                # warning, we check sys.meta_path explicitly and raise the error                # ourselves to fall back to creating a dummy module.                if not sys.meta_path:                    raise ModuleNotFoundError                importlib.import_module(module_name)            except ModuleNotFoundError:                module = ModuleType(                    module_name,                    doc="Empty module created by pytest's importmode=importlib.",                )                modules[module_name] = module         module_parts.pop(-1)         module_name = ".".join(module_parts)


import math import pprint<ins>from collections.abc import Collection</ins> from collections.abc import Sized from decimal import Decimal from numbers import Complex


from typing import Callable from typing import cast from typing import Generic<del>from typing import Iterable</del> from typing import List from typing import Mapping from typing import Optional


raise TypeError(msg.format(key, value, pprint.pformat(self.expected)))  class ApproxSequencelike(ApproxBase):class ApproxSequenceLike(ApproxBase):     """Perform approximate comparisons where the expected value is a sequence of numbers."""      def __repr__(self) -> str:         seq_type = type(self.expected)        if seq_type not in (tuple, list, set):        if seq_type not in (tuple, list):             seq_type = list         return "approx({!r})".format(             seq_type(self._approx_scalar(x) for x in self.expected)


def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase:    """Assert that two numbers (or two sets of numbers) are equal to each other    """Assert that two numbers (or two ordered sequences of numbers) are equal to each other     within some tolerance.      Due to the :std:doc:`tutorial/floatingpoint`, numbers that we


>>> 0.1 + 0.2 == approx(0.3)         True     The same syntax also works for sequences of numbers::    The same syntax also works for ordered sequences of numbers::          >>> (0.1 + 0.2, 0.2 + 0.4) == approx((0.3, 0.6))         True     Dictionary *values*::        >>> {'a': 0.1 + 0.2, 'b': 0.2 + 0.4} == approx({'a': 0.3, 'b': 0.6})        True     ``numpy`` arrays::          >>> import numpy as np                                                          # doctest: +SKIP


>>> np.array([0.1, 0.2]) + np.array([0.2, 0.1]) == approx(0.3) # doctest: +SKIP         True <ins>    Only ordered sequences are supported, because ``approx`` needs    to infer the relative position of the sequences without ambiguity. This means    ``sets`` and other unordered sequences are not supported.    Finally, dictionary *values* can also be compared::        >>> {'a': 0.1 + 0.2, 'b': 0.2 + 0.4} == approx({'a': 0.3, 'b': 0.6})        True    The comparision will be true if both mappings have the same keys and their    respective values match the expected tolerances.    **Tolerances**</ins>     By default, ``approx`` considers numbers within a relative tolerance of     ``1e-6`` (i.e. one part in a million) of its expected value to be equal.     This treatment would lead to surprising results if the expected value was


expected = _as_numpy_array(expected)         cls = ApproxNumpy     elif (        isinstance(expected, Iterable)        hasattr(expected, "__getitem__")         and isinstance(expected, Sized)         # Type ignored because the error is wrong -- not unreachable.         and not isinstance(expected, STRING_TYPES)  # type: ignore[unreachable]     ):        cls = ApproxSequencelike        cls = ApproxSequenceLike    elif (        isinstance(expected, Collection)        # Type ignored because the error is wrong -- not unreachable.        and not isinstance(expected, STRING_TYPES)  # type: ignore[unreachable]    ):        msg = f"pytest.approx() only supports ordered sequences, but got: {repr(expected)}"        raise TypeError(msg)     else:         cls = ApproxScalar


"""         if self._confcutdir is None:             return True        try:            path.relative_to(self._confcutdir)        except ValueError:            return False        return True        return path not in self._confcutdir.parents      def _try_load_conftest(         self, anchor: Path, importmode: Union[str, ImportMode], rootpath: Path


def _repr_compare(self, other_side: Sequence[float]) -> List[str]:         import math<del>        import numpy as np</del>          if len(self.expected) != len(other_side):             return [


abs_diff = abs(approx_value.expected - other_value)                 max_abs_diff = max(max_abs_diff, abs_diff)                 if other_value == 0.0:                    max_rel_diff = np.inf                    max_rel_diff = math.inf                 else:                     max_rel_diff = max(max_rel_diff, abs_diff / abs(other_value))                 different_ids.append(i)


"""     __tracebackhide__ = True <ins>    if not expected_exception:        raise ValueError(            f"Expected an exception type or a tuple of exception types, but got `{expected_exception!r}`. "            f"Raising exceptions is already understood as failing the test, so you don't need "            f"any special code to say 'this should never raise an exception'."        )</ins>     if isinstance(expected_exception, type):         excepted_exceptions: Tuple[Type[E], ...] = (expected_exception,)     else:


from _pytest.pathlib import visit from _pytest.scope import Scope from _pytest.warning_types import PytestCollectionWarningfrom _pytest.warning_types import PytestReturnNotNoneWarning from _pytest.warning_types import PytestUnhandledCoroutineWarning  if TYPE_CHECKING:     from typing_extensions import Literal     from _pytest.scope import _ScopeName


result = testfunction(**testargs)     if hasattr(result, "__await__") or hasattr(result, "__aiter__"):         async_warn_and_skip(pyfuncitem.nodeid)    elif result is not None:        warnings.warn(            PytestReturnNotNoneWarning(                f"Expected None, but {pyfuncitem.nodeid} returned {result!r}, which will be an error in a "                "future version of pytest.  Did you mean to use `assert` instead of `return`?"            )        )     return True  diff --git a/src/_pytest/warning_types.py b/src/_pytest/warning_types.py-- a/src/_pytest/warning_types.py++ b/src/_pytest/warning_types.py


__module__ = "pytest"  @finalclass PytestReturnNotNoneWarning(PytestDeprecationWarning):    """Warning emitted when a test function is returning value other than None."""    __module__ = "pytest" @final class PytestExperimentalApiWarning(PytestWarning, FutureWarning):     """Warning category used to denote experiments in pytest.diff --git a/src/pytest/__init__.py b/src/pytest/__init__.py-- a/src/pytest/__init__.py++ b/src/pytest/__init__.py


from _pytest.warning_types import PytestDeprecationWarning from _pytest.warning_types import PytestExperimentalApiWarning from _pytest.warning_types import PytestRemovedIn8Warning<ins>from _pytest.warning_types import PytestReturnNotNoneWarning</ins> from _pytest.warning_types import PytestUnhandledCoroutineWarning from _pytest.warning_types import PytestUnhandledThreadExceptionWarning from _pytest.warning_types import PytestUnknownMarkWarning


"PytestDeprecationWarning",     "PytestExperimentalApiWarning",     "PytestRemovedIn8Warning",<ins>    "PytestReturnNotNoneWarning",</ins>     "Pytester",     "PytestPluginManager",     "PytestUnhandledCoroutineWarning",


>>> enc.inverse_transform([[0, 1, 1, 0, 0], [0, 0, 0, 1, 0]])     array([['Male', 1],            [None, 2]], dtype=object)<ins>    >>> enc.get_feature_names()    array(['x0_Female', 'x0_Male', 'x1_1', 'x1_2', 'x1_3'], dtype=object)</ins>      See also     --------


return X_tr <ins>    def get_feature_names(self, input_features=None):        """Return feature names for output features.        Parameters        ----------        input_features : list of string, length n_features, optional            String names for input features if available. By default,            "x0", "x1", ... "xn_features" is used.        Returns        -------        output_feature_names : array of string, length n_output_features        """        check_is_fitted(self, 'categories_')        cats = self.categories_        if input_features is None:            input_features = ['x%d' % i for i in range(len(cats))]        elif(len(input_features) != len(self.categories_)):            raise ValueError(                "input_features should have length equal to number of "                "features ({}), got {}".format(len(self.categories_),                                               len(input_features)))        feature_names = []        for i in range(len(cats)):            names = [                input_features[i] + '_' + six.text_type(t) for t in cats[i]]            feature_names.extend(names)        return np.array(feature_names, dtype=object)</ins>  class OrdinalEncoder(_BaseEncoder):     """Encode categorical features as an integer array.


store_cv_values : boolean, default=False         Flag indicating if the cross-validation values corresponding to        each alpha should be stored in the `cv_values_` attribute (see        below). This flag is only compatible with `cv=None` (i.e. using        each alpha should be stored in the ``cv_values_`` attribute (see        below). This flag is only compatible with ``cv=None`` (i.e. using         Generalized Cross-Validation).      Attributes     ----------     cv_values_ : array, shape = [n_samples, n_alphas] or \         shape = [n_samples, n_targets, n_alphas], optional        Cross-validation values for each alpha (if `store_cv_values=True` and \        `cv=None`). After `fit()` has been called, this attribute will \        contain the mean squared errors (by default) or the values of the \        `{loss,score}_func` function (if provided in the constructor).        Cross-validation values for each alpha (if ``store_cv_values=True``\        and ``cv=None``). After ``fit()`` has been called, this attribute \        will contain the mean squared errors (by default) or the values \        of the ``{loss,score}_func`` function (if provided in the constructor).      coef_ : array, shape = [n_features] or [n_targets, n_features]         Weight vector(s).


weights inversely proportional to class frequencies in the input data         as ``n_samples / (n_classes * np.bincount(y))``     store_cv_values : boolean, default=False        Flag indicating if the cross-validation values corresponding to        each alpha should be stored in the ``cv_values_`` attribute (see        below). This flag is only compatible with ``cv=None`` (i.e. using        Generalized Cross-Validation).     Attributes     ----------    cv_values_ : array, shape = [n_samples, n_alphas] or \    shape = [n_samples, n_responses, n_alphas], optional        Cross-validation values for each alpha (if `store_cv_values=True` and    `cv=None`). After `fit()` has been called, this attribute will contain \    the mean squared errors (by default) or the values of the \    `{loss,score}_func` function (if provided in the constructor).    cv_values_ : array, shape = [n_samples, n_targets, n_alphas], optional        Cross-validation values for each alpha (if ``store_cv_values=True`` and        ``cv=None``). After ``fit()`` has been called, this attribute will        contain the mean squared errors (by default) or the values of the        ``{loss,score}_func`` function (if provided in the constructor).      coef_ : array, shape = [n_features] or [n_targets, n_features]         Weight vector(s).


advantage of the multi-variate response support in Ridge.     """     def __init__(self, alphas=(0.1, 1.0, 10.0), fit_intercept=True,                 normalize=False, scoring=None, cv=None, class_weight=None):                 normalize=False, scoring=None, cv=None, class_weight=None,                 store_cv_values=False):         super(RidgeClassifierCV, self).__init__(             alphas=alphas, fit_intercept=fit_intercept, normalize=normalize,            scoring=scoring, cv=cv)            scoring=scoring, cv=cv, store_cv_values=store_cv_values)         self.class_weight = class_weight      def fit(self, X, y, sample_weight=None):


raise ValueError('All labels must be in [0, n labels). '                                  'Got %d < 0' % np.min(labels)) <ins>        if n_labels is not None:</ins>             y_true = y_true[:, labels[:n_labels]]             y_pred = y_pred[:, labels[:n_labels]]


...         pass     ...     print(repr(w[-1].message))     ... # doctest: +NORMALIZE_WHITESPACE    FitFailedWarning("Classifier fit failed. The score on this train-test    partition for these parameters will be set to 0.000000. Details:    \\nValueError('Penalty term must be positive; got (C=-2)',)",)    FitFailedWarning('Estimator fit failed. The score on this train-test    partition for these parameters will be set to 0.000000.    Details: \\nValueError: Penalty term must be positive; got (C=-2)\\n',)      .. versionchanged:: 0.18        Moved from sklearn.cross_validation.diff --git a/sklearn/model_selection/_validation.py b/sklearn/model_selection/_validation.py-- a/sklearn/model_selection/_validation.py++ b/sklearn/model_selection/_validation.py


import warnings import numbers import time<ins>from traceback import format_exception_only</ins>  import numpy as np import scipy.sparse as sp


test_scores = error_score                 if return_train_score:                     train_scores = error_score            warnings.warn("Classifier fit failed. The score on this train-test"            warnings.warn("Estimator fit failed. The score on this train-test"                           " partition for these parameters will be set to %f. "                          "Details: \n%r" % (error_score, e), FitFailedWarning)                          "Details: \n%s" %                          (error_score, format_exception_only(type(e), e)[0]),                          FitFailedWarning)         else:             raise ValueError("error_score must be the string 'raise' or a"                              " numeric value. (Hint: if using 'raise', please"


a one-versus-all approach. Concretely, this is implemented by taking     advantage of the multi-variate response support in Ridge.     """<ins></ins>     def __init__(self, alpha=1.0, fit_intercept=True, normalize=False,                  copy_X=True, max_iter=None, tol=1e-3, class_weight=None,                  solver="auto", random_state=None):


scorer = check_scoring(self, scoring=self.scoring, allow_none=True)         error = scorer is None         if np.any(self.alphas < 0):            raise ValueError("alphas cannot be negative. "                             "Got {} containing some "                             "negative value instead.".format(self.alphas))         for i, alpha in enumerate(self.alphas):             if error:                out, c = _errors(alpha, y, v, Q, QT_y)                out, c = _errors(float(alpha), y, v, Q, QT_y)             else:                out, c = _values(alpha, y, v, Q, QT_y)                out, c = _values(float(alpha), y, v, Q, QT_y)             cv_values[:, i] = out.ravel()             C.append(c)


fit_intercept=True, normalize=False, scoring=None,                  cv=None, gcv_mode=None,                  store_cv_values=False):        self.alphas = alphas        self.alphas = np.asarray(alphas)         self.fit_intercept = fit_intercept         self.normalize = normalize         self.scoring = scoring


a one-versus-all approach. Concretely, this is implemented by taking     advantage of the multi-variate response support in Ridge.     """<ins></ins>     def __init__(self, alphas=(0.1, 1.0, 10.0), fit_intercept=True,                  normalize=False, scoring=None, cv=None, class_weight=None):         super(RidgeClassifierCV, self).__init__(


>>> first_img_data.dtype               #doctest: +SKIP     dtype('uint8')     """    # Try to import imread from scipy. We do this lazily here to prevent    # this module from depending on PIL.    try:        try:            from scipy.misc import imread        except ImportError:            from scipy.misc.pilutil import imread    except ImportError:        raise ImportError("The Python Imaging Library (PIL) "                          "is required to load data from jpeg files")    # import PIL only when needed    from ..externals._pilutil import imread     module_path = join(dirname(__file__), "images")     with open(join(module_path, 'README.txt')) as f:         descr = f.read()diff --git a/sklearn/datasets/lfw.py b/sklearn/datasets/lfw.py-- a/sklearn/datasets/lfw.py++ b/sklearn/datasets/lfw.py


from .base import get_data_home, _fetch_remote, RemoteFileMetadata from ..utils import Bunch from ..externals.joblib import Memory<del></del> from ..externals.six import b  logger = logging.getLogger(__name__)


def _load_imgs(file_paths, slice_, color, resize):     """Internally used to load images"""    # Try to import imread and imresize from PIL. We do this here to prevent    # the whole sklearn.datasets module from depending on PIL.    try:        try:            from scipy.misc import imread        except ImportError:            from scipy.misc.pilutil import imread        from scipy.misc import imresize    except ImportError:        raise ImportError("The Python Imaging Library (PIL)"                          " is required to load data from jpeg files")    # import PIL only when needed    from ..externals._pilutil import imread, imresize      # compute the portion of the images to load to respect the slice_ parameter     # given by the callerdiff --git a/sklearn/externals/_pilutil.py b/sklearn/externals/_pilutil.pynew file mode 100644-- /dev/null++ b/sklearn/externals/_pilutil.py


<ins>"""A collection of image utilities using the Python Imaging Library (PIL).This is a local version of utility functions from scipy that are wrapping PILfunctionality. These functions are deprecated in scipy 1.0.0 and will beremoved in scipy 1.2.0. Therefore, the functionality used in sklearn is copiedhere. This file is taken from scipy/misc/pilutil.py in scipy1.0.0. Modifications include: making this module importable if pillow is notinstalled, removal of DeprecationWarning, removal of functions scikit-learndoes not need.Copyright (c) 2001, 2002 Enthought, Inc.All rights reserved.Copyright (c) 2003-2017 SciPy Developers.All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions are met:  a. Redistributions of source code must retain the above copyright notice,     this list of conditions and the following disclaimer.  b. Redistributions in binary form must reproduce the above copyright     notice, this list of conditions and the following disclaimer in the     documentation and/or other materials provided with the distribution.  c. Neither the name of Enthought nor the names of the SciPy Developers     may be used to endorse or promote products derived from this software     without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSEARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORSBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OFSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESSINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OFTHE POSSIBILITY OF SUCH DAMAGE."""from __future__ import division, print_function, absolute_importimport numpyimport tempfilefrom numpy import (amin, amax, ravel, asarray, arange, ones, newaxis,                   transpose, iscomplexobj, uint8, issubdtype, array)# Modification of original scipy pilutil.py to make this module importable if# pillow is not installed. If pillow is not installed, functions will raise# ImportError when called.try:    try:        from PIL import Image    except ImportError:        import Image    pillow_installed = True    if not hasattr(Image, 'frombytes'):        Image.frombytes = Image.fromstringexcept ImportError:    pillow_installed = False__all__ = ['bytescale', 'imread', 'imsave', 'fromimage', 'toimage', 'imresize']def bytescale(data, cmin=None, cmax=None, high=255, low=0):    """    Byte scales an array (image).    Byte scaling means converting the input image to uint8 dtype and scaling    the range to ``(low, high)`` (default 0-255).    If the input image already has dtype uint8, no scaling is done.    This function is only available if Python Imaging Library (PIL) is installed.    Parameters    ----------    data : ndarray        PIL image data array.    cmin : scalar, optional        Bias scaling of small values. Default is ``data.min()``.    cmax : scalar, optional        Bias scaling of large values. Default is ``data.max()``.    high : scalar, optional        Scale max value to `high`.  Default is 255.    low : scalar, optional        Scale min value to `low`.  Default is 0.    Returns    -------    img_array : uint8 ndarray        The byte-scaled array.    Examples    --------    >>> from scipy.misc import bytescale    >>> img = np.array([[ 91.06794177,   3.39058326,  84.4221549 ],    ...                 [ 73.88003259,  80.91433048,   4.88878881],    ...                 [ 51.53875334,  34.45808177,  27.5873488 ]])    >>> bytescale(img)    array([[255,   0, 236],           [205, 225,   4],           [140,  90,  70]], dtype=uint8)    >>> bytescale(img, high=200, low=100)    array([[200, 100, 192],           [180, 188, 102],           [155, 135, 128]], dtype=uint8)    >>> bytescale(img, cmin=0, cmax=255)    array([[91,  3, 84],           [74, 81,  5],           [52, 34, 28]], dtype=uint8)    """    if data.dtype == uint8:        return data    if high > 255:        raise ValueError("`high` should be less than or equal to 255.")    if low < 0:        raise ValueError("`low` should be greater than or equal to 0.")    if high < low:        raise ValueError("`high` should be greater than or equal to `low`.")    if cmin is None:        cmin = data.min()    if cmax is None:        cmax = data.max()    cscale = cmax - cmin    if cscale < 0:        raise ValueError("`cmax` should be larger than `cmin`.")    elif cscale == 0:        cscale = 1    scale = float(high - low) / cscale    bytedata = (data - cmin) * scale + low    return (bytedata.clip(low, high) + 0.5).astype(uint8)def imread(name, flatten=False, mode=None):    """    Read an image from a file as an array.    This function is only available if Python Imaging Library (PIL) is installed.    Parameters    ----------    name : str or file object        The file name or file object to be read.    flatten : bool, optional        If True, flattens the color layers into a single gray-scale layer.    mode : str, optional        Mode to convert image to, e.g. ``'RGB'``.  See the Notes for more        details.    Returns    -------    imread : ndarray        The array obtained by reading the image.    Notes    -----    `imread` uses the Python Imaging Library (PIL) to read an image.    The following notes are from the PIL documentation.    `mode` can be one of the following strings:    * 'L' (8-bit pixels, black and white)    * 'P' (8-bit pixels, mapped to any other mode using a color palette)    * 'RGB' (3x8-bit pixels, true color)    * 'RGBA' (4x8-bit pixels, true color with transparency mask)    * 'CMYK' (4x8-bit pixels, color separation)    * 'YCbCr' (3x8-bit pixels, color video format)    * 'I' (32-bit signed integer pixels)    * 'F' (32-bit floating point pixels)    PIL also provides limited support for a few special modes, including    'LA' ('L' with alpha), 'RGBX' (true color with padding) and 'RGBa'    (true color with premultiplied alpha).    When translating a color image to black and white (mode 'L', 'I' or    'F'), the library uses the ITU-R 601-2 luma transform::        L = R * 299/1000 + G * 587/1000 + B * 114/1000    When `flatten` is True, the image is converted using mode 'F'.    When `mode` is not None and `flatten` is True, the image is first    converted according to `mode`, and the result is then flattened using    mode 'F'.    """    if not pillow_installed:        raise ImportError("The Python Imaging Library (PIL) "                          "is required to load data from jpeg files")    im = Image.open(name)    return fromimage(im, flatten=flatten, mode=mode)def imsave(name, arr, format=None):    """    Save an array as an image.    This function is only available if Python Imaging Library (PIL) is installed.    .. warning::        This function uses `bytescale` under the hood to rescale images to use        the full (0, 255) range if ``mode`` is one of ``None, 'L', 'P', 'l'``.        It will also cast data for 2-D images to ``uint32`` for ``mode=None``        (which is the default).    Parameters    ----------    name : str or file object        Output file name or file object.    arr : ndarray, MxN or MxNx3 or MxNx4        Array containing image values.  If the shape is ``MxN``, the array        represents a grey-level image.  Shape ``MxNx3`` stores the red, green        and blue bands along the last dimension.  An alpha layer may be        included, specified as the last colour band of an ``MxNx4`` array.    format : str        Image format. If omitted, the format to use is determined from the        file name extension. If a file object was used instead of a file name,        this parameter should always be used.    Examples    --------    Construct an array of gradient intensity values and save to file:    >>> from scipy.misc import imsave    >>> x = np.zeros((255, 255))    >>> x = np.zeros((255, 255), dtype=np.uint8)    >>> x[:] = np.arange(255)    >>> imsave('gradient.png', x)    Construct an array with three colour bands (R, G, B) and store to file:    >>> rgb = np.zeros((255, 255, 3), dtype=np.uint8)    >>> rgb[..., 0] = np.arange(255)    >>> rgb[..., 1] = 55    >>> rgb[..., 2] = 1 - np.arange(255)    >>> imsave('rgb_gradient.png', rgb)    """    im = toimage(arr, channel_axis=2)    if format is None:        im.save(name)    else:        im.save(name, format)    returndef fromimage(im, flatten=False, mode=None):    """    Return a copy of a PIL image as a numpy array.    This function is only available if Python Imaging Library (PIL) is installed.    Parameters    ----------    im : PIL image        Input image.    flatten : bool        If true, convert the output to grey-scale.    mode : str, optional        Mode to convert image to, e.g. ``'RGB'``.  See the Notes of the        `imread` docstring for more details.    Returns    -------    fromimage : ndarray        The different colour bands/channels are stored in the        third dimension, such that a grey-image is MxN, an        RGB-image MxNx3 and an RGBA-image MxNx4.    """    if not pillow_installed:        raise ImportError("The Python Imaging Library (PIL) "                          "is required to load data from jpeg files")    if not Image.isImageType(im):        raise TypeError("Input is not a PIL image.")    if mode is not None:        if mode != im.mode:            im = im.convert(mode)    elif im.mode == 'P':        # Mode 'P' means there is an indexed "palette".  If we leave the mode        # as 'P', then when we do `a = array(im)` below, `a` will be a 2-D        # containing the indices into the palette, and not a 3-D array        # containing the RGB or RGBA values.        if 'transparency' in im.info:            im = im.convert('RGBA')        else:            im = im.convert('RGB')    if flatten:        im = im.convert('F')    elif im.mode == '1':        # Workaround for crash in PIL. When im is 1-bit, the call array(im)        # can cause a seg. fault, or generate garbage. See        # https://github.com/scipy/scipy/issues/2138 and        # https://github.com/python-pillow/Pillow/issues/350.        #        # This converts im from a 1-bit image to an 8-bit image.        im = im.convert('L')    a = array(im)    return a_errstr = "Mode is unknown or incompatible with input array shape."def toimage(arr, high=255, low=0, cmin=None, cmax=None, pal=None,            mode=None, channel_axis=None):    """Takes a numpy array and returns a PIL image.    This function is only available if Python Imaging Library (PIL) is installed.    The mode of the PIL image depends on the array shape and the `pal` and    `mode` keywords.    For 2-D arrays, if `pal` is a valid (N,3) byte-array giving the RGB values    (from 0 to 255) then ``mode='P'``, otherwise ``mode='L'``, unless mode    is given as 'F' or 'I' in which case a float and/or integer array is made.    .. warning::        This function uses `bytescale` under the hood to rescale images to use        the full (0, 255) range if ``mode`` is one of ``None, 'L', 'P', 'l'``.        It will also cast data for 2-D images to ``uint32`` for ``mode=None``        (which is the default).    Notes    -----    For 3-D arrays, the `channel_axis` argument tells which dimension of the    array holds the channel data.    For 3-D arrays if one of the dimensions is 3, the mode is 'RGB'    by default or 'YCbCr' if selected.    The numpy array must be either 2 dimensional or 3 dimensional.    """    if not pillow_installed:        raise ImportError("The Python Imaging Library (PIL) "                          "is required to load data from jpeg files")    data = asarray(arr)    if iscomplexobj(data):        raise ValueError("Cannot convert a complex-valued array.")    shape = list(data.shape)    valid = len(shape) == 2 or ((len(shape) == 3) and                                ((3 in shape) or (4 in shape)))    if not valid:        raise ValueError("'arr' does not have a suitable array shape for "                         "any mode.")    if len(shape) == 2:        shape = (shape[1], shape[0])  # columns show up first        if mode == 'F':            data32 = data.astype(numpy.float32)            image = Image.frombytes(mode, shape, data32.tostring())            return image        if mode in [None, 'L', 'P']:            bytedata = bytescale(data, high=high, low=low,                                 cmin=cmin, cmax=cmax)            image = Image.frombytes('L', shape, bytedata.tostring())            if pal is not None:                image.putpalette(asarray(pal, dtype=uint8).tostring())                # Becomes a mode='P' automagically.            elif mode == 'P':  # default gray-scale                pal = (arange(0, 256, 1, dtype=uint8)[:, newaxis] *                       ones((3,), dtype=uint8)[newaxis, :])                image.putpalette(asarray(pal, dtype=uint8).tostring())            return image        if mode == '1':  # high input gives threshold for 1            bytedata = (data > high)            image = Image.frombytes('1', shape, bytedata.tostring())            return image        if cmin is None:            cmin = amin(ravel(data))        if cmax is None:            cmax = amax(ravel(data))        data = (data*1.0 - cmin)*(high - low)/(cmax - cmin) + low        if mode == 'I':            data32 = data.astype(numpy.uint32)            image = Image.frombytes(mode, shape, data32.tostring())        else:            raise ValueError(_errstr)        return image    # if here then 3-d array with a 3 or a 4 in the shape length.    # Check for 3 in datacube shape --- 'RGB' or 'YCbCr'    if channel_axis is None:        if (3 in shape):            ca = numpy.flatnonzero(asarray(shape) == 3)[0]        else:            ca = numpy.flatnonzero(asarray(shape) == 4)            if len(ca):                ca = ca[0]            else:                raise ValueError("Could not find channel dimension.")    else:        ca = channel_axis    numch = shape[ca]    if numch not in [3, 4]:        raise ValueError("Channel axis dimension is not valid.")    bytedata = bytescale(data, high=high, low=low, cmin=cmin, cmax=cmax)    if ca == 2:        strdata = bytedata.tostring()        shape = (shape[1], shape[0])    elif ca == 1:        strdata = transpose(bytedata, (0, 2, 1)).tostring()        shape = (shape[2], shape[0])    elif ca == 0:        strdata = transpose(bytedata, (1, 2, 0)).tostring()        shape = (shape[2], shape[1])    if mode is None:        if numch == 3:            mode = 'RGB'        else:            mode = 'RGBA'    if mode not in ['RGB', 'RGBA', 'YCbCr', 'CMYK']:        raise ValueError(_errstr)    if mode in ['RGB', 'YCbCr']:        if numch != 3:            raise ValueError("Invalid array shape for mode.")    if mode in ['RGBA', 'CMYK']:        if numch != 4:            raise ValueError("Invalid array shape for mode.")    # Here we know data and mode is correct    image = Image.frombytes(mode, shape, strdata)    return imagedef imresize(arr, size, interp='bilinear', mode=None):    """    Resize an image.    This function is only available if Python Imaging Library (PIL) is installed.    .. warning::        This function uses `bytescale` under the hood to rescale images to use        the full (0, 255) range if ``mode`` is one of ``None, 'L', 'P', 'l'``.        It will also cast data for 2-D images to ``uint32`` for ``mode=None``        (which is the default).    Parameters    ----------    arr : ndarray        The array of image to be resized.    size : int, float or tuple        * int   - Percentage of current size.        * float - Fraction of current size.        * tuple - Size of the output image (height, width).    interp : str, optional        Interpolation to use for re-sizing ('nearest', 'lanczos', 'bilinear',        'bicubic' or 'cubic').    mode : str, optional        The PIL image mode ('P', 'L', etc.) to convert `arr` before resizing.        If ``mode=None`` (the default), 2-D images will be treated like        ``mode='L'``, i.e. casting to long integer.  For 3-D and 4-D arrays,        `mode` will be set to ``'RGB'`` and ``'RGBA'`` respectively.    Returns    -------    imresize : ndarray        The resized array of image.    See Also    --------    toimage : Implicitly used to convert `arr` according to `mode`.    scipy.ndimage.zoom : More generic implementation that does not use PIL.    """    im = toimage(arr, mode=mode)    ts = type(size)    if issubdtype(ts, numpy.signedinteger):        percent = size / 100.0        size = tuple((array(im.size)*percent).astype(int))    elif issubdtype(type(size), numpy.floating):        size = tuple((array(im.size)*size).astype(int))    else:        size = (size[1], size[0])    func = {'nearest': 0, 'lanczos': 1, 'bilinear': 2, 'bicubic': 3, 'cubic': 3}    imnew = im.resize(size, resample=func[interp])    return fromimage(imnew)</ins>


for check in _yield_clustering_checks(name, estimator):             yield check     yield check_fit2d_predict1d<ins>    yield check_methods_subset_invariance</ins>     if name != 'GaussianProcess':  # FIXME         # XXX GaussianProcess deprecated in 0.20         yield check_fit2d_1sample


getattr(estimator, method), X[0])  <ins>def _apply_func(func, X):    # apply function on the whole set and on mini batches    result_full = func(X)    n_features = X.shape[1]    result_by_batch = [func(batch.reshape(1, n_features))                       for batch in X]    # func can output tuple (e.g. score_samples)    if type(result_full) == tuple:        result_full = result_full[0]        result_by_batch = list(map(lambda x: x[0], result_by_batch))    return np.ravel(result_full), np.ravel(result_by_batch)@ignore_warnings(category=(DeprecationWarning, FutureWarning))def check_methods_subset_invariance(name, estimator_orig):    # check that method gives invariant results if applied    # on mini bathes or the whole set    rnd = np.random.RandomState(0)    X = 3 * rnd.uniform(size=(20, 3))    X = pairwise_estimator_convert_X(X, estimator_orig)    y = X[:, 0].astype(np.int)    estimator = clone(estimator_orig)    y = multioutput_estimator_convert_y_2d(estimator, y)    if hasattr(estimator, "n_components"):        estimator.n_components = 1    if hasattr(estimator, "n_clusters"):        estimator.n_clusters = 1    set_random_state(estimator, 1)    estimator.fit(X, y)    for method in ["predict", "transform", "decision_function",                   "score_samples", "predict_proba"]:        msg = ("{method} of {name} is not invariant when applied "               "to a subset.").format(method=method, name=name)        # TODO remove cases when corrected        if (name, method) in [('SVC', 'decision_function'),                              ('SparsePCA', 'transform'),                              ('MiniBatchSparsePCA', 'transform'),                              ('BernoulliRBM', 'score_samples')]:            raise SkipTest(msg)        if hasattr(estimator, method):            result_full, result_by_batch = _apply_func(                getattr(estimator, method), X)            assert_allclose(result_full, result_by_batch,                            atol=1e-7, err_msg=msg)</ins> @ignore_warnings def check_fit2d_1sample(name, estimator_orig):     # Check that fitting a 2d array with only one sample either works or


-------         self : instance         """        n_samples, n_features = check_array(X).shape        n_samples, n_features = check_array(X, accept_sparse=True).shape         combinations = self._combinations(n_features, self.degree,                                           self.interaction_only,                                           self.include_bias)


Parameters         ----------        X : array-like, shape [n_samples, n_features]        X : array-like or sparse matrix, shape [n_samples, n_features]             The data to transform, row by row.            Sparse input should preferably be in CSC format.          Returns         -------        XP : np.ndarray shape [n_samples, NP]        XP : np.ndarray or CSC sparse matrix, shape [n_samples, NP]             The matrix of features, where NP is the number of polynomial             features generated from the combination of inputs.         """         check_is_fitted(self, ['n_input_features_', 'n_output_features_'])         X = check_array(X, dtype=FLOAT_DTYPES)        X = check_array(X, dtype=FLOAT_DTYPES, accept_sparse='csc')         n_samples, n_features = X.shape          if n_features != self.n_input_features_:             raise ValueError("X shape does not match training shape")         # allocate output data        XP = np.empty((n_samples, self.n_output_features_), dtype=X.dtype)         combinations = self._combinations(n_features, self.degree,                                           self.interaction_only,                                           self.include_bias)        for i, c in enumerate(combinations):            XP[:, i] = X[:, c].prod(1)        if sparse.isspmatrix(X):            columns = []            for comb in combinations:                if comb:                    out_col = 1                    for col_idx in comb:                        out_col = X[:, col_idx].multiply(out_col)                    columns.append(out_col)                else:                    columns.append(sparse.csc_matrix(np.ones((X.shape[0], 1))))            XP = sparse.hstack(columns, dtype=X.dtype).tocsc()        else:            XP = np.empty((n_samples, self.n_output_features_), dtype=X.dtype)            for i, comb in enumerate(combinations):                XP[:, i] = X[:, comb].prod(1)          return XP


warnings.simplefilter('ignore', NonBLASDotWarning)  def _assert_all_finite(X):def _assert_all_finite(X, allow_nan=False):     """Like assert_all_finite, but only for ndarray."""     if _get_config()['assume_finite']:         return


# First try an O(n) time, O(1) space solution for the common case that     # everything is finite; fall back to O(n) space np.isfinite to prevent     # false positives from overflow in sum method.    if (X.dtype.char in np.typecodes['AllFloat'] and not np.isfinite(X.sum())            and not np.isfinite(X).all()):        raise ValueError("Input contains NaN, infinity"                         " or a value too large for %r." % X.dtype)def assert_all_finite(X):    is_float = X.dtype.kind in 'fc'    if is_float and np.isfinite(X.sum()):        pass    elif is_float:        msg_err = "Input contains {} or a value too large for {!r}."        if (allow_nan and np.isinf(X).any() or                not allow_nan and not np.isfinite(X).all()):            type_err = 'infinity' if allow_nan else 'NaN, infinity'            raise ValueError(msg_err.format(type_err, X.dtype))def assert_all_finite(X, allow_nan=False):     """Throw a ValueError if X contains NaN or infinity.      Parameters     ----------     X : array or sparse matrix    allow_nan : bool     """    _assert_all_finite(X.data if sp.issparse(X) else X)    _assert_all_finite(X.data if sp.issparse(X) else X, allow_nan)   def as_float_array(X, copy=True, force_all_finite=True):


If True, a copy of X will be created. If False, a copy may still be         returned if X's dtype is not a floating point type.     force_all_finite : boolean (default=True)        Whether to raise an error on np.inf and np.nan in X.    force_all_finite : boolean or 'allow-nan', (default=True)        Whether to raise an error on np.inf and np.nan in X. The possibilities        are:        - True: Force all values of X to be finite.        - False: accept both np.inf and np.nan in X.        - 'allow-nan':  accept  only  np.nan  values in  X.  Values  cannot  be          infinite.        .. versionadded:: 0.20           ``force_all_finite`` accepts the string ``'allow-nan'``.      Returns     -------


Whether a forced copy will be triggered. If copy=False, a copy might         be triggered by a conversion.     force_all_finite : boolean        Whether to raise an error on np.inf and np.nan in X.    force_all_finite : boolean or 'allow-nan', (default=True)        Whether to raise an error on np.inf and np.nan in X. The possibilities        are:        - True: Force all values of X to be finite.        - False: accept both np.inf and np.nan in X.        - 'allow-nan':  accept  only  np.nan  values in  X.  Values  cannot  be          infinite.        .. versionadded:: 0.20           ``force_all_finite`` accepts the string ``'allow-nan'``.      Returns     -------


warnings.warn("Can't check %s sparse matrix for nan or inf."                           % spmatrix.format)         else:            _assert_all_finite(spmatrix.data)            _assert_all_finite(spmatrix.data,                               allow_nan=force_all_finite == 'allow-nan')     return spmatrix


Whether a forced copy will be triggered. If copy=False, a copy might         be triggered by a conversion.     force_all_finite : boolean (default=True)        Whether to raise an error on np.inf and np.nan in X.    force_all_finite : boolean or 'allow-nan', (default=True)        Whether to raise an error on np.inf and np.nan in X. The possibilities        are:        - True: Force all values of X to be finite.        - False: accept both np.inf and np.nan in X.        - 'allow-nan':  accept  only  np.nan  values in  X.  Values  cannot  be          infinite.        .. versionadded:: 0.20           ``force_all_finite`` accepts the string ``'allow-nan'``.      ensure_2d : boolean (default=True)         Whether to raise a value error if X is not 2d.


# list of accepted types.             dtype = dtype[0] <ins>    if force_all_finite not in (True, False, 'allow-nan'):        raise ValueError('force_all_finite should be a bool or "allow-nan"'                         '. Got {!r} instead'.format(force_all_finite))</ins>     if estimator is not None:         if isinstance(estimator, six.string_types):             estimator_name = estimator


raise ValueError("Found array with dim %d. %s expected <= 2."                              % (array.ndim, estimator_name))         if force_all_finite:            _assert_all_finite(array)            _assert_all_finite(array,                               allow_nan=force_all_finite == 'allow-nan')      shape_repr = _shape_repr(array.shape)     if ensure_min_samples > 0:


Whether a forced copy will be triggered. If copy=False, a copy might         be triggered by a conversion.     force_all_finite : boolean (default=True)    force_all_finite : boolean or 'allow-nan', (default=True)         Whether to raise an error on np.inf and np.nan in X. This parameter         does not influence whether y can have np.inf or np.nan values.        The possibilities are:        - True: Force all values of X to be finite.        - False: accept both np.inf and np.nan in X.        - 'allow-nan':  accept  only  np.nan  values in  X.  Values  cannot  be          infinite.        .. versionadded:: 0.20           ``force_all_finite`` accepts the string ``'allow-nan'``.      ensure_2d : boolean (default=True)         Whether to make X at least 2d.


from sklearn.datasets import load_boston from sklearn.ensemble import RandomForestRegressor from sklearn.pipeline import Pipelinefrom sklearn.preprocessing import Imputerfrom sklearn.impute import SimpleImputer from sklearn.model_selection import cross_val_score  rng = np.random.RandomState(0)


X_missing = X_full.copy() X_missing[np.where(missing_samples)[0], missing_features] = 0 y_missing = y_full.copy()estimator = Pipeline([("imputer", Imputer(missing_values=0,                                          strategy="mean",                                          axis=0)),estimator = Pipeline([("imputer", SimpleImputer(missing_values=0,                                                strategy="mean",                                                axis=0)),                       ("forest", RandomForestRegressor(random_state=0,                                                        n_estimators=100))]) score = cross_val_score(estimator, X_missing, y_missing).mean()diff --git a/sklearn/__init__.py b/sklearn/__init__.py-- a/sklearn/__init__.py++ b/sklearn/__init__.py


'mixture', 'model_selection', 'multiclass', 'multioutput',                'naive_bayes', 'neighbors', 'neural_network', 'pipeline',                'preprocessing', 'random_projection', 'semi_supervised',               'svm', 'tree', 'discriminant_analysis',               'svm', 'tree', 'discriminant_analysis', 'impute',                # Non-modules:                'clone', 'get_config', 'set_config', 'config_context'] diff --git a/sklearn/impute.py b/sklearn/impute.pynew file mode 100644-- /dev/null++ b/sklearn/impute.py


"""Transformers for missing value imputation"""# Authors: Nicolas Tresegnie <nicolas.tresegnie@gmail.com># License: BSD 3 clauseimport warningsimport numpy as npimport numpy.ma as mafrom scipy import sparsefrom scipy import statsfrom .base import BaseEstimator, TransformerMixinfrom .utils import check_arrayfrom .utils.sparsefuncs import _get_medianfrom .utils.validation import check_is_fittedfrom .utils.validation import FLOAT_DTYPESfrom .externals import sixzip = six.moves.zipmap = six.moves.map__all__ = [    'SimpleImputer',]def _get_mask(X, value_to_mask):    """Compute the boolean mask X == missing_values."""    if value_to_mask == "NaN" or np.isnan(value_to_mask):        return np.isnan(X)    else:        return X == value_to_maskdef _most_frequent(array, extra_value, n_repeat):    """Compute the most frequent value in a 1d array extended with       [extra_value] * n_repeat, where extra_value is assumed to be not part       of the array."""    # Compute the most frequent value in array only    if array.size > 0:        mode = stats.mode(array)        most_frequent_value = mode[0][0]        most_frequent_count = mode[1][0]    else:        most_frequent_value = 0        most_frequent_count = 0    # Compare to array + [extra_value] * n_repeat    if most_frequent_count == 0 and n_repeat == 0:        return np.nan    elif most_frequent_count < n_repeat:        return extra_value    elif most_frequent_count > n_repeat:        return most_frequent_value    elif most_frequent_count == n_repeat:        # Ties the breaks. Copy the behaviour of scipy.stats.mode        if most_frequent_value < extra_value:            return most_frequent_value        else:            return extra_valueclass SimpleImputer(BaseEstimator, TransformerMixin):    """Imputation transformer for completing missing values.    Read more in the :ref:`User Guide <impute>`.    Parameters    ----------    missing_values : integer or "NaN", optional (default="NaN")        The placeholder for the missing values. All occurrences of        `missing_values` will be imputed. For missing values encoded as np.nan,        use the string value "NaN".    strategy : string, optional (default="mean")        The imputation strategy.        - If "mean", then replace missing values using the mean along          the axis.        - If "median", then replace missing values using the median along          the axis.        - If "most_frequent", then replace missing using the most frequent          value along the axis.    axis : integer, optional (default=0)        The axis along which to impute.        - If `axis=0`, then impute along columns.        - If `axis=1`, then impute along rows.    verbose : integer, optional (default=0)        Controls the verbosity of the imputer.    copy : boolean, optional (default=True)        If True, a copy of X will be created. If False, imputation will        be done in-place whenever possible. Note that, in the following cases,        a new copy will always be made, even if `copy=False`:        - If X is not an array of floating values;        - If X is sparse and `missing_values=0`;        - If `axis=0` and X is encoded as a CSR matrix;        - If `axis=1` and X is encoded as a CSC matrix.    Attributes    ----------    statistics_ : array of shape (n_features,)        The imputation fill value for each feature if axis == 0.    Notes    -----    - When ``axis=0``, columns which only contained missing values at `fit`      are discarded upon `transform`.    - When ``axis=1``, an exception is raised if there are rows for which it is      not possible to fill in the missing values (e.g., because they only      contain missing values).    """    def __init__(self, missing_values="NaN", strategy="mean",                 axis=0, verbose=0, copy=True):        self.missing_values = missing_values        self.strategy = strategy        self.axis = axis        self.verbose = verbose        self.copy = copy    def fit(self, X, y=None):        """Fit the imputer on X.        Parameters        ----------        X : {array-like, sparse matrix}, shape (n_samples, n_features)            Input data, where ``n_samples`` is the number of samples and            ``n_features`` is the number of features.        Returns        -------        self : SimpleImputer        """        # Check parameters        allowed_strategies = ["mean", "median", "most_frequent"]        if self.strategy not in allowed_strategies:            raise ValueError("Can only use these strategies: {0} "                             " got strategy={1}".format(allowed_strategies,                                                        self.strategy))        if self.axis not in [0, 1]:            raise ValueError("Can only impute missing values on axis 0 and 1, "                             " got axis={0}".format(self.axis))        # Since two different arrays can be provided in fit(X) and        # transform(X), the imputation data will be computed in transform()        # when the imputation is done per sample (i.e., when axis=1).        if self.axis == 0:            X = check_array(X, accept_sparse='csc', dtype=np.float64,                            force_all_finite=False)            if sparse.issparse(X):                self.statistics_ = self._sparse_fit(X,                                                    self.strategy,                                                    self.missing_values,                                                    self.axis)            else:                self.statistics_ = self._dense_fit(X,                                                   self.strategy,                                                   self.missing_values,                                                   self.axis)        return self    def _sparse_fit(self, X, strategy, missing_values, axis):        """Fit the transformer on sparse data."""        # Imputation is done "by column", so if we want to do it        # by row we only need to convert the matrix to csr format.        if axis == 1:            X = X.tocsr()        else:            X = X.tocsc()        # Count the zeros        if missing_values == 0:            n_zeros_axis = np.zeros(X.shape[not axis], dtype=int)        else:            n_zeros_axis = X.shape[axis] - np.diff(X.indptr)        # Mean        if strategy == "mean":            if missing_values != 0:                n_non_missing = n_zeros_axis                # Mask the missing elements                mask_missing_values = _get_mask(X.data, missing_values)                mask_valids = np.logical_not(mask_missing_values)                # Sum only the valid elements                new_data = X.data.copy()                new_data[mask_missing_values] = 0                X = sparse.csc_matrix((new_data, X.indices, X.indptr),                                      copy=False)                sums = X.sum(axis=0)                # Count the elements != 0                mask_non_zeros = sparse.csc_matrix(                    (mask_valids.astype(np.float64),                     X.indices,                     X.indptr), copy=False)                s = mask_non_zeros.sum(axis=0)                n_non_missing = np.add(n_non_missing, s)            else:                sums = X.sum(axis=axis)                n_non_missing = np.diff(X.indptr)            # Ignore the error, columns with a np.nan statistics_            # are not an error at this point. These columns will            # be removed in transform            with np.errstate(all="ignore"):                return np.ravel(sums) / np.ravel(n_non_missing)        # Median + Most frequent        else:            # Remove the missing values, for each column            columns_all = np.hsplit(X.data, X.indptr[1:-1])            mask_missing_values = _get_mask(X.data, missing_values)            mask_valids = np.hsplit(np.logical_not(mask_missing_values),                                    X.indptr[1:-1])            # astype necessary for bug in numpy.hsplit before v1.9            columns = [col[mask.astype(bool, copy=False)]                       for col, mask in zip(columns_all, mask_valids)]            # Median            if strategy == "median":                median = np.empty(len(columns))                for i, column in enumerate(columns):                    median[i] = _get_median(column, n_zeros_axis[i])                return median            # Most frequent            elif strategy == "most_frequent":                most_frequent = np.empty(len(columns))                for i, column in enumerate(columns):                    most_frequent[i] = _most_frequent(column,                                                      0,                                                      n_zeros_axis[i])                return most_frequent    def _dense_fit(self, X, strategy, missing_values, axis):        """Fit the transformer on dense data."""        X = check_array(X, force_all_finite=False)        mask = _get_mask(X, missing_values)        masked_X = ma.masked_array(X, mask=mask)        # Mean        if strategy == "mean":            mean_masked = np.ma.mean(masked_X, axis=axis)            # Avoid the warning "Warning: converting a masked element to nan."            mean = np.ma.getdata(mean_masked)            mean[np.ma.getmask(mean_masked)] = np.nan            return mean        # Median        elif strategy == "median":            if tuple(int(v) for v in np.__version__.split('.')[:2]) < (1, 5):                # In old versions of numpy, calling a median on an array                # containing nans returns nan. This is different is                # recent versions of numpy, which we want to mimic                masked_X.mask = np.logical_or(masked_X.mask,                                              np.isnan(X))            median_masked = np.ma.median(masked_X, axis=axis)            # Avoid the warning "Warning: converting a masked element to nan."            median = np.ma.getdata(median_masked)            median[np.ma.getmaskarray(median_masked)] = np.nan            return median        # Most frequent        elif strategy == "most_frequent":            # scipy.stats.mstats.mode cannot be used because it will no work            # properly if the first element is masked and if its frequency            # is equal to the frequency of the most frequent valid element            # See https://github.com/scipy/scipy/issues/2636            # To be able access the elements by columns            if axis == 0:                X = X.transpose()                mask = mask.transpose()            most_frequent = np.empty(X.shape[0])            for i, (row, row_mask) in enumerate(zip(X[:], mask[:])):                row_mask = np.logical_not(row_mask).astype(np.bool)                row = row[row_mask]                most_frequent[i] = _most_frequent(row, np.nan, 0)            return most_frequent    def transform(self, X):        """Impute all missing values in X.        Parameters        ----------        X : {array-like, sparse matrix}, shape = [n_samples, n_features]            The input data to complete.        """        if self.axis == 0:            check_is_fitted(self, 'statistics_')            X = check_array(X, accept_sparse='csc', dtype=FLOAT_DTYPES,                            force_all_finite=False, copy=self.copy)            statistics = self.statistics_            if X.shape[1] != statistics.shape[0]:                raise ValueError("X has %d features per sample, expected %d"                                 % (X.shape[1], self.statistics_.shape[0]))        # Since two different arrays can be provided in fit(X) and        # transform(X), the imputation data need to be recomputed        # when the imputation is done per sample        else:            X = check_array(X, accept_sparse='csr', dtype=FLOAT_DTYPES,                            force_all_finite=False, copy=self.copy)            if sparse.issparse(X):                statistics = self._sparse_fit(X,                                              self.strategy,                                              self.missing_values,                                              self.axis)            else:                statistics = self._dense_fit(X,                                             self.strategy,                                             self.missing_values,                                             self.axis)        # Delete the invalid rows/columns        invalid_mask = np.isnan(statistics)        valid_mask = np.logical_not(invalid_mask)        valid_statistics = statistics[valid_mask]        valid_statistics_indexes = np.where(valid_mask)[0]        missing = np.arange(X.shape[not self.axis])[invalid_mask]        if self.axis == 0 and invalid_mask.any():            if self.verbose:                warnings.warn("Deleting features without "                              "observed values: %s" % missing)            X = X[:, valid_statistics_indexes]        elif self.axis == 1 and invalid_mask.any():            raise ValueError("Some rows only contain "                             "missing values: %s" % missing)        # Do actual imputation        if sparse.issparse(X) and self.missing_values != 0:            mask = _get_mask(X.data, self.missing_values)            indexes = np.repeat(np.arange(len(X.indptr) - 1, dtype=np.int),                                np.diff(X.indptr))[mask]            X.data[mask] = valid_statistics[indexes].astype(X.dtype,                                                            copy=False)        else:            if sparse.issparse(X):                X = X.toarray()            mask = _get_mask(X, self.missing_values)            n_missing = np.sum(mask, axis=self.axis)            values = np.repeat(valid_statistics, n_missing)            if self.axis == 0:                coordinates = np.where(mask.transpose())[::-1]            else:                coordinates = mask            X[coordinates] = values        return Xdiff --git a/sklearn/preprocessing/imputation.py b/sklearn/preprocessing/imputation.py-- a/sklearn/preprocessing/imputation.py++ b/sklearn/preprocessing/imputation.py


from ..base import BaseEstimator, TransformerMixin from ..utils import check_array<ins>from ..utils import deprecated</ins> from ..utils.sparsefuncs import _get_median from ..utils.validation import check_is_fitted from ..utils.validation import FLOAT_DTYPES


return extra_value  @deprecated("Imputer was deprecated in version 0.20 and will be "            "removed in 0.22. Import impute.SimpleImputer from "            "sklearn instead.") class Imputer(BaseEstimator, TransformerMixin):     """Imputation transformer for completing missing values. diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py-- a/sklearn/utils/estimator_checks.py++ b/sklearn/utils/estimator_checks.py


# cross-decomposition's "transform" returns X and Y         yield check_pipeline_consistency     if name not in ['Imputer']:    if name not in ['SimpleImputer', 'Imputer']:         # Test that all estimators check their input for NaN's and infs         yield check_estimators_nan_inf


# To ensure that array flags are maintained             array = np.array(array, dtype=dtype, order=order, copy=copy) <ins>        # in the future np.flexible dtypes will be handled like object dtypes        if dtype_numeric and np.issubdtype(array.dtype, np.flexible):            warnings.warn(                "Beginning in version 0.22, arrays of strings will be "                "interpreted as decimal numbers if parameter 'dtype' is "                "'numeric'. It is recommended that you convert the array to "                "type np.float64 before passing it to check_array.",                FutureWarning)</ins>         # make sure we actually converted to numeric:         if dtype_numeric and array.dtype.kind == "O":             array = array.astype(np.float64)


"""         check_is_fitted(self, 'classes_')         y = column_or_1d(y, warn=True)<ins>        # transform of empty array is empty array        if _num_samples(y) == 0:            return np.array([])</ins>          classes = np.unique(y)         if len(np.intersect1d(classes, self.classes_)) < len(classes):


y : numpy array of shape [n_samples]         """         check_is_fitted(self, 'classes_')<ins>        y = column_or_1d(y, warn=True)        # inverse transform of empty array is empty array        if _num_samples(y) == 0:            return np.array([])</ins>          diff = np.setdiff1d(y, np.arange(len(self.classes_)))         if len(diff):


X_missing[np.where(missing_samples)[0], missing_features] = 0 y_missing = y_full.copy() estimator = Pipeline([("imputer", Imputer(missing_values=0,                                          strategy="mean",                                          axis=0)),                                          strategy="mean")),                       ("forest", RandomForestRegressor(random_state=0,                                                        n_estimators=100))]) score = cross_val_score(estimator, X_missing, y_missing).mean()diff --git a/sklearn/preprocessing/imputation.py b/sklearn/preprocessing/imputation.py-- a/sklearn/preprocessing/imputation.py++ b/sklearn/preprocessing/imputation.py


- If "most_frequent", then replace missing using the most frequent           value along the axis.     axis : integer, optional (default=0)    axis : integer, optional (default=None)         The axis along which to impute.          - If `axis=0`, then impute along columns.         - If `axis=1`, then impute along rows.         .. deprecated:: 0.20           Parameter ``axis`` has been deprecated in 0.20 and will be removed           in 0.22. Future (and default) behavior is equivalent to ``axis=0``           (impute along columns). Row-wise imputation can be performed with           FunctionTransformer (e.g.,           ``FunctionTransformer(lambda X: Imputer().fit_transform(X.T).T)``).     verbose : integer, optional (default=0)         Controls the verbosity of the imputer.


contain missing values).     """     def __init__(self, missing_values="NaN", strategy="mean",                 axis=0, verbose=0, copy=True):                 axis=None, verbose=0, copy=True):         self.missing_values = missing_values         self.strategy = strategy         self.axis = axis


" got strategy={1}".format(allowed_strategies,                                                         self.strategy))         if self.axis not in [0, 1]:        if self.axis is None:            self._axis = 0        else:            warnings.warn("Parameter 'axis' has been deprecated in 0.20 and "                          "will be removed in 0.22. Future (and default) "                          "behavior is equivalent to 'axis=0' (impute along "                          "columns). Row-wise imputation can be performed "                          "with FunctionTransformer.", DeprecationWarning)            self._axis = self.axis        if self._axis not in [0, 1]:             raise ValueError("Can only impute missing values on axis 0 and 1, "                             " got axis={0}".format(self.axis))                             " got axis={0}".format(self._axis))          # Since two different arrays can be provided in fit(X) and         # transform(X), the imputation data will be computed in transform()         # when the imputation is done per sample (i.e., when axis=1).        if self.axis == 0:        if self._axis == 0:             X = check_array(X, accept_sparse='csc', dtype=np.float64,                             force_all_finite=False)


self.statistics_ = self._sparse_fit(X,                                                     self.strategy,                                                     self.missing_values,                                                    self.axis)                                                    self._axis)             else:                 self.statistics_ = self._dense_fit(X,                                                    self.strategy,                                                    self.missing_values,                                                   self.axis)                                                   self._axis)          return self


X : {array-like, sparse matrix}, shape = [n_samples, n_features]             The input data to complete.         """        if self.axis == 0:        if self._axis == 0:             check_is_fitted(self, 'statistics_')             X = check_array(X, accept_sparse='csc', dtype=FLOAT_DTYPES,                             force_all_finite=False, copy=self.copy)


statistics = self._sparse_fit(X,                                               self.strategy,                                               self.missing_values,                                              self.axis)                                              self._axis)              else:                 statistics = self._dense_fit(X,                                              self.strategy,                                              self.missing_values,                                             self.axis)                                             self._axis)          # Delete the invalid rows/columns         invalid_mask = np.isnan(statistics)         valid_mask = np.logical_not(invalid_mask)         valid_statistics = statistics[valid_mask]         valid_statistics_indexes = np.where(valid_mask)[0]        missing = np.arange(X.shape[not self.axis])[invalid_mask]        missing = np.arange(X.shape[not self._axis])[invalid_mask]         if self.axis == 0 and invalid_mask.any():        if self._axis == 0 and invalid_mask.any():             if self.verbose:                 warnings.warn("Deleting features without "                               "observed values: %s" % missing)             X = X[:, valid_statistics_indexes]        elif self.axis == 1 and invalid_mask.any():        elif self._axis == 1 and invalid_mask.any():             raise ValueError("Some rows only contain "                              "missing values: %s" % missing)


X = X.toarray()              mask = _get_mask(X, self.missing_values)            n_missing = np.sum(mask, axis=self.axis)            n_missing = np.sum(mask, axis=self._axis)             values = np.repeat(valid_statistics, n_missing)             if self.axis == 0:            if self._axis == 0:                 coordinates = np.where(mask.transpose())[::-1]             else:                 coordinates = mask


import numpy as np import matplotlib.pyplot as plt from sklearn import svmfrom sklearn.datasets import make_blobs # we create clusters with 1000 and 100 pointsrng = np.random.RandomState(0)# we create two clusters of random points n_samples_1 = 1000 n_samples_2 = 100X = np.r_[1.5 * rng.randn(n_samples_1, 2),          0.5 * rng.randn(n_samples_2, 2) + [2, 2]]y = [0] * (n_samples_1) + [1] * (n_samples_2)centers = [[0.0, 0.0], [2.0, 2.0]]clusters_std = [1.5, 0.5]X, y = make_blobs(n_samples=[n_samples_1, n_samples_2],                  centers=centers,                  cluster_std=clusters_std,                  random_state=0, shuffle=False)  # fit the model and get the separating hyperplane clf = svm.SVC(kernel='linear', C=1.0)diff --git a/sklearn/datasets/samples_generator.py b/sklearn/datasets/samples_generator.py-- a/sklearn/datasets/samples_generator.py++ b/sklearn/datasets/samples_generator.py


import numpy as np from scipy import linalg import scipy.sparse as sp<ins>from collections import Iterable</ins>  from ..preprocessing import MultiLabelBinarizer from ..utils import check_array, check_random_state


return X, y  def make_blobs(n_samples=100, n_features=2, centers=3, cluster_std=1.0,def make_blobs(n_samples=100, n_features=2, centers=None, cluster_std=1.0,                center_box=(-10.0, 10.0), shuffle=True, random_state=None):     """Generate isotropic Gaussian blobs for clustering.


Parameters     ----------    n_samples : int, optional (default=100)        The total number of points equally divided among clusters.    n_samples : int or array-like, optional (default=100)        If int, it is the the total number of points equally divided among        clusters.        If array-like, each element of the sequence indicates        the number of samples per cluster.      n_features : int, optional (default=2)         The number of features for each sample.      centers : int or array of shape [n_centers, n_features], optional        (default=3)        (default=None)         The number of centers to generate, or the fixed center locations.        If n_samples is an int and centers is None, 3 centers are generated.        If n_samples is array-like, centers must be        either None or an array of length equal to the length of n_samples.      cluster_std : float or sequence of floats, optional (default=1.0)         The standard deviation of the clusters.


(10, 2)     >>> y     array([0, 0, 1, 0, 2, 2, 2, 1, 1, 0])<ins>    >>> X, y = make_blobs(n_samples=[3, 3, 4], centers=None, n_features=2,    ...                   random_state=0)    >>> print(X.shape)    (10, 2)    >>> y    array([0, 1, 2, 0, 2, 2, 2, 1, 1, 0])</ins>      See also     --------