Bläddra i källkod

Apply pylint to scripts/manifest_check*.py

1. Run pyformat scripts/<script>.py -s 4 --force_quote_type
none -i to fix formatting
2. Annotate #pylint: disable, where straightforward fix is not available

Test: m manifest_check_test
Test: pylint --rcfile tools/repohooks/tools/pylintrc
build/soong/scripts/manifest_check.py
build/soong/scripts/manifest_check_test.py
Bug: 195738175

Change-Id: I9af498c4abd6ac9f8b9df4f93cbdd4424eacff8e
Spandan Das 2 år sedan
förälder
incheckning
f880742582
2 ändrade filer med 495 tillägg och 431 borttagningar
  1. 280 249
      scripts/manifest_check.py
  2. 215 182
      scripts/manifest_check_test.py

+ 280 - 249
scripts/manifest_check.py

@@ -25,7 +25,6 @@ import subprocess
 import sys
 from xml.dom import minidom
 
-
 from manifest import android_ns
 from manifest import get_children_with_tag
 from manifest import parse_manifest
@@ -33,49 +32,61 @@ from manifest import write_xml
 
 
 class ManifestMismatchError(Exception):
-  pass
+    pass
 
 
 def parse_args():
-  """Parse commandline arguments."""
-
-  parser = argparse.ArgumentParser()
-  parser.add_argument('--uses-library', dest='uses_libraries',
-                      action='append',
-                      help='specify uses-library entries known to the build system')
-  parser.add_argument('--optional-uses-library',
-                      dest='optional_uses_libraries',
-                      action='append',
-                      help='specify uses-library entries known to the build system with required:false')
-  parser.add_argument('--enforce-uses-libraries',
-                      dest='enforce_uses_libraries',
-                      action='store_true',
-                      help='check the uses-library entries known to the build system against the manifest')
-  parser.add_argument('--enforce-uses-libraries-relax',
-                      dest='enforce_uses_libraries_relax',
-                      action='store_true',
-                      help='do not fail immediately, just save the error message to file')
-  parser.add_argument('--enforce-uses-libraries-status',
-                      dest='enforce_uses_libraries_status',
-                      help='output file to store check status (error message)')
-  parser.add_argument('--extract-target-sdk-version',
-                      dest='extract_target_sdk_version',
-                      action='store_true',
-                      help='print the targetSdkVersion from the manifest')
-  parser.add_argument('--dexpreopt-config',
-                      dest='dexpreopt_configs',
-                      action='append',
-                      help='a paths to a dexpreopt.config of some library')
-  parser.add_argument('--aapt',
-                      dest='aapt',
-                      help='path to aapt executable')
-  parser.add_argument('--output', '-o', dest='output', help='output AndroidManifest.xml file')
-  parser.add_argument('input', help='input AndroidManifest.xml file')
-  return parser.parse_args()
+    """Parse commandline arguments."""
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        '--uses-library',
+        dest='uses_libraries',
+        action='append',
+        help='specify uses-library entries known to the build system')
+    parser.add_argument(
+        '--optional-uses-library',
+        dest='optional_uses_libraries',
+        action='append',
+        help='specify uses-library entries known to the build system with '
+        'required:false'
+    )
+    parser.add_argument(
+        '--enforce-uses-libraries',
+        dest='enforce_uses_libraries',
+        action='store_true',
+        help='check the uses-library entries known to the build system against '
+        'the manifest'
+    )
+    parser.add_argument(
+        '--enforce-uses-libraries-relax',
+        dest='enforce_uses_libraries_relax',
+        action='store_true',
+        help='do not fail immediately, just save the error message to file')
+    parser.add_argument(
+        '--enforce-uses-libraries-status',
+        dest='enforce_uses_libraries_status',
+        help='output file to store check status (error message)')
+    parser.add_argument(
+        '--extract-target-sdk-version',
+        dest='extract_target_sdk_version',
+        action='store_true',
+        help='print the targetSdkVersion from the manifest')
+    parser.add_argument(
+        '--dexpreopt-config',
+        dest='dexpreopt_configs',
+        action='append',
+        help='a paths to a dexpreopt.config of some library')
+    parser.add_argument('--aapt', dest='aapt', help='path to aapt executable')
+    parser.add_argument(
+        '--output', '-o', dest='output', help='output AndroidManifest.xml file')
+    parser.add_argument('input', help='input AndroidManifest.xml file')
+    return parser.parse_args()
 
 
 def enforce_uses_libraries(manifest, required, optional, relax, is_apk, path):
-  """Verify that the <uses-library> tags in the manifest match those provided
+    """Verify that the <uses-library> tags in the manifest match those provided
+
   by the build system.
 
   Args:
@@ -84,274 +95,294 @@ def enforce_uses_libraries(manifest, required, optional, relax, is_apk, path):
     optional: optional libs known to the build system
     relax:    if true, suppress error on mismatch and just write it to file
     is_apk:   if the manifest comes from an APK or an XML file
-  """
-  if is_apk:
-    manifest_required, manifest_optional, tags = extract_uses_libs_apk(manifest)
-  else:
-    manifest_required, manifest_optional, tags = extract_uses_libs_xml(manifest)
-
-  # Trim namespace component. Normally Soong does that automatically when it
-  # handles module names specified in Android.bp properties. However not all
-  # <uses-library> entries in the manifest correspond to real modules: some of
-  # the optional libraries may be missing at build time. Therefor this script
-  # accepts raw module names as spelled in Android.bp/Amdroid.mk and trims the
-  # optional namespace part manually.
-  required = trim_namespace_parts(required)
-  optional = trim_namespace_parts(optional)
-
-  if manifest_required == required and manifest_optional == optional:
-    return None
-
-  errmsg = ''.join([
-    'mismatch in the <uses-library> tags between the build system and the '
-      'manifest:\n',
-    '\t- required libraries in build system: [%s]\n' % ', '.join(required),
-    '\t                 vs. in the manifest: [%s]\n' % ', '.join(manifest_required),
-    '\t- optional libraries in build system: [%s]\n' % ', '.join(optional),
-    '\t                 vs. in the manifest: [%s]\n' % ', '.join(manifest_optional),
-    '\t- tags in the manifest (%s):\n' % path,
-    '\t\t%s\n' % '\t\t'.join(tags),
-      'note: the following options are available:\n',
-    '\t- to temporarily disable the check on command line, rebuild with ',
-      'RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" ',
-      'and disable AOT-compilation in dexpreopt)\n',
-    '\t- to temporarily disable the check for the whole product, set ',
-      'PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles\n',
-    '\t- to fix the check, make build system properties coherent with the '
-      'manifest\n',
-    '\t- see build/make/Changes.md for details\n'])
-
-  if not relax:
-    raise ManifestMismatchError(errmsg)
-
-  return errmsg
-
-
-MODULE_NAMESPACE = re.compile("^//[^:]+:")
-
-def trim_namespace_parts(modules):
-  """Trim the namespace part of each module, if present. Leave only the name."""
-
-  trimmed = []
-  for module in modules:
-    trimmed.append(MODULE_NAMESPACE.sub('', module))
-  return trimmed
-
-
-def extract_uses_libs_apk(badging):
-  """Extract <uses-library> tags from the manifest of an APK."""
-
-  pattern = re.compile("^uses-library(-not-required)?:'(.*)'$", re.MULTILINE)
-
-  required = []
-  optional = []
-  lines = []
-  for match in re.finditer(pattern, badging):
-    lines.append(match.group(0))
-    libname = match.group(2)
-    if match.group(1) == None:
-      required.append(libname)
+    """
+    if is_apk:
+        manifest_required, manifest_optional, tags = extract_uses_libs_apk(
+            manifest)
     else:
-      optional.append(libname)
-
-  required = first_unique_elements(required)
-  optional = first_unique_elements(optional)
-  tags = first_unique_elements(lines)
-  return required, optional, tags
+        manifest_required, manifest_optional, tags = extract_uses_libs_xml(
+            manifest)
+
+    # Trim namespace component. Normally Soong does that automatically when it
+    # handles module names specified in Android.bp properties. However not all
+    # <uses-library> entries in the manifest correspond to real modules: some of
+    # the optional libraries may be missing at build time. Therefor this script
+    # accepts raw module names as spelled in Android.bp/Amdroid.mk and trims the
+    # optional namespace part manually.
+    required = trim_namespace_parts(required)
+    optional = trim_namespace_parts(optional)
+
+    if manifest_required == required and manifest_optional == optional:
+        return None
+
+    #pylint: disable=line-too-long
+    errmsg = ''.join([
+        'mismatch in the <uses-library> tags between the build system and the '
+        'manifest:\n',
+        '\t- required libraries in build system: [%s]\n' % ', '.join(required),
+        '\t                 vs. in the manifest: [%s]\n' %
+        ', '.join(manifest_required),
+        '\t- optional libraries in build system: [%s]\n' % ', '.join(optional),
+        '\t                 vs. in the manifest: [%s]\n' %
+        ', '.join(manifest_optional),
+        '\t- tags in the manifest (%s):\n' % path,
+        '\t\t%s\n' % '\t\t'.join(tags),
+        'note: the following options are available:\n',
+        '\t- to temporarily disable the check on command line, rebuild with ',
+        'RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" ',
+        'and disable AOT-compilation in dexpreopt)\n',
+        '\t- to temporarily disable the check for the whole product, set ',
+        'PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles\n',
+        '\t- to fix the check, make build system properties coherent with the '
+        'manifest\n', '\t- see build/make/Changes.md for details\n'
+    ])
+    #pylint: enable=line-too-long
+
+    if not relax:
+        raise ManifestMismatchError(errmsg)
+
+    return errmsg
+
+
+MODULE_NAMESPACE = re.compile('^//[^:]+:')
 
 
-def extract_uses_libs_xml(xml):
-  """Extract <uses-library> tags from the manifest."""
-
-  manifest = parse_manifest(xml)
-  elems = get_children_with_tag(manifest, 'application')
-  application = elems[0] if len(elems) == 1 else None
-  if len(elems) > 1:
-    raise RuntimeError('found multiple <application> tags')
-  elif not elems:
-    if uses_libraries or optional_uses_libraries:
-      raise ManifestMismatchError('no <application> tag found')
-    return
+def trim_namespace_parts(modules):
+    """Trim the namespace part of each module, if present.
 
-  libs = get_children_with_tag(application, 'uses-library')
+    Leave only the name.
+    """
 
-  required = [uses_library_name(x) for x in libs if uses_library_required(x)]
-  optional = [uses_library_name(x) for x in libs if not uses_library_required(x)]
+    trimmed = []
+    for module in modules:
+        trimmed.append(MODULE_NAMESPACE.sub('', module))
+    return trimmed
 
-  # render <uses-library> tags as XML for a pretty error message
-  tags = []
-  for lib in libs:
-    tags.append(lib.toprettyxml())
 
-  required = first_unique_elements(required)
-  optional = first_unique_elements(optional)
-  tags = first_unique_elements(tags)
-  return required, optional, tags
+def extract_uses_libs_apk(badging):
+    """Extract <uses-library> tags from the manifest of an APK."""
+
+    pattern = re.compile("^uses-library(-not-required)?:'(.*)'$", re.MULTILINE)
+
+    required = []
+    optional = []
+    lines = []
+    for match in re.finditer(pattern, badging):
+        lines.append(match.group(0))
+        libname = match.group(2)
+        if match.group(1) is None:
+            required.append(libname)
+        else:
+            optional.append(libname)
+
+    required = first_unique_elements(required)
+    optional = first_unique_elements(optional)
+    tags = first_unique_elements(lines)
+    return required, optional, tags
+
+
+def extract_uses_libs_xml(xml): #pylint: disable=inconsistent-return-statements
+    """Extract <uses-library> tags from the manifest."""
+
+    manifest = parse_manifest(xml)
+    elems = get_children_with_tag(manifest, 'application')
+    application = elems[0] if len(elems) == 1 else None
+    if len(elems) > 1: #pylint: disable=no-else-raise
+        raise RuntimeError('found multiple <application> tags')
+    elif not elems:
+        if uses_libraries or optional_uses_libraries: #pylint: disable=undefined-variable
+            raise ManifestMismatchError('no <application> tag found')
+        return
+
+    libs = get_children_with_tag(application, 'uses-library')
+
+    required = [uses_library_name(x) for x in libs if uses_library_required(x)]
+    optional = [
+        uses_library_name(x) for x in libs if not uses_library_required(x)
+    ]
+
+    # render <uses-library> tags as XML for a pretty error message
+    tags = []
+    for lib in libs:
+        tags.append(lib.toprettyxml())
+
+    required = first_unique_elements(required)
+    optional = first_unique_elements(optional)
+    tags = first_unique_elements(tags)
+    return required, optional, tags
 
 
 def first_unique_elements(l):
-  result = []
-  [result.append(x) for x in l if x not in result]
-  return result
+    result = []
+    for x in l:
+        if x not in result:
+            result.append(x)
+    return result
 
 
 def uses_library_name(lib):
-  """Extract the name attribute of a uses-library tag.
+    """Extract the name attribute of a uses-library tag.
 
   Args:
     lib: a <uses-library> tag.
-  """
-  name = lib.getAttributeNodeNS(android_ns, 'name')
-  return name.value if name is not None else ""
+    """
+    name = lib.getAttributeNodeNS(android_ns, 'name')
+    return name.value if name is not None else ''
 
 
 def uses_library_required(lib):
-  """Extract the required attribute of a uses-library tag.
+    """Extract the required attribute of a uses-library tag.
 
   Args:
     lib: a <uses-library> tag.
-  """
-  required = lib.getAttributeNodeNS(android_ns, 'required')
-  return (required.value == 'true') if required is not None else True
+    """
+    required = lib.getAttributeNodeNS(android_ns, 'required')
+    return (required.value == 'true') if required is not None else True
 
 
-def extract_target_sdk_version(manifest, is_apk = False):
-  """Returns the targetSdkVersion from the manifest.
+def extract_target_sdk_version(manifest, is_apk=False):
+    """Returns the targetSdkVersion from the manifest.
 
   Args:
     manifest: manifest (either parsed XML or aapt dump of APK)
     is_apk:   if the manifest comes from an APK or an XML file
-  """
-  if is_apk:
-    return extract_target_sdk_version_apk(manifest)
-  else:
-    return extract_target_sdk_version_xml(manifest)
+    """
+    if is_apk: #pylint: disable=no-else-return
+        return extract_target_sdk_version_apk(manifest)
+    else:
+        return extract_target_sdk_version_xml(manifest)
 
 
 def extract_target_sdk_version_apk(badging):
-  """Extract targetSdkVersion tags from the manifest of an APK."""
+    """Extract targetSdkVersion tags from the manifest of an APK."""
 
-  pattern = re.compile("^targetSdkVersion?:'(.*)'$", re.MULTILINE)
+    pattern = re.compile("^targetSdkVersion?:'(.*)'$", re.MULTILINE)
 
-  for match in re.finditer(pattern, badging):
-    return match.group(1)
+    for match in re.finditer(pattern, badging):
+        return match.group(1)
 
-  raise RuntimeError('cannot find targetSdkVersion in the manifest')
+    raise RuntimeError('cannot find targetSdkVersion in the manifest')
 
 
 def extract_target_sdk_version_xml(xml):
-  """Extract targetSdkVersion tags from the manifest."""
+    """Extract targetSdkVersion tags from the manifest."""
 
-  manifest = parse_manifest(xml)
+    manifest = parse_manifest(xml)
 
-  # Get or insert the uses-sdk element
-  uses_sdk = get_children_with_tag(manifest, 'uses-sdk')
-  if len(uses_sdk) > 1:
-    raise RuntimeError('found multiple uses-sdk elements')
-  elif len(uses_sdk) == 0:
-    raise RuntimeError('missing uses-sdk element')
+    # Get or insert the uses-sdk element
+    uses_sdk = get_children_with_tag(manifest, 'uses-sdk')
+    if len(uses_sdk) > 1: #pylint: disable=no-else-raise
+        raise RuntimeError('found multiple uses-sdk elements')
+    elif len(uses_sdk) == 0:
+        raise RuntimeError('missing uses-sdk element')
 
-  uses_sdk = uses_sdk[0]
+    uses_sdk = uses_sdk[0]
 
-  min_attr = uses_sdk.getAttributeNodeNS(android_ns, 'minSdkVersion')
-  if min_attr is None:
-    raise RuntimeError('minSdkVersion is not specified')
+    min_attr = uses_sdk.getAttributeNodeNS(android_ns, 'minSdkVersion')
+    if min_attr is None:
+        raise RuntimeError('minSdkVersion is not specified')
 
-  target_attr = uses_sdk.getAttributeNodeNS(android_ns, 'targetSdkVersion')
-  if target_attr is None:
-    target_attr = min_attr
+    target_attr = uses_sdk.getAttributeNodeNS(android_ns, 'targetSdkVersion')
+    if target_attr is None:
+        target_attr = min_attr
 
-  return target_attr.value
+    return target_attr.value
 
 
 def load_dexpreopt_configs(configs):
-  """Load dexpreopt.config files and map module names to library names."""
-  module_to_libname = {}
+    """Load dexpreopt.config files and map module names to library names."""
+    module_to_libname = {}
 
-  if configs is None:
-    configs = []
+    if configs is None:
+        configs = []
 
-  for config in configs:
-    with open(config, 'r') as f:
-      contents = json.load(f)
-    module_to_libname[contents['Name']] = contents['ProvidesUsesLibrary']
+    for config in configs:
+        with open(config, 'r') as f:
+            contents = json.load(f)
+        module_to_libname[contents['Name']] = contents['ProvidesUsesLibrary']
 
-  return module_to_libname
+    return module_to_libname
 
 
 def translate_libnames(modules, module_to_libname):
-  """Translate module names into library names using the mapping."""
-  if modules is None:
-    modules = []
+    """Translate module names into library names using the mapping."""
+    if modules is None:
+        modules = []
 
-  libnames = []
-  for name in modules:
-    if name in module_to_libname:
-      name = module_to_libname[name]
-    libnames.append(name)
+    libnames = []
+    for name in modules:
+        if name in module_to_libname:
+            name = module_to_libname[name]
+        libnames.append(name)
 
-  return libnames
+    return libnames
 
 
 def main():
-  """Program entry point."""
-  try:
-    args = parse_args()
+    """Program entry point."""
+    try:
+        args = parse_args()
+
+        # The input can be either an XML manifest or an APK, they are parsed and
+        # processed in different ways.
+        is_apk = args.input.endswith('.apk')
+        if is_apk:
+            aapt = args.aapt if args.aapt is not None else 'aapt'
+            manifest = subprocess.check_output(
+                [aapt, 'dump', 'badging', args.input])
+        else:
+            manifest = minidom.parse(args.input)
+
+        if args.enforce_uses_libraries:
+            # Load dexpreopt.config files and build a mapping from module
+            # names to library names. This is necessary because build system
+            # addresses libraries by their module name (`uses_libs`,
+            # `optional_uses_libs`, `LOCAL_USES_LIBRARIES`,
+            # `LOCAL_OPTIONAL_LIBRARY_NAMES` all contain module names), while
+            # the manifest addresses libraries by their name.
+            mod_to_lib = load_dexpreopt_configs(args.dexpreopt_configs)
+            required = translate_libnames(args.uses_libraries, mod_to_lib)
+            optional = translate_libnames(args.optional_uses_libraries,
+                                          mod_to_lib)
+
+            # Check if the <uses-library> lists in the build system agree with
+            # those in the manifest. Raise an exception on mismatch, unless the
+            # script was passed a special parameter to suppress exceptions.
+            errmsg = enforce_uses_libraries(manifest, required, optional,
+                                            args.enforce_uses_libraries_relax,
+                                            is_apk, args.input)
+
+            # Create a status file that is empty on success, or contains an
+            # error message on failure. When exceptions are suppressed,
+            # dexpreopt command command will check file size to determine if
+            # the check has failed.
+            if args.enforce_uses_libraries_status:
+                with open(args.enforce_uses_libraries_status, 'w') as f:
+                    if not errmsg is not None:
+                        f.write('%s\n' % errmsg)
+
+        if args.extract_target_sdk_version:
+            try:
+                print(extract_target_sdk_version(manifest, is_apk))
+            except: #pylint: disable=bare-except
+                # Failed; don't crash, return "any" SDK version. This will
+                # result in dexpreopt not adding any compatibility libraries.
+                print(10000)
+
+        if args.output:
+            # XML output is supposed to be written only when this script is
+            # invoked with XML input manifest, not with an APK.
+            if is_apk:
+                raise RuntimeError('cannot save APK manifest as XML')
+
+            with open(args.output, 'wb') as f:
+                write_xml(f, manifest)
+
+    # pylint: disable=broad-except
+    except Exception as err:
+        print('error: ' + str(err), file=sys.stderr)
+        sys.exit(-1)
 
-    # The input can be either an XML manifest or an APK, they are parsed and
-    # processed in different ways.
-    is_apk = args.input.endswith('.apk')
-    if is_apk:
-      aapt = args.aapt if args.aapt != None else "aapt"
-      manifest = subprocess.check_output([aapt, "dump", "badging", args.input])
-    else:
-      manifest = minidom.parse(args.input)
-
-    if args.enforce_uses_libraries:
-      # Load dexpreopt.config files and build a mapping from module names to
-      # library names. This is necessary because build system addresses
-      # libraries by their module name (`uses_libs`, `optional_uses_libs`,
-      # `LOCAL_USES_LIBRARIES`, `LOCAL_OPTIONAL_LIBRARY_NAMES` all contain
-      # module names), while the manifest addresses libraries by their name.
-      mod_to_lib = load_dexpreopt_configs(args.dexpreopt_configs)
-      required = translate_libnames(args.uses_libraries, mod_to_lib)
-      optional = translate_libnames(args.optional_uses_libraries, mod_to_lib)
-
-      # Check if the <uses-library> lists in the build system agree with those
-      # in the manifest. Raise an exception on mismatch, unless the script was
-      # passed a special parameter to suppress exceptions.
-      errmsg = enforce_uses_libraries(manifest, required, optional,
-        args.enforce_uses_libraries_relax, is_apk, args.input)
-
-      # Create a status file that is empty on success, or contains an error
-      # message on failure. When exceptions are suppressed, dexpreopt command
-      # command will check file size to determine if the check has failed.
-      if args.enforce_uses_libraries_status:
-        with open(args.enforce_uses_libraries_status, 'w') as f:
-          if not errmsg == None:
-            f.write("%s\n" % errmsg)
-
-    if args.extract_target_sdk_version:
-      try:
-        print(extract_target_sdk_version(manifest, is_apk))
-      except:
-        # Failed; don't crash, return "any" SDK version. This will result in
-        # dexpreopt not adding any compatibility libraries.
-        print(10000)
-
-    if args.output:
-      # XML output is supposed to be written only when this script is invoked
-      # with XML input manifest, not with an APK.
-      if is_apk:
-        raise RuntimeError('cannot save APK manifest as XML')
-
-      with open(args.output, 'wb') as f:
-        write_xml(f, manifest)
-
-  # pylint: disable=broad-except
-  except Exception as err:
-    print('error: ' + str(err), file=sys.stderr)
-    sys.exit(-1)
 
 if __name__ == '__main__':
-  main()
+    main()

+ 215 - 182
scripts/manifest_check_test.py

@@ -26,202 +26,235 @@ sys.dont_write_bytecode = True
 
 
 def uses_library_xml(name, attr=''):
-  return '<uses-library android:name="%s"%s />' % (name, attr)
+    return '<uses-library android:name="%s"%s />' % (name, attr)
 
 
 def required_xml(value):
-  return ' android:required="%s"' % ('true' if value else 'false')
+    return ' android:required="%s"' % ('true' if value else 'false')
 
 
 def uses_library_apk(name, sfx=''):
-  return "uses-library%s:'%s'" % (sfx, name)
+    return "uses-library%s:'%s'" % (sfx, name)
 
 
 def required_apk(value):
-  return '' if value else '-not-required'
+    return '' if value else '-not-required'
 
 
 class EnforceUsesLibrariesTest(unittest.TestCase):
-  """Unit tests for add_extract_native_libs function."""
-
-  def run_test(self, xml, apk, uses_libraries=[], optional_uses_libraries=[]):
-    doc = minidom.parseString(xml)
-    try:
-      relax = False
-      manifest_check.enforce_uses_libraries(doc, uses_libraries,
-        optional_uses_libraries, relax, False, 'path/to/X/AndroidManifest.xml')
-      manifest_check.enforce_uses_libraries(apk, uses_libraries,
-        optional_uses_libraries, relax, True, 'path/to/X/X.apk')
-      return True
-    except manifest_check.ManifestMismatchError:
-      return False
-
-  xml_tmpl = (
-      '<?xml version="1.0" encoding="utf-8"?>\n'
-      '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
-      '    <application>\n'
-      '    %s\n'
-      '    </application>\n'
-      '</manifest>\n')
-
-  apk_tmpl = (
-      "package: name='com.google.android.something' versionCode='100'\n"
-      "sdkVersion:'29'\n"
-      "targetSdkVersion:'29'\n"
-      "uses-permission: name='android.permission.ACCESS_NETWORK_STATE'\n"
-      "%s\n"
-      "densities: '160' '240' '320' '480' '640' '65534")
-
-  def test_uses_library(self):
-    xml = self.xml_tmpl % (uses_library_xml('foo'))
-    apk = self.apk_tmpl % (uses_library_apk('foo'))
-    matches = self.run_test(xml, apk, uses_libraries=['foo'])
-    self.assertTrue(matches)
-
-  def test_uses_library_required(self):
-    xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(True)))
-    apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(True)))
-    matches = self.run_test(xml, apk, uses_libraries=['foo'])
-    self.assertTrue(matches)
-
-  def test_optional_uses_library(self):
-    xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
-    apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
-    matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
-    self.assertTrue(matches)
-
-  def test_expected_uses_library(self):
-    xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
-    apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
-    matches = self.run_test(xml, apk, uses_libraries=['foo'])
-    self.assertFalse(matches)
-
-  def test_expected_optional_uses_library(self):
-    xml = self.xml_tmpl % (uses_library_xml('foo'))
-    apk = self.apk_tmpl % (uses_library_apk('foo'))
-    matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
-    self.assertFalse(matches)
-
-  def test_missing_uses_library(self):
-    xml = self.xml_tmpl % ('')
-    apk = self.apk_tmpl % ('')
-    matches = self.run_test(xml, apk, uses_libraries=['foo'])
-    self.assertFalse(matches)
-
-  def test_missing_optional_uses_library(self):
-    xml = self.xml_tmpl % ('')
-    apk = self.apk_tmpl % ('')
-    matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
-    self.assertFalse(matches)
-
-  def test_extra_uses_library(self):
-    xml = self.xml_tmpl % (uses_library_xml('foo'))
-    apk = self.apk_tmpl % (uses_library_xml('foo'))
-    matches = self.run_test(xml, apk)
-    self.assertFalse(matches)
-
-  def test_extra_optional_uses_library(self):
-    xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
-    apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
-    matches = self.run_test(xml, apk)
-    self.assertFalse(matches)
-
-  def test_multiple_uses_library(self):
-    xml = self.xml_tmpl % ('\n'.join([uses_library_xml('foo'),
-                                      uses_library_xml('bar')]))
-    apk = self.apk_tmpl % ('\n'.join([uses_library_apk('foo'),
-                                      uses_library_apk('bar')]))
-    matches = self.run_test(xml, apk, uses_libraries=['foo', 'bar'])
-    self.assertTrue(matches)
-
-  def test_multiple_optional_uses_library(self):
-    xml = self.xml_tmpl % ('\n'.join([uses_library_xml('foo', required_xml(False)),
-                                      uses_library_xml('bar', required_xml(False))]))
-    apk = self.apk_tmpl % ('\n'.join([uses_library_apk('foo', required_apk(False)),
-                                      uses_library_apk('bar', required_apk(False))]))
-    matches = self.run_test(xml, apk, optional_uses_libraries=['foo', 'bar'])
-    self.assertTrue(matches)
-
-  def test_order_uses_library(self):
-    xml = self.xml_tmpl % ('\n'.join([uses_library_xml('foo'),
-                                      uses_library_xml('bar')]))
-    apk = self.apk_tmpl % ('\n'.join([uses_library_apk('foo'),
-                                      uses_library_apk('bar')]))
-    matches = self.run_test(xml, apk, uses_libraries=['bar', 'foo'])
-    self.assertFalse(matches)
-
-  def test_order_optional_uses_library(self):
-    xml = self.xml_tmpl % ('\n'.join([uses_library_xml('foo', required_xml(False)),
-                                      uses_library_xml('bar', required_xml(False))]))
-    apk = self.apk_tmpl % ('\n'.join([uses_library_apk('foo', required_apk(False)),
-                                      uses_library_apk('bar', required_apk(False))]))
-    matches = self.run_test(xml, apk, optional_uses_libraries=['bar', 'foo'])
-    self.assertFalse(matches)
-
-  def test_duplicate_uses_library(self):
-    xml = self.xml_tmpl % ('\n'.join([uses_library_xml('foo'),
-                                      uses_library_xml('foo')]))
-    apk = self.apk_tmpl % ('\n'.join([uses_library_apk('foo'),
-                                      uses_library_apk('foo')]))
-    matches = self.run_test(xml, apk, uses_libraries=['foo'])
-    self.assertTrue(matches)
-
-  def test_duplicate_optional_uses_library(self):
-    xml = self.xml_tmpl % ('\n'.join([uses_library_xml('foo', required_xml(False)),
-                                      uses_library_xml('foo', required_xml(False))]))
-    apk = self.apk_tmpl % ('\n'.join([uses_library_apk('foo', required_apk(False)),
-                                      uses_library_apk('foo', required_apk(False))]))
-    matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
-    self.assertTrue(matches)
-
-  def test_mixed(self):
-    xml = self.xml_tmpl % ('\n'.join([uses_library_xml('foo'),
-                                      uses_library_xml('bar', required_xml(False))]))
-    apk = self.apk_tmpl % ('\n'.join([uses_library_apk('foo'),
-                                      uses_library_apk('bar', required_apk(False))]))
-    matches = self.run_test(xml, apk, uses_libraries=['foo'],
-                            optional_uses_libraries=['bar'])
-    self.assertTrue(matches)
-
-  def test_mixed_with_namespace(self):
-    xml = self.xml_tmpl % ('\n'.join([uses_library_xml('foo'),
-                                      uses_library_xml('bar', required_xml(False))]))
-    apk = self.apk_tmpl % ('\n'.join([uses_library_apk('foo'),
-                                      uses_library_apk('bar', required_apk(False))]))
-    matches = self.run_test(xml, apk, uses_libraries=['//x/y/z:foo'],
-                            optional_uses_libraries=['//x/y/z:bar'])
-    self.assertTrue(matches)
+    """Unit tests for add_extract_native_libs function."""
+
+    def run_test(self, xml, apk, uses_libraries=[], optional_uses_libraries=[]): #pylint: disable=dangerous-default-value
+        doc = minidom.parseString(xml)
+        try:
+            relax = False
+            manifest_check.enforce_uses_libraries(
+                doc, uses_libraries, optional_uses_libraries, relax, False,
+                'path/to/X/AndroidManifest.xml')
+            manifest_check.enforce_uses_libraries(apk, uses_libraries,
+                                                  optional_uses_libraries,
+                                                  relax, True,
+                                                  'path/to/X/X.apk')
+            return True
+        except manifest_check.ManifestMismatchError:
+            return False
+
+    xml_tmpl = (
+        '<?xml version="1.0" encoding="utf-8"?>\n<manifest '
+        'xmlns:android="http://schemas.android.com/apk/res/android">\n    '
+        '<application>\n    %s\n    </application>\n</manifest>\n')
+
+    apk_tmpl = (
+        "package: name='com.google.android.something' versionCode='100'\n"
+        "sdkVersion:'29'\n"
+        "targetSdkVersion:'29'\n"
+        "uses-permission: name='android.permission.ACCESS_NETWORK_STATE'\n"
+        '%s\n'
+        "densities: '160' '240' '320' '480' '640' '65534")
+
+    def test_uses_library(self):
+        xml = self.xml_tmpl % (uses_library_xml('foo'))
+        apk = self.apk_tmpl % (uses_library_apk('foo'))
+        matches = self.run_test(xml, apk, uses_libraries=['foo'])
+        self.assertTrue(matches)
+
+    def test_uses_library_required(self):
+        xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(True)))
+        apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(True)))
+        matches = self.run_test(xml, apk, uses_libraries=['foo'])
+        self.assertTrue(matches)
+
+    def test_optional_uses_library(self):
+        xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
+        apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
+        matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
+        self.assertTrue(matches)
+
+    def test_expected_uses_library(self):
+        xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
+        apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
+        matches = self.run_test(xml, apk, uses_libraries=['foo'])
+        self.assertFalse(matches)
+
+    def test_expected_optional_uses_library(self):
+        xml = self.xml_tmpl % (uses_library_xml('foo'))
+        apk = self.apk_tmpl % (uses_library_apk('foo'))
+        matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
+        self.assertFalse(matches)
+
+    def test_missing_uses_library(self):
+        xml = self.xml_tmpl % ('')
+        apk = self.apk_tmpl % ('')
+        matches = self.run_test(xml, apk, uses_libraries=['foo'])
+        self.assertFalse(matches)
+
+    def test_missing_optional_uses_library(self):
+        xml = self.xml_tmpl % ('')
+        apk = self.apk_tmpl % ('')
+        matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
+        self.assertFalse(matches)
+
+    def test_extra_uses_library(self):
+        xml = self.xml_tmpl % (uses_library_xml('foo'))
+        apk = self.apk_tmpl % (uses_library_xml('foo'))
+        matches = self.run_test(xml, apk)
+        self.assertFalse(matches)
+
+    def test_extra_optional_uses_library(self):
+        xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
+        apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
+        matches = self.run_test(xml, apk)
+        self.assertFalse(matches)
+
+    def test_multiple_uses_library(self):
+        xml = self.xml_tmpl % ('\n'.join(
+            [uses_library_xml('foo'),
+             uses_library_xml('bar')]))
+        apk = self.apk_tmpl % ('\n'.join(
+            [uses_library_apk('foo'),
+             uses_library_apk('bar')]))
+        matches = self.run_test(xml, apk, uses_libraries=['foo', 'bar'])
+        self.assertTrue(matches)
+
+    def test_multiple_optional_uses_library(self):
+        xml = self.xml_tmpl % ('\n'.join([
+            uses_library_xml('foo', required_xml(False)),
+            uses_library_xml('bar', required_xml(False))
+        ]))
+        apk = self.apk_tmpl % ('\n'.join([
+            uses_library_apk('foo', required_apk(False)),
+            uses_library_apk('bar', required_apk(False))
+        ]))
+        matches = self.run_test(
+            xml, apk, optional_uses_libraries=['foo', 'bar'])
+        self.assertTrue(matches)
+
+    def test_order_uses_library(self):
+        xml = self.xml_tmpl % ('\n'.join(
+            [uses_library_xml('foo'),
+             uses_library_xml('bar')]))
+        apk = self.apk_tmpl % ('\n'.join(
+            [uses_library_apk('foo'),
+             uses_library_apk('bar')]))
+        matches = self.run_test(xml, apk, uses_libraries=['bar', 'foo'])
+        self.assertFalse(matches)
+
+    def test_order_optional_uses_library(self):
+        xml = self.xml_tmpl % ('\n'.join([
+            uses_library_xml('foo', required_xml(False)),
+            uses_library_xml('bar', required_xml(False))
+        ]))
+        apk = self.apk_tmpl % ('\n'.join([
+            uses_library_apk('foo', required_apk(False)),
+            uses_library_apk('bar', required_apk(False))
+        ]))
+        matches = self.run_test(
+            xml, apk, optional_uses_libraries=['bar', 'foo'])
+        self.assertFalse(matches)
+
+    def test_duplicate_uses_library(self):
+        xml = self.xml_tmpl % ('\n'.join(
+            [uses_library_xml('foo'),
+             uses_library_xml('foo')]))
+        apk = self.apk_tmpl % ('\n'.join(
+            [uses_library_apk('foo'),
+             uses_library_apk('foo')]))
+        matches = self.run_test(xml, apk, uses_libraries=['foo'])
+        self.assertTrue(matches)
+
+    def test_duplicate_optional_uses_library(self):
+        xml = self.xml_tmpl % ('\n'.join([
+            uses_library_xml('foo', required_xml(False)),
+            uses_library_xml('foo', required_xml(False))
+        ]))
+        apk = self.apk_tmpl % ('\n'.join([
+            uses_library_apk('foo', required_apk(False)),
+            uses_library_apk('foo', required_apk(False))
+        ]))
+        matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
+        self.assertTrue(matches)
+
+    def test_mixed(self):
+        xml = self.xml_tmpl % ('\n'.join([
+            uses_library_xml('foo'),
+            uses_library_xml('bar', required_xml(False))
+        ]))
+        apk = self.apk_tmpl % ('\n'.join([
+            uses_library_apk('foo'),
+            uses_library_apk('bar', required_apk(False))
+        ]))
+        matches = self.run_test(
+            xml, apk, uses_libraries=['foo'], optional_uses_libraries=['bar'])
+        self.assertTrue(matches)
+
+    def test_mixed_with_namespace(self):
+        xml = self.xml_tmpl % ('\n'.join([
+            uses_library_xml('foo'),
+            uses_library_xml('bar', required_xml(False))
+        ]))
+        apk = self.apk_tmpl % ('\n'.join([
+            uses_library_apk('foo'),
+            uses_library_apk('bar', required_apk(False))
+        ]))
+        matches = self.run_test(
+            xml,
+            apk,
+            uses_libraries=['//x/y/z:foo'],
+            optional_uses_libraries=['//x/y/z:bar'])
+        self.assertTrue(matches)
 
 
 class ExtractTargetSdkVersionTest(unittest.TestCase):
-  def run_test(self, xml, apk, version):
-    doc = minidom.parseString(xml)
-    v = manifest_check.extract_target_sdk_version(doc, is_apk=False)
-    self.assertEqual(v, version)
-    v = manifest_check.extract_target_sdk_version(apk, is_apk=True)
-    self.assertEqual(v, version)
-
-  xml_tmpl = (
-      '<?xml version="1.0" encoding="utf-8"?>\n'
-      '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
-      '    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="%s" />\n'
-      '</manifest>\n')
-
-  apk_tmpl = (
-      "package: name='com.google.android.something' versionCode='100'\n"
-      "sdkVersion:'28'\n"
-      "targetSdkVersion:'%s'\n"
-      "uses-permission: name='android.permission.ACCESS_NETWORK_STATE'\n")
-
-  def test_targert_sdk_version_28(self):
-    xml = self.xml_tmpl % "28"
-    apk = self.apk_tmpl % "28"
-    self.run_test(xml, apk, "28")
-
-  def test_targert_sdk_version_29(self):
-    xml = self.xml_tmpl % "29"
-    apk = self.apk_tmpl % "29"
-    self.run_test(xml, apk, "29")
+
+    def run_test(self, xml, apk, version):
+        doc = minidom.parseString(xml)
+        v = manifest_check.extract_target_sdk_version(doc, is_apk=False)
+        self.assertEqual(v, version)
+        v = manifest_check.extract_target_sdk_version(apk, is_apk=True)
+        self.assertEqual(v, version)
+
+    xml_tmpl = (
+        '<?xml version="1.0" encoding="utf-8"?>\n<manifest '
+        'xmlns:android="http://schemas.android.com/apk/res/android">\n    '
+        '<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="%s" '
+        '/>\n</manifest>\n')
+
+    apk_tmpl = (
+        "package: name='com.google.android.something' versionCode='100'\n"
+        "sdkVersion:'28'\n"
+        "targetSdkVersion:'%s'\n"
+        "uses-permission: name='android.permission.ACCESS_NETWORK_STATE'\n")
+
+    def test_targert_sdk_version_28(self):
+        xml = self.xml_tmpl % '28'
+        apk = self.apk_tmpl % '28'
+        self.run_test(xml, apk, '28')
+
+    def test_targert_sdk_version_29(self):
+        xml = self.xml_tmpl % '29'
+        apk = self.apk_tmpl % '29'
+        self.run_test(xml, apk, '29')
+
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)