@@ -106,3 +106,212 @@ Backtracking reduces the risk that installing a new package will accidentally
106
106
break an existing installed package, and so reduces the risk that your
107
107
environment gets messed up. To do this, pip has to do more work, to find out
108
108
which version of a package is a good candidate to install.
109
+
110
+ ## Possible ways to reduce backtracking
111
+
112
+ There is no one-size-fits-all answer to situations where pip is backtracking
113
+ excessively during dependency resolution. There are ways to reduce the
114
+ degree to which pip might backtrack though. Nearly all of these approaches
115
+ require some amount of trial and error.
116
+
117
+ ### Allow pip to complete its backtracking
118
+
119
+ In most cases, pip will complete the backtracking process successfully.
120
+ This could take a very long time to complete, so this may not be your
121
+ preferred option.
122
+
123
+ However, it is a possible that pip will not be able to find a set of
124
+ compatible versions. For this, pip will try every possible combination that
125
+ it needs to and determine that there is no compatible set.
126
+
127
+ If you'd prefer not to wait, you can interrupt pip (Ctrl+c) and try the
128
+ strategies listed below.
129
+
130
+ ### Reduce the number of versions pip is trying to use
131
+
132
+ It is usually a good idea to add constraints the package(s) that pip is backtracking on (e.g. in the above example - ` cup ` ).
133
+
134
+ You could try something like:
135
+
136
+ ``` {pip-cli}
137
+ $ pip install tea "cup >= 3.13"
138
+ ```
139
+
140
+ This will reduce the number of versions of ` cup ` it tries, and
141
+ possibly reduce the time pip takes to install.
142
+
143
+ There is a possibility that the addition constraint is incorrect. When this
144
+ happens, the reduced search space makes it easier for pip to more quickly
145
+ determine what caused the conflict and present that to the user. It could also
146
+ result in pip backtracking on a different package due to some other conflict.
147
+
148
+ ### Use constraint files or lockfiles
149
+
150
+ This option is a progression of the previous section. It requires users to know
151
+ how to in
10000
spect:
152
+
153
+ - the packages they're trying to install
154
+ - the package release frequency and compatibility policies
155
+ - their release notes and changelogs from past versions
156
+
157
+ During deployment, you can create a lockfile stating the exact package and
158
+ version number for for each dependency of that package. You can create this
159
+ with ` pip-tools <https://github.com/jazzband/pip-tools/> ` \_\_ .
160
+
161
+ This means the "work" is done once during development process, and thus
162
+ will avoid performing dependency resolution during deployment.
163
+
164
+ ## Dealing with dependency conflicts
165
+
166
+ This section provides practical suggestions to pip users who encounter
167
+ a ` ResolutionImpossible ` error, where pip cannot install their specified
168
+ packages due to conflicting dependencies.
169
+
170
+ ### Understanding your error message
171
+
172
+ When you get a ` ResolutionImpossible ` error, you might see something
173
+ like this:
174
+
175
+ ``` {pip-cli}
176
+ $ pip install "pytest < 4.6" pytest-cov==2.12.1
177
+ [regular pip output]
178
+ ERROR: Cannot install pytest-cov==2.12.1 and pytest<4.6 because these package versions have conflicting dependencies.
179
+
180
+ The conflict is caused by:
181
+ The user requested pytest<4.6
182
+ pytest-cov 2.12.1 depends on pytest>=4.6
183
+ ```
184
+
185
+ In this example, pip cannot install the packages requested because they are
186
+ asking for conflicting versions of pytest.
187
+
188
+ - ` pytest-cov ` version ` 2.12.1 ` , requires ` pytest ` with a version or equal to
189
+ ` 4.6 ` .
190
+ - ` package_tea ` version ` 4.3.0 ` depends on version ` 2.3.1 ` of
191
+ ` package_water `
192
+
193
+ Sometimes these messages are straightforward to read, because they use
194
+ commonly understood comparison operators to specify the required version
195
+ (e.g. ` < ` or ` > ` ).
196
+
197
+ However, Python packaging also supports some more complex ways for
198
+ specifying package versions (e.g. ` ~= ` or ` * ` ):
199
+
200
+ | Operator | Description | Example |
201
+ | -------- | -------------------------------------------------------------- | --------------------------------------------------- |
202
+ | ` > ` | Any version greater than the specified version. | ` >3.1 ` : any version greater than ` 3.1 ` . |
203
+ | ` < ` | Any version less than the specified version. | ` <3.1 ` : any version less than ` 3.1 ` . |
204
+ | ` <= ` | Any version less than or equal to the specified version. | ` <=3.1 ` : any version less than or equal to ` 3.1 ` . |
205
+ | ` >= ` | Any version greater than or equal to the specified version. | ` >=3.1 ` : version ` 3.1 ` and greater. |
206
+ | ` == ` | Exactly the specified version. | ` ==3.1 ` : only ` 3.1 ` . |
207
+ | ` != ` | Any version not equal to the specified version. | ` !=3.1 ` : any version other than ` 3.1 ` . |
208
+ | ` ~= ` | Any compatible{sup}` 1 ` version. | ` ~=3.1 ` : any version compatible{sup}` 1 ` with ` 3.1 ` . |
209
+ | ` * ` | Can be used at the end of a version number to represent _ all_ . | ` ==3.1.* ` : any version that starts with ` 3.1 ` . |
210
+
211
+ {sup}` 1 ` Compatible versions are higher versions that only differ in the final segment.
212
+ ` ~=3.1.2 ` is equivalent to ` >=3.1.2, ==3.1.* ` . ` ~=3.1 ` is equivalent to ` >=3.1, ==3.* ` .
213
+
214
+ The detailed specification of supported comparison operators can be
215
+ found in {pep}` 440 ` .
216
+
217
+ ### Possible solutions
218
+
219
+ The solution to your error will depend on your individual use case. Here
220
+ are some things to try:
221
+
222
+ #### Audit your top level requirements
223
+
224
+ As a first step, it is useful to audit your project and remove any
225
+ unnecessary or out of date requirements (e.g. from your ` setup.py ` or
226
+ ` requirements.txt ` files). Removing these can significantly reduce the
227
+ complexity of your dependency tree, thereby reducing opportunities for
228
+ conflicts to occur.
229
+
230
+ #### Loosen your top level requirements
231
+
232
+ Sometimes the packages that you have asked pip to install are
233
+ incompatible because you have been too strict when you specified the
234
+ package version.
235
+
236
+ In our first example both ` package_coffee ` and ` package_tea ` have been
237
+ _ pinned_ to use specific versions
238
+ (` package_coffee==0.44.1b0 package_tea==4.3.0 ` ).
239
+
240
+ To find a version of both ` package_coffee ` and ` package_tea ` that depend on
241
+ the same version of ` package_water ` , you might consider:
242
+
243
+ - Loosening the range of packages that you are prepared to install
244
+ (e.g. ` pip install "package_coffee>0.44.*" "package_tea>4.0.0" ` )
245
+ - Asking pip to install _ any_ version of ` package_coffee ` and ` package_tea `
246
+ by removing the version specifiers altogether (e.g.
247
+ ` pip install package_coffee package_tea ` )
248
+
249
+ In the second case, pip will automatically find a version of both
250
+ ` package_coffee ` and ` package_tea ` that depend on the same version of
251
+ ` package_water ` , installing:
252
+
253
+ - ` package_coffee 0.46.0b0 ` , which depends on ` package_water 2.6.1 `
254
+ - ` package_tea 4.3.0 ` which _ also_ depends on ` package_water 2.6.1 `
255
+
256
+ If you want to prioritize one package over another, you can add version
257
+ specifiers to _ only_ the more important package:
258
+
259
+ ``` {pip-cli}
260
+ $ pip install package_coffee==0.44.1b0 package_tea
261
+ ```
262
+
263
+ This will result in:
264
+
265
+ - ` package_coffee 0.44.1b0 ` , which depends on ` package_water 2.6.1 `
266
+ - ` package_tea 4.1.3 ` which also depends on ` package_water 2.6.1 `
267
+
268
+ Now that you have resolved the issue, you can repin the compatible
269
+ package versions as required.
270
+
271
+ #### Loosen the requirements of your dependencies
272
+
273
+ Assuming that you cannot resolve the conflict by loosening the version
274
+ of the package you require (as above), you can try to fix the issue on
275
+ your _ dependency_ by:
276
+
277
+ - Requesting that the package maintainers loosen _ their_ dependencies
278
+ - Forking the package and loosening the dependencies yourself
279
+
280
+ :::{warning}
281
+ If you choose to fork the package yourself, you are _ opting out_ of
282
+ any support provided by the package maintainers. Proceed at your own risk!
283
+ :::
284
+
285
+ #### All requirements are appropriate, but a solution does not exist
286
+
287
+ Sometimes it's simply impossible to find a combination of package
288
+ versions that do not conflict. Welcome to [ dependency hell] .
289
+
290
+ In this situation, you could consider:
291
+
292
+ - Using an alternative package, if that is acceptable for your project.
293
+ See [ Awesome Python] for similar packages.
294
+ - Refactoring your project to reduce the number of dependencies (for
295
+ example, by breaking up a monolithic code base into smaller pieces).
296
+
297
+ ### Getting help
298
+
299
+ If none of the suggestions above work for you, we recommend that you ask
300
+ for help on:
301
+
302
+ - [ Python user Discourse] ( https://discuss.python.org/c/users/7 )
303
+ - [ Python user forums] ( https://www.python.org/community/forums/ )
304
+ - [ Python developers Slack channel] ( https://pythondev.slack.com/ )
305
+ - [ Python IRC] ( https://www.python.org/community/irc/ )
306
+ - [ Stack Overflow] ( https://stackoverflow.com/questions/tagged/python )
307
+
308
+ See [ "How do I ask a good question?"] for tips on asking for help.
309
+
310
+ Unfortunately, ** the pip team cannot provide support for individual
311
+ dependency conflict errors** . Please _ only_ open a ticket on
312
+ [ pip's issue tracker] ( https://github.com/pypa/pip/issues ) if you believe
313
+ that your problem has exposed a bug in pip.
314
+
315
+ [ "how do i ask a good question?" ] : https://stackoverflow.com/help/how-to-ask
316
+ [ awesome python ] : https://python.libhunt.com/
317
+ [ dependency hell ] : https://en.wikipedia.org/wiki/Dependency_hell
0 commit comments