Patterns and precedence

http://docs.ansible.com/intro_patterns.html shows

  webservers:dbservers:&staging:!phoenix

as an example of a combination of unions and intersections, and says that
this means

  all machines in the groups `webservers' and `dbservers' are to be
  managed if they are in the group `staging' also, but the machines are
  not to be managed if they are in the group `phoenix'

To simplify slightly, because I don't actualy need the negation in my
example, it's saying that

  webservers:dbservers:&staging

means

  (websevers UNION dbservers) INTERSECTION staging

which is cool.

But, I have a use case where I want to say

  webservers UNION (dbservers INTERSECTION staging)

i.e. I want to manage with all webservers and only staging dbservers. I
didn't see an obvious way to do that; all three of

  webservers:dbservers:&staging
  webservers:staging:&dbservers
  dbservers:&staging:webservers
  staging:&dbservers:webservers

seem to be equivalent, and adding parentheses didn't seem to be supported
(I got "ERROR: provided hosts list is empty").

I particularly want to use it in a --limit argument, if that matters.

Is there a way to do this, or does union always take precedence over
intersection?

                                      -Josh (jbs@care.com)

This email is intended for the person(s) to whom it is addressed and may contain information that is PRIVILEGED or CONFIDENTIAL. Any unauthorized use, distribution, copying, or disclosure by any person other than the addressee(s) is strictly prohibited. If you have received this email in error, please notify the sender immediately by return email and delete the message and any attachments from your system.

There magic happens in lib/ansible/inventory.get_hosts() [1].

# when applying the host selectors, run those without the "&" or "!"
# first, then the &s, then the !s.
patterns = pattern_regular + pattern_intersection + pattern_exclude

[...]

if p.startswith("!"):
  hosts = [ h for h in hosts if h not in that ]
elif p.startswith("&"):
  hosts = [ h for h in hosts if h in that ]
else:
  to_append = [ h for h in that if h.name not in [ y.name for y in hosts
  ] ]
  hosts.extend(to_append)

My brain can't find a way to define what you want using patterns alone.

Filled issue#10234 as a possible improvement [2].

[1] -
https://github.com/ansible/ansible/blob/devel/lib/ansible/inventory/__init__.py#L176
[2] - https://github.com/ansible/ansible/issues/10234

Giovanni