protocol_alt.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #! python
  2. #
  3. # This module implements a special URL handler that allows selecting an
  4. # alternate implementation provided by some backends.
  5. #
  6. # This file is part of pySerial. https://github.com/pyserial/pyserial
  7. # (C) 2015 Chris Liechti <cliechti@gmx.net>
  8. #
  9. # SPDX-License-Identifier: BSD-3-Clause
  10. #
  11. # URL format: alt://port[?option[=value][&option[=value]]]
  12. # options:
  13. # - class=X used class named X instead of Serial
  14. #
  15. # example:
  16. # use poll based implementation on Posix (Linux):
  17. # python -m serial.tools.miniterm alt:///dev/ttyUSB0?class=PosixPollSerial
  18. try:
  19. import urlparse
  20. except ImportError:
  21. import urllib.parse as urlparse
  22. import serial
  23. def serial_class_for_url(url):
  24. """extract host and port from an URL string"""
  25. parts = urlparse.urlsplit(url)
  26. if parts.scheme != 'alt':
  27. raise serial.SerialException(
  28. 'expected a string in the form "alt://port[?option[=value][&option[=value]]]": '
  29. 'not starting with alt:// ({!r})'.format(parts.scheme))
  30. class_name = 'Serial'
  31. try:
  32. for option, values in urlparse.parse_qs(parts.query, True).items():
  33. if option == 'class':
  34. class_name = values[0]
  35. else:
  36. raise ValueError('unknown option: {!r}'.format(option))
  37. except ValueError as e:
  38. raise serial.SerialException(
  39. 'expected a string in the form '
  40. '"alt://port[?option[=value][&option[=value]]]": {!r}'.format(e))
  41. if not hasattr(serial, class_name):
  42. raise ValueError('unknown class: {!r}'.format(class_name))
  43. cls = getattr(serial, class_name)
  44. if not issubclass(cls, serial.Serial):
  45. raise ValueError('class {!r} is not an instance of Serial'.format(class_name))
  46. return (''.join([parts.netloc, parts.path]), cls)
  47. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  48. if __name__ == '__main__':
  49. s = serial.serial_for_url('alt:///dev/ttyS0?class=PosixPollSerial')
  50. print(s)