Python 2 and Python 3 differences

This topic discusses the difference between Python 2 and 3 as it applies to the Orchestration & Automation application.

The differences that exist between Python 2 and Python 3 are covered in detail in Python documentation. For example, see What's New in Python 3.0. In addition, you need to be aware of differences that apply in the context of Orchestration & Automation.

Importing modules

The scripts feature allows you to import Python modules when writing a script. If the Language field is set to Python 2, you can import the java.util.Date and re modules only. If set to Python 3, you can import the following modules:
  • array
  • base64
  • bs4
  • calendar
  • collections
  • datetime (equivalent to the Python 2 java.util.Date module)
  • email
  • enum
  • hashlib
  • html
  • html2text
  • json
  • random
  • re
  • regex
  • string
  • time
  • xml
In addition, the following Python built-ins are available for Python 3 scripts only:
  • all()
  • any()
  • bytearray()
  • bytes()
  • classmethod
  • staticmethod
  • type()

Types of errors

The Python 3 implementation introduces two new error types:
  • ResilientSecurityException occurs if a script attempts to breach the security restrictions.
  • ResilientMemoryLimitException occurs if the script tries to allocate more than the maximum amount of RAM permitted (64MB).

'from' keyword

The from keyword in Python 3 clashes with the from attribute in the email message context object. For this reason, the use of emailmessage.from is not supported in Python 3 scripts and should be replaced by emailmessage.sender. Python 2 still supports emailmessage.from.

Non-existent fields

In Python 2, the attempt to access a context object attribute that does not exist succeeds and returns None. However, in Python 3, the same operation throws an attribute error, which states that the field name is invalid. This behavior is in line with standard Python 3. The hasattr() method can be used to check if an attribute exists. For example:
if hasattr(incident, 'nonExistentField'):
  log.info(incident.nonExistentField)
else:
  log.info('Tried to access a field that does not exist')
The script returns the following log message:
INFO: Cannot access a field that does not exist.

Unicode support

Python 3 supports unicode out of the box. This means that you no longer need to explicitly use the u prefix or the unicode() function to store a string as unicode. If you convert existing scripts from Python 2 to Python 3, you must check and remove these elements to avoid unicode-related errors in Python 3. For more information, see the Python 3 documentation https://docs.python.org/3.6/howto/unicode.html.

Text object data type

Text object data types behave differently in Python 2 and Python 3. These differences do not necessarily break scripts that are converted from Python 2 to 3 but might be of interest.
  • In Python 3, whether you set the value of a text-area field using a simple string or a helper function, the value is stored as a TextObject. In Python 2, if you set the value of a text-area field using a simple string, the value is stored as a unicode object. If you set it using a helper function, the value is stored as a SimpleTextContentDTO.
  • In Python 3, the default format for objects of type TextObject is ‘html’. The format is set to 'text' only if the field value is set by invoking helper.createPlainText(). In Python 2, the format for objects of type SimpleTextContentDTO may be TEXT or HTML, depending on the helper that is invoked to set the value.
You can explore the differences in Python versions by running the following script and checking the log messages:
incident.description = 'set direct'
log.info(type(incident.description)) 

incident.description = helper.createPlainText('set using createPlainText helper') 
log.info(type(incident.description)) 

incident.description = helper.createRichText('set using createRichText helper') 
log.info(type(incident.description))