def determine_nonschema_privileges_for_schema(role, objkind, schema, dbcontext):
    """
    Determine all non-schema privileges granted to a given role for all objects of objkind in
    the specified schema. Results will be returned as two sets: objects granted write access
    and objects granted read access.

    We explicitly start with writes because if a role has write access then pgbedrock will also
    grant it read access, meaning we won't need to grant that object a read. As a result, we have
    to start with writes first.

    If any write default privileges exist for this role x objkind x schema then we assume that write
    default privileges should be applied universally in this schema. This could definitely not be
    the case though. For example, because default privileges are scoped based on the grantor, it's
    possible that the role had write default privileges for things created by roleA but not for
    things created by roleB. pgbedrock is not fine-grained enough to handle a situation like this
    though, so if there is a write default privilege we just assume that this role should have
    default writes for all objects of objkind in this schema.

    Also note that we're lumping all write default privileges together. It is possible a role might
    have default privileges for UPDATE on all tables but no other write-level default privileges.
    Again, pgbedrock isn't meant to be this fine-grained: if it sees any write-level default
    privilege then it will identify this as a role that should get write default privileges, which
    means that this role will get _all_ write-level default privileges for that objkind in this
    schema.
    """
    # Get all objects of this objkind in this schema and which are not owned by this role
    objects_and_owners = dbcontext.get_schema_objects(schema)
    schema_objects = set()
    for entry in objects_and_owners:
        if entry.kind == objkind and entry.owner != role:
            schema_objects.add(entry.name)

    has_default_write = dbcontext.has_default_privilege(role, schema, objkind, 'write')
    all_writes = dbcontext.get_role_objects_with_access(role, schema, objkind, 'write')

    if has_default_write or (all_writes == schema_objects and all_writes != set()):
        # In the second condition, every object has a write privilege, so we assume that means
        # that this role should have default write privileges
        return set([schema + '.*']), set()

    # If we haven't returned yet then no write default privilege exists; we will have to
    # grant each write individually, meaning we also need to look at read privileges
    has_default_read = dbcontext.has_default_privilege(role, schema, objkind, 'read')
    all_reads = dbcontext.get_role_objects_with_access(role, schema, objkind, 'read')

    if has_default_read or (all_reads == schema_objects and all_reads != set()):
        # In the second condition, every object has a read privilege, so we assume that means
        # that this role should have default read privileges
        return all_writes, set([schema + '.*'])
    else:
        # We have to grant each read individually as well. Because a write will already grant
        # a read, we have to remove all write-granted objects from our read grants
        only_reads = all_reads.difference(all_writes)
        return all_writes, only_reads