Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/past/types/oldstr.py: 57%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

37 statements  

1""" 

2Pure-Python implementation of a Python 2-like str object for Python 3. 

3""" 

4 

5from numbers import Integral 

6 

7from past.utils import PY2, with_metaclass 

8 

9if PY2: 

10 from collections import Iterable 

11else: 

12 from collections.abc import Iterable 

13 

14_builtin_bytes = bytes 

15 

16 

17class BaseOldStr(type): 

18 def __instancecheck__(cls, instance): 

19 return isinstance(instance, _builtin_bytes) 

20 

21 

22def unescape(s): 

23 r""" 

24 Interprets strings with escape sequences 

25 

26 Example: 

27 >>> s = unescape(r'abc\\def') # i.e. 'abc\\\\def' 

28 >>> print(s) 

29 'abc\def' 

30 >>> s2 = unescape('abc\\ndef') 

31 >>> len(s2) 

32 8 

33 >>> print(s2) 

34 abc 

35 def 

36 """ 

37 return s.encode().decode('unicode_escape') 

38 

39 

40class oldstr(with_metaclass(BaseOldStr, _builtin_bytes)): 

41 """ 

42 A forward port of the Python 2 8-bit string object to Py3 

43 """ 

44 # Python 2 strings have no __iter__ method: 

45 @property 

46 def __iter__(self): 

47 raise AttributeError 

48 

49 def __dir__(self): 

50 return [thing for thing in dir(_builtin_bytes) if thing != '__iter__'] 

51 

52 # def __new__(cls, *args, **kwargs): 

53 # """ 

54 # From the Py3 bytes docstring: 

55 

56 # bytes(iterable_of_ints) -> bytes 

57 # bytes(string, encoding[, errors]) -> bytes 

58 # bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer 

59 # bytes(int) -> bytes object of size given by the parameter initialized with null bytes 

60 # bytes() -> empty bytes object 

61 # 

62 # Construct an immutable array of bytes from: 

63 # - an iterable yielding integers in range(256) 

64 # - a text string encoded using the specified encoding 

65 # - any object implementing the buffer API. 

66 # - an integer 

67 # """ 

68 # 

69 # if len(args) == 0: 

70 # return super(newbytes, cls).__new__(cls) 

71 # # Was: elif isinstance(args[0], newbytes): 

72 # # We use type() instead of the above because we're redefining 

73 # # this to be True for all unicode string subclasses. Warning: 

74 # # This may render newstr un-subclassable. 

75 # elif type(args[0]) == newbytes: 

76 # return args[0] 

77 # elif isinstance(args[0], _builtin_bytes): 

78 # value = args[0] 

79 # elif isinstance(args[0], unicode): 

80 # if 'encoding' not in kwargs: 

81 # raise TypeError('unicode string argument without an encoding') 

82 # ### 

83 # # Was: value = args[0].encode(**kwargs) 

84 # # Python 2.6 string encode() method doesn't take kwargs: 

85 # # Use this instead: 

86 # newargs = [kwargs['encoding']] 

87 # if 'errors' in kwargs: 

88 # newargs.append(kwargs['errors']) 

89 # value = args[0].encode(*newargs) 

90 # ### 

91 # elif isinstance(args[0], Iterable): 

92 # if len(args[0]) == 0: 

93 # # What is this? 

94 # raise ValueError('unknown argument type') 

95 # elif len(args[0]) > 0 and isinstance(args[0][0], Integral): 

96 # # It's a list of integers 

97 # value = b''.join([chr(x) for x in args[0]]) 

98 # else: 

99 # raise ValueError('item cannot be interpreted as an integer') 

100 # elif isinstance(args[0], Integral): 

101 # if args[0] < 0: 

102 # raise ValueError('negative count') 

103 # value = b'\x00' * args[0] 

104 # else: 

105 # value = args[0] 

106 # return super(newbytes, cls).__new__(cls, value) 

107 

108 def __repr__(self): 

109 s = super(oldstr, self).__repr__() # e.g. b'abc' on Py3, b'abc' on Py3 

110 return s[1:] 

111 

112 def __str__(self): 

113 s = super(oldstr, self).__str__() # e.g. "b'abc'" or "b'abc\\ndef' 

114 # TODO: fix this: 

115 assert s[:2] == "b'" and s[-1] == "'" 

116 return unescape(s[2:-1]) # e.g. 'abc' or 'abc\ndef' 

117 

118 def __getitem__(self, y): 

119 if isinstance(y, Integral): 

120 return super(oldstr, self).__getitem__(slice(y, y+1)) 

121 else: 

122 return super(oldstr, self).__getitem__(y) 

123 

124 def __getslice__(self, *args): 

125 return self.__getitem__(slice(*args)) 

126 

127 def __contains__(self, key): 

128 if isinstance(key, int): 

129 return False 

130 

131 def __native__(self): 

132 return bytes(self) 

133 

134 

135__all__ = ['oldstr']