Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/phonenumbers/util.py: 38%
95 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""Python 2.x/3.x compatibility utilities.
3This module defines a collection of functions that allow the same Python
4source code to be used in both Python 2.x and Python 3.x.
6 - prnt() prints its arguments to a file, with given separator and ending.
7 - to_long() creates a (long) integer object from its input parameter.
8 - u() allows string literals involving non-ASCII characters to be
9 used in both Python 2.x / 3.x, e.g. u("\u0101 is a-with-macron")
10 - unicod() forces its argument to a Unicode string.
11 - rpr() generates a representation of a string that can be parsed in either
12 Python 2.x or 3.x, assuming use of the u() function above.
14>>> from .util import prnt, u, rpr
15>>> prnt("hello")
16hello
17>>> prnt("hello", "world")
18hello world
19>>> prnt("hello", "world", sep=":")
20hello:world
21>>> prnt("hello", "world", sep=":", end='!\\n')
22hello:world!
23>>> u('\u0101') == u('\U00000101')
24True
25>>> u('\u0101') == u('\N{LATIN SMALL LETTER A WITH MACRON}')
26True
27>>> a_macron = u('\u0101')
28>>> rpr(a_macron)
29"u('\\\\u0101')"
30>>> rpr(u('abc')) == "'abc'" # In Python 2, LHS is Unicode but RHS is string
31True
32>>> rpr("'")
33"'\\\\''"
34"""
35import sys
38if sys.version_info >= (3, 0): # pragma no cover 38 ↛ 58line 38 didn't jump to line 58, because the condition on line 38 was never false
39 import builtins
40 print3 = builtins.__dict__['print']
42 unicod = str
43 u = str
44 to_long = int
46 def prnt(*args, **kwargs):
47 sep = kwargs.get('sep', ' ')
48 end = kwargs.get('end', '\n')
49 file = kwargs.get('file', None)
50 print3(*args, **{'sep': sep, 'end': end, 'file': file})
52 class UnicodeMixin(object):
53 """Mixin class to define a __str__ method in terms of __unicode__ method"""
54 def __str__(self):
55 return self.__unicode__()
57else: # pragma no cover
58 unicod = unicode
60 import unicodedata
61 import re
62 # \N{name} = character named name in the Unicode database
63 _UNAME_RE = re.compile(r'\\N\{(?P<name>[^}]+)\}')
64 # \uxxxx = character with 16-bit hex value xxxx
65 _U16_RE = re.compile(r'\\u(?P<hexval>[0-9a-fA-F]{4})')
66 # \Uxxxxxxxx = character with 32-bit hex value xxxxxxxx
67 _U32_RE = re.compile(r'\\U(?P<hexval>[0-9a-fA-F]{8})')
69 def u(s):
70 """Generate Unicode string from a string input, encoding Unicode characters.
72 This is expected to work in the same way as u'<string>' would work in Python
73 2.x (although it is not completely robust as it is based on a simple set of
74 regexps).
75 """
76 us = re.sub(_U16_RE, lambda m: unichr(int(m.group('hexval'), 16)), unicode(s))
77 us = re.sub(_U32_RE, lambda m: unichr(int(m.group('hexval'), 16)), us)
78 us = re.sub(_UNAME_RE, lambda m: unicodedata.lookup(m.group('name')), us)
79 return us
81 to_long = long
83 def prnt(*args, **kwargs):
84 sep = kwargs.get('sep', ' ')
85 end = kwargs.get('end', '\n')
86 file = kwargs.get('file', None)
87 if file is None:
88 file = sys.stdout
89 print >> file, sep.join([str(arg) for arg in args]) + end,
91 class UnicodeMixin(object): # pragma no cover
92 """Mixin class to define a __str__ method in terms of __unicode__ method"""
93 def __str__(self):
94 return unicode(self).encode('utf-8')
96# Constants for Unicode strings
97U_EMPTY_STRING = unicod("")
98U_SPACE = unicod(" ")
99U_DASH = unicod("-")
100U_TILDE = unicod("~")
101U_PLUS = unicod("+")
102U_STAR = unicod("*")
103U_ZERO = unicod("0")
104U_SLASH = unicod("/")
105U_SEMICOLON = unicod(";")
106U_X_LOWER = unicod("x")
107U_X_UPPER = unicod("X")
108U_PERCENT = unicod("%")
111def rpr(s):
112 """Create a representation of a Unicode string that can be used in both
113 Python 2 and Python 3k, allowing for use of the u() function"""
114 if s is None:
115 return 'None'
116 seen_unicode = False
117 results = []
118 for cc in s:
119 ccn = ord(cc)
120 if ccn >= 32 and ccn < 127:
121 if cc == "'": # escape single quote
122 results.append('\\')
123 results.append(cc)
124 elif cc == "\\": # escape backslash
125 results.append('\\')
126 results.append(cc)
127 else:
128 results.append(cc)
129 else:
130 seen_unicode = True
131 if ccn <= 0xFFFF:
132 results.append('\\u')
133 results.append("%04x" % ccn)
134 else: # pragma no cover
135 results.append('\\U')
136 results.append("%08x" % ccn)
137 result = "'" + "".join(results) + "'"
138 if seen_unicode:
139 return "u(" + result + ")"
140 else:
141 return result
144def force_unicode(s):
145 """Force the argument to be a Unicode string, preserving None"""
146 if s is None:
147 return None
148 else:
149 return unicod(s)
152class ImmutableMixin(object):
153 """Mixin class to make objects of subclasses immutable"""
154 _mutable = False
156 def __setattr__(self, name, value):
157 if self._mutable or name == "_mutable": 157 ↛ 160line 157 didn't jump to line 160, because the condition on line 157 was never false
158 object.__setattr__(self, name, value)
159 else:
160 raise TypeError("Can't modify immutable instance")
162 def __delattr__(self, name):
163 if self._mutable:
164 object.__delattr__(self, name)
165 else:
166 raise TypeError("Can't modify immutable instance")
169def mutating_method(func):
170 """Decorator for methods that are allowed to modify immutable objects"""
171 def wrapper(self, *__args, **__kwargs):
172 old_mutable = self._mutable
173 self._mutable = True
174 try:
175 # Call the wrapped function
176 return func(self, *__args, **__kwargs)
177 finally:
178 self._mutable = old_mutable
179 return wrapper
182if __name__ == '__main__': # pragma no cover 182 ↛ 183line 182 didn't jump to line 183, because the condition on line 182 was never true
183 import doctest
184 doctest.testmod()