docs: def create(cls, arg, attributes=None, named_attributes=None, include_primary_key=True):
          """
          :param arg: The QueryExression to be projected
          :param attributes:  attributes to select
          :param named_attributes:  new attributes to create by renaming or computing
          :param include_primary_key:  True if the primary key must be included even if it's not in attributes.
          :return: the resulting Projection object
          """
          obj = cls()
          obj._connection = arg.connection
          named_attributes = {k: v.strip() for k, v in named_attributes.items()}  # clean up values
          obj._distinct = arg.distinct
          if include_primary_key:  # include primary key of the QueryExpression
              attributes = (list(a for a in arg.primary_key if a not in named_attributes.values()) +
                            list(a for a in attributes if a not in arg.primary_key))
          else:
              # make distinct if the primary key is not completely selected
              obj._distinct = obj._distinct or not set(arg.primary_key).issubset(
                  set(attributes) | set(named_attributes.values()))
          if obj._distinct or cls._need_subquery(arg, attributes, named_attributes):
              obj._arg = Subquery.create(arg)
              obj._heading = obj._arg.heading.project(attributes, named_attributes)
              if not include_primary_key:
                  obj._heading = obj._heading.extend_primary_key(attributes)
          else:
              obj._arg = arg
              obj._heading = obj._arg.heading.project(attributes, named_attributes)
              obj &= arg.restriction  # copy restriction when no subquery
          return obj