Skip to content

fix(filter): exclude_entity_globs now overrides include_entity_globs (#33)#34

Merged
jonathan-gtd merged 1 commit intojonathan-gtd:masterfrom
SAY-5:fix/exclude-globs-override-include-globs-33
May 6, 2026
Merged

fix(filter): exclude_entity_globs now overrides include_entity_globs (#33)#34
jonathan-gtd merged 1 commit intojonathan-gtd:masterfrom
SAY-5:fix/exclude-globs-override-include-globs-33

Conversation

@SAY-5
Copy link
Copy Markdown
Contributor

@SAY-5 SAY-5 commented Apr 28, 2026

Closes #33.

Reproduction (from the issue)

include_entity_globs: [\"sensor.*_temperature\"]
exclude_entity_globs: [\"sensor.processor_*\"]

Expected: sensor.processor_temperature is excluded.
Actual: sensor.processor_temperature is still recorded.

Root cause

Home Assistant's generate_filter (homeassistant.helpers.entityfilter._generate_filter_from_sets_and_pattern_lists, case 4a) lets include_entity_globs short-circuit over exclude_entity_globs:

return entity_id in include_e or (
    entity_id not in exclude_e
    and (
        bool(include_eg and include_eg.match(entity_id))   # <-- include glob wins, exclude never checked
        or (
            split_entity_id(entity_id)[0] in include_d
            and not (exclude_eg and exclude_eg.match(entity_id))
        )
    )
)

So when both globs match, the include glob short-circuits to True and the exclude glob is never consulted. Scribe users — and the issue reporter — expect the opposite.

Fix

Wrap the result of generate_filter with a small _build_exclude_priority_filter that:

  1. checks exclude_entities and exclude_entity_globs first; on any match the entity is rejected,
  2. otherwise defers to the upstream filter.

The wrapper preserves HA semantics for everything else (domain include/exclude, entity-level include, no-filter pass-through), and is a no-op when no excludes are configured (common-case fast path).

entity_filter = generate_filter(...)
entity_filter = _build_exclude_priority_filter(entity_filter, exclude_entities, exclude_entity_globs)

Test plan

Added test_exclude_entity_globs_overrides_include_entity_globs in tests/test_filter.py — the exact reproduction from the issue (include: sensor.*_temperature, exclude: sensor.processor_*):

  • sensor.living_room_temperature (include only) → recorded.
  • sensor.processor_temperature (matches both) → excluded (was: incorrectly recorded).
  • sensor.processor_use (exclude only) → excluded.

Local results:

  • python3 -m ast parses both modified files cleanly.
  • Standalone Python repro confirms the wrapper produces the documented behavior on simulated generate_filter output.
  • Full pytest suite requires the home-assistant test harness which the repo bootstraps via requirements_test.txt; CI will run it.

…onathan-gtd#33)

Closes jonathan-gtd#33.

Home Assistant's `generate_filter` (case 4a in
homeassistant.helpers.entityfilter) lets `include_entity_globs`
short-circuit *over* `exclude_entity_globs`: when an entity
matches an include glob, the exclude globs are never checked. Per
the issue, scribe users expect the opposite — an
`exclude_entity_globs` match should be a hard reject, even when
an `include_entity_globs` entry would otherwise have matched.

Wrap the result of `generate_filter` with a small
`_build_exclude_priority_filter` that:
1. checks `exclude_entities` and `exclude_entity_globs` first,
   returning False on any match,
2. otherwise defers to the upstream filter.

The existing HA semantics for everything else (domain
include/exclude, entity-level include, no-filter pass-through) are
preserved exactly. The wrapper is a no-op when neither
`exclude_entities` nor `exclude_entity_globs` is configured, so
the common-case fast path is unchanged.

Tests:
* test_exclude_entity_globs_overrides_include_entity_globs —
  exact reproduction from the issue
  (`include: sensor.*_temperature`, `exclude: sensor.processor_*`):
  `sensor.processor_temperature` is now excluded,
  `sensor.living_room_temperature` is still included, and
  `sensor.processor_use` (excluded only) stays excluded.
@jonathan-gtd jonathan-gtd merged commit 8e47cb2 into jonathan-gtd:master May 6, 2026
1 check passed
@jonathan-gtd
Copy link
Copy Markdown
Owner

Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

exclude_entity_globs does not override include_entity_globs

2 participants