<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def port_list_with_trunk_types(request, **params):
 """List neutron Ports for this tenant with possible TrunkPort indicated :param request: request context NOTE Performing two API calls is not atomic, but this is not worse than the original idea when we call port_list repeatedly for each network to perform identification run-time. We should handle the inconsistencies caused by non-atomic API requests gracefully. """

    LOG.debug("port_list_with_trunk_types(): params=%s", params)

    # When trunk feature is disabled in neutron, we have no need to fetch
    # trunk information and port_list() is enough.
    if not is_extension_supported(request, 'trunk'):
        return port_list(request, **params)

    ports = neutronclient(request).list_ports(**params)['ports']
    trunk_filters = {}
    if 'tenant_id' in params:
        trunk_filters['tenant_id'] = params['tenant_id']
    trunks = neutronclient(request).list_trunks(**trunk_filters)['trunks']
    parent_ports = set(t['port_id'] for t in trunks)
    # Create a dict map for child ports (port ID to trunk info)
    child_ports = dict((s['port_id'],
                        {'trunk_id': t['id'],
                         'segmentation_type': s['segmentation_type'],
                         'segmentation_id': s['segmentation_id']})
                       for t in trunks
                       for s in t['sub_ports'])

    def _get_port_info(port):
        if port['id'] in parent_ports:
            return PortTrunkParent(port)
        elif port['id'] in child_ports:
            return PortTrunkSubport(port, child_ports[port['id']])
        else:
            return Port(port)

    return [_get_port_info(p) for p in ports]