We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
'install_folder' attribute is not always set
To reproduce, take https://github.com/memsharded/conan-hello example with one addition:
```python
    def package(self):
        print("self.source_folder:", self.source_folder)
        print("self.build_folder:", self.build_folder)
        print("self.install_folder:", self.install_folder)
        ...
```
now package it:
```
conan create . dbely/testing
```
everything goes well, with the output
```
Hello/0.1@dbely/testing: Calling package()
self.source_folder: C:\Users\dbely\.conan\data\Hello\0.1\dbely\testing\build\6cc50b139b9c3d27b3e9042d5f5372d327b3a9f7
self.build_folder: C:\Users\dbely\.conan\data\Hello\0.1\dbely\testing\build\6cc50b139b9c3d27b3e9042d5f5372d327b3a9f7
self.install_folder: C:\Users\dbely\.conan\data\Hello\0.1\dbely\testing\build\6cc50b139b9c3d27b3e9042d5f5372d327b3a9f7
```
Now do it step by step:
```
conan source .
conan install .
conan build .
conan package .
```
All the commands succeed except the last one:
```
PROJECT: Calling package()
self.source_folder: C:\Users\dbely\conan\conan-hello.git
self.build_folder: C:\Users\dbely\conan\conan-hello.git
ERROR: Hello/0.1@PROJECT: Error in package() method, line 21
        print("self.install_folder:", self.install_folder)
        AttributeError: 'HelloConan' object has no attribute 'install_folder'
```


--- 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/packager.py`
Content:
```
1 import os
2 import shutil
3 
4 from conans.client import tools
5 from conans.util.files import mkdir, save, rmdir
6 from conans.util.log import logger
7 from conans.paths import CONANINFO, CONAN_MANIFEST
8 from conans.errors import ConanException, ConanExceptionInUserConanfileMethod, conanfile_exception_formatter
9 from conans.model.manifest import FileTreeManifest
10 from conans.client.output import ScopedOutput
11 from conans.client.file_copier import FileCopier
12 
13 
14 def create_package(conanfile, source_folder, build_folder, package_folder, install_folder,
15                    output, local=False, copy_info=False):
16     """ copies built artifacts, libs, headers, data, etc from build_folder to
17     package folder
18     """
19     mkdir(package_folder)
20 
21     # Make the copy of all the patterns
22     output.info("Generating the package")
23     output.info("Package folder %s" % (package_folder))
24 
25     try:
26         package_output = ScopedOutput("%s package()" % output.scope, output)
27         output.highlight("Calling package()")
28         conanfile.package_folder = package_folder
29         conanfile.source_folder = source_folder
30         conanfile.build_folder = build_folder
31 
32         def recipe_has(conanfile, attribute):
33             return attribute in conanfile.__class__.__dict__
34 
35         if source_folder != build_folder:
36             conanfile.copy = FileCopier(source_folder, package_folder, build_folder)
37             with conanfile_exception_formatter(str(conanfile), "package"):
38                 with tools.chdir(source_folder):
39                     conanfile.package()
40             warn = recipe_has(conanfile, "package")
41             conanfile.copy.report(package_output, warn=warn)
42 
43         conanfile.copy = FileCopier(build_folder, package_folder)
44         with tools.chdir(build_folder):
45             with conanfile_exception_formatter(str(conanfile), "package"):
46                 conanfile.package()
47         warn = recipe_has(conanfile, "build") and recipe_has(conanfile, "package")
48         conanfile.copy.report(package_output, warn=warn)
49     except Exception as e:
50         if not local:
51             os.chdir(build_folder)
52             try:
53                 rmdir(package_folder)
54             except Exception as e_rm:
55                 output.error("Unable to remove package folder %s\n%s" % (package_folder, str(e_rm)))
56                 output.warn("**** Please delete it manually ****")
57 
58         if isinstance(e, ConanExceptionInUserConanfileMethod):
59             raise
60         raise ConanException(e)
61 
62     _create_aux_files(install_folder, package_folder, conanfile, copy_info)
63     output.success("Package '%s' created" % os.path.basename(package_folder))
64 
65 
66 def _create_aux_files(install_folder, package_folder, conanfile, copy_info):
67     """ auxiliary method that creates CONANINFO and manifest in
68     the package_folder
69     """
70     logger.debug("Creating config files to %s" % package_folder)
71     if copy_info:
72         try:
73             shutil.copy(os.path.join(install_folder, CONANINFO), package_folder)
74         except IOError:
75             raise ConanException("%s does not exist inside of your %s folder. "
76                                  "Try to re-build it again to solve it."
77                                  % (CONANINFO, install_folder))
78     else:
79         save(os.path.join(package_folder, CONANINFO), conanfile.info.dumps())
80 
81     # Create the digest for the package
82     digest = FileTreeManifest.create(package_folder)
83     save(os.path.join(package_folder, CONAN_MANIFEST), str(digest))
84
```
--- 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/packager.py b/conans/client/packager.py
--- a/conans/client/packager.py
+++ b/conans/client/packager.py
@@ -27,6 +27,7 @@
         output.highlight("Calling package()")
         conanfile.package_folder = package_folder
         conanfile.source_folder = source_folder
+        conanfile.install_folder = install_folder
         conanfile.build_folder = build_folder
 
         def recipe_has(conanfile, attribute):

{"golden_diff": "diff --git a/conans/client/packager.py b/conans/client/packager.py\n--- a/conans/client/packager.py\n+++ b/conans/client/packager.py\n@@ -27,6 +27,7 @@\n         output.highlight(\"Calling package()\")\n         conanfile.package_folder = package_folder\n         conanfile.source_folder = source_folder\n+        conanfile.install_folder = install_folder\n         conanfile.build_folder = build_folder\n \n         def recipe_has(conanfile, attribute):\n", "issue": "'install_folder' attribute is not always set\nTo reproduce, take https://github.com/memsharded/conan-hello example with one addition:\r\n```python\r\n    def package(self):\r\n        print(\"self.source_folder:\", self.source_folder)\r\n        print(\"self.build_folder:\", self.build_folder)\r\n        print(\"self.install_folder:\", self.install_folder)\r\n        ...\r\n```\r\nnow package it:\r\n```\r\nconan create . dbely/testing\r\n```\r\neverything goes well, with the output\r\n```\r\nHello/0.1@dbely/testing: Calling package()\r\nself.source_folder: C:\\Users\\dbely\\.conan\\data\\Hello\\0.1\\dbely\\testing\\build\\6cc50b139b9c3d27b3e9042d5f5372d327b3a9f7\r\nself.build_folder: C:\\Users\\dbely\\.conan\\data\\Hello\\0.1\\dbely\\testing\\build\\6cc50b139b9c3d27b3e9042d5f5372d327b3a9f7\r\nself.install_folder: C:\\Users\\dbely\\.conan\\data\\Hello\\0.1\\dbely\\testing\\build\\6cc50b139b9c3d27b3e9042d5f5372d327b3a9f7\r\n```\r\nNow do it step by step:\r\n```\r\nconan source .\r\nconan install .\r\nconan build .\r\nconan package .\r\n```\r\nAll the commands succeed except the last one:\r\n```\r\nPROJECT: Calling package()\r\nself.source_folder: C:\\Users\\dbely\\conan\\conan-hello.git\r\nself.build_folder: C:\\Users\\dbely\\conan\\conan-hello.git\r\nERROR: Hello/0.1@PROJECT: Error in package() method, line 21\r\n        print(\"self.install_folder:\", self.install_folder)\r\n        AttributeError: 'HelloConan' object has no attribute 'install_folder'\r\n```\r\n\n", "before_files": [{"content": "import os\nimport shutil\n\nfrom conans.client import tools\nfrom conans.util.files import mkdir, save, rmdir\nfrom conans.util.log import logger\nfrom conans.paths import CONANINFO, CONAN_MANIFEST\nfrom conans.errors import ConanException, ConanExceptionInUserConanfileMethod, conanfile_exception_formatter\nfrom conans.model.manifest import FileTreeManifest\nfrom conans.client.output import ScopedOutput\nfrom conans.client.file_copier import FileCopier\n\n\ndef create_package(conanfile, source_folder, build_folder, package_folder, install_folder,\n                   output, local=False, copy_info=False):\n    \"\"\" copies built artifacts, libs, headers, data, etc from build_folder to\n    package folder\n    \"\"\"\n    mkdir(package_folder)\n\n    # Make the copy of all the patterns\n    output.info(\"Generating the package\")\n    output.info(\"Package folder %s\" % (package_folder))\n\n    try:\n        package_output = ScopedOutput(\"%s package()\" % output.scope, output)\n        output.highlight(\"Calling package()\")\n        conanfile.package_folder = package_folder\n        conanfile.source_folder = source_folder\n        conanfile.build_folder = build_folder\n\n        def recipe_has(conanfile, attribute):\n            return attribute in conanfile.__class__.__dict__\n\n        if source_folder != build_folder:\n            conanfile.copy = FileCopier(source_folder, package_folder, build_folder)\n            with conanfile_exception_formatter(str(conanfile), \"package\"):\n                with tools.chdir(source_folder):\n                    conanfile.package()\n            warn = recipe_has(conanfile, \"package\")\n            conanfile.copy.report(package_output, warn=warn)\n\n        conanfile.copy = FileCopier(build_folder, package_folder)\n        with tools.chdir(build_folder):\n            with conanfile_exception_formatter(str(conanfile), \"package\"):\n                conanfile.package()\n        warn = recipe_has(conanfile, \"build\") and recipe_has(conanfile, \"package\")\n        conanfile.copy.report(package_output, warn=warn)\n    except Exception as e:\n        if not local:\n            os.chdir(build_folder)\n            try:\n                rmdir(package_folder)\n            except Exception as e_rm:\n                output.error(\"Unable to remove package folder %s\\n%s\" % (package_folder, str(e_rm)))\n                output.warn(\"**** Please delete it manually ****\")\n\n        if isinstance(e, ConanExceptionInUserConanfileMethod):\n            raise\n        raise ConanException(e)\n\n    _create_aux_files(install_folder, package_folder, conanfile, copy_info)\n    output.success(\"Package '%s' created\" % os.path.basename(package_folder))\n\n\ndef _create_aux_files(install_folder, package_folder, conanfile, copy_info):\n    \"\"\" auxiliary method that creates CONANINFO and manifest in\n    the package_folder\n    \"\"\"\n    logger.debug(\"Creating config files to %s\" % package_folder)\n    if copy_info:\n        try:\n            shutil.copy(os.path.join(install_folder, CONANINFO), package_folder)\n        except IOError:\n            raise ConanException(\"%s does not exist inside of your %s folder. \"\n                                 \"Try to re-build it again to solve it.\"\n                                 % (CONANINFO, install_folder))\n    else:\n        save(os.path.join(package_folder, CONANINFO), conanfile.info.dumps())\n\n    # Create the digest for the package\n    digest = FileTreeManifest.create(package_folder)\n    save(os.path.join(package_folder, CONAN_MANIFEST), str(digest))\n", "path": "conans/client/packager.py"}], "after_files": [{"content": "import os\nimport shutil\n\nfrom conans.client import tools\nfrom conans.util.files import mkdir, save, rmdir\nfrom conans.util.log import logger\nfrom conans.paths import CONANINFO, CONAN_MANIFEST\nfrom conans.errors import ConanException, ConanExceptionInUserConanfileMethod, conanfile_exception_formatter\nfrom conans.model.manifest import FileTreeManifest\nfrom conans.client.output import ScopedOutput\nfrom conans.client.file_copier import FileCopier\n\n\ndef create_package(conanfile, source_folder, build_folder, package_folder, install_folder,\n                   output, local=False, copy_info=False):\n    \"\"\" copies built artifacts, libs, headers, data, etc from build_folder to\n    package folder\n    \"\"\"\n    mkdir(package_folder)\n\n    # Make the copy of all the patterns\n    output.info(\"Generating the package\")\n    output.info(\"Package folder %s\" % (package_folder))\n\n    try:\n        package_output = ScopedOutput(\"%s package()\" % output.scope, output)\n        output.highlight(\"Calling package()\")\n        conanfile.package_folder = package_folder\n        conanfile.source_folder = source_folder\n        conanfile.install_folder = install_folder\n        conanfile.build_folder = build_folder\n\n        def recipe_has(conanfile, attribute):\n            return attribute in conanfile.__class__.__dict__\n\n        if source_folder != build_folder:\n            conanfile.copy = FileCopier(source_folder, package_folder, build_folder)\n            with conanfile_exception_formatter(str(conanfile), \"package\"):\n                with tools.chdir(source_folder):\n                    conanfile.package()\n            warn = recipe_has(conanfile, \"package\")\n            conanfile.copy.report(package_output, warn=warn)\n\n        conanfile.copy = FileCopier(build_folder, package_folder)\n        with tools.chdir(build_folder):\n            with conanfile_exception_formatter(str(conanfile), \"package\"):\n                conanfile.package()\n        warn = recipe_has(conanfile, \"build\") and recipe_has(conanfile, \"package\")\n        conanfile.copy.report(package_output, warn=warn)\n    except Exception as e:\n        if not local:\n            os.chdir(build_folder)\n            try:\n                rmdir(package_folder)\n            except Exception as e_rm:\n                output.error(\"Unable to remove package folder %s\\n%s\" % (package_folder, str(e_rm)))\n                output.warn(\"**** Please delete it manually ****\")\n\n        if isinstance(e, ConanExceptionInUserConanfileMethod):\n            raise\n        raise ConanException(e)\n\n    _create_aux_files(install_folder, package_folder, conanfile, copy_info)\n    output.success(\"Package '%s' created\" % os.path.basename(package_folder))\n\n\ndef _create_aux_files(install_folder, package_folder, conanfile, copy_info):\n    \"\"\" auxiliary method that creates CONANINFO and manifest in\n    the package_folder\n    \"\"\"\n    logger.debug(\"Creating config files to %s\" % package_folder)\n    if copy_info:\n        try:\n            shutil.copy(os.path.join(install_folder, CONANINFO), package_folder)\n        except IOError:\n            raise ConanException(\"%s does not exist inside of your %s folder. \"\n                                 \"Try to re-build it again to solve it.\"\n                                 % (CONANINFO, install_folder))\n    else:\n        save(os.path.join(package_folder, CONANINFO), conanfile.info.dumps())\n\n    # Create the digest for the package\n    digest = FileTreeManifest.create(package_folder)\n    save(os.path.join(package_folder, CONAN_MANIFEST), str(digest))\n", "path": "conans/client/packager.py"}]}