-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Only write lock file when installation is success #7498
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Only write lock file when installation is success #7498
Conversation
poetry add rollback poetry.lock when installation failurepoetry add to rollback poetry.lock when installation failure
poetry add to rollback poetry.lock when installation failurepoetry add to rollback poetry.lock when installation fails
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as resolved.
This comment was marked as resolved.
|
#395 was scoped only at not leaving the lock file inconsistent with the pyproject.toml. This goes further in also rolling back changes to the virtual environment. I'm not sure whether this is a good idea. Though I can see how this might be desirable, it adds complexity and edge cases. (What if the rollback itself fails? What if the user had previously gone The failed install left the user with no hint that the lockfile might be inconsistent with pyproject.toml. No question that #395 identifies a bug here that wants fixing. However, the failed install made plenty of logs saying "Installing package-foo" etc and so it should be obvious to a user that their environment has changed. Given the difficulty of reliably restoring exactly the previous environment, it's simpler and safer to let the user decide what to do about that. Eg maybe they'd actually prefer to keep the 90% of the install that was successful while they fix up some missing I'd suggest limiting the scope of this MR to leaving |
I don't doubt this PR requires some polishing, but this is exactly what I'm doing here, no? In case of installation failure, I'm not removing any package, not really. I'm cleaning up the objects in the scope of |
|
Oh, now I realized the source of confusion. Here I'm not in no way making changes to environment. I mean, AFAIK installer in lock only mode don't change the environment, so I'm relying on it. |
|
Oh, perhaps I misread. Still I am surprised that this fix requires any re-locking: I'd expect to arrange things so that the file isn't written (or is explicitly rewritten with a saved copy of the old file) in case of failure - more like the handling of Also maybe cf #7401 - it seems to be uncertain whether anyone likes that enough to merge it as a whole, but the |
|
What about Maybe you already looked into this, perhaps a better place to catch all such examples would be the Installer's |
Good points. Excellent points, actually. This will require a further investigation, and probably a more complex change. At least I already have the test 😸 |
|
looking at your latest draft, I'd definitely suggest that simpler than backing up and restoring the lockfile would be to refactor
|
Thank you very much for looking at the draft and for the suggestion. Lazy as I am, I was avoiding to make any rewrite, but I was definitely starting to think along these lines 😸
I have a few ideas I'll try this week. But |
poetry add to rollback poetry.lock when installation fails|
@dimbleby when you have a chance, check my latest update. I am applying a delay in the write to lock file by creating an internal |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
Okay, I feel this is ready for a review. There are only 2 things I am uncertain:
@dimbleby I am still thinking on a possible refactor on |
| self._lock = Path(lock_path.joinpath("poetry.lock")) | ||
| self._written_data = None | ||
| self._locked = False | ||
| self._lock_data = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason: some tests were failing due to the lack of this property (that exists on parent Locker)
This comment was marked as duplicate.
This comment was marked as duplicate.
|
I don't much like it! This adds a pile of code that I don't think ought to be needed.
|
It is a good question. I tried to rearrange Right now the All in all, I am open to discussions, here or in Discord 🙂 |
|
Update: I incorporated the transactional state into All existing I kept the implementation as simple as possible. |
|
I realized that indeed the lock file can be written after installation without any transaction mechanism. I let the failures in my initial investigations misled me, which turned to my current solution. Ashamed 😶 Now I have a working solution that do that, but there is a side effect in the output: "Writing lock file" message is shifted to the end (see below). Is this desired??? Current output Using version ^1.1.2 for foo
Updating dependencies
Resolving dependencies...
Writing lock file
Package operations: 1 install, 0 updates, 0 removals
- Installing foo (1.1.2)New output writing lock file in the end Using version ^1.1.2 for foo
Updating dependencies
Resolving dependencies...
Package operations: 1 install, 0 updates, 0 removals
- Installing foo (1.1.2)
Writing lock file |
|
IMO the "writing lock file" message should be printed when the lock file is written. If it is written before installation it should be printed before. If it is written after installation it should be printed afterwards. |
|
In that case, I will publish the solution postponing lock file writing to the end. |
|
I assume you "just" have to add two json files for See https://github.com/python-poetry/poetry/blob/master/tests/repositories/fixtures/pypi.org/json/setuptools.json and https://github.com/python-poetry/poetry/blob/master/tests/repositories/fixtures/pypi.org/json/setuptools/39.2.0.json for example. That's where the ancient setuptools 39.2.0 in #7498 (comment) comes from. |
|
Thank, @radoering, I got the idea now. But this is getting weirder, I added the Notice it was logged "Installing setuptools (39.2.0)", but I have a dependency on setuptools??? It makes no sense. Updating dependencies
Resolving dependencies...
Writing lock file
Package operations: 7 installs, 0 updates, 0 removals
• Installing six (1.11.0)
• Installing attrs (17.4.0)
• Installing more-itertools (4.1.0)
• Installing pluggy (0.6.0)
• Installing py (1.5.3)
• Installing setuptools (39.2.0)
SolveFailure
Because -root- depends on setuptools (>=40.8.0) which doesn't match any versions, version solving failed. |
|
I also made a different investigation by switching off my network and noticed this test is requiring network to work. See below. Was that supposed to be??? Updating dependencies
Resolving dependencies...
Writing lock file
Package operations: 7 installs, 0 updates, 0 removals
• Installing six (1.11.0)
gaierror
[Errno -3] Temporary failure in name resolution
at /usr/lib/python3.8/socket.py:918 in getaddrinfo
914│ """
915│ # We override this function since we want to translate the numeric family
916│ # and socket type values to enum constants.
917│ addrlist = []
→ 918│ for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
919│ af, socktype, proto, canonname, sa = res
920│ addrlist.append((_intenum_converter(af, AddressFamily),
921│ _intenum_converter(socktype, SocketKind),
922│ proto, canonname, sa))
The following error occurred when trying to handle this error:
NewConnectionError
<urllib3.connection.HTTPSConnection object at 0x7f973c75afd0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution
at ~/.cache/pypoetry/virtualenvs/poetry-Iqs9p7vq-py3.8/lib/python3.8/site-packages/urllib3/connection.py:186 in _new_conn
182│ % (self.host, self.timeout),
183│ )
184│
185│ except SocketError as e:
→ 186│ raise NewConnectionError(
187│ self, "Failed to establish a new connection: %s" % e
188│ )
189│
190│ return conn
The following error occurred when trying to handle this error:
MaxRetryError
HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Max retries exceeded with url: /packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f973c75afd0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))
at ~/.cache/pypoetry/virtualenvs/poetry-Iqs9p7vq-py3.8/lib/python3.8/site-packages/urllib3/util/retry.py:592 in increment
588│ history=history,
589│ )
590│
591│ if new_retry.is_exhausted():
→ 592│ raise MaxRetryError(_pool, url, error or ResponseError(cause))
593│
594│ log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)
595│
596│ return new_retry
The following error occurred when trying to handle this error:
ConnectionError
HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Max retries exceeded with url: /packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f973c75afd0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))
at ~/.cache/pypoetry/virtualenvs/poetry-Iqs9p7vq-py3.8/lib/python3.8/site-packages/requests/adapters.py:565 in send
561│ if isinstance(e.reason, _SSLError):
562│ # This branch is for urllib3 v1.22 and later.
563│ raise SSLError(e, request=request)
564│
→ 565│ raise ConnectionError(e, request=request)
566│
567│ except ClosedPoolError as e:
568│ raise ConnectionError(e, request=request)
569│ |
|
I didn't include the wheel files. They are in another branch that I am experimenting.
|
like the earlier dependency on wheel, this will be a default build requirement for a package that needs building and that does not specify its build requirements. certainly it's undesirable for these tests to rely on having an internet connection |
I will take your word. Still, don't you think that's weird the solver to show to the user and in the end to display |
|
pretty sure it's just an unlucky coincidence that this testcase happens to pick up a dependency on setuptools 39.2.0, while some other dependency has (by default) a build-time dependency on setuptools 40.8.0. Agree that it's not completely obvious that this is what is happening, if you haven't got enough to fix in this MR already feel free also to make the messages better! |
|
For example, we should replace poetry/src/poetry/installation/chef.py Line 69 in 40061f9
|
|
it definitely comes from there, |
|
@wagnerluis1982 if you're still interested in progressing this then it's going to be worth rebasing on master, the testcase that was giving you trouble is fixed as at #7759 |
|
@dimbleby thanks. I'm still interested. Will do the rebase ASAP. |
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [poetry](https://python-poetry.org/) ([source](https://github.com/python-poetry/poetry), [changelog](https://python-poetry.org/history/)) | minor | `1.4.2` -> `1.5.0` | --- ### Release Notes <details> <summary>python-poetry/poetry</summary> ### [`v1.5.0`](https://github.com/python-poetry/poetry/blob/HEAD/CHANGELOG.md#​150---2023-05-19) [Compare Source](python-poetry/poetry@1.4.2...1.5.0) ##### Added - **Introduce the new source priorities `explicit` and `supplemental`** ([#​7658](python-poetry/poetry#7658), [#​6879](python-poetry/poetry#6879)). - **Introduce the option to configure the priority of the implicit PyPI source** ([#​7801](python-poetry/poetry#7801)). - Add handling for corrupt cache files ([#​7453](python-poetry/poetry#7453)). - Improve caching of URL and git dependencies ([#​7693](python-poetry/poetry#7693), [#​7473](python-poetry/poetry#7473)). - Add option to skip installing directory dependencies ([#​6845](python-poetry/poetry#6845), [#​7923](python-poetry/poetry#7923)). - Add `--executable` option to `poetry env info` ([#​7547](python-poetry/poetry#7547)). - Add `--top-level` option to `poetry show` ([#​7415](python-poetry/poetry#7415)). - Add `--lock` option to `poetry remove` ([#​7917](python-poetry/poetry#7917)). - Add experimental `POETRY_REQUESTS_TIMEOUT` option ([#​7081](python-poetry/poetry#7081)). - Improve performance of wheel inspection by avoiding unnecessary file copy operations ([#​7916](python-poetry/poetry#7916)). ##### Changed - **Remove the old deprecated installer and the corresponding setting `experimental.new-installer`** ([#​7356](python-poetry/poetry#7356)). - **Introduce `priority` key for sources and deprecate flags `default` and `secondary`** ([#​7658](python-poetry/poetry#7658)). - Deprecate `poetry run <entry point>` if the entry point was not previously installed via `poetry install` ([#​7606](python-poetry/poetry#7606)). - Only write the lock file if the installation succeeds ([#​7498](python-poetry/poetry#7498)). - Do not write the unused package category into the lock file ([#​7637](python-poetry/poetry#7637)). ##### Fixed - Fix an issue where Poetry's internal pyproject.toml continually grows larger with empty lines ([#​7705](python-poetry/poetry#7705)). - Fix an issue where Poetry crashes due to corrupt cache files ([#​7453](python-poetry/poetry#7453)). - Fix an issue where the `Retry-After` in HTTP responses was not respected and retries were handled inconsistently ([#​7072](python-poetry/poetry#7072)). - Fix an issue where Poetry silently ignored invalid groups ([#​7529](python-poetry/poetry#7529)). - Fix an issue where Poetry does not find a compatible Python version if not given explicitly ([#​7771](python-poetry/poetry#7771)). - Fix an issue where the `direct_url.json` of an editable install from a git dependency was invalid ([#​7473](python-poetry/poetry#7473)). - Fix an issue where error messages from build backends were not decoded correctly ([#​7781](python-poetry/poetry#7781)). - Fix an infinite loop when adding certain dependencies ([#​7405](python-poetry/poetry#7405)). - Fix an issue where pre-commit hooks skip pyproject.toml files in subdirectories ([#​7239](python-poetry/poetry#7239)). - Fix an issue where pre-commit hooks do not use the expected Python version ([#​6989](python-poetry/poetry#6989)). - Fix an issue where an unclear error message is printed if the project name is the same as one of its dependencies ([#​7757](python-poetry/poetry#7757)). - Fix an issue where `poetry install` returns a zero exit status even though the build script failed ([#​7812](python-poetry/poetry#7812)). - Fix an issue where an existing `.venv` was not used if `in-project` was not set ([#​7792](python-poetry/poetry#7792)). - Fix an issue where multiple extras passed to `poetry add` were not parsed correctly ([#​7836](python-poetry/poetry#7836)). - Fix an issue where `poetry shell` did not send a newline to `fish` ([#​7884](python-poetry/poetry#7884)). - Fix an issue where `poetry update --lock` printed operations that were not executed ([#​7915](python-poetry/poetry#7915)). - Fix an issue where `poetry add --lock` did perform a full update of all dependencies ([#​7920](python-poetry/poetry#7920)). - Fix an issue where `poetry shell` did not work with `nushell` ([#​7919](python-poetry/poetry#7919)). - Fix an issue where subprocess calls failed on Python 3.7 ([#​7932](python-poetry/poetry#7932)). - Fix an issue where keyring was called even though the password was stored in an environment variable ([#​7928](python-poetry/poetry#7928)). ##### Docs - Add information about what to use instead of `--dev` ([#​7647](python-poetry/poetry#7647)). - Promote semantic versioning less aggressively ([#​7517](python-poetry/poetry#7517)). - Explain Poetry's own versioning scheme in the FAQ ([#​7517](python-poetry/poetry#7517)). - Update documentation for configuration with environment variables ([#​6711](python-poetry/poetry#6711)). - Add details how to disable the virtualenv prompt ([#​7874](python-poetry/poetry#7874)). - Improve documentation on whether to commit `poetry.lock` ([#​7506](python-poetry/poetry#7506)). - Improve documentation of `virtualenv.create` ([#​7608](python-poetry/poetry#7608)). ##### poetry-core ([`1.6.0`](https://github.com/python-poetry/poetry-core/releases/tag/1.6.0)) - Improve error message for invalid markers ([#​569](python-poetry/poetry-core#569)). - Increase robustness when deleting temporary directories on Windows ([#​460](python-poetry/poetry-core#460)). - Replace `tomlkit` with `tomli`, which changes the interface of some *internal* classes ([#​483](python-poetry/poetry-core#483)). - Deprecate `Package.category` ([#​561](python-poetry/poetry-core#561)). - Fix a performance regression in marker handling ([#​568](python-poetry/poetry-core#568)). - Fix an issue where wildcard version constraints were not handled correctly ([#​402](python-poetry/poetry-core#402)). - Fix an issue where `poetry build` created duplicate Python classifiers if they were specified manually ([#​578](python-poetry/poetry-core#578)). - Fix an issue where local versions where not handled correctly ([#​579](python-poetry/poetry-core#579)). </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS44Mi4wIiwidXBkYXRlZEluVmVyIjoiMzUuODIuMCIsInRhcmdldEJyYW5jaCI6Im1hc3RlciJ9--> Reviewed-on: https://git.walbeck.it/walbeck-it/docker-python-poetry/pulls/717 Co-authored-by: renovate-bot <[email protected]> Co-committed-by: renovate-bot <[email protected]>
|
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Pull Request Check List
Resolves: #395
How it appear to users
The user experience is almost the same, but "Writing lock file" only appears in the end of the process, and only if the installation process succeeds.
On success ("Writing lock file" displays after installation)
On failure ("Writing lock file" is not displayed)