Best Python code snippet using hypothesis
pretty_printers.py
Source:pretty_printers.py
1# Pretty-printer commands.2# Copyright (C) 2010-2018 Free Software Foundation, Inc.3# This program is free software; you can redistribute it and/or modify4# it under the terms of the GNU General Public License as published by5# the Free Software Foundation; either version 3 of the License, or6# (at your option) any later version.7#8# This program is distributed in the hope that it will be useful,9# but WITHOUT ANY WARRANTY; without even the implied warranty of10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11# GNU General Public License for more details.12#13# You should have received a copy of the GNU General Public License14# along with this program. If not, see <http://www.gnu.org/licenses/>.15"""GDB commands for working with pretty-printers."""16import copy17import gdb18import re19def parse_printer_regexps(arg):20 """Internal utility to parse a pretty-printer command argv.21 Arguments:22 arg: The arguments to the command. The format is:23 [object-regexp [name-regexp]].24 Individual printers in a collection are named as25 printer-name;subprinter-name.26 Returns:27 The result is a 3-tuple of compiled regular expressions, except that28 the resulting compiled subprinter regexp is None if not provided.29 Raises:30 SyntaxError: an error processing ARG31 """32 argv = gdb.string_to_argv(arg);33 argc = len(argv)34 object_regexp = "" # match everything35 name_regexp = "" # match everything36 subname_regexp = None37 if argc > 3:38 raise SyntaxError("too many arguments")39 if argc >= 1:40 object_regexp = argv[0]41 if argc >= 2:42 name_subname = argv[1].split(";", 1)43 name_regexp = name_subname[0]44 if len(name_subname) == 2:45 subname_regexp = name_subname[1]46 # That re.compile raises SyntaxError was determined empirically.47 # We catch it and reraise it to provide a slightly more useful48 # error message for the user.49 try:50 object_re = re.compile(object_regexp)51 except SyntaxError:52 raise SyntaxError("invalid object regexp: %s" % object_regexp)53 try:54 name_re = re.compile (name_regexp)55 except SyntaxError:56 raise SyntaxError("invalid name regexp: %s" % name_regexp)57 if subname_regexp is not None:58 try:59 subname_re = re.compile(subname_regexp)60 except SyntaxError:61 raise SyntaxError("invalid subname regexp: %s" % subname_regexp)62 else:63 subname_re = None64 return(object_re, name_re, subname_re)65def printer_enabled_p(printer):66 """Internal utility to see if printer (or subprinter) is enabled."""67 if hasattr(printer, "enabled"):68 return printer.enabled69 else:70 return True71class InfoPrettyPrinter(gdb.Command):72 """GDB command to list all registered pretty-printers.73 Usage: info pretty-printer [object-regexp [name-regexp]]74 OBJECT-REGEXP is a regular expression matching the objects to list.75 Objects are "global", the program space's file, and the objfiles within76 that program space.77 NAME-REGEXP matches the name of the pretty-printer.78 Individual printers in a collection are named as79 printer-name;subprinter-name.80 """81 def __init__ (self):82 super(InfoPrettyPrinter, self).__init__("info pretty-printer",83 gdb.COMMAND_DATA)84 @staticmethod85 def enabled_string(printer):86 """Return "" if PRINTER is enabled, otherwise " [disabled]"."""87 if printer_enabled_p(printer):88 return ""89 else:90 return " [disabled]"91 @staticmethod92 def printer_name(printer):93 """Return the printer's name."""94 if hasattr(printer, "name"):95 return printer.name96 if hasattr(printer, "__name__"):97 return printer.__name__98 # This "shouldn't happen", but the public API allows for99 # direct additions to the pretty-printer list, and we shouldn't100 # crash because someone added a bogus printer.101 # Plus we want to give the user a way to list unknown printers.102 return "unknown"103 def list_pretty_printers(self, pretty_printers, name_re, subname_re):104 """Print a list of pretty-printers."""105 # A potential enhancement is to provide an option to list printers in106 # "lookup order" (i.e. unsorted).107 sorted_pretty_printers = sorted (copy.copy(pretty_printers),108 key = self.printer_name)109 for printer in sorted_pretty_printers:110 name = self.printer_name(printer)111 enabled = self.enabled_string(printer)112 if name_re.match(name):113 print (" %s%s" % (name, enabled))114 if (hasattr(printer, "subprinters") and115 printer.subprinters is not None):116 sorted_subprinters = sorted (copy.copy(printer.subprinters),117 key = self.printer_name)118 for subprinter in sorted_subprinters:119 if (not subname_re or120 subname_re.match(subprinter.name)):121 print (" %s%s" %122 (subprinter.name,123 self.enabled_string(subprinter)))124 def invoke1(self, title, printer_list,125 obj_name_to_match, object_re, name_re, subname_re):126 """Subroutine of invoke to simplify it."""127 if printer_list and object_re.match(obj_name_to_match):128 print (title)129 self.list_pretty_printers(printer_list, name_re, subname_re)130 def invoke(self, arg, from_tty):131 """GDB calls this to perform the command."""132 (object_re, name_re, subname_re) = parse_printer_regexps(arg)133 self.invoke1("global pretty-printers:", gdb.pretty_printers,134 "global", object_re, name_re, subname_re)135 cp = gdb.current_progspace()136 self.invoke1("progspace %s pretty-printers:" % cp.filename,137 cp.pretty_printers, "progspace",138 object_re, name_re, subname_re)139 for objfile in gdb.objfiles():140 self.invoke1(" objfile %s pretty-printers:" % objfile.filename,141 objfile.pretty_printers, objfile.filename,142 object_re, name_re, subname_re)143def count_enabled_printers(pretty_printers):144 """Return a 2-tuple of number of enabled and total printers."""145 enabled = 0146 total = 0147 for printer in pretty_printers:148 if (hasattr(printer, "subprinters")149 and printer.subprinters is not None):150 if printer_enabled_p(printer):151 for subprinter in printer.subprinters:152 if printer_enabled_p(subprinter):153 enabled += 1154 total += len(printer.subprinters)155 else:156 if printer_enabled_p(printer):157 enabled += 1158 total += 1159 return (enabled, total)160def count_all_enabled_printers():161 """Return a 2-tuble of the enabled state and total number of all printers.162 This includes subprinters.163 """164 enabled_count = 0165 total_count = 0166 (t_enabled, t_total) = count_enabled_printers(gdb.pretty_printers)167 enabled_count += t_enabled168 total_count += t_total169 (t_enabled, t_total) = count_enabled_printers(gdb.current_progspace().pretty_printers)170 enabled_count += t_enabled171 total_count += t_total172 for objfile in gdb.objfiles():173 (t_enabled, t_total) = count_enabled_printers(objfile.pretty_printers)174 enabled_count += t_enabled175 total_count += t_total176 return (enabled_count, total_count)177def pluralize(text, n, suffix="s"):178 """Return TEXT pluralized if N != 1."""179 if n != 1:180 return "%s%s" % (text, suffix)181 else:182 return text183def show_pretty_printer_enabled_summary():184 """Print the number of printers enabled/disabled.185 We count subprinters individually.186 """187 (enabled_count, total_count) = count_all_enabled_printers()188 print ("%d of %d printers enabled" % (enabled_count, total_count))189def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag):190 """Worker for enabling/disabling pretty-printers.191 Arguments:192 pretty_printers: list of pretty-printers193 name_re: regular-expression object to select printers194 subname_re: regular expression object to select subprinters or None195 if all are affected196 flag: True for Enable, False for Disable197 Returns:198 The number of printers affected.199 This is just for informational purposes for the user.200 """201 total = 0202 for printer in pretty_printers:203 if (hasattr(printer, "name") and name_re.match(printer.name) or204 hasattr(printer, "__name__") and name_re.match(printer.__name__)):205 if (hasattr(printer, "subprinters") and206 printer.subprinters is not None):207 if not subname_re:208 # Only record printers that change state.209 if printer_enabled_p(printer) != flag:210 for subprinter in printer.subprinters:211 if printer_enabled_p(subprinter):212 total += 1213 # NOTE: We preserve individual subprinter settings.214 printer.enabled = flag215 else:216 # NOTE: Whether this actually disables the subprinter217 # depends on whether the printer's lookup function supports218 # the "enable" API. We can only assume it does.219 for subprinter in printer.subprinters:220 if subname_re.match(subprinter.name):221 # Only record printers that change state.222 if (printer_enabled_p(printer) and223 printer_enabled_p(subprinter) != flag):224 total += 1225 subprinter.enabled = flag226 else:227 # This printer has no subprinters.228 # If the user does "disable pretty-printer .* .* foo"229 # should we disable printers that don't have subprinters?230 # How do we apply "foo" in this context? Since there is no231 # "foo" subprinter it feels like we should skip this printer.232 # There's still the issue of how to handle233 # "disable pretty-printer .* .* .*", and every other variation234 # that can match everything. For now punt and only support235 # "disable pretty-printer .* .*" (i.e. subname is elided)236 # to disable everything.237 if not subname_re:238 # Only record printers that change state.239 if printer_enabled_p(printer) != flag:240 total += 1241 printer.enabled = flag242 return total243def do_enable_pretty_printer (arg, flag):244 """Internal worker for enabling/disabling pretty-printers."""245 (object_re, name_re, subname_re) = parse_printer_regexps(arg)246 total = 0247 if object_re.match("global"):248 total += do_enable_pretty_printer_1(gdb.pretty_printers,249 name_re, subname_re, flag)250 cp = gdb.current_progspace()251 if object_re.match("progspace"):252 total += do_enable_pretty_printer_1(cp.pretty_printers,253 name_re, subname_re, flag)254 for objfile in gdb.objfiles():255 if object_re.match(objfile.filename):256 total += do_enable_pretty_printer_1(objfile.pretty_printers,257 name_re, subname_re, flag)258 if flag:259 state = "enabled"260 else:261 state = "disabled"262 print ("%d %s %s" % (total, pluralize("printer", total), state))263 # Print the total list of printers currently enabled/disabled.264 # This is to further assist the user in determining whether the result265 # is expected. Since we use regexps to select it's useful.266 show_pretty_printer_enabled_summary()267# Enable/Disable one or more pretty-printers.268#269# This is intended for use when a broken pretty-printer is shipped/installed270# and the user wants to disable that printer without disabling all the other271# printers.272#273# A useful addition would be -v (verbose) to show each printer affected.274class EnablePrettyPrinter (gdb.Command):275 """GDB command to enable the specified pretty-printer.276 Usage: enable pretty-printer [object-regexp [name-regexp]]277 OBJECT-REGEXP is a regular expression matching the objects to examine.278 Objects are "global", the program space's file, and the objfiles within279 that program space.280 NAME-REGEXP matches the name of the pretty-printer.281 Individual printers in a collection are named as282 printer-name;subprinter-name.283 """284 def __init__(self):285 super(EnablePrettyPrinter, self).__init__("enable pretty-printer",286 gdb.COMMAND_DATA)287 def invoke(self, arg, from_tty):288 """GDB calls this to perform the command."""289 do_enable_pretty_printer(arg, True)290class DisablePrettyPrinter (gdb.Command):291 """GDB command to disable the specified pretty-printer.292 Usage: disable pretty-printer [object-regexp [name-regexp]]293 OBJECT-REGEXP is a regular expression matching the objects to examine.294 Objects are "global", the program space's file, and the objfiles within295 that program space.296 NAME-REGEXP matches the name of the pretty-printer.297 Individual printers in a collection are named as298 printer-name;subprinter-name.299 """300 def __init__(self):301 super(DisablePrettyPrinter, self).__init__("disable pretty-printer",302 gdb.COMMAND_DATA)303 def invoke(self, arg, from_tty):304 """GDB calls this to perform the command."""305 do_enable_pretty_printer(arg, False)306def register_pretty_printer_commands():307 """Call from a top level script to install the pretty-printer commands."""308 InfoPrettyPrinter()309 EnablePrettyPrinter()310 DisablePrettyPrinter()...
test_pretty.py
Source:test_pretty.py
...24 p.text(",")25 p.breakable()26 else:27 p.breakable("")28 p.pretty(child)29class MyDict(dict):30 def _repr_pretty_(self, p, cycle):31 p.text("MyDict(...)")32class MyObj(object):33 def somemethod(self):34 pass35class Dummy1(object):36 def _repr_pretty_(self, p, cycle):37 p.text("Dummy1(...)")38class Dummy2(Dummy1):39 _repr_pretty_ = None40class NoModule(object):41 pass42NoModule.__module__ = None43class Breaking(object):44 def _repr_pretty_(self, p, cycle):45 with p.group(4,"TG: ",":"):46 p.text("Breaking(")47 p.break_()48 p.text(")")49class BreakingRepr(object):50 def __repr__(self):51 return "Breaking(\n)"52class BadRepr(object):53 54 def __repr__(self):55 return 1/056def test_indentation():57 """Test correct indentation in groups"""58 count = 4059 gotoutput = pretty.pretty(MyList(range(count)))60 expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"61 nt.assert_equal(gotoutput, expectedoutput)62def test_dispatch():63 """64 Test correct dispatching: The _repr_pretty_ method for MyDict65 must be found before the registered printer for dict.66 """67 gotoutput = pretty.pretty(MyDict())68 expectedoutput = "MyDict(...)"69 nt.assert_equal(gotoutput, expectedoutput)70def test_callability_checking():71 """72 Test that the _repr_pretty_ method is tested for callability and skipped if73 not.74 """75 gotoutput = pretty.pretty(Dummy2())76 expectedoutput = "Dummy1(...)"77 nt.assert_equal(gotoutput, expectedoutput)78def test_sets():79 """80 Test that set and frozenset use Python 3 formatting.81 """82 objects = [set(), frozenset(), set([1]), frozenset([1]), set([1, 2]),83 frozenset([1, 2]), set([-1, -2, -3])]84 expected = ['set()', 'frozenset()', '{1}', 'frozenset({1})', '{1, 2}',85 'frozenset({1, 2})', '{-3, -2, -1}']86 for obj, expected_output in zip(objects, expected):87 got_output = pretty.pretty(obj)88 yield nt.assert_equal, got_output, expected_output89@skip_without('xxlimited')90def test_pprint_heap_allocated_type():91 """92 Test that pprint works for heap allocated types.93 """94 import xxlimited95 output = pretty.pretty(xxlimited.Null)96 nt.assert_equal(output, 'xxlimited.Null')97def test_pprint_nomod():98 """99 Test that pprint works for classes with no __module__.100 """101 output = pretty.pretty(NoModule)102 nt.assert_equal(output, 'NoModule')103 104def test_pprint_break():105 """106 Test that p.break_ produces expected output107 """108 output = pretty.pretty(Breaking())109 expected = "TG: Breaking(\n ):"110 nt.assert_equal(output, expected)111def test_pprint_break_repr():112 """113 Test that p.break_ is used in repr114 """115 output = pretty.pretty([[BreakingRepr()]])116 expected = "[[Breaking(\n )]]"117 nt.assert_equal(output, expected)118 output = pretty.pretty([[BreakingRepr()]*2])119 expected = "[[Breaking(\n ),\n Breaking(\n )]]"120 nt.assert_equal(output, expected)121def test_bad_repr():122 """Don't catch bad repr errors"""123 with nt.assert_raises(ZeroDivisionError):124 pretty.pretty(BadRepr())125class BadException(Exception):126 def __str__(self):127 return -1128class ReallyBadRepr(object):129 __module__ = 1130 @property131 def __class__(self):132 raise ValueError("I am horrible")133 134 def __repr__(self):135 raise BadException()136def test_really_bad_repr():137 with nt.assert_raises(BadException):138 pretty.pretty(ReallyBadRepr())139class SA(object):140 pass141class SB(SA):142 pass143class TestsPretty(unittest.TestCase):144 def test_super_repr(self):145 # "<super: module_name.SA, None>"146 output = pretty.pretty(super(SA))147 self.assertRegex(output, r"<super: \S+.SA, None>")148 # "<super: module_name.SA, <module_name.SB at 0x...>>"149 sb = SB()150 output = pretty.pretty(super(SA, sb))151 self.assertRegex(output, r"<super: \S+.SA,\s+<\S+.SB at 0x\S+>>")152 def test_long_list(self):153 lis = list(range(10000))154 p = pretty.pretty(lis)155 last2 = p.rsplit('\n', 2)[-2:]156 self.assertEqual(last2, [' 999,', ' ...]'])157 def test_long_set(self):158 s = set(range(10000))159 p = pretty.pretty(s)160 last2 = p.rsplit('\n', 2)[-2:]161 self.assertEqual(last2, [' 999,', ' ...}'])162 def test_long_tuple(self):163 tup = tuple(range(10000))164 p = pretty.pretty(tup)165 last2 = p.rsplit('\n', 2)[-2:]166 self.assertEqual(last2, [' 999,', ' ...)'])167 def test_long_dict(self):168 d = { n:n for n in range(10000) }169 p = pretty.pretty(d)170 last2 = p.rsplit('\n', 2)[-2:]171 self.assertEqual(last2, [' 999: 999,', ' ...}'])172 def test_unbound_method(self):173 output = pretty.pretty(MyObj.somemethod)174 self.assertIn('MyObj.somemethod', output)175class MetaClass(type):176 def __new__(cls, name):177 return type.__new__(cls, name, (object,), {'name': name})178 def __repr__(self):179 return "[CUSTOM REPR FOR CLASS %s]" % self.name180ClassWithMeta = MetaClass('ClassWithMeta')181def test_metaclass_repr():182 output = pretty.pretty(ClassWithMeta)183 nt.assert_equal(output, "[CUSTOM REPR FOR CLASS ClassWithMeta]")184def test_unicode_repr():185 u = u"üniçodé"186 ustr = u187 188 class C(object):189 def __repr__(self):190 return ustr191 192 c = C()193 p = pretty.pretty(c)194 nt.assert_equal(p, u)195 p = pretty.pretty([c])196 nt.assert_equal(p, u'[%s]' % u)197def test_basic_class():198 def type_pprint_wrapper(obj, p, cycle):199 if obj is MyObj:200 type_pprint_wrapper.called = True201 return pretty._type_pprint(obj, p, cycle)202 type_pprint_wrapper.called = False203 stream = StringIO()204 printer = pretty.RepresentationPrinter(stream)205 printer.type_pprinters[type] = type_pprint_wrapper206 printer.pretty(MyObj)207 printer.flush()208 output = stream.getvalue()209 nt.assert_equal(output, '%s.MyObj' % __name__)210 nt.assert_true(type_pprint_wrapper.called)211def test_collections_defaultdict():212 # Create defaultdicts with cycles213 a = defaultdict()214 a.default_factory = a215 b = defaultdict(list)216 b['key'] = b217 # Dictionary order cannot be relied on, test against single keys.218 cases = [219 (defaultdict(list), 'defaultdict(list, {})'),220 (defaultdict(list, {'key': '-' * 50}),221 "defaultdict(list,\n"222 " {'key': '--------------------------------------------------'})"),223 (a, 'defaultdict(defaultdict(...), {})'),224 (b, "defaultdict(list, {'key': defaultdict(...)})"),225 ]226 for obj, expected in cases:227 nt.assert_equal(pretty.pretty(obj), expected)228def test_collections_ordereddict():229 # Create OrderedDict with cycle230 a = OrderedDict()231 a['key'] = a232 cases = [233 (OrderedDict(), 'OrderedDict()'),234 (OrderedDict((i, i) for i in range(1000, 1010)),235 'OrderedDict([(1000, 1000),\n'236 ' (1001, 1001),\n'237 ' (1002, 1002),\n'238 ' (1003, 1003),\n'239 ' (1004, 1004),\n'240 ' (1005, 1005),\n'241 ' (1006, 1006),\n'242 ' (1007, 1007),\n'243 ' (1008, 1008),\n'244 ' (1009, 1009)])'),245 (a, "OrderedDict([('key', OrderedDict(...))])"),246 ]247 for obj, expected in cases:248 nt.assert_equal(pretty.pretty(obj), expected)249def test_collections_deque():250 # Create deque with cycle251 a = deque()252 a.append(a)253 cases = [254 (deque(), 'deque([])'),255 (deque(i for i in range(1000, 1020)),256 'deque([1000,\n'257 ' 1001,\n'258 ' 1002,\n'259 ' 1003,\n'260 ' 1004,\n'261 ' 1005,\n'262 ' 1006,\n'263 ' 1007,\n'264 ' 1008,\n'265 ' 1009,\n'266 ' 1010,\n'267 ' 1011,\n'268 ' 1012,\n'269 ' 1013,\n'270 ' 1014,\n'271 ' 1015,\n'272 ' 1016,\n'273 ' 1017,\n'274 ' 1018,\n'275 ' 1019])'),276 (a, 'deque([deque(...)])'),277 ]278 for obj, expected in cases:279 nt.assert_equal(pretty.pretty(obj), expected)280def test_collections_counter():281 class MyCounter(Counter):282 pass283 cases = [284 (Counter(), 'Counter()'),285 (Counter(a=1), "Counter({'a': 1})"),286 (MyCounter(a=1), "MyCounter({'a': 1})"),287 ]288 for obj, expected in cases:289 nt.assert_equal(pretty.pretty(obj), expected)290def test_mappingproxy():291 MP = types.MappingProxyType292 underlying_dict = {}293 mp_recursive = MP(underlying_dict)294 underlying_dict[2] = mp_recursive295 underlying_dict[3] = underlying_dict296 cases = [297 (MP({}), "mappingproxy({})"),298 (MP({None: MP({})}), "mappingproxy({None: mappingproxy({})})"),299 (MP({k: k.upper() for k in string.ascii_lowercase}),300 "mappingproxy({'a': 'A',\n"301 " 'b': 'B',\n"302 " 'c': 'C',\n"303 " 'd': 'D',\n"304 " 'e': 'E',\n"305 " 'f': 'F',\n"306 " 'g': 'G',\n"307 " 'h': 'H',\n"308 " 'i': 'I',\n"309 " 'j': 'J',\n"310 " 'k': 'K',\n"311 " 'l': 'L',\n"312 " 'm': 'M',\n"313 " 'n': 'N',\n"314 " 'o': 'O',\n"315 " 'p': 'P',\n"316 " 'q': 'Q',\n"317 " 'r': 'R',\n"318 " 's': 'S',\n"319 " 't': 'T',\n"320 " 'u': 'U',\n"321 " 'v': 'V',\n"322 " 'w': 'W',\n"323 " 'x': 'X',\n"324 " 'y': 'Y',\n"325 " 'z': 'Z'})"),326 (mp_recursive, "mappingproxy({2: {...}, 3: {2: {...}, 3: {...}}})"),327 (underlying_dict,328 "{2: mappingproxy({2: {...}, 3: {...}}), 3: {...}}"),329 ]330 for obj, expected in cases:331 nt.assert_equal(pretty.pretty(obj), expected)332def test_simplenamespace():333 SN = types.SimpleNamespace334 sn_recursive = SN()335 sn_recursive.first = sn_recursive336 sn_recursive.second = sn_recursive337 cases = [338 (SN(), "namespace()"),339 (SN(x=SN()), "namespace(x=namespace())"),340 (SN(a_long_name=[SN(s=string.ascii_lowercase)]*3, a_short_name=None),341 "namespace(a_long_name=[namespace(s='abcdefghijklmnopqrstuvwxyz'),\n"342 " namespace(s='abcdefghijklmnopqrstuvwxyz'),\n"343 " namespace(s='abcdefghijklmnopqrstuvwxyz')],\n"344 " a_short_name=None)"),345 (sn_recursive, "namespace(first=namespace(...), second=namespace(...))"),346 ]347 for obj, expected in cases:348 nt.assert_equal(pretty.pretty(obj), expected)349def test_pretty_environ():350 dict_repr = pretty.pretty(dict(os.environ))351 # reindent to align with 'environ' prefix352 dict_indented = dict_repr.replace('\n', '\n' + (' ' * len('environ')))353 env_repr = pretty.pretty(os.environ)354 nt.assert_equal(env_repr, 'environ' + dict_indented)355def test_function_pretty():356 "Test pretty print of function"357 # posixpath is a pure python module, its interface is consistent358 # across Python distributions359 import posixpath360 nt.assert_equal(pretty.pretty(posixpath.join), '<function posixpath.join(a, *p)>')361 362 # custom function363 def meaning_of_life(question=None):364 if question:365 return 42366 return "Don't panic"367 nt.assert_in('meaning_of_life(question=None)', pretty.pretty(meaning_of_life))368class OrderedCounter(Counter, OrderedDict):369 'Counter that remembers the order elements are first encountered'370 def __repr__(self):371 return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))372 def __reduce__(self):373 return self.__class__, (OrderedDict(self),)374class MySet(set): # Override repr of a basic type375 def __repr__(self):376 return 'mine'377def test_custom_repr():378 """A custom repr should override a pretty printer for a parent type"""379 oc = OrderedCounter("abracadabra")380 nt.assert_in("OrderedCounter(OrderedDict", pretty.pretty(oc))...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!