diff --git a/httpie/cli/argparser.py b/httpie/cli/argparser.py index ffe2dd24..73e3d27b 100644 --- a/httpie/cli/argparser.py +++ b/httpie/cli/argparser.py @@ -176,7 +176,7 @@ class HTTPieArgumentParser(argparse.ArgumentParser): self.args.output_file.seek(0) try: self.args.output_file.truncate() - except IOError as e: + except OSError as e: if e.errno == errno.EINVAL: # E.g. /dev/null on Linux. pass diff --git a/httpie/cli/argtypes.py b/httpie/cli/argtypes.py index 6d42c22d..f77d5e0a 100644 --- a/httpie/cli/argtypes.py +++ b/httpie/cli/argtypes.py @@ -180,8 +180,8 @@ def readable_file_arg(filename): try: with open(filename, 'rb'): return filename - except IOError as ex: - raise argparse.ArgumentTypeError(f'{filename}: {ex.args[1]}') + except OSError as ex: + raise argparse.ArgumentTypeError(f'{ex.filename}: {ex.strerror}') def parse_format_options(s: str, defaults: Optional[dict]) -> dict: diff --git a/httpie/cli/requestitems.py b/httpie/cli/requestitems.py index 3ddc6f62..9aa00f99 100644 --- a/httpie/cli/requestitems.py +++ b/httpie/cli/requestitems.py @@ -106,7 +106,7 @@ def process_file_upload_arg(arg: KeyValueArg) -> Tuple[str, IO, str]: mime_type = parts[1] if len(parts) > 1 else None try: f = open(os.path.expanduser(filename), 'rb') - except IOError as e: + except OSError as e: raise ParseError(f'{arg.orig!r}: {e}') return ( os.path.basename(filename), @@ -139,7 +139,7 @@ def load_text_file(item: KeyValueArg) -> str: try: with open(os.path.expanduser(path), 'rb') as f: return f.read().decode() - except IOError as e: + except OSError as e: raise ParseError(f'{item.orig!r}: {e}') except UnicodeDecodeError: raise ParseError( diff --git a/httpie/config.py b/httpie/config.py index 5960a6bb..5187da7e 100644 --- a/httpie/config.py +++ b/httpie/config.py @@ -72,11 +72,7 @@ class BaseConfigDict(dict): self.path = path def ensure_directory(self): - try: - self.path.parent.mkdir(mode=0o700, parents=True) - except OSError as e: - if e.errno != errno.EEXIST: - raise + self.path.parent.mkdir(mode=0o700, parents=True, exist_ok=True) def is_new(self) -> bool: return not self.path.exists() @@ -92,9 +88,10 @@ class BaseConfigDict(dict): f'invalid {config_type} file: {e} [{self.path}]' ) self.update(data) - except IOError as e: - if e.errno != errno.ENOENT: - raise ConfigFileError(f'cannot read {config_type} file: {e}') + except FileNotFoundError: + pass + except OSError as e: + raise ConfigFileError(f'cannot read {config_type} file: {e}') def save(self, fail_silently=False): self['__meta__'] = { @@ -116,16 +113,16 @@ class BaseConfigDict(dict): ) try: self.path.write_text(json_string + '\n') - except IOError: + except OSError: if not fail_silently: raise def delete(self): try: + # TODO: use `missing_ok` kwarg when supporting Python 3.8+ only self.path.unlink() - except OSError as e: - if e.errno != errno.ENOENT: - raise + except FileNotFoundError: + pass class Config(BaseConfigDict): diff --git a/httpie/downloads.py b/httpie/downloads.py index f9a66f5e..074ea41b 100644 --- a/httpie/downloads.py +++ b/httpie/downloads.py @@ -267,7 +267,7 @@ class Downloader: try: self._output_file.seek(0) self._output_file.truncate() - except IOError: + except OSError: pass # stdout self.status.started( diff --git a/httpie/output/writer.py b/httpie/output/writer.py index 380e62eb..94d51cb5 100644 --- a/httpie/output/writer.py +++ b/httpie/output/writer.py @@ -42,7 +42,7 @@ def write_message( write_stream_with_colors_win_py3(**write_stream_kwargs) else: write_stream(**write_stream_kwargs) - except IOError as e: + except OSError as e: show_traceback = args.debug or args.traceback if not show_traceback and e.errno == errno.EPIPE: # Ignore broken pipes unless --traceback. diff --git a/tests/test_ssl.py b/tests/test_ssl.py index 1062000e..7b3807d9 100644 --- a/tests/test_ssl.py +++ b/tests/test_ssl.py @@ -76,7 +76,7 @@ class TestClientCert: '--cert', '/__not_found__', tolerate_error_exit_status=True) assert r.exit_status == ExitStatus.ERROR - assert 'No such file or directory' in r.stderr + assert '/__not_found__: No such file or directory' in r.stderr def test_cert_file_invalid(self, httpbin_secure): with pytest.raises(ssl_errors): @@ -117,8 +117,8 @@ class TestServerCert: http(httpbin_secure_untrusted.url + '/get') def test_verify_custom_ca_bundle_invalid_path(self, httpbin_secure): - # since 2.14.0 requests raises IOError - with pytest.raises(ssl_errors + (IOError,)): + # since 2.14.0 requests raises IOError (an OSError subclass) + with pytest.raises(ssl_errors + (OSError,)): http(httpbin_secure.url + '/get', '--verify', '/__not_found__') def test_verify_custom_ca_bundle_invalid_bundle(self, httpbin_secure):