Robot Framework
encodingsniffer.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import os
17 import sys
18 import locale
19 
20 from .misc import isatty
21 from .platform import UNIXY, WINDOWS
22 
23 
24 if UNIXY:
25  DEFAULT_CONSOLE_ENCODING = 'UTF-8'
26  DEFAULT_SYSTEM_ENCODING = 'UTF-8'
27 else:
28  DEFAULT_CONSOLE_ENCODING = 'cp437'
29  DEFAULT_SYSTEM_ENCODING = 'cp1252'
30 
31 
33  platform_getters = [(True, _get_python_system_encoding),
34  (UNIXY, _get_unixy_encoding),
35  (WINDOWS, _get_windows_system_encoding)]
36  return _get_encoding(platform_getters, DEFAULT_SYSTEM_ENCODING)
37 
38 
40  platform_getters = [(True, _get_stream_output_encoding),
41  (UNIXY, _get_unixy_encoding),
42  (WINDOWS, _get_windows_console_encoding)]
43  return _get_encoding(platform_getters, DEFAULT_CONSOLE_ENCODING)
44 
45 
46 def _get_encoding(platform_getters, default):
47  for platform, getter in platform_getters:
48  if platform:
49  encoding = getter()
50  if _is_valid(encoding):
51  return encoding
52  return default
53 
54 
56  return locale.getpreferredencoding(False)
57 
58 
60  # Cannot use `locale.getdefaultlocale()` because it raises ValueError
61  # if encoding is invalid. Using same environment variables here anyway.
62  # https://docs.python.org/3/library/locale.html#locale.getdefaultlocale
63  for name in 'LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE':
64  if name in os.environ:
65  # Encoding can be in format like `UTF-8` or `en_US.UTF-8`
66  encoding = os.environ[name].split('.')[-1]
67  if _is_valid(encoding):
68  return encoding
69  return None
70 
71 
73  # Python 3.6+ uses UTF-8 as encoding with output streams.
74  # We want the real console encoding regardless the platform.
75  if WINDOWS:
76  return None
77  for stream in sys.__stdout__, sys.__stderr__, sys.__stdin__:
78  if isatty(stream):
79  encoding = getattr(stream, 'encoding', None)
80  if _is_valid(encoding):
81  return encoding
82  return None
83 
84 
86  return _get_code_page('GetACP')
87 
88 
90  return _get_code_page('GetConsoleOutputCP')
91 
92 
93 def _get_code_page(method_name):
94  from ctypes import cdll
95  method = getattr(cdll.kernel32, method_name)
96  return 'cp%s' % method()
97 
98 
99 def _is_valid(encoding):
100  if not encoding:
101  return False
102  try:
103  'test'.encode(encoding)
104  except LookupError:
105  return False
106  else:
107  return True
def _get_code_page(method_name)
def _get_encoding(platform_getters, default)
def isatty(stream)
Definition: misc.py:116