commit 0ac3294df858f08b6e8815e2b1188dfa4bc59123 Author: Damian Johnson atagar@torproject.org Date: Fri Apr 10 09:18:46 2015 -0700
Better standarizing on single quotes
We already standardized this codebase on single quotes several months ago but new test check found a handful of instances that slipped in since then. --- docs/republish.py | 16 ++++----- run_tests.py | 4 +-- stem/connection.py | 2 +- stem/control.py | 10 +++--- stem/descriptor/hidden_service_descriptor.py | 2 +- stem/descriptor/router_status_entry.py | 2 +- stem/descriptor/server_descriptor.py | 2 +- stem/exit_policy.py | 6 ++-- stem/interpreter/commands.py | 2 +- stem/util/connection.py | 2 +- stem/util/lru_cache.py | 2 +- stem/util/proc.py | 2 +- stem/util/str_tools.py | 2 +- stem/util/test_tools.py | 5 +-- test/integ/descriptor/remote.py | 2 +- test/integ/process.py | 10 +++--- test/unit/descriptor/networkstatus/document_v3.py | 10 +++--- test/unit/tutorial.py | 8 ++--- test/unit/tutorial_examples.py | 38 ++++++++++----------- test/unit/util/proc.py | 4 +-- test/unit/util/tor_tools.py | 10 +++--- 21 files changed, 71 insertions(+), 70 deletions(-)
diff --git a/docs/republish.py b/docs/republish.py index 8e168b6..f2241e5 100644 --- a/docs/republish.py +++ b/docs/republish.py @@ -4,7 +4,7 @@ import subprocess import sys import time
-LOGGER = logging.getLogger("republish") +LOGGER = logging.getLogger('republish') LOGGER.setLevel(logging.INFO)
handler = logging.FileHandler('/home/stem/republish.log') @@ -14,8 +14,8 @@ handler.setFormatter(logging.Formatter( )) LOGGER.addHandler(handler)
-OPT = "r:h" -OPT_EXPANDED = ["repeat=", "help"] +OPT = 'r:h' +OPT_EXPANDED = ['repeat=', 'help']
HELP_MSG = """\ Republishes stem's website. This can either be done or on a reoccurring basis. @@ -49,31 +49,31 @@ def republish_site(): run('sudo -u mirroradm static-master-update-component stem.torproject.org')
runtime = int(time.time() - start_time) - LOGGER.log(logging.INFO, " site republished (took %s seconds)" % runtime) + LOGGER.log(logging.INFO, ' site republished (took %s seconds)' % runtime)
if __name__ == '__main__': try: opts = getopt.getopt(sys.argv[1:], OPT, OPT_EXPANDED)[0] except getopt.GetoptError as exc: - print("%s (for usage provide --help)" % exc) + print('%s (for usage provide --help)' % exc) sys.exit(1)
repeat_rate = None
for opt, arg in opts: - if opt in ("-r", "--repeat"): + if opt in ('-r', '--repeat'): if arg.isdigit(): repeat_rate = int(arg) else: print("The --repeat argument must be an integer, got '%s'" % arg) sys.exit(1) - elif opt in ("-h", "--help"): + elif opt in ('-h', '--help'): print(HELP_MSG) sys.exit()
if repeat_rate: - LOGGER.log(logging.INFO, "Starting stem site republisher") + LOGGER.log(logging.INFO, 'Starting stem site republisher') latest_run = 0 # unix timestamp for when we last ran
while True: diff --git a/run_tests.py b/run_tests.py index 9903c61..8f70d09 100755 --- a/run_tests.py +++ b/run_tests.py @@ -359,10 +359,10 @@ def _run_test(args, test_class, output_filters, logging_buffer): suite = unittest.TestLoader().loadTestsFromName(test_class) except AttributeError: # should only come up if user provided '--test' for something that doesn't exist - println(" no such test", ERROR) + println(' no such test', ERROR) return None except Exception as exc: - println(" failed", ERROR) + println(' failed', ERROR) traceback.print_exc(exc) return None
diff --git a/stem/connection.py b/stem/connection.py index 277ba11..fb85225 100644 --- a/stem/connection.py +++ b/stem/connection.py @@ -901,7 +901,7 @@ def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True) raise UnrecognizedAuthChallengeMethod(authchallenge_response_str, cookie_path) elif 'Invalid base16 client nonce' in authchallenge_response_str: raise InvalidClientNonce(authchallenge_response_str, cookie_path) - elif "Cookie authentication is disabled" in authchallenge_response_str: + elif 'Cookie authentication is disabled' in authchallenge_response_str: raise CookieAuthRejected(authchallenge_response_str, cookie_path, True) else: raise AuthChallengeFailed(authchallenge_response, cookie_path) diff --git a/stem/control.py b/stem/control.py index 32e50d5..52a8de3 100644 --- a/stem/control.py +++ b/stem/control.py @@ -1528,7 +1528,7 @@ class Controller(BaseController): raise exc
if not desc_content: - raise stem.DescriptorUnavailable("Descriptor information is unavailable, tor might still be downloading it") + raise stem.DescriptorUnavailable('Descriptor information is unavailable, tor might still be downloading it')
return stem.descriptor.microdescriptor.Microdescriptor(desc_content)
@@ -1636,7 +1636,7 @@ class Controller(BaseController): raise exc
if not desc_content: - raise stem.DescriptorUnavailable("Descriptor information is unavailable, tor might still be downloading it") + raise stem.DescriptorUnavailable('Descriptor information is unavailable, tor might still be downloading it')
return stem.descriptor.server_descriptor.RelayDescriptor(desc_content) except Exception as exc: @@ -1679,7 +1679,7 @@ class Controller(BaseController): if not self._is_server_descriptors_available(): raise stem.ControllerError(SERVER_DESCRIPTORS_UNSUPPORTED) else: - raise stem.DescriptorUnavailable("Descriptor information is unavailable, tor might still be downloading it") + raise stem.DescriptorUnavailable('Descriptor information is unavailable, tor might still be downloading it')
for desc in stem.descriptor.server_descriptor._parse_file(io.BytesIO(desc_content)): yield desc @@ -1763,7 +1763,7 @@ class Controller(BaseController): raise exc
if not desc_content: - raise stem.DescriptorUnavailable("Descriptor information is unavailable, tor might still be downloading it") + raise stem.DescriptorUnavailable('Descriptor information is unavailable, tor might still be downloading it')
if self.get_conf('UseMicrodescriptors', '0') == '1': return stem.descriptor.router_status_entry.RouterStatusEntryMicroV3(desc_content) @@ -1812,7 +1812,7 @@ class Controller(BaseController): desc_content = self.get_info('ns/all', get_bytes = True)
if not desc_content: - raise stem.DescriptorUnavailable("Descriptor information is unavailable, tor might still be downloading it") + raise stem.DescriptorUnavailable('Descriptor information is unavailable, tor might still be downloading it')
desc_iterator = stem.descriptor.router_status_entry._parse_file( io.BytesIO(desc_content), diff --git a/stem/descriptor/hidden_service_descriptor.py b/stem/descriptor/hidden_service_descriptor.py index b0a9551..fec17e4 100644 --- a/stem/descriptor/hidden_service_descriptor.py +++ b/stem/descriptor/hidden_service_descriptor.py @@ -302,7 +302,7 @@ class HiddenServiceDescriptor(Descriptor): raise DecryptionFailure("Unrecognized authentication type '%s', presently we only support basic auth (%s) and stealth auth (%s)" % (authentication_type, BASIC_AUTH, STEALTH_AUTH))
if not content.startswith(b'introduction-point '): - raise DecryptionFailure("Unable to decrypt the introduction-points, maybe this is the wrong key?") + raise DecryptionFailure('Unable to decrypt the introduction-points, maybe this is the wrong key?') elif not content.startswith(b'introduction-point '): raise DecryptionFailure('introduction-points content is encrypted, you need to provide its authentication_cookie')
diff --git a/stem/descriptor/router_status_entry.py b/stem/descriptor/router_status_entry.py index c77f438..561f855 100644 --- a/stem/descriptor/router_status_entry.py +++ b/stem/descriptor/router_status_entry.py @@ -194,7 +194,7 @@ def _parse_s_line(descriptor, entries): for flag in flags: if flags.count(flag) > 1: raise ValueError('%s had duplicate flags: s %s' % (descriptor._name(), value)) - elif flag == "": + elif flag == '': raise ValueError("%s had extra whitespace on its 's' line: s %s" % (descriptor._name(), value))
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py index 9870cf2..b375066 100644 --- a/stem/descriptor/server_descriptor.py +++ b/stem/descriptor/server_descriptor.py @@ -760,7 +760,7 @@ class BridgeDescriptor(ServerDescriptor): if not self.address.startswith('10.'): issues.append("Router line's address should be scrubbed to be '10.x.x.x': %s" % self.address)
- if self.contact and self.contact != "somebody": + if self.contact and self.contact != 'somebody': issues.append("Contact line should be scrubbed to be 'somebody', but instead had '%s'" % self.contact)
for address, _, is_ipv6 in self.or_addresses: diff --git a/stem/exit_policy.py b/stem/exit_policy.py index 5413792..62b9a12 100644 --- a/stem/exit_policy.py +++ b/stem/exit_policy.py @@ -133,7 +133,7 @@ def get_config_policy(rules, ip_address = None): continue
if ':' not in rule: - rule = "%s:*" % rule + rule = '%s:*' % rule
if 'private' in rule: acceptance = rule.split(' ', 1)[0] @@ -149,7 +149,7 @@ def get_config_policy(rules, ip_address = None): pass # we might not have a network connection
for private_addr in addresses: - result.append(ExitPolicyRule("%s %s:%s" % (acceptance, private_addr, port))) + result.append(ExitPolicyRule('%s %s:%s' % (acceptance, private_addr, port))) else: result.append(ExitPolicyRule(rule))
@@ -1003,7 +1003,7 @@ class ExitPolicyRule(object): self.min_port = self.max_port = int(portspec) else: raise ValueError("'%s' isn't within a valid port range: %s" % (portspec, rule)) - elif "-" in portspec: + elif '-' in portspec: # provided with a port range port_comp = portspec.split('-', 1)
diff --git a/stem/interpreter/commands.py b/stem/interpreter/commands.py index c87efea..f065110 100644 --- a/stem/interpreter/commands.py +++ b/stem/interpreter/commands.py @@ -176,7 +176,7 @@ class ControlInterpretor(code.InteractiveConsole): # being optional.
if not ns_desc: - return format("Unable to find consensus information for %s" % fingerprint, *ERROR_OUTPUT) + return format('Unable to find consensus information for %s' % fingerprint, *ERROR_OUTPUT)
# More likely than not we'll have the microdescriptor but not server and # extrainfo descriptors. If so then fetching them. diff --git a/stem/util/connection.py b/stem/util/connection.py index 475c7f5..88d70d5 100644 --- a/stem/util/connection.py +++ b/stem/util/connection.py @@ -492,7 +492,7 @@ def expand_ipv6_address(address):
# expands collapsed groupings, there can only be a single '::' in a valid # address - if "::" in address: + if '::' in address: missing_groups = 7 - address.count(':') address = address.replace('::', '::' + ':' * missing_groups)
diff --git a/stem/util/lru_cache.py b/stem/util/lru_cache.py index f1e427c..011d445 100644 --- a/stem/util/lru_cache.py +++ b/stem/util/lru_cache.py @@ -18,7 +18,7 @@ from collections import namedtuple from functools import update_wrapper from threading import RLock
-_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"]) +_CacheInfo = namedtuple('CacheInfo', ['hits', 'misses', 'maxsize', 'currsize'])
class _HashedSeq(list): diff --git a/stem/util/proc.py b/stem/util/proc.py index 05dfd65..e4a826e 100644 --- a/stem/util/proc.py +++ b/stem/util/proc.py @@ -321,7 +321,7 @@ def file_descriptors_used(pid): try: return len(os.listdir('/proc/%i/fd' % pid)) except Exception as exc: - raise IOError("Unable to check number of file descriptors used: %s" % exc) + raise IOError('Unable to check number of file descriptors used: %s' % exc)
def connections(pid): diff --git a/stem/util/str_tools.py b/stem/util/str_tools.py index 3cbbe9f..497564e 100644 --- a/stem/util/str_tools.py +++ b/stem/util/str_tools.py @@ -462,7 +462,7 @@ def _parse_timestamp(entry): try: time = [int(x) for x in _timestamp_re.match(entry).groups()] except AttributeError: - raise ValueError("Expected timestamp in format YYYY-MM-DD HH:MM:ss but got " + entry) + raise ValueError('Expected timestamp in format YYYY-MM-DD HH:MM:ss but got ' + entry)
return datetime.datetime(time[0], time[1], time[2], time[3], time[4], time[5])
diff --git a/stem/util/test_tools.py b/stem/util/test_tools.py index 907af63..d6a81c4 100644 --- a/stem/util/test_tools.py +++ b/stem/util/test_tools.py @@ -235,10 +235,11 @@ def stylistic_issues(paths, check_two_space_indents = False, check_newlines = Fa if prefer_single_quotes and line and not is_block_comment: content = line.strip().split('#', 1)[0]
- if '"' in content and "'" not in content and '"""' not in content: + if '"' in content and "'" not in content and '"""' not in content and not content.endswith('\'): # Checking if the line already has any single quotes since that # usually means double quotes are preferable for the content (for - # instance "I'm hungry"). + # instance "I'm hungry"). Also checking for '' at the end since + # that can indicate a multi-line string.
issues.setdefault(path, []).append(Issue(index + 1, "use single rather than double quotes", line))
diff --git a/test/integ/descriptor/remote.py b/test/integ/descriptor/remote.py index 78b1add..4c7779b 100644 --- a/test/integ/descriptor/remote.py +++ b/test/integ/descriptor/remote.py @@ -42,7 +42,7 @@ class TestDescriptorDownloader(unittest.TestCase): continue # skip due to https://trac.torproject.org/projects/tor/ticket/14955
if getattr(auth, attr) != getattr(stem_auth, attr): - self.fail("%s has %s %s, but we expected %s" % (auth.nickname, attr, getattr(auth, attr), getattr(stem_auth, attr))) + self.fail('%s has %s %s, but we expected %s' % (auth.nickname, attr, getattr(auth, attr), getattr(stem_auth, attr)))
@require_online @only_run_once diff --git a/test/integ/process.py b/test/integ/process.py index d77c46f..eec1e1e 100644 --- a/test/integ/process.py +++ b/test/integ/process.py @@ -87,11 +87,11 @@ class TestProcess(unittest.TestCase):
output = self.run_tor('--hush', '--invalid_argument', expect_failure = True) self.assertTrue("[warn] Command-line option '--invalid_argument' with no value. Failing." in output) - self.assertTrue("[err] Reading config failed--see warnings above." in output) + self.assertTrue('[err] Reading config failed--see warnings above.' in output)
output = self.run_tor('--hush', '--invalid_argument', 'true', expect_failure = True) self.assertTrue("[warn] Failed to parse/validate config: Unknown option 'invalid_argument'. Failing." in output) - self.assertTrue("[err] Reading config failed--see warnings above." in output) + self.assertTrue('[err] Reading config failed--see warnings above.' in output)
def test_hash_password(self): """ @@ -101,7 +101,7 @@ class TestProcess(unittest.TestCase): """
output = self.run_tor('--hush', '--hash-password', 'my_password') - self.assertTrue(re.match("^16:[0-9A-F]{58}\n$", output)) + self.assertTrue(re.match('^16:[0-9A-F]{58}\n$', output))
# I'm not gonna even pretend to understand the following. Ported directly # from tor's test_cmdline_args.py. @@ -128,7 +128,7 @@ class TestProcess(unittest.TestCase):
output = self.run_tor('--hash-password', expect_failure = True) self.assertTrue("[warn] Command-line option '--hash-password' with no value. Failing." in output) - self.assertTrue("[err] Reading config failed--see warnings above." in output) + self.assertTrue('[err] Reading config failed--see warnings above.' in output)
def test_dump_config_argument(self): """ @@ -448,7 +448,7 @@ class TestProcess(unittest.TestCase): stdin = kwargs.pop('stdin', None)
if kwargs: - raise ValueError("Got unexpected keyword arguments: %s" % kwargs) + raise ValueError('Got unexpected keyword arguments: %s' % kwargs)
if with_torrc: args = ['-f', test.runner.get_runner().get_torrc_path()] + list(args) diff --git a/test/unit/descriptor/networkstatus/document_v3.py b/test/unit/descriptor/networkstatus/document_v3.py index f440bbf..aaf857a 100644 --- a/test/unit/descriptor/networkstatus/document_v3.py +++ b/test/unit/descriptor/networkstatus/document_v3.py @@ -861,14 +861,14 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w= """
test_values = ( - "foo=", - "foo=abc", - "foo=+123", - "foo=12\tbar=12", + 'foo=', + 'foo=abc', + 'foo=+123', + 'foo=12\tbar=12', )
for test_value in test_values: - content = get_network_status_document_v3({"params": test_value}, content = True) + content = get_network_status_document_v3({'params': test_value}, content = True) self.assertRaises(ValueError, NetworkStatusDocumentV3, content, True)
document = NetworkStatusDocumentV3(content, False) diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py index 7d20437..4ae82c7 100644 --- a/test/unit/tutorial.py +++ b/test/unit/tutorial.py @@ -72,7 +72,7 @@ class TestTutorial(unittest.TestCase):
@app.route('/') def index(): - return "<h1>Hi Grandma!</h1>" + return '<h1>Hi Grandma!</h1>'
print(' * Connecting to tor')
@@ -87,14 +87,14 @@ class TestTutorial(unittest.TestCase): # Create a hidden service where visitors of port 80 get redirected to local # port 5000 (this is where flask runs by default).
- print(" * Creating our hidden service in %s" % hidden_service_dir) + print(' * Creating our hidden service in %s' % hidden_service_dir) result = controller.create_hidden_service(hidden_service_dir, 80, target_port = 5000)
# The hostname is only available we can read the hidden service directory. # This requires us to be running with the same user as tor.
if result.hostname: - print(" * Our service is available at %s, press ctrl+c to quit" % result.hostname) + print(' * Our service is available at %s, press ctrl+c to quit' % result.hostname) else: print(" * Unable to determine our service's hostname, probably due to being unable to read the hidden service directory")
@@ -105,7 +105,7 @@ class TestTutorial(unittest.TestCase): # want to delete the hidden service directory if you'd like to have this # same *.onion address in the future.
- print(" * Shutting down our hidden service") + print(' * Shutting down our hidden service') controller.remove_hidden_service(hidden_service_dir) shutil.rmtree(hidden_service_dir)
diff --git a/test/unit/tutorial_examples.py b/test/unit/tutorial_examples.py index 2985281..3b470f5 100644 --- a/test/unit/tutorial_examples.py +++ b/test/unit/tutorial_examples.py @@ -159,7 +159,7 @@ class TestTutorialExamples(unittest.TestCase): if circ.status != CircStatus.BUILT: continue
- print("\nCircuit %s (%s)" % (circ.id, circ.purpose)) + print('\nCircuit %s (%s)' % (circ.id, circ.purpose))
for i, entry in enumerate(circ.path): div = '+' if (i == len(circ.path) - 1) else '|' @@ -168,7 +168,7 @@ class TestTutorialExamples(unittest.TestCase): desc = controller.get_network_status(fingerprint, None) address = desc.address if desc else 'unknown'
- print(" %s- %s (%s, %s)" % (div, fingerprint, nickname, address)) + print(' %s- %s (%s, %s)' % (div, fingerprint, nickname, address))
path_1 = ('B1FA7D51B8B6F0CB585D944F450E7C06EDE7E44C', 'ByTORAndTheSnowDog') path_2 = ('0DD9935C5E939CFA1E07B8DDA6D91C1A2A9D9338', 'afo02') @@ -186,13 +186,13 @@ class TestTutorialExamples(unittest.TestCase): controller.get_circuits.return_value = [circuit_4, circuit_6, circuit_10]
controller.get_network_status.side_effect = lambda fingerprint, *args: { - path_1[0]: _get_router_status("173.209.180.61"), - path_2[0]: _get_router_status("87.238.194.176"), - path_3[0]: _get_router_status("109.163.234.10"), - path_4[0]: _get_router_status("46.165.197.96"), - path_5[0]: _get_router_status("96.47.226.20"), - path_6[0]: _get_router_status("86.59.119.83"), - path_7[0]: _get_router_status("176.67.169.171") + path_1[0]: _get_router_status('173.209.180.61'), + path_2[0]: _get_router_status('87.238.194.176'), + path_3[0]: _get_router_status('109.163.234.10'), + path_4[0]: _get_router_status('46.165.197.96'), + path_5[0]: _get_router_status('96.47.226.20'), + path_6[0]: _get_router_status('86.59.119.83'), + path_7[0]: _get_router_status('176.67.169.171') }[fingerprint]
tutorial_example() @@ -225,11 +225,11 @@ class TestTutorialExamples(unittest.TestCase): exit_fingerprint = circ.path[-1][0] exit_relay = controller.get_network_status(exit_fingerprint)
- print("Exit relay for our connection to %s" % (event.target)) - print(" address: %s:%i" % (exit_relay.address, exit_relay.or_port)) - print(" fingerprint: %s" % exit_relay.fingerprint) - print(" nickname: %s" % exit_relay.nickname) - print(" locale: %s\n" % controller.get_info("ip-to-country/%s" % exit_relay.address, 'unknown')) + print('Exit relay for our connection to %s' % (event.target)) + print(' address: %s:%i' % (exit_relay.address, exit_relay.or_port)) + print(' fingerprint: %s' % exit_relay.fingerprint) + print(' nickname: %s' % exit_relay.nickname) + print(' locale: %s\n' % controller.get_info('ip-to-country/%s' % exit_relay.address, 'unknown'))
main()
@@ -259,17 +259,17 @@ class TestTutorialExamples(unittest.TestCase): downloader = DescriptorDownloader() count, with_contact = 0, 0
- print("Checking for outdated relays...\n") + print('Checking for outdated relays...\n')
for desc in downloader.get_server_descriptors(): if desc.tor_version < Version('0.2.3.0'): count += 1
if desc.contact: - print(' %-15s %s' % (desc.tor_version, desc.contact.decode("utf-8", "replace"))) + print(' %-15s %s' % (desc.tor_version, desc.contact.decode('utf-8', 'replace'))) with_contact += 1
- print("\n%i outdated relays found, %i had contact information" % (count, with_contact)) + print('\n%i outdated relays found, %i had contact information' % (count, with_contact))
downloader_mock().get_server_descriptors.return_value = [ get_relay_server_descriptor({'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}), @@ -399,7 +399,7 @@ class TestTutorialExamples(unittest.TestCase):
print(' %i measured entries and %i unmeasured' % (measured, unmeasured)) except Exception as exc: - print(" failed to get the vote (%s)" % exc) + print(' failed to get the vote (%s)' % exc)
directory_values = [ DIRECTORY_AUTHORITIES['gabelmoo'], @@ -460,7 +460,7 @@ class TestTutorialExamples(unittest.TestCase): ))
for fingerprint, relay in consensus.routers.items(): - print("%s: %s" % (fingerprint, relay.nickname)) + print('%s: %s' % (fingerprint, relay.nickname))
network_status = get_network_status_document_v3(routers = (get_router_status_entry_v3(),)) query_mock().run.return_value = [network_status] diff --git a/test/unit/util/proc.py b/test/unit/util/proc.py index d1fb4aa..ea206b8 100644 --- a/test/unit/util/proc.py +++ b/test/unit/util/proc.py @@ -164,9 +164,9 @@ class TestProc(unittest.TestCase):
try: proc.file_descriptors_used(2118) - self.fail("We should raise when listdir() fails") + self.fail('We should raise when listdir() fails') except IOError as exc: - expected = "Unable to check number of file descriptors used: %s" % error_msg + expected = 'Unable to check number of file descriptors used: %s' % error_msg self.assertEqual(expected, str(exc))
# successful calls diff --git a/test/unit/util/tor_tools.py b/test/unit/util/tor_tools.py index 80362f7..c0881db 100644 --- a/test/unit/util/tor_tools.py +++ b/test/unit/util/tor_tools.py @@ -92,8 +92,8 @@ class TestTorTools(unittest.TestCase): """
valid_hex_digits = ( - "12345", - "AbCdE", + '12345', + 'AbCdE', )
invalid_hex_digits = ( @@ -101,9 +101,9 @@ class TestTorTools(unittest.TestCase): '', 5, 'X', - "1234", - "ABCDEF", - [1, "2", (3, 4)] + '1234', + 'ABCDEF', + [1, '2', (3, 4)] )
for hex_digits in valid_hex_digits: