1
0
mirror of https://github.com/httpie/cli.git synced 2024-11-28 08:38:44 +02:00
httpie-cli/httpie/context.py
Michael Sloan c5ca9d248e Allow stdin to be a closed fd
Before this change, the following invocation would not work

```
$ http http://neverhttps.com <&-
```

The "<&-" at the end closes the stdin fd. Specifically, it would fail with

```
  ...
  File "/home/mgsloan/.local/lib/python3.6/site-packages/httpie/context.py", line 26, in Environment
    stdin_isatty = stdin.isatty()
AttributeError: 'NoneType' object has no attribute 'isatty'
```

This can occur when httpie is being programmatically invoked, and may
as well be supported.
2019-07-17 23:02:49 -06:00

100 lines
3.0 KiB
Python

import sys
try:
import curses
except ImportError:
curses = None # Compiled w/o curses
from httpie.compat import is_windows
from httpie.config import DEFAULT_CONFIG_DIR, Config
from httpie.utils import repr_dict_nice
class Environment(object):
"""
Information about the execution context
(standard streams, config directory, etc).
By default, it represents the actual environment.
All of the attributes can be overwritten though, which
is used by the test suite to simulate various scenarios.
"""
is_windows = is_windows
config_dir = DEFAULT_CONFIG_DIR
stdin = sys.stdin
stdin_isatty = stdin.isatty() if stdin else False
stdin_encoding = None
stdout = sys.stdout
stdout_isatty = stdout.isatty()
stdout_encoding = None
stderr = sys.stderr
stderr_isatty = stderr.isatty()
colors = 256
if not is_windows:
if curses:
try:
curses.setupterm()
colors = curses.tigetnum('colors')
except curses.error:
pass
else:
# noinspection PyUnresolvedReferences
import colorama.initialise
stdout = colorama.initialise.wrap_stream(
stdout, convert=None, strip=None,
autoreset=True, wrap=True
)
stderr = colorama.initialise.wrap_stream(
stderr, convert=None, strip=None,
autoreset=True, wrap=True
)
del colorama
def __init__(self, **kwargs):
"""
Use keyword arguments to overwrite
any of the class attributes for this instance.
"""
assert all(hasattr(type(self), attr) for attr in kwargs.keys())
self.__dict__.update(**kwargs)
# Keyword arguments > stream.encoding > default utf8
if self.stdin and self.stdin_encoding is None:
self.stdin_encoding = getattr(
self.stdin, 'encoding', None) or 'utf8'
if self.stdout_encoding is None:
actual_stdout = self.stdout
if is_windows:
# noinspection PyUnresolvedReferences
from colorama import AnsiToWin32
if isinstance(self.stdout, AnsiToWin32):
actual_stdout = self.stdout.wrapped
self.stdout_encoding = getattr(
actual_stdout, 'encoding', None) or 'utf8'
@property
def config(self):
if not hasattr(self, '_config'):
self._config = Config(directory=self.config_dir)
if self._config.is_new():
self._config.save()
else:
self._config.load()
return self._config
def __str__(self):
defaults = dict(type(self).__dict__)
actual = dict(defaults)
actual.update(self.__dict__)
actual['config'] = self.config
return repr_dict_nice(dict(
(key, value)
for key, value in actual.items()
if not key.startswith('_'))
)
def __repr__(self):
return '<{0} {1}>'.format(type(self).__name__, str(self))