utils.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2017 Google Inc. All Rights Reserved.
  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. """Utilities for tests."""
  16. import contextlib
  17. import io
  18. import os
  19. import sys
  20. import tempfile
  21. @contextlib.contextmanager
  22. def stdout_redirector(stream): # pylint: disable=invalid-name
  23. old_stdout = sys.stdout
  24. sys.stdout = stream
  25. try:
  26. yield
  27. finally:
  28. sys.stdout = old_stdout
  29. # NamedTemporaryFile is useless because on Windows the temporary file would be
  30. # created with O_TEMPORARY, which would not allow the file to be opened a
  31. # second time, even by the same process, unless the same flag is used.
  32. # Thus we provide a simplified version ourselves.
  33. #
  34. # Note: returns a tuple of (io.file_obj, file_path), instead of a file_obj with
  35. # a .name attribute
  36. #
  37. # Note: `buffering` is set to -1 despite documentation of NamedTemporaryFile
  38. # says None. This is probably a problem with the python documentation.
  39. @contextlib.contextmanager
  40. def NamedTempFile(mode='w+b',
  41. buffering=-1,
  42. encoding=None,
  43. errors=None,
  44. newline=None,
  45. suffix=None,
  46. prefix=None,
  47. dirname=None,
  48. text=False):
  49. """Context manager creating a new temporary file in text mode."""
  50. (fd, fname) = tempfile.mkstemp(
  51. suffix=suffix, prefix=prefix, dir=dirname, text=text)
  52. f = io.open(
  53. fd,
  54. mode=mode,
  55. buffering=buffering,
  56. encoding=encoding,
  57. errors=errors,
  58. newline=newline)
  59. yield f, fname
  60. f.close()
  61. os.remove(fname)
  62. @contextlib.contextmanager
  63. def TempFileContents(dirname,
  64. contents,
  65. encoding='utf-8',
  66. newline='',
  67. suffix=None):
  68. # Note: NamedTempFile properly handles unicode encoding when using mode='w'
  69. with NamedTempFile(
  70. dirname=dirname,
  71. mode='w',
  72. encoding=encoding,
  73. newline=newline,
  74. suffix=suffix) as (f, fname):
  75. f.write(contents)
  76. f.flush()
  77. yield fname