Skip to content

IMP: recognize type-mapped Bool variables as Bool variables#401

Open
colinvwood wants to merge 1 commit into
qiime2:devfrom
colinvwood:recognize-typemapped-bool
Open

IMP: recognize type-mapped Bool variables as Bool variables#401
colinvwood wants to merge 1 commit into
qiime2:devfrom
colinvwood:recognize-typemapped-bool

Conversation

@colinvwood

Copy link
Copy Markdown
Contributor

Description

Fixes an issue where type-mapped Bool variables were not recognized as Bools and rendering on the cli fell back to the standard --p-param VALUE format.

AI Disclosure

  • NO AI USED.
  • AI USED.

AI Usage Details

Generated by Codex while working on qiime2/q2-dada2#190

@colinvwood

Copy link
Copy Markdown
Contributor Author

Needed by qiime2/q2-dada2#190

@colinvwood colinvwood self-assigned this Jun 15, 2026
@ebolyen ebolyen assigned ebolyen and unassigned colinvwood Jun 16, 2026

@ebolyen ebolyen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you actually need this PR for what you wanted to do, but I have no objection to making it so that TypeVar where all branches are Bool is treated the same as Bool % TypeVar.

Comment thread q2cli/core/state.py
def _is_bool_ast(ast):
if ast['type'] == 'expression':
return ast['name'] == 'Bool'
if ast['type'] == 'variable':

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branch isn't actually tested I think because bool-flag-swaps-output-method uses:
Bool % (Choices(True)¹ | Choices(False)²)
instead of
Bool % Choices(True)¹ | Bool % Choices(False)²

Which means that the name of the first type is still just "Bool" which worked before I think. This maybe also suggests that the DADA2 PR can just lift the annotation up to the predicate instead and q2cli will do what you want.

Comment thread q2cli/core/state.py
return multiple, is_bool_flag, metadata


def _is_bool_ast(ast):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would drop the ast bit and call to_ast() inside the method.

Comment thread q2cli/core/state.py
return ast['name'] == 'Bool'
if ast['type'] == 'variable':
index = ast['index']
return all(_is_bool_ast(row[index]) for row in ast['mapping'])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense, and I think the AST is actually the easier way to work this out. I checked if it would be reasonable to just use the type's own fields, but they are annoying in this case.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just kidding, we can do this instead:

def _is_bool(type_expr):
    return all(x.name == 'Bool' for x in type_expr) and not type_expr.is_bottom()

__iter__ is a fancy way to get project Union/TypeVars into iterables (I think this makes it a kind of homomorphism over the two monoids) which work on base types as well as higher-level constructs:

In [5]: T
Out[5]: Bool % Choices(False| Bool % Choices(TrueIn [6]: list(T)
Out[6]: [Bool % Choices(False), Bool % Choices(True)]

In [7]: list(Bool)
Out[7]: [Bool]

The is_bottom() check avoids all([]) from being trivially boolean.

@ebolyen ebolyen assigned colinvwood and unassigned ebolyen Jun 17, 2026
@colinvwood

Copy link
Copy Markdown
Contributor Author

What's your preference re keeping this? Indeed your changes in q2-dada2 got me to the same place.

@ebolyen

ebolyen commented Jun 19, 2026

Copy link
Copy Markdown
Member

I think there's no harm in making this work. I guess the only difficulty is testing and if it's worth adding another action to dummy_plugin for it.

I'm also fine with putting it on the back-burner. There are perhaps other ways to handle this directly, such as distributing the TypeVar branches over the predicate so that it just always normalizes. Although it may be tricky to ensure that it still looks correct at different call-sites.

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.

3 participants