In Ansible inventory, can I exclude children from a host group?

Q: "In Ansible inventory, can I exclude children from a host group?"

A: No. The patterns can't be used inside inventory files. Quoting from Using patterns

"The pattern is the only element of an ad-hoc command that has no flag. It is usually the second element:"

shell> ansible <pattern> -m <module_name> -a "<module options>"

"In a playbook, the pattern is the content of the hosts: line for each play:"

- name: <play_name>
  hosts: <pattern>

For example, the inventory

shell> cat hosts
[idrac]
host1-idrac
host2-idrac
host3-idrac
; ...and 97 more that I won't write here

[idrac_use_py3]
host1-idrac
host3-idrac

[idrac_use_py2:children]
; syntax to include group idrac
; and exclude hosts that are in idrac_use_py3?

and the playbook

shell> cat pb.yml
- hosts: idrac:!idrac_use_py3
  gather_facts: false
  tasks:
    - debug:
        var: ansible_play_hosts_all
      run_once: true

work with the required pattern as expected

shell> ansible-playbook -i hosts pb.yml

PLAY [idrac:!idrac_use_py3] *********************************************

TASK [debug] ************************************************************
ok: [host2-idrac] => 
  ansible_play_hosts_all:
  - host2-idrac

PLAY RECAP **********************************************************************
host2-idrac: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

The next option is to create the group dynamically in the first play and use it in the second e.g.

shell> cat pb.yml
- hosts: all
  gather_facts: false
  tasks:
    - add_host:
        name: "{{ item }}"
        groups: idrac_use_py2
      loop: "{{ groups.idrac|difference(groups.idrac_use_py3) }}"
      run_once: true

- hosts: idrac_use_py2
  gather_facts: false
  tasks:
    - debug:
        var: ansible_play_hosts_all
      run_once: true

gives

shell> ansible-playbook -i hosts pb.yml

PLAY [all] **************************************************************

TASK [add_host] *********************************************************
changed: [host1-idrac] => (item=host2-idrac)

PLAY [idrac_use_py2] ****************************************************

TASK [debug] ************************************************************
ok: [host2-idrac] => 
  ansible_play_hosts_all:
  - host2-idrac

PLAY RECAP **************************************************************
host1-idrac: ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host2-idrac: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0