We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Unnecessary and deranging override message when using alias packages
In a situation with 3 packages CA, CB and CC where CB requires CA (via an alias) and CC requires CB and CA also via aliases, when installing CC with a "conan install ..." conan reports a version override while actually the alias is pointing to exaclty the version of the package that conan says overrides the alias:

CB/0.0.2@user/testing requirement CA/ALIAS@user/testing overriden by CC/0.0.3@user/testing to CA/0.0.1@user/testing


To help us debug your issue please `explain:`

- [X] I've read the [CONTRIBUTING guide](https://raw.githubusercontent.com/conan-io/conan/develop/.github/CONTRIBUTING.md).
- [X] I've specified the Conan version, operating system version and any tool that can be relevant.
- [X] I've explained the steps to reproduce the error or the motivation/use case of the question/suggestion.



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `conans/client/graph/graph_builder.py`
Content:
```
1 import time
2 
3 from conans.model.conan_file import get_env_context_manager
4 from conans.model.requires import Requirements
5 from conans.model.ref import ConanFileReference
6 from conans.errors import (ConanException, conanfile_exception_formatter,
7                            ConanExceptionInUserConanfileMethod)
8 from conans.client.output import ScopedOutput
9 from conans.util.log import logger
10 from conans.client.graph.graph import DepsGraph, Node, RECIPE_WORKSPACE
11 from conans.model.workspace import WORKSPACE_FILE
12 
13 
14 class DepsGraphBuilder(object):
15     """ Responsible for computing the dependencies graph DepsGraph
16     """
17     def __init__(self, proxy, output, loader, resolver, workspace, recorder):
18         self._proxy = proxy
19         self._output = output
20         self._loader = loader
21         self._resolver = resolver
22         self._workspace = workspace
23         self._recorder = recorder
24 
25     def load_graph(self, conanfile, check_updates, update, remote_name, processed_profile):
26         check_updates = check_updates or update
27         dep_graph = DepsGraph()
28         # compute the conanfile entry point for this dependency graph
29         root_node = Node(None, conanfile)
30         dep_graph.add_node(root_node)
31         public_deps = {}  # {name: Node} dict with public nodes, so they are not added again
32         aliased = {}
33         # enter recursive computation
34         t1 = time.time()
35         loop_ancestors = []
36         self._load_deps(root_node, Requirements(), dep_graph, public_deps, None, None,
37                         loop_ancestors, aliased, check_updates, update, remote_name,
38                         processed_profile)
39         logger.debug("Deps-builder: Time to load deps %s" % (time.time() - t1))
40         t1 = time.time()
41         dep_graph.compute_package_ids()
42         logger.debug("Deps-builder: Propagate info %s" % (time.time() - t1))
43         return dep_graph
44 
45     def _resolve_deps(self, node, aliased, update, remote_name):
46         # Resolve possible version ranges of the current node requirements
47         # new_reqs is a shallow copy of what is propagated upstream, so changes done by the
48         # RangeResolver are also done in new_reqs, and then propagated!
49         conanfile, conanref = node.conanfile, node.conan_ref
50         for _, require in conanfile.requires.items():
51             self._resolver.resolve(require, conanref, update, remote_name)
52 
53         # After resolving ranges,
54         for req in conanfile.requires.values():
55             alias = aliased.get(req.conan_reference)
56             if alias:
57                 req.conan_reference = alias
58 
59         if not hasattr(conanfile, "_conan_evaluated_requires"):
60             conanfile._conan_evaluated_requires = conanfile.requires.copy()
61         elif conanfile.requires != conanfile._conan_evaluated_requires:
62             raise ConanException("%s: Incompatible requirements obtained in different "
63                                  "evaluations of 'requirements'\n"
64                                  "    Previous requirements: %s\n"
65                                  "    New requirements: %s"
66                                  % (conanref, list(conanfile._conan_evaluated_requires.values()),
67                                     list(conanfile.requires.values())))
68 
69     def _load_deps(self, node, down_reqs, dep_graph, public_deps, down_ref, down_options,
70                    loop_ancestors, aliased, check_updates, update, remote_name, processed_profile):
71         """ loads a Conan object from the given file
72         param node: Node object to be expanded in this step
73         down_reqs: the Requirements as coming from downstream, which can overwrite current
74                     values
75         param deps: DepsGraph result
76         param public_deps: {name: Node} of already expanded public Nodes, not to be repeated
77                            in graph
78         param down_ref: ConanFileReference of who is depending on current node for this expansion
79         """
80         # basic node configuration
81         new_reqs, new_options = self._config_node(node, down_reqs, down_ref, down_options)
82 
83         self._resolve_deps(node, aliased, update, remote_name)
84 
85         # Expand each one of the current requirements
86         for name, require in node.conanfile.requires.items():
87             if require.override:
88                 continue
89             if require.conan_reference in loop_ancestors:
90                 raise ConanException("Loop detected: %s"
91                                      % "->".join(str(r) for r in loop_ancestors))
92             new_loop_ancestors = loop_ancestors[:]  # Copy for propagating
93             new_loop_ancestors.append(require.conan_reference)
94             previous = public_deps.get(name)
95             if require.private or not previous:  # new node, must be added and expanded
96                 new_node = self._create_new_node(node, dep_graph, require, public_deps, name,
97                                                  aliased, check_updates, update, remote_name,
98                                                  processed_profile)
99                 # RECURSION!
100                 # Make sure the subgraph is truly private
101                 new_public_deps = {} if require.private else public_deps
102                 self._load_deps(new_node, new_reqs, dep_graph, new_public_deps, node.conan_ref,
103                                 new_options, new_loop_ancestors, aliased, check_updates, update,
104                                 remote_name, processed_profile)
105             else:  # a public node already exist with this name
106                 previous_node, closure = previous
107                 alias_ref = aliased.get(require.conan_reference, require.conan_reference)
108                 # Necessary to make sure that it is pointing to the correct aliased
109                 require.conan_reference = alias_ref
110                 if previous_node.conan_ref != alias_ref:
111                     raise ConanException("Conflict in %s\n"
112                                          "    Requirement %s conflicts with already defined %s\n"
113                                          "    Keeping %s\n"
114                                          "    To change it, override it in your base requirements"
115                                          % (node.conan_ref, require.conan_reference,
116                                             previous_node.conan_ref, previous_node.conan_ref))
117                 dep_graph.add_edge(node, previous_node)
118                 # RECURSION!
119                 if closure is None:
120                     closure = dep_graph.closure(node)
121                     public_deps[name] = previous_node, closure
122                 if self._recurse(closure, new_reqs, new_options):
123                     self._load_deps(previous_node, new_reqs, dep_graph, public_deps, node.conan_ref,
124                                     new_options, new_loop_ancestors, aliased, check_updates, update,
125                                     remote_name, processed_profile)
126 
127     def _recurse(self, closure, new_reqs, new_options):
128         """ For a given closure, if some requirements or options coming from downstream
129         is incompatible with the current closure, then it is necessary to recurse
130         then, incompatibilities will be raised as usually"""
131         for req in new_reqs.values():
132             n = closure.get(req.conan_reference.name)
133             if n and n.conan_ref != req.conan_reference:
134                 return True
135         for pkg_name, options_values in new_options.items():
136             n = closure.get(pkg_name)
137             if n:
138                 options = n.conanfile.options
139                 for option, value in options_values.items():
140                     if getattr(options, option) != value:
141                         return True
142         return False
143 
144     def _config_node(self, node, down_reqs, down_ref, down_options):
145         """ update settings and option in the current ConanFile, computing actual
146         requirement values, cause they can be overridden by downstream requires
147         param settings: dict of settings values => {"os": "windows"}
148         """
149         try:
150             conanfile, conanref = node.conanfile, node.conan_ref
151             # Avoid extra time manipulating the sys.path for python
152             with get_env_context_manager(conanfile, without_python=True):
153                 if hasattr(conanfile, "config"):
154                     if not conanref:
155                         output = ScopedOutput(str("PROJECT"), self._output)
156                         output.warn("config() has been deprecated."
157                                     " Use config_options and configure")
158                     with conanfile_exception_formatter(str(conanfile), "config"):
159                         conanfile.config()
160                 with conanfile_exception_formatter(str(conanfile), "config_options"):
161                     conanfile.config_options()
162                 conanfile.options.propagate_upstream(down_options, down_ref, conanref)
163                 if hasattr(conanfile, "config"):
164                     with conanfile_exception_formatter(str(conanfile), "config"):
165                         conanfile.config()
166 
167                 with conanfile_exception_formatter(str(conanfile), "configure"):
168                     conanfile.configure()
169 
170                 conanfile.settings.validate()  # All has to be ok!
171                 conanfile.options.validate()
172 
173                 # Update requirements (overwrites), computing new upstream
174                 if hasattr(conanfile, "requirements"):
175                     # If re-evaluating the recipe, in a diamond graph, with different options,
176                     # it could happen that one execution path of requirements() defines a package
177                     # and another one a different package raising Duplicate dependency error
178                     # Or the two consecutive calls, adding 2 different dependencies for the two paths
179                     # So it is necessary to save the "requires" state and restore it before a second
180                     # execution of requirements(). It is a shallow copy, if first iteration is
181                     # RequireResolve'd or overridden, the inner requirements are modified
182                     if not hasattr(conanfile, "_conan_original_requires"):
183                         conanfile._conan_original_requires = conanfile.requires.copy()
184                     else:
185                         conanfile.requires = conanfile._conan_original_requires.copy()
186 
187                     with conanfile_exception_formatter(str(conanfile), "requirements"):
188                         conanfile.requirements()
189 
190                 new_options = conanfile.options.deps_package_values
191                 new_down_reqs = conanfile.requires.update(down_reqs, self._output, conanref,
192                                                           down_ref)
193         except ConanExceptionInUserConanfileMethod:
194             raise
195         except ConanException as e:
196             raise ConanException("%s: %s" % (conanref or "Conanfile", str(e)))
197         except Exception as e:
198             raise ConanException(e)
199 
200         return new_down_reqs, new_options
201 
202     def _create_new_node(self, current_node, dep_graph, requirement, public_deps, name_req, aliased,
203                          check_updates, update, remote_name, processed_profile, alias_ref=None):
204         """ creates and adds a new node to the dependency graph
205         """
206         workspace_package = self._workspace[requirement.conan_reference] if self._workspace else None
207         if workspace_package:
208             conanfile_path = workspace_package.conanfile_path
209             recipe_status = RECIPE_WORKSPACE
210             remote = WORKSPACE_FILE
211         else:
212             try:
213                 result = self._proxy.get_recipe(requirement.conan_reference,
214                                                 check_updates, update, remote_name, self._recorder)
215             except ConanException as e:
216                 base_ref = str(current_node.conan_ref or "PROJECT")
217                 self._output.error("Failed requirement '%s' from '%s'"
218                                    % (requirement.conan_reference, base_ref))
219                 raise e
220             conanfile_path, recipe_status, remote, _ = result
221 
222         output = ScopedOutput(str(requirement.conan_reference), self._output)
223         dep_conanfile = self._loader.load_conanfile(conanfile_path, output, processed_profile,
224                                                     reference=requirement.conan_reference)
225 
226         if workspace_package:
227             workspace_package.conanfile = dep_conanfile
228         if getattr(dep_conanfile, "alias", None):
229             alias_reference = alias_ref or requirement.conan_reference
230             requirement.conan_reference = ConanFileReference.loads(dep_conanfile.alias)
231             aliased[alias_reference] = requirement.conan_reference
232             return self._create_new_node(current_node, dep_graph, requirement, public_deps,
233                                          name_req, aliased, check_updates, update,
234                                          remote_name, processed_profile, alias_ref=alias_reference)
235 
236         new_node = Node(requirement.conan_reference, dep_conanfile)
237         new_node.recipe = recipe_status
238         new_node.remote = remote
239         dep_graph.add_node(new_node)
240         dep_graph.add_edge(current_node, new_node, requirement.private)
241         if not requirement.private:
242             public_deps[name_req] = new_node, None
243         return new_node
244
```
--- 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()

```

diff --git a/conans/client/graph/graph_builder.py b/conans/client/graph/graph_builder.py
--- a/conans/client/graph/graph_builder.py
+++ b/conans/client/graph/graph_builder.py
@@ -78,7 +78,7 @@
         param down_ref: ConanFileReference of who is depending on current node for this expansion
         """
         # basic node configuration
-        new_reqs, new_options = self._config_node(node, down_reqs, down_ref, down_options)
+        new_reqs, new_options = self._config_node(node, down_reqs, down_ref, down_options, aliased)
 
         self._resolve_deps(node, aliased, update, remote_name)
 
@@ -141,7 +141,7 @@
                         return True
         return False
 
-    def _config_node(self, node, down_reqs, down_ref, down_options):
+    def _config_node(self, node, down_reqs, down_ref, down_options, aliased):
         """ update settings and option in the current ConanFile, computing actual
         requirement values, cause they can be overridden by downstream requires
         param settings: dict of settings values => {"os": "windows"}
@@ -188,8 +188,12 @@
                         conanfile.requirements()
 
                 new_options = conanfile.options.deps_package_values
-                new_down_reqs = conanfile.requires.update(down_reqs, self._output, conanref,
-                                                          down_ref)
+                if aliased:
+                    for req in conanfile.requires.values():
+                        req.conan_reference = aliased.get(req.conan_reference,
+                                                          req.conan_reference)
+                new_down_reqs = conanfile.requires.update(down_reqs, self._output,
+                                                          conanref, down_ref)
         except ConanExceptionInUserConanfileMethod:
             raise
         except ConanException as e:

{"golden_diff": "diff --git a/conans/client/graph/graph_builder.py b/conans/client/graph/graph_builder.py\n--- a/conans/client/graph/graph_builder.py\n+++ b/conans/client/graph/graph_builder.py\n@@ -78,7 +78,7 @@\n         param down_ref: ConanFileReference of who is depending on current node for this expansion\n         \"\"\"\n         # basic node configuration\n-        new_reqs, new_options = self._config_node(node, down_reqs, down_ref, down_options)\n+        new_reqs, new_options = self._config_node(node, down_reqs, down_ref, down_options, aliased)\n \n         self._resolve_deps(node, aliased, update, remote_name)\n \n@@ -141,7 +141,7 @@\n                         return True\n         return False\n \n-    def _config_node(self, node, down_reqs, down_ref, down_options):\n+    def _config_node(self, node, down_reqs, down_ref, down_options, aliased):\n         \"\"\" update settings and option in the current ConanFile, computing actual\n         requirement values, cause they can be overridden by downstream requires\n         param settings: dict of settings values => {\"os\": \"windows\"}\n@@ -188,8 +188,12 @@\n                         conanfile.requirements()\n \n                 new_options = conanfile.options.deps_package_values\n-                new_down_reqs = conanfile.requires.update(down_reqs, self._output, conanref,\n-                                                          down_ref)\n+                if aliased:\n+                    for req in conanfile.requires.values():\n+                        req.conan_reference = aliased.get(req.conan_reference,\n+                                                          req.conan_reference)\n+                new_down_reqs = conanfile.requires.update(down_reqs, self._output,\n+                                                          conanref, down_ref)\n         except ConanExceptionInUserConanfileMethod:\n             raise\n         except ConanException as e:\n", "issue": "Unnecessary and deranging override message when using alias packages\nIn a situation with 3 packages CA, CB and CC where CB requires CA (via an alias) and CC requires CB and CA also via aliases, when installing CC with a \"conan install ...\" conan reports a version override while actually the alias is pointing to exaclty the version of the package that conan says overrides the alias:\r\n\r\nCB/0.0.2@user/testing requirement CA/ALIAS@user/testing overriden by CC/0.0.3@user/testing to CA/0.0.1@user/testing\r\n\r\n\r\nTo help us debug your issue please `explain:`\r\n\r\n- [X] I've read the [CONTRIBUTING guide](https://raw.githubusercontent.com/conan-io/conan/develop/.github/CONTRIBUTING.md).\r\n- [X] I've specified the Conan version, operating system version and any tool that can be relevant.\r\n- [X] I've explained the steps to reproduce the error or the motivation/use case of the question/suggestion.\r\n\r\n\n", "before_files": [{"content": "import time\n\nfrom conans.model.conan_file import get_env_context_manager\nfrom conans.model.requires import Requirements\nfrom conans.model.ref import ConanFileReference\nfrom conans.errors import (ConanException, conanfile_exception_formatter,\n                           ConanExceptionInUserConanfileMethod)\nfrom conans.client.output import ScopedOutput\nfrom conans.util.log import logger\nfrom conans.client.graph.graph import DepsGraph, Node, RECIPE_WORKSPACE\nfrom conans.model.workspace import WORKSPACE_FILE\n\n\nclass DepsGraphBuilder(object):\n    \"\"\" Responsible for computing the dependencies graph DepsGraph\n    \"\"\"\n    def __init__(self, proxy, output, loader, resolver, workspace, recorder):\n        self._proxy = proxy\n        self._output = output\n        self._loader = loader\n        self._resolver = resolver\n        self._workspace = workspace\n        self._recorder = recorder\n\n    def load_graph(self, conanfile, check_updates, update, remote_name, processed_profile):\n        check_updates = check_updates or update\n        dep_graph = DepsGraph()\n        # compute the conanfile entry point for this dependency graph\n        root_node = Node(None, conanfile)\n        dep_graph.add_node(root_node)\n        public_deps = {}  # {name: Node} dict with public nodes, so they are not added again\n        aliased = {}\n        # enter recursive computation\n        t1 = time.time()\n        loop_ancestors = []\n        self._load_deps(root_node, Requirements(), dep_graph, public_deps, None, None,\n                        loop_ancestors, aliased, check_updates, update, remote_name,\n                        processed_profile)\n        logger.debug(\"Deps-builder: Time to load deps %s\" % (time.time() - t1))\n        t1 = time.time()\n        dep_graph.compute_package_ids()\n        logger.debug(\"Deps-builder: Propagate info %s\" % (time.time() - t1))\n        return dep_graph\n\n    def _resolve_deps(self, node, aliased, update, remote_name):\n        # Resolve possible version ranges of the current node requirements\n        # new_reqs is a shallow copy of what is propagated upstream, so changes done by the\n        # RangeResolver are also done in new_reqs, and then propagated!\n        conanfile, conanref = node.conanfile, node.conan_ref\n        for _, require in conanfile.requires.items():\n            self._resolver.resolve(require, conanref, update, remote_name)\n\n        # After resolving ranges,\n        for req in conanfile.requires.values():\n            alias = aliased.get(req.conan_reference)\n            if alias:\n                req.conan_reference = alias\n\n        if not hasattr(conanfile, \"_conan_evaluated_requires\"):\n            conanfile._conan_evaluated_requires = conanfile.requires.copy()\n        elif conanfile.requires != conanfile._conan_evaluated_requires:\n            raise ConanException(\"%s: Incompatible requirements obtained in different \"\n                                 \"evaluations of 'requirements'\\n\"\n                                 \"    Previous requirements: %s\\n\"\n                                 \"    New requirements: %s\"\n                                 % (conanref, list(conanfile._conan_evaluated_requires.values()),\n                                    list(conanfile.requires.values())))\n\n    def _load_deps(self, node, down_reqs, dep_graph, public_deps, down_ref, down_options,\n                   loop_ancestors, aliased, check_updates, update, remote_name, processed_profile):\n        \"\"\" loads a Conan object from the given file\n        param node: Node object to be expanded in this step\n        down_reqs: the Requirements as coming from downstream, which can overwrite current\n                    values\n        param deps: DepsGraph result\n        param public_deps: {name: Node} of already expanded public Nodes, not to be repeated\n                           in graph\n        param down_ref: ConanFileReference of who is depending on current node for this expansion\n        \"\"\"\n        # basic node configuration\n        new_reqs, new_options = self._config_node(node, down_reqs, down_ref, down_options)\n\n        self._resolve_deps(node, aliased, update, remote_name)\n\n        # Expand each one of the current requirements\n        for name, require in node.conanfile.requires.items():\n            if require.override:\n                continue\n            if require.conan_reference in loop_ancestors:\n                raise ConanException(\"Loop detected: %s\"\n                                     % \"->\".join(str(r) for r in loop_ancestors))\n            new_loop_ancestors = loop_ancestors[:]  # Copy for propagating\n            new_loop_ancestors.append(require.conan_reference)\n            previous = public_deps.get(name)\n            if require.private or not previous:  # new node, must be added and expanded\n                new_node = self._create_new_node(node, dep_graph, require, public_deps, name,\n                                                 aliased, check_updates, update, remote_name,\n                                                 processed_profile)\n                # RECURSION!\n                # Make sure the subgraph is truly private\n                new_public_deps = {} if require.private else public_deps\n                self._load_deps(new_node, new_reqs, dep_graph, new_public_deps, node.conan_ref,\n                                new_options, new_loop_ancestors, aliased, check_updates, update,\n                                remote_name, processed_profile)\n            else:  # a public node already exist with this name\n                previous_node, closure = previous\n                alias_ref = aliased.get(require.conan_reference, require.conan_reference)\n                # Necessary to make sure that it is pointing to the correct aliased\n                require.conan_reference = alias_ref\n                if previous_node.conan_ref != alias_ref:\n                    raise ConanException(\"Conflict in %s\\n\"\n                                         \"    Requirement %s conflicts with already defined %s\\n\"\n                                         \"    Keeping %s\\n\"\n                                         \"    To change it, override it in your base requirements\"\n                                         % (node.conan_ref, require.conan_reference,\n                                            previous_node.conan_ref, previous_node.conan_ref))\n                dep_graph.add_edge(node, previous_node)\n                # RECURSION!\n                if closure is None:\n                    closure = dep_graph.closure(node)\n                    public_deps[name] = previous_node, closure\n                if self._recurse(closure, new_reqs, new_options):\n                    self._load_deps(previous_node, new_reqs, dep_graph, public_deps, node.conan_ref,\n                                    new_options, new_loop_ancestors, aliased, check_updates, update,\n                                    remote_name, processed_profile)\n\n    def _recurse(self, closure, new_reqs, new_options):\n        \"\"\" For a given closure, if some requirements or options coming from downstream\n        is incompatible with the current closure, then it is necessary to recurse\n        then, incompatibilities will be raised as usually\"\"\"\n        for req in new_reqs.values():\n            n = closure.get(req.conan_reference.name)\n            if n and n.conan_ref != req.conan_reference:\n                return True\n        for pkg_name, options_values in new_options.items():\n            n = closure.get(pkg_name)\n            if n:\n                options = n.conanfile.options\n                for option, value in options_values.items():\n                    if getattr(options, option) != value:\n                        return True\n        return False\n\n    def _config_node(self, node, down_reqs, down_ref, down_options):\n        \"\"\" update settings and option in the current ConanFile, computing actual\n        requirement values, cause they can be overridden by downstream requires\n        param settings: dict of settings values => {\"os\": \"windows\"}\n        \"\"\"\n        try:\n            conanfile, conanref = node.conanfile, node.conan_ref\n            # Avoid extra time manipulating the sys.path for python\n            with get_env_context_manager(conanfile, without_python=True):\n                if hasattr(conanfile, \"config\"):\n                    if not conanref:\n                        output = ScopedOutput(str(\"PROJECT\"), self._output)\n                        output.warn(\"config() has been deprecated.\"\n                                    \" Use config_options and configure\")\n                    with conanfile_exception_formatter(str(conanfile), \"config\"):\n                        conanfile.config()\n                with conanfile_exception_formatter(str(conanfile), \"config_options\"):\n                    conanfile.config_options()\n                conanfile.options.propagate_upstream(down_options, down_ref, conanref)\n                if hasattr(conanfile, \"config\"):\n                    with conanfile_exception_formatter(str(conanfile), \"config\"):\n                        conanfile.config()\n\n                with conanfile_exception_formatter(str(conanfile), \"configure\"):\n                    conanfile.configure()\n\n                conanfile.settings.validate()  # All has to be ok!\n                conanfile.options.validate()\n\n                # Update requirements (overwrites), computing new upstream\n                if hasattr(conanfile, \"requirements\"):\n                    # If re-evaluating the recipe, in a diamond graph, with different options,\n                    # it could happen that one execution path of requirements() defines a package\n                    # and another one a different package raising Duplicate dependency error\n                    # Or the two consecutive calls, adding 2 different dependencies for the two paths\n                    # So it is necessary to save the \"requires\" state and restore it before a second\n                    # execution of requirements(). It is a shallow copy, if first iteration is\n                    # RequireResolve'd or overridden, the inner requirements are modified\n                    if not hasattr(conanfile, \"_conan_original_requires\"):\n                        conanfile._conan_original_requires = conanfile.requires.copy()\n                    else:\n                        conanfile.requires = conanfile._conan_original_requires.copy()\n\n                    with conanfile_exception_formatter(str(conanfile), \"requirements\"):\n                        conanfile.requirements()\n\n                new_options = conanfile.options.deps_package_values\n                new_down_reqs = conanfile.requires.update(down_reqs, self._output, conanref,\n                                                          down_ref)\n        except ConanExceptionInUserConanfileMethod:\n            raise\n        except ConanException as e:\n            raise ConanException(\"%s: %s\" % (conanref or \"Conanfile\", str(e)))\n        except Exception as e:\n            raise ConanException(e)\n\n        return new_down_reqs, new_options\n\n    def _create_new_node(self, current_node, dep_graph, requirement, public_deps, name_req, aliased,\n                         check_updates, update, remote_name, processed_profile, alias_ref=None):\n        \"\"\" creates and adds a new node to the dependency graph\n        \"\"\"\n        workspace_package = self._workspace[requirement.conan_reference] if self._workspace else None\n        if workspace_package:\n            conanfile_path = workspace_package.conanfile_path\n            recipe_status = RECIPE_WORKSPACE\n            remote = WORKSPACE_FILE\n        else:\n            try:\n                result = self._proxy.get_recipe(requirement.conan_reference,\n                                                check_updates, update, remote_name, self._recorder)\n            except ConanException as e:\n                base_ref = str(current_node.conan_ref or \"PROJECT\")\n                self._output.error(\"Failed requirement '%s' from '%s'\"\n                                   % (requirement.conan_reference, base_ref))\n                raise e\n            conanfile_path, recipe_status, remote, _ = result\n\n        output = ScopedOutput(str(requirement.conan_reference), self._output)\n        dep_conanfile = self._loader.load_conanfile(conanfile_path, output, processed_profile,\n                                                    reference=requirement.conan_reference)\n\n        if workspace_package:\n            workspace_package.conanfile = dep_conanfile\n        if getattr(dep_conanfile, \"alias\", None):\n            alias_reference = alias_ref or requirement.conan_reference\n            requirement.conan_reference = ConanFileReference.loads(dep_conanfile.alias)\n            aliased[alias_reference] = requirement.conan_reference\n            return self._create_new_node(current_node, dep_graph, requirement, public_deps,\n                                         name_req, aliased, check_updates, update,\n                                         remote_name, processed_profile, alias_ref=alias_reference)\n\n        new_node = Node(requirement.conan_reference, dep_conanfile)\n        new_node.recipe = recipe_status\n        new_node.remote = remote\n        dep_graph.add_node(new_node)\n        dep_graph.add_edge(current_node, new_node, requirement.private)\n        if not requirement.private:\n            public_deps[name_req] = new_node, None\n        return new_node\n", "path": "conans/client/graph/graph_builder.py"}], "after_files": [{"content": "import time\n\nfrom conans.model.conan_file import get_env_context_manager\nfrom conans.model.requires import Requirements\nfrom conans.model.ref import ConanFileReference\nfrom conans.errors import (ConanException, conanfile_exception_formatter,\n                           ConanExceptionInUserConanfileMethod)\nfrom conans.client.output import ScopedOutput\nfrom conans.util.log import logger\nfrom conans.client.graph.graph import DepsGraph, Node, RECIPE_WORKSPACE\nfrom conans.model.workspace import WORKSPACE_FILE\n\n\nclass DepsGraphBuilder(object):\n    \"\"\" Responsible for computing the dependencies graph DepsGraph\n    \"\"\"\n    def __init__(self, proxy, output, loader, resolver, workspace, recorder):\n        self._proxy = proxy\n        self._output = output\n        self._loader = loader\n        self._resolver = resolver\n        self._workspace = workspace\n        self._recorder = recorder\n\n    def load_graph(self, conanfile, check_updates, update, remote_name, processed_profile):\n        check_updates = check_updates or update\n        dep_graph = DepsGraph()\n        # compute the conanfile entry point for this dependency graph\n        root_node = Node(None, conanfile)\n        dep_graph.add_node(root_node)\n        public_deps = {}  # {name: Node} dict with public nodes, so they are not added again\n        aliased = {}\n        # enter recursive computation\n        t1 = time.time()\n        loop_ancestors = []\n        self._load_deps(root_node, Requirements(), dep_graph, public_deps, None, None,\n                        loop_ancestors, aliased, check_updates, update, remote_name,\n                        processed_profile)\n        logger.debug(\"Deps-builder: Time to load deps %s\" % (time.time() - t1))\n        t1 = time.time()\n        dep_graph.compute_package_ids()\n        logger.debug(\"Deps-builder: Propagate info %s\" % (time.time() - t1))\n        return dep_graph\n\n    def _resolve_deps(self, node, aliased, update, remote_name):\n        # Resolve possible version ranges of the current node requirements\n        # new_reqs is a shallow copy of what is propagated upstream, so changes done by the\n        # RangeResolver are also done in new_reqs, and then propagated!\n        conanfile, conanref = node.conanfile, node.conan_ref\n        for _, require in conanfile.requires.items():\n            self._resolver.resolve(require, conanref, update, remote_name)\n\n        # After resolving ranges,\n        for req in conanfile.requires.values():\n            alias = aliased.get(req.conan_reference)\n            if alias:\n                req.conan_reference = alias\n\n        if not hasattr(conanfile, \"_conan_evaluated_requires\"):\n            conanfile._conan_evaluated_requires = conanfile.requires.copy()\n        elif conanfile.requires != conanfile._conan_evaluated_requires:\n            raise ConanException(\"%s: Incompatible requirements obtained in different \"\n                                 \"evaluations of 'requirements'\\n\"\n                                 \"    Previous requirements: %s\\n\"\n                                 \"    New requirements: %s\"\n                                 % (conanref, list(conanfile._conan_evaluated_requires.values()),\n                                    list(conanfile.requires.values())))\n\n    def _load_deps(self, node, down_reqs, dep_graph, public_deps, down_ref, down_options,\n                   loop_ancestors, aliased, check_updates, update, remote_name, processed_profile):\n        \"\"\" loads a Conan object from the given file\n        param node: Node object to be expanded in this step\n        down_reqs: the Requirements as coming from downstream, which can overwrite current\n                    values\n        param deps: DepsGraph result\n        param public_deps: {name: Node} of already expanded public Nodes, not to be repeated\n                           in graph\n        param down_ref: ConanFileReference of who is depending on current node for this expansion\n        \"\"\"\n        # basic node configuration\n        new_reqs, new_options = self._config_node(node, down_reqs, down_ref, down_options, aliased)\n\n        self._resolve_deps(node, aliased, update, remote_name)\n\n        # Expand each one of the current requirements\n        for name, require in node.conanfile.requires.items():\n            if require.override:\n                continue\n            if require.conan_reference in loop_ancestors:\n                raise ConanException(\"Loop detected: %s\"\n                                     % \"->\".join(str(r) for r in loop_ancestors))\n            new_loop_ancestors = loop_ancestors[:]  # Copy for propagating\n            new_loop_ancestors.append(require.conan_reference)\n            previous = public_deps.get(name)\n            if require.private or not previous:  # new node, must be added and expanded\n                new_node = self._create_new_node(node, dep_graph, require, public_deps, name,\n                                                 aliased, check_updates, update, remote_name,\n                                                 processed_profile)\n                # RECURSION!\n                # Make sure the subgraph is truly private\n                new_public_deps = {} if require.private else public_deps\n                self._load_deps(new_node, new_reqs, dep_graph, new_public_deps, node.conan_ref,\n                                new_options, new_loop_ancestors, aliased, check_updates, update,\n                                remote_name, processed_profile)\n            else:  # a public node already exist with this name\n                previous_node, closure = previous\n                alias_ref = aliased.get(require.conan_reference, require.conan_reference)\n                # Necessary to make sure that it is pointing to the correct aliased\n                require.conan_reference = alias_ref\n                if previous_node.conan_ref != alias_ref:\n                    raise ConanException(\"Conflict in %s\\n\"\n                                         \"    Requirement %s conflicts with already defined %s\\n\"\n                                         \"    Keeping %s\\n\"\n                                         \"    To change it, override it in your base requirements\"\n                                         % (node.conan_ref, require.conan_reference,\n                                            previous_node.conan_ref, previous_node.conan_ref))\n                dep_graph.add_edge(node, previous_node)\n                # RECURSION!\n                if closure is None:\n                    closure = dep_graph.closure(node)\n                    public_deps[name] = previous_node, closure\n                if self._recurse(closure, new_reqs, new_options):\n                    self._load_deps(previous_node, new_reqs, dep_graph, public_deps, node.conan_ref,\n                                    new_options, new_loop_ancestors, aliased, check_updates, update,\n                                    remote_name, processed_profile)\n\n    def _recurse(self, closure, new_reqs, new_options):\n        \"\"\" For a given closure, if some requirements or options coming from downstream\n        is incompatible with the current closure, then it is necessary to recurse\n        then, incompatibilities will be raised as usually\"\"\"\n        for req in new_reqs.values():\n            n = closure.get(req.conan_reference.name)\n            if n and n.conan_ref != req.conan_reference:\n                return True\n        for pkg_name, options_values in new_options.items():\n            n = closure.get(pkg_name)\n            if n:\n                options = n.conanfile.options\n                for option, value in options_values.items():\n                    if getattr(options, option) != value:\n                        return True\n        return False\n\n    def _config_node(self, node, down_reqs, down_ref, down_options, aliased):\n        \"\"\" update settings and option in the current ConanFile, computing actual\n        requirement values, cause they can be overridden by downstream requires\n        param settings: dict of settings values => {\"os\": \"windows\"}\n        \"\"\"\n        try:\n            conanfile, conanref = node.conanfile, node.conan_ref\n            # Avoid extra time manipulating the sys.path for python\n            with get_env_context_manager(conanfile, without_python=True):\n                if hasattr(conanfile, \"config\"):\n                    if not conanref:\n                        output = ScopedOutput(str(\"PROJECT\"), self._output)\n                        output.warn(\"config() has been deprecated.\"\n                                    \" Use config_options and configure\")\n                    with conanfile_exception_formatter(str(conanfile), \"config\"):\n                        conanfile.config()\n                with conanfile_exception_formatter(str(conanfile), \"config_options\"):\n                    conanfile.config_options()\n                conanfile.options.propagate_upstream(down_options, down_ref, conanref)\n                if hasattr(conanfile, \"config\"):\n                    with conanfile_exception_formatter(str(conanfile), \"config\"):\n                        conanfile.config()\n\n                with conanfile_exception_formatter(str(conanfile), \"configure\"):\n                    conanfile.configure()\n\n                conanfile.settings.validate()  # All has to be ok!\n                conanfile.options.validate()\n\n                # Update requirements (overwrites), computing new upstream\n                if hasattr(conanfile, \"requirements\"):\n                    # If re-evaluating the recipe, in a diamond graph, with different options,\n                    # it could happen that one execution path of requirements() defines a package\n                    # and another one a different package raising Duplicate dependency error\n                    # Or the two consecutive calls, adding 2 different dependencies for the two paths\n                    # So it is necessary to save the \"requires\" state and restore it before a second\n                    # execution of requirements(). It is a shallow copy, if first iteration is\n                    # RequireResolve'd or overridden, the inner requirements are modified\n                    if not hasattr(conanfile, \"_conan_original_requires\"):\n                        conanfile._conan_original_requires = conanfile.requires.copy()\n                    else:\n                        conanfile.requires = conanfile._conan_original_requires.copy()\n\n                    with conanfile_exception_formatter(str(conanfile), \"requirements\"):\n                        conanfile.requirements()\n\n                new_options = conanfile.options.deps_package_values\n                if aliased:\n                    for req in conanfile.requires.values():\n                        req.conan_reference = aliased.get(req.conan_reference,\n                                                          req.conan_reference)\n                new_down_reqs = conanfile.requires.update(down_reqs, self._output,\n                                                          conanref, down_ref)\n        except ConanExceptionInUserConanfileMethod:\n            raise\n        except ConanException as e:\n            raise ConanException(\"%s: %s\" % (conanref or \"Conanfile\", str(e)))\n        except Exception as e:\n            raise ConanException(e)\n\n        return new_down_reqs, new_options\n\n    def _create_new_node(self, current_node, dep_graph, requirement, public_deps, name_req, aliased,\n                         check_updates, update, remote_name, processed_profile, alias_ref=None):\n        \"\"\" creates and adds a new node to the dependency graph\n        \"\"\"\n        workspace_package = self._workspace[requirement.conan_reference] if self._workspace else None\n        if workspace_package:\n            conanfile_path = workspace_package.conanfile_path\n            recipe_status = RECIPE_WORKSPACE\n            remote = WORKSPACE_FILE\n        else:\n            try:\n                result = self._proxy.get_recipe(requirement.conan_reference,\n                                                check_updates, update, remote_name, self._recorder)\n            except ConanException as e:\n                base_ref = str(current_node.conan_ref or \"PROJECT\")\n                self._output.error(\"Failed requirement '%s' from '%s'\"\n                                   % (requirement.conan_reference, base_ref))\n                raise e\n            conanfile_path, recipe_status, remote, _ = result\n\n        output = ScopedOutput(str(requirement.conan_reference), self._output)\n        dep_conanfile = self._loader.load_conanfile(conanfile_path, output, processed_profile,\n                                                    reference=requirement.conan_reference)\n\n        if workspace_package:\n            workspace_package.conanfile = dep_conanfile\n        if getattr(dep_conanfile, \"alias\", None):\n            alias_reference = alias_ref or requirement.conan_reference\n            requirement.conan_reference = ConanFileReference.loads(dep_conanfile.alias)\n            aliased[alias_reference] = requirement.conan_reference\n            return self._create_new_node(current_node, dep_graph, requirement, public_deps,\n                                         name_req, aliased, check_updates, update,\n                                         remote_name, processed_profile, alias_ref=alias_reference)\n\n        new_node = Node(requirement.conan_reference, dep_conanfile)\n        new_node.recipe = recipe_status\n        new_node.remote = remote\n        dep_graph.add_node(new_node)\n        dep_graph.add_edge(current_node, new_node, requirement.private)\n        if not requirement.private:\n            public_deps[name_req] = new_node, None\n        return new_node\n", "path": "conans/client/graph/graph_builder.py"}]}