Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/nbconvert/utils/io.py: 25%

56 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-01 06:54 +0000

1"""io-related utilities""" 

2 

3# Copyright (c) Jupyter Development Team. 

4# Distributed under the terms of the Modified BSD License. 

5 

6import codecs 

7import errno 

8import os 

9import random 

10import shutil 

11import sys 

12 

13 

14def unicode_std_stream(stream="stdout"): 

15 """Get a wrapper to write unicode to stdout/stderr as UTF-8. 

16 

17 This ignores environment variables and default encodings, to reliably write 

18 unicode to stdout or stderr. 

19 

20 :: 

21 

22 unicode_std_stream().write(u'ł@e¶ŧ←') 

23 """ 

24 assert stream in ("stdout", "stderr") # noqa 

25 stream = getattr(sys, stream) 

26 

27 try: 

28 stream_b = stream.buffer 

29 except AttributeError: 

30 # sys.stdout has been replaced - use it directly 

31 return stream 

32 

33 return codecs.getwriter("utf-8")(stream_b) 

34 

35 

36def unicode_stdin_stream(): 

37 """Get a wrapper to read unicode from stdin as UTF-8. 

38 

39 This ignores environment variables and default encodings, to reliably read unicode from stdin. 

40 

41 :: 

42 

43 totreat = unicode_stdin_stream().read() 

44 """ 

45 stream = sys.stdin 

46 try: 

47 stream_b = stream.buffer 

48 except AttributeError: 

49 return stream 

50 

51 return codecs.getreader("utf-8")(stream_b) 

52 

53 

54class FormatSafeDict(dict): 

55 """Format a dictionary safely.""" 

56 

57 def __missing__(self, key): 

58 """Handle missing value.""" 

59 return "{" + key + "}" 

60 

61 

62try: 

63 ENOLINK = errno.ENOLINK 

64except AttributeError: 

65 ENOLINK = 1998 

66 

67 

68def link(src, dst): 

69 """Hard links ``src`` to ``dst``, returning 0 or errno. 

70 

71 Note that the special errno ``ENOLINK`` will be returned if ``os.link`` isn't 

72 supported by the operating system. 

73 """ 

74 

75 if not hasattr(os, "link"): 

76 return ENOLINK 

77 link_errno = 0 

78 try: 

79 os.link(src, dst) 

80 except OSError as e: 

81 link_errno = e.errno 

82 return link_errno 

83 

84 

85def link_or_copy(src, dst): 

86 """Attempts to hardlink ``src`` to ``dst``, copying if the link fails. 

87 

88 Attempts to maintain the semantics of ``shutil.copy``. 

89 

90 Because ``os.link`` does not overwrite files, a unique temporary file 

91 will be used if the target already exists, then that file will be moved 

92 into place. 

93 """ 

94 

95 if os.path.isdir(dst): 

96 dst = os.path.join(dst, os.path.basename(src)) 

97 

98 link_errno = link(src, dst) 

99 if link_errno == errno.EEXIST: 

100 if os.stat(src).st_ino == os.stat(dst).st_ino: 

101 # dst is already a hard link to the correct file, so we don't need 

102 # to do anything else. If we try to link and rename the file 

103 # anyway, we get duplicate files - see http://bugs.python.org/issue21876 

104 return 

105 

106 new_dst = dst + f"-temp-{random.randint(1, 16**4):04X}" # noqa 

107 try: 

108 link_or_copy(src, new_dst) 

109 except BaseException: 

110 try: 

111 os.remove(new_dst) 

112 except OSError: 

113 pass 

114 raise 

115 os.rename(new_dst, dst) 

116 elif link_errno != 0: 

117 # Either link isn't supported, or the filesystem doesn't support 

118 # linking, or 'src' and 'dst' are on different filesystems. 

119 shutil.copy(src, dst)