Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lint.py 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. from __future__ import absolute_import, division, unicode_literals
  2. from pip._vendor.six import text_type
  3. from . import base
  4. from ..constants import namespaces, voidElements
  5. from ..constants import spaceCharacters
  6. spaceCharacters = "".join(spaceCharacters)
  7. class Filter(base.Filter):
  8. """Lints the token stream for errors
  9. If it finds any errors, it'll raise an ``AssertionError``.
  10. """
  11. def __init__(self, source, require_matching_tags=True):
  12. """Creates a Filter
  13. :arg source: the source token stream
  14. :arg require_matching_tags: whether or not to require matching tags
  15. """
  16. super(Filter, self).__init__(source)
  17. self.require_matching_tags = require_matching_tags
  18. def __iter__(self):
  19. open_elements = []
  20. for token in base.Filter.__iter__(self):
  21. type = token["type"]
  22. if type in ("StartTag", "EmptyTag"):
  23. namespace = token["namespace"]
  24. name = token["name"]
  25. assert namespace is None or isinstance(namespace, text_type)
  26. assert namespace != ""
  27. assert isinstance(name, text_type)
  28. assert name != ""
  29. assert isinstance(token["data"], dict)
  30. if (not namespace or namespace == namespaces["html"]) and name in voidElements:
  31. assert type == "EmptyTag"
  32. else:
  33. assert type == "StartTag"
  34. if type == "StartTag" and self.require_matching_tags:
  35. open_elements.append((namespace, name))
  36. for (namespace, name), value in token["data"].items():
  37. assert namespace is None or isinstance(namespace, text_type)
  38. assert namespace != ""
  39. assert isinstance(name, text_type)
  40. assert name != ""
  41. assert isinstance(value, text_type)
  42. elif type == "EndTag":
  43. namespace = token["namespace"]
  44. name = token["name"]
  45. assert namespace is None or isinstance(namespace, text_type)
  46. assert namespace != ""
  47. assert isinstance(name, text_type)
  48. assert name != ""
  49. if (not namespace or namespace == namespaces["html"]) and name in voidElements:
  50. assert False, "Void element reported as EndTag token: %(tag)s" % {"tag": name}
  51. elif self.require_matching_tags:
  52. start = open_elements.pop()
  53. assert start == (namespace, name)
  54. elif type == "Comment":
  55. data = token["data"]
  56. assert isinstance(data, text_type)
  57. elif type in ("Characters", "SpaceCharacters"):
  58. data = token["data"]
  59. assert isinstance(data, text_type)
  60. assert data != ""
  61. if type == "SpaceCharacters":
  62. assert data.strip(spaceCharacters) == ""
  63. elif type == "Doctype":
  64. name = token["name"]
  65. assert name is None or isinstance(name, text_type)
  66. assert token["publicId"] is None or isinstance(name, text_type)
  67. assert token["systemId"] is None or isinstance(name, text_type)
  68. elif type == "Entity":
  69. assert isinstance(token["name"], text_type)
  70. elif type == "SerializerError":
  71. assert isinstance(token["data"], text_type)
  72. else:
  73. assert False, "Unknown token type: %(type)s" % {"type": type}
  74. yield token