prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Name normalization issue in 10.0.0b1 yields false-positive installation warnings
  * Pip version: 10.0.0b1
  * Python version: 2.7.14
  * Operating system: Linux
  
  ### Description:
  
  The new pip check mode used during installation wrongly reports that packages are not being installed. This only happens for package containing a `.` (dot) in the name.
  
  ### What I've run:
  
  ```
  pip install pyramid
  Collecting pyramid
    Using cached pyramid-1.9.1-py2.py3-none-any.whl
  Collecting zope.interface>=3.8.0 (from pyramid)
    Using cached zope.interface-4.4.3-cp36-cp36m-manylinux1_x86_64.whl
  Collecting hupper (from pyramid)
    Using cached hupper-1.1-py2.py3-none-any.whl
  Collecting zope.deprecation>=3.5.0 (from pyramid)
    Using cached zope.deprecation-4.3.0-py2.py3-none-any.whl
  Collecting translationstring>=0.4 (from pyramid)
    Using cached translationstring-1.3-py2.py3-none-any.whl
  Requirement already satisfied: setuptools in ./venv-ex/lib/python3.6/site-packages (from pyramid) (39.0.1)
  Collecting WebOb>=1.7.0rc2 (from pyramid)
    Using cached WebOb-1.8.0rc1-py2.py3-none-any.whl
  Collecting venusian>=1.0a3 (from pyramid)
    Using cached venusian-1.1.0-py2.py3-none-any.whl
  Collecting repoze.lru>=0.4 (from pyramid)
    Using cached repoze.lru-0.7-py3-none-any.whl
  Collecting plaster-pastedeploy (from pyramid)
    Using cached plaster_pastedeploy-0.5-py2.py3-none-any.whl
  Collecting PasteDeploy>=1.5.0 (from pyramid)
    Using cached PasteDeploy-1.5.2-py2.py3-none-any.whl
  Collecting plaster (from pyramid)
    Using cached plaster-1.0-py2.py3-none-any.whl
  pyramid 1.9.1 requires repoze.lru>=0.4, which is not installed.
  pyramid 1.9.1 requires zope.deprecation>=3.5.0, which is not installed.
  pyramid 1.9.1 requires zope.interface>=3.8.0, which is not installed.
  Installing collected packages: zope.interface, hupper, zope.deprecation, translationstring, WebOb, venusian, repoze.lru, PasteDeploy, plaster, plaster-pastedeploy, pyramid
  Successfully installed PasteDeploy-1.5.2 WebOb-1.8.0rc1 hupper-1.1 plaster-1.0 plaster-pastedeploy-0.5 pyramid-1.9.1 repoze.lru-0.7 translationstring-1.3 venusian-1.1.0 zope.deprecation-4.3.0 zope.interface-4.4.3
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/pip/_internal/operations/check.py`
  Content:
  ```
  1 """Validation of dependencies of packages
  2 """
  3 
  4 from collections import namedtuple
  5 
  6 from pip._vendor.packaging.utils import canonicalize_name
  7 
  8 from pip._internal.operations.prepare import make_abstract_dist
  9 
  10 from pip._internal.utils.misc import get_installed_distributions
  11 from pip._internal.utils.typing import MYPY_CHECK_RUNNING
  12 
  13 if MYPY_CHECK_RUNNING:
  14     from pip._internal.req.req_install import InstallRequirement
  15     from typing import Any, Dict, Iterator, Set, Tuple, List
  16 
  17     # Shorthands
  18     PackageSet = Dict[str, 'PackageDetails']
  19     Missing = Tuple[str, Any]
  20     Conflicting = Tuple[str, str, Any]
  21 
  22     MissingDict = Dict[str, List[Missing]]
  23     ConflictingDict = Dict[str, List[Conflicting]]
  24     CheckResult = Tuple[MissingDict, ConflictingDict]
  25 
  26 PackageDetails = namedtuple('PackageDetails', ['version', 'requires'])
  27 
  28 
  29 def create_package_set_from_installed(**kwargs):
  30     # type: (**Any) -> PackageSet
  31     """Converts a list of distributions into a PackageSet.
  32     """
  33     retval = {}
  34     for dist in get_installed_distributions(**kwargs):
  35         name = canonicalize_name(dist.project_name)
  36         retval[name] = PackageDetails(dist.version, dist.requires())
  37     return retval
  38 
  39 
  40 def check_package_set(package_set):
  41     # type: (PackageSet) -> CheckResult
  42     """Check if a package set is consistent
  43     """
  44     missing = dict()
  45     conflicting = dict()
  46 
  47     for package_name in package_set:
  48         # Info about dependencies of package_name
  49         missing_deps = set()  # type: Set[Missing]
  50         conflicting_deps = set()  # type: Set[Conflicting]
  51 
  52         for req in package_set[package_name].requires:
  53             name = canonicalize_name(req.project_name)  # type: str
  54 
  55             # Check if it's missing
  56             if name not in package_set:
  57                 missed = True
  58                 if req.marker is not None:
  59                     missed = req.marker.evaluate()
  60                 if missed:
  61                     missing_deps.add((name, req))
  62                 continue
  63 
  64             # Check if there's a conflict
  65             version = package_set[name].version  # type: str
  66             if version not in req.specifier:
  67                 conflicting_deps.add((name, version, req))
  68 
  69         def str_key(x):
  70             return str(x)
  71 
  72         if missing_deps:
  73             missing[package_name] = sorted(missing_deps, key=str_key)
  74         if conflicting_deps:
  75             conflicting[package_name] = sorted(conflicting_deps, key=str_key)
  76 
  77     return missing, conflicting
  78 
  79 
  80 def check_install_conflicts(to_install):
  81     # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult]
  82     """For checking if the dependency graph would be consistent after \
  83     installing given requirements
  84     """
  85     # Start from the current state
  86     state = create_package_set_from_installed()
  87     _simulate_installation_of(to_install, state)
  88     return state, check_package_set(state)
  89 
  90 
  91 # NOTE from @pradyunsg
  92 # This required a minor update in dependency link handling logic over at
  93 # operations.prepare.IsSDist.dist() to get it working
  94 def _simulate_installation_of(to_install, state):
  95     # type: (List[InstallRequirement], PackageSet) -> None
  96     """Computes the version of packages after installing to_install.
  97     """
  98 
  99     # Modify it as installing requirement_set would (assuming no errors)
  100     for inst_req in to_install:
  101         dist = make_abstract_dist(inst_req).dist(finder=None)
  102         state[dist.key] = PackageDetails(dist.version, dist.requires())
  103
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/pip/_internal/operations/check.py b/src/pip/_internal/operations/check.py
  --- a/src/pip/_internal/operations/check.py
  +++ b/src/pip/_internal/operations/check.py
  @@ -99,4 +99,5 @@
       # Modify it as installing requirement_set would (assuming no errors)
       for inst_req in to_install:
           dist = make_abstract_dist(inst_req).dist(finder=None)
  -        state[dist.key] = PackageDetails(dist.version, dist.requires())
  +        name = canonicalize_name(dist.key)
  +        state[name] = PackageDetails(dist.version, dist.requires())
  
verification_info: {"golden_diff": "diff --git a/src/pip/_internal/operations/check.py b/src/pip/_internal/operations/check.py\n--- a/src/pip/_internal/operations/check.py\n+++ b/src/pip/_internal/operations/check.py\n@@ -99,4 +99,5 @@\n     # Modify it as installing requirement_set would (assuming no errors)\n     for inst_req in to_install:\n         dist = make_abstract_dist(inst_req).dist(finder=None)\n-        state[dist.key] = PackageDetails(dist.version, dist.requires())\n+        name = canonicalize_name(dist.key)\n+        state[name] = PackageDetails(dist.version, dist.requires())\n", "issue": "Name normalization issue in 10.0.0b1 yields false-positive installation warnings\n* Pip version: 10.0.0b1\r\n* Python version: 2.7.14\r\n* Operating system: Linux\r\n\r\n### Description:\r\n\r\nThe new pip check mode used during installation wrongly reports that packages are not being installed. This only happens for package containing a `.` (dot) in the name.\r\n\r\n### What I've run:\r\n\r\n```\r\npip install pyramid\r\nCollecting pyramid\r\n  Using cached pyramid-1.9.1-py2.py3-none-any.whl\r\nCollecting zope.interface>=3.8.0 (from pyramid)\r\n  Using cached zope.interface-4.4.3-cp36-cp36m-manylinux1_x86_64.whl\r\nCollecting hupper (from pyramid)\r\n  Using cached hupper-1.1-py2.py3-none-any.whl\r\nCollecting zope.deprecation>=3.5.0 (from pyramid)\r\n  Using cached zope.deprecation-4.3.0-py2.py3-none-any.whl\r\nCollecting translationstring>=0.4 (from pyramid)\r\n  Using cached translationstring-1.3-py2.py3-none-any.whl\r\nRequirement already satisfied: setuptools in ./venv-ex/lib/python3.6/site-packages (from pyramid) (39.0.1)\r\nCollecting WebOb>=1.7.0rc2 (from pyramid)\r\n  Using cached WebOb-1.8.0rc1-py2.py3-none-any.whl\r\nCollecting venusian>=1.0a3 (from pyramid)\r\n  Using cached venusian-1.1.0-py2.py3-none-any.whl\r\nCollecting repoze.lru>=0.4 (from pyramid)\r\n  Using cached repoze.lru-0.7-py3-none-any.whl\r\nCollecting plaster-pastedeploy (from pyramid)\r\n  Using cached plaster_pastedeploy-0.5-py2.py3-none-any.whl\r\nCollecting PasteDeploy>=1.5.0 (from pyramid)\r\n  Using cached PasteDeploy-1.5.2-py2.py3-none-any.whl\r\nCollecting plaster (from pyramid)\r\n  Using cached plaster-1.0-py2.py3-none-any.whl\r\npyramid 1.9.1 requires repoze.lru>=0.4, which is not installed.\r\npyramid 1.9.1 requires zope.deprecation>=3.5.0, which is not installed.\r\npyramid 1.9.1 requires zope.interface>=3.8.0, which is not installed.\r\nInstalling collected packages: zope.interface, hupper, zope.deprecation, translationstring, WebOb, venusian, repoze.lru, PasteDeploy, plaster, plaster-pastedeploy, pyramid\r\nSuccessfully installed PasteDeploy-1.5.2 WebOb-1.8.0rc1 hupper-1.1 plaster-1.0 plaster-pastedeploy-0.5 pyramid-1.9.1 repoze.lru-0.7 translationstring-1.3 venusian-1.1.0 zope.deprecation-4.3.0 zope.interface-4.4.3\r\n```\r\n\n", "before_files": [{"content": "\"\"\"Validation of dependencies of packages\n\"\"\"\n\nfrom collections import namedtuple\n\nfrom pip._vendor.packaging.utils import canonicalize_name\n\nfrom pip._internal.operations.prepare import make_abstract_dist\n\nfrom pip._internal.utils.misc import get_installed_distributions\nfrom pip._internal.utils.typing import MYPY_CHECK_RUNNING\n\nif MYPY_CHECK_RUNNING:\n    from pip._internal.req.req_install import InstallRequirement\n    from typing import Any, Dict, Iterator, Set, Tuple, List\n\n    # Shorthands\n    PackageSet = Dict[str, 'PackageDetails']\n    Missing = Tuple[str, Any]\n    Conflicting = Tuple[str, str, Any]\n\n    MissingDict = Dict[str, List[Missing]]\n    ConflictingDict = Dict[str, List[Conflicting]]\n    CheckResult = Tuple[MissingDict, ConflictingDict]\n\nPackageDetails = namedtuple('PackageDetails', ['version', 'requires'])\n\n\ndef create_package_set_from_installed(**kwargs):\n    # type: (**Any) -> PackageSet\n    \"\"\"Converts a list of distributions into a PackageSet.\n    \"\"\"\n    retval = {}\n    for dist in get_installed_distributions(**kwargs):\n        name = canonicalize_name(dist.project_name)\n        retval[name] = PackageDetails(dist.version, dist.requires())\n    return retval\n\n\ndef check_package_set(package_set):\n    # type: (PackageSet) -> CheckResult\n    \"\"\"Check if a package set is consistent\n    \"\"\"\n    missing = dict()\n    conflicting = dict()\n\n    for package_name in package_set:\n        # Info about dependencies of package_name\n        missing_deps = set()  # type: Set[Missing]\n        conflicting_deps = set()  # type: Set[Conflicting]\n\n        for req in package_set[package_name].requires:\n            name = canonicalize_name(req.project_name)  # type: str\n\n            # Check if it's missing\n            if name not in package_set:\n                missed = True\n                if req.marker is not None:\n                    missed = req.marker.evaluate()\n                if missed:\n                    missing_deps.add((name, req))\n                continue\n\n            # Check if there's a conflict\n            version = package_set[name].version  # type: str\n            if version not in req.specifier:\n                conflicting_deps.add((name, version, req))\n\n        def str_key(x):\n            return str(x)\n\n        if missing_deps:\n            missing[package_name] = sorted(missing_deps, key=str_key)\n        if conflicting_deps:\n            conflicting[package_name] = sorted(conflicting_deps, key=str_key)\n\n    return missing, conflicting\n\n\ndef check_install_conflicts(to_install):\n    # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult]\n    \"\"\"For checking if the dependency graph would be consistent after \\\n    installing given requirements\n    \"\"\"\n    # Start from the current state\n    state = create_package_set_from_installed()\n    _simulate_installation_of(to_install, state)\n    return state, check_package_set(state)\n\n\n# NOTE from @pradyunsg\n# This required a minor update in dependency link handling logic over at\n# operations.prepare.IsSDist.dist() to get it working\ndef _simulate_installation_of(to_install, state):\n    # type: (List[InstallRequirement], PackageSet) -> None\n    \"\"\"Computes the version of packages after installing to_install.\n    \"\"\"\n\n    # Modify it as installing requirement_set would (assuming no errors)\n    for inst_req in to_install:\n        dist = make_abstract_dist(inst_req).dist(finder=None)\n        state[dist.key] = PackageDetails(dist.version, dist.requires())\n", "path": "src/pip/_internal/operations/check.py"}], "after_files": [{"content": "\"\"\"Validation of dependencies of packages\n\"\"\"\n\nfrom collections import namedtuple\n\nfrom pip._vendor.packaging.utils import canonicalize_name\n\nfrom pip._internal.operations.prepare import make_abstract_dist\n\nfrom pip._internal.utils.misc import get_installed_distributions\nfrom pip._internal.utils.typing import MYPY_CHECK_RUNNING\n\nif MYPY_CHECK_RUNNING:\n    from pip._internal.req.req_install import InstallRequirement\n    from typing import Any, Dict, Iterator, Set, Tuple, List\n\n    # Shorthands\n    PackageSet = Dict[str, 'PackageDetails']\n    Missing = Tuple[str, Any]\n    Conflicting = Tuple[str, str, Any]\n\n    MissingDict = Dict[str, List[Missing]]\n    ConflictingDict = Dict[str, List[Conflicting]]\n    CheckResult = Tuple[MissingDict, ConflictingDict]\n\nPackageDetails = namedtuple('PackageDetails', ['version', 'requires'])\n\n\ndef create_package_set_from_installed(**kwargs):\n    # type: (**Any) -> PackageSet\n    \"\"\"Converts a list of distributions into a PackageSet.\n    \"\"\"\n    retval = {}\n    for dist in get_installed_distributions(**kwargs):\n        name = canonicalize_name(dist.project_name)\n        retval[name] = PackageDetails(dist.version, dist.requires())\n    return retval\n\n\ndef check_package_set(package_set):\n    # type: (PackageSet) -> CheckResult\n    \"\"\"Check if a package set is consistent\n    \"\"\"\n    missing = dict()\n    conflicting = dict()\n\n    for package_name in package_set:\n        # Info about dependencies of package_name\n        missing_deps = set()  # type: Set[Missing]\n        conflicting_deps = set()  # type: Set[Conflicting]\n\n        for req in package_set[package_name].requires:\n            name = canonicalize_name(req.project_name)  # type: str\n\n            # Check if it's missing\n            if name not in package_set:\n                missed = True\n                if req.marker is not None:\n                    missed = req.marker.evaluate()\n                if missed:\n                    missing_deps.add((name, req))\n                continue\n\n            # Check if there's a conflict\n            version = package_set[name].version  # type: str\n            if version not in req.specifier:\n                conflicting_deps.add((name, version, req))\n\n        def str_key(x):\n            return str(x)\n\n        if missing_deps:\n            missing[package_name] = sorted(missing_deps, key=str_key)\n        if conflicting_deps:\n            conflicting[package_name] = sorted(conflicting_deps, key=str_key)\n\n    return missing, conflicting\n\n\ndef check_install_conflicts(to_install):\n    # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult]\n    \"\"\"For checking if the dependency graph would be consistent after \\\n    installing given requirements\n    \"\"\"\n    # Start from the current state\n    state = create_package_set_from_installed()\n    _simulate_installation_of(to_install, state)\n    return state, check_package_set(state)\n\n\n# NOTE from @pradyunsg\n# This required a minor update in dependency link handling logic over at\n# operations.prepare.IsSDist.dist() to get it working\ndef _simulate_installation_of(to_install, state):\n    # type: (List[InstallRequirement], PackageSet) -> None\n    \"\"\"Computes the version of packages after installing to_install.\n    \"\"\"\n\n    # Modify it as installing requirement_set would (assuming no errors)\n    for inst_req in to_install:\n        dist = make_abstract_dist(inst_req).dist(finder=None)\n        name = canonicalize_name(dist.key)\n        state[name] = PackageDetails(dist.version, dist.requires())\n", "path": "src/pip/_internal/operations/check.py"}]}