Skip to content

Commit b5c7c1e

Browse files
authored
Drop crayons in exceptions.py (#5080)
* Remove crayons usage from exceptions.py Replace all crayon color with appropriate `click.style` calls.
1 parent e5d08fb commit b5c7c1e

File tree

1 file changed

+72
-73
lines changed

1 file changed

+72
-73
lines changed

pipenv/exceptions.py

+72-73
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
import itertools
2-
import re
32
import sys
43
from collections import namedtuple
54
from traceback import format_tb
65

76
from pipenv import environments
87
from pipenv._compat import decode_for_output
9-
from pipenv.patched import crayons
10-
from pipenv.vendor import vistir
8+
from pipenv.vendor import click, vistir
119
from pipenv.vendor.click.exceptions import ClickException, FileError, UsageError
1210
from pipenv.vendor.vistir.misc import echo as click_echo
1311

14-
ANSI_REMOVAL_RE = re.compile(r"\033\[((?:\d|;)*)([a-zA-Z])", re.MULTILINE)
15-
STRING_TYPES = ((str,), crayons.ColoredString)
16-
1712
if sys.version_info[:2] >= (3, 7):
1813
KnownException = namedtuple(
1914
"KnownException",
@@ -62,7 +57,7 @@ def handle_exception(exc_type, exception, traceback, hook=sys.excepthook):
6257

6358

6459
class PipenvException(ClickException):
65-
message = "{0}: {{0}}".format(crayons.red("ERROR", bold=True))
60+
message = "{0}: {{0}}".format(click.style("ERROR", fg="red", bold=True))
6661

6762
def __init__(self, message=None, **kwargs):
6863
if not message:
@@ -76,15 +71,14 @@ def show(self, file=None):
7671
if file is None:
7772
file = vistir.misc.get_text_stderr()
7873
if self.extra:
79-
if isinstance(self.extra, STRING_TYPES):
74+
if isinstance(self.extra, str):
8075
self.extra = [self.extra]
8176
for extra in self.extra:
8277
extra = "[pipenv.exceptions.{!s}]: {}".format(
8378
self.__class__.__name__, extra
8479
)
85-
extra = decode_for_output(extra, file)
86-
click_echo(extra, file=file)
87-
click_echo(decode_for_output(f"{self.message}", file), file=file)
80+
click.echo(extra, file=file)
81+
click.echo(f"{self.message}", file=file)
8882

8983

9084
class PipenvCmdError(PipenvException):
@@ -99,25 +93,24 @@ def __init__(self, cmd, out="", err="", exit_code=1):
9993
def show(self, file=None):
10094
if file is None:
10195
file = vistir.misc.get_text_stderr()
102-
click_echo(
96+
click.echo(
10397
"{} {}".format(
104-
crayons.red("Error running command: "),
105-
crayons.normal(decode_for_output(f"$ {self.cmd}", file), bold=True),
98+
click.style("Error running command: ", fg="red"),
99+
click.style(f"$ {self.cmd}", bold=True),
106100
),
107101
err=True,
102+
file=file,
108103
)
109104
if self.out:
110-
click_echo(
111-
"{} {}".format(
112-
crayons.normal("OUTPUT: "), decode_for_output(self.out, file)
113-
),
105+
click.echo(
106+
"{} {}".format("OUTPUT: ", self.out),
107+
file=file,
114108
err=True,
115109
)
116110
if self.err:
117111
click_echo(
118-
"{} {}".format(
119-
crayons.normal("STDERR: "), decode_for_output(self.err, file)
120-
),
112+
"{} {}".format("STDERR: ", self.err),
113+
file=file,
121114
err=True,
122115
)
123116

@@ -131,14 +124,14 @@ def show(self, file=None):
131124
if file is None:
132125
file = vistir.misc.get_text_stderr()
133126
message = "{}\n{}".format(
134-
crayons.normal("Failed parsing JSON results:", bold=True),
127+
click.style("Failed parsing JSON results:", bold=True),
135128
decode_for_output(self.message.strip(), file),
136129
)
137130
click_echo(message, err=True)
138131
if self.error_text:
139132
click_echo(
140133
"{} {}".format(
141-
crayons.normal("ERROR TEXT:", bold=True),
134+
click.style("ERROR TEXT:", bold=True),
142135
decode_for_output(self.error_text, file),
143136
),
144137
err=True,
@@ -148,10 +141,10 @@ def show(self, file=None):
148141
class PipenvUsageError(UsageError):
149142
def __init__(self, message=None, ctx=None, **kwargs):
150143
formatted_message = "{0}: {1}"
151-
msg_prefix = crayons.red("ERROR:", bold=True)
144+
msg_prefix = click.style("ERROR:", fg="red", bold=True)
152145
if not message:
153146
message = "Pipenv encountered a problem and had to exit."
154-
message = formatted_message.format(msg_prefix, crayons.normal(message, bold=True))
147+
message = formatted_message.format(msg_prefix, click.style(message, bold=True))
155148
self.message = message
156149
extra = kwargs.pop("extra", [])
157150
UsageError.__init__(self, decode_for_output(message), ctx)
@@ -164,32 +157,34 @@ def show(self, file=None):
164157
if self.ctx is not None:
165158
color = self.ctx.color
166159
if self.extra:
167-
if isinstance(self.extra, STRING_TYPES):
160+
if isinstance(self.extra, str):
168161
self.extra = [self.extra]
169162
for extra in self.extra:
170163
if color:
171-
extra = getattr(crayons, color, "blue")(extra)
172-
click_echo(decode_for_output(extra, file), file=file)
164+
extra = click.style(extra, fg=color)
165+
click.echo(extra, file=file)
173166
hint = ""
174167
if self.cmd is not None and self.cmd.get_help_option(self.ctx) is not None:
175168
hint = 'Try "%s %s" for help.\n' % (
176169
self.ctx.command_path,
177170
self.ctx.help_option_names[0],
178171
)
179172
if self.ctx is not None:
180-
click_echo(self.ctx.get_usage() + "\n%s" % hint, file=file, color=color)
181-
click_echo(self.message, file=file)
173+
click.echo(self.ctx.get_usage() + "\n%s" % hint, file=file, color=color)
174+
click.echo(self.message, file=file)
182175

183176

184177
class PipenvFileError(FileError):
185-
formatted_message = "{0} {{0}} {{1}}".format(crayons.red("ERROR:", bold=True))
178+
formatted_message = "{0} {{0}} {{1}}".format(
179+
click.style("ERROR:", fg="red", bold=True)
180+
)
186181

187182
def __init__(self, filename, message=None, **kwargs):
188183
extra = kwargs.pop("extra", [])
189184
if not message:
190-
message = crayons.normal("Please ensure that the file exists!", bold=True)
185+
message = click.style("Please ensure that the file exists!", bold=True)
191186
message = self.formatted_message.format(
192-
crayons.normal(f"{filename} not found!", bold=True), message
187+
click.style(f"{filename} not found!", bold=True), message
193188
)
194189
FileError.__init__(
195190
self, filename=filename, hint=decode_for_output(message), **kwargs
@@ -200,7 +195,7 @@ def show(self, file=None):
200195
if file is None:
201196
file = vistir.misc.get_text_stderr()
202197
if self.extra:
203-
if isinstance(self.extra, STRING_TYPES):
198+
if isinstance(self.extra, str):
204199
self.extra = [self.extra]
205200
for extra in self.extra:
206201
click_echo(decode_for_output(extra, file), file=file)
@@ -211,8 +206,8 @@ class PipfileNotFound(PipenvFileError):
211206
def __init__(self, filename="Pipfile", extra=None, **kwargs):
212207
extra = kwargs.pop("extra", [])
213208
message = "{} {}".format(
214-
crayons.red("Aborting!", bold=True),
215-
crayons.normal(
209+
click.style("Aborting!", bold=True, fg="red"),
210+
click.style(
216211
"Please ensure that the file exists and is located in your"
217212
" project root directory.",
218213
bold=True,
@@ -225,17 +220,17 @@ class LockfileNotFound(PipenvFileError):
225220
def __init__(self, filename="Pipfile.lock", extra=None, **kwargs):
226221
extra = kwargs.pop("extra", [])
227222
message = "{} {} {}".format(
228-
crayons.normal("You need to run", bold=True),
229-
crayons.red("$ pipenv lock", bold=True),
230-
crayons.normal("before you can continue.", bold=True),
223+
click.style("You need to run", bold=True),
224+
click.style("$ pipenv lock", bold=True, fg="red"),
225+
click.style("before you can continue.", bold=True),
231226
)
232227
super().__init__(filename, message=message, extra=extra, **kwargs)
233228

234229

235230
class DeployException(PipenvUsageError):
236231
def __init__(self, message=None, **kwargs):
237232
if not message:
238-
message = str(crayons.normal("Aborting deploy", bold=True))
233+
message = click.style("Aborting deploy", bold=True)
239234
extra = kwargs.pop("extra", [])
240235
PipenvUsageError.__init__(self, message=message, extra=extra, **kwargs)
241236

@@ -254,12 +249,12 @@ def __init__(self, option_name="system", message=None, ctx=None, **kwargs):
254249
extra += [
255250
"{}: --system is intended to be used for Pipfile installation, "
256251
"not installation of specific packages. Aborting.".format(
257-
crayons.red("Warning", bold=True)
252+
click.style("Warning", bold=True, fg="red")
258253
),
259254
]
260255
if message is None:
261-
message = str(
262-
crayons.cyan("See also: {}".format(crayons.normal("--deploy flag.")))
256+
message = "{} --deploy flag".format(
257+
click.style("See also: {}", fg="cyan"),
263258
)
264259
super().__init__(option_name, message=message, ctx=ctx, extra=extra, **kwargs)
265260

@@ -296,14 +291,11 @@ def __init__(self, message=None, **kwargs):
296291
message = "Failed to create virtual environment."
297292
self.message = message
298293
extra = kwargs.pop("extra", None)
299-
if extra is not None and isinstance(extra, STRING_TYPES):
300-
# note we need the format interpolation because ``crayons.ColoredString``
301-
# is not an actual string type but is only a preparation for interpolation
302-
# so replacement or parsing requires this step
303-
extra = ANSI_REMOVAL_RE.sub("", f"{extra}")
294+
if extra is not None and isinstance(extra, str):
295+
extra = click.unstyle(f"{extra}")
304296
if "KeyboardInterrupt" in extra:
305-
extra = str(
306-
crayons.red("Virtualenv creation interrupted by user", bold=True)
297+
extra = click.style(
298+
"Virtualenv creation interrupted by user", fg="red", bold=True
307299
)
308300
self.extra = extra = [extra]
309301
VirtualenvException.__init__(self, message, extra=extra)
@@ -313,16 +305,18 @@ class UninstallError(PipenvException):
313305
def __init__(self, package, command, return_values, return_code, **kwargs):
314306
extra = [
315307
"{} {}".format(
316-
crayons.cyan("Attempted to run command: "),
317-
crayons.yellow(f"$ {command!r}", bold=True),
308+
click.style("Attempted to run command: ", fg="cyan"),
309+
click.style(f"$ {command!r}", bold=True, fg="yellow"),
318310
)
319311
]
320-
extra.extend([crayons.cyan(line.strip()) for line in return_values.splitlines()])
312+
extra.extend(
313+
[click.style(line.strip(), fg="cyan") for line in return_values.splitlines()]
314+
)
321315
if isinstance(package, (tuple, list, set)):
322316
package = " ".join(package)
323317
message = "{!s} {!s}...".format(
324-
crayons.normal("Failed to uninstall package(s)"),
325-
crayons.yellow(f"{package}!s", bold=True),
318+
click.style("Failed to uninstall package(s)", fg="reset"),
319+
click.style(f"{package}!s", bold=True, fg="yellow"),
326320
)
327321
self.exit_code = return_code
328322
PipenvException.__init__(self, message=message, extra=extra)
@@ -334,10 +328,11 @@ def __init__(self, package, **kwargs):
334328
package_message = ""
335329
if package is not None:
336330
package_message = "Couldn't install package: {}\n".format(
337-
crayons.normal(f"{package!s}", bold=True)
331+
click.style(f"{package!s}", bold=True)
338332
)
339333
message = "{} {}".format(
340-
f"{package_message}", crayons.yellow("Package installation failed...")
334+
f"{package_message}",
335+
click.style("Package installation failed...", fg="yellow"),
341336
)
342337
extra = kwargs.pop("extra", [])
343338
PipenvException.__init__(self, message=message, extra=extra, **kwargs)
@@ -346,9 +341,9 @@ def __init__(self, package, **kwargs):
346341
class CacheError(PipenvException):
347342
def __init__(self, path, **kwargs):
348343
message = "{} {}\n{}".format(
349-
crayons.cyan("Corrupt cache file"),
350-
crayons.normal(f"{path!s}"),
351-
crayons.normal('Consider trying "pipenv lock --clear" to clear the cache.'),
344+
click.style("Corrupt cache file", fg="cyan"),
345+
click.style(f"{path!s}", fg="reset", bg="reset"),
346+
click.style('Consider trying "pipenv lock --clear" to clear the cache.'),
352347
)
353348
PipenvException.__init__(self, message=message)
354349

@@ -357,9 +352,10 @@ class DependencyConflict(PipenvException):
357352
def __init__(self, message):
358353
extra = [
359354
"{} {}".format(
360-
crayons.red("The operation failed...", bold=True),
361-
crayons.red(
362-
"A dependency conflict was detected and could not be resolved."
355+
click.style("The operation failed...", bold=True, fg="red"),
356+
click.style(
357+
"A dependency conflict was detected and could not be resolved.",
358+
fg="red",
363359
),
364360
)
365361
]
@@ -375,21 +371,22 @@ def __init__(self, message, no_version_found=False):
375371
"{} to inspect the situation.\n "
376372
"Hint: try {} if it is a pre-release dependency."
377373
"".format(
378-
crayons.red("Warning", bold=True),
379-
crayons.yellow("$ pipenv install --skip-lock"),
380-
crayons.yellow("$ pipenv graph"),
381-
crayons.yellow("$ pipenv lock --pre"),
374+
click.style("Warning", fg="red", bold=True),
375+
click.style("$ pipenv install --skip-lock", fg="yellow"),
376+
click.style("$ pipenv graph", fg="yellow"),
377+
click.style("$ pipenv lock --pre", fg="yellow"),
382378
),
383379
)
384380
if "no version found at all" in message:
385381
no_version_found = True
386-
message = crayons.yellow(f"{message}")
382+
message = click.style(f"{message}", fg="yellow")
387383
if no_version_found:
388384
message = "{}\n{}".format(
389385
message,
390-
crayons.cyan(
386+
click.style(
391387
"Please check your version specifier and version number. "
392-
"See PEP440 for more information."
388+
"See PEP440 for more information.",
389+
fg="cyan",
393390
),
394391
)
395392
PipenvException.__init__(self, message, extra=extra)
@@ -428,9 +425,11 @@ def __init__(self, req=None):
428425
req_value = "\n".join([f" {k}: {v}" for k, v in values])
429426
else:
430427
req_value = getattr(req.line_instance, "line", None)
431-
message = "{} {}".format(
432-
crayons.normal(decode_for_output("Failed creating requirement instance")),
433-
crayons.normal(decode_for_output(f"{req_value!r}")),
428+
message = click.style(
429+
f"Failed creating requirement instance {req_value}",
430+
bold=False,
431+
fg="reset",
432+
bg="reset",
434433
)
435434
extra = [str(req)]
436435
PipenvException.__init__(self, message, extra=extra)

0 commit comments

Comments
 (0)