iris-hep / func_adl

Construct hierarchical data queries using SQL-like concepts in python
MIT License
8 stars 4 forks source link

Variables in lambdas with identical names in a query #115

Closed alexander-held closed 1 year ago

alexander-held commented 1 year ago

Using func-adl version 3.2.2, the following query works:

ds.Where(lambda e: e.met_e > 25).Select(lambda event: event.jet_pt)

but the same query does no longer work when the variables in both lambdas have the same name:

ds.Where(lambda e: e.met_e > 25).Select(lambda e: e.jet_pt)

raises

ValueError: Found multiple calls to on same line - split the calls across lines or change lambda argument names so they are different.

Splitting across lines does not seem to help, e.g.

ds.Where(lambda e: e.met_e > 25).\
Select(lambda e: e.jet_pt)

similarly crashes.


Reproducer:

from func_adl_uproot import UprootDataset

dataset_opendata = "http://xrootd-local.unl.edu:1094//store/user/AGC/datasets/RunIIFall15MiniAODv2/"\
                   "TT_TuneCUETP8M1_13TeV-powheg-pythia8/MINIAODSIM//PU25nsData2015v1_76X_mcRun2_"\
                   "asymptotic_v12_ext3-v1/00000/00DF0A73-17C2-E511-B086-E41D2D08DE30.root"
ds = UprootDataset(dataset_opendata, "events")
jet_pt_query = ds.Where(lambda e: e.met_e > 25).Select(lambda ev: ev.jet_pt)
print(jet_pt_query.value())

I used func-adl-uproot version 1.10.0. Full traceback:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [25], in <cell line: 6>()
      3 dataset_opendata = "http://xrootd-local.unl.edu:1094//store/user/AGC/datasets/RunIIFall15MiniAODv2/TT_TuneCUETP8M1_13TeV-powheg-pythia8/"\
      4                    "MINIAODSIM//PU25nsData2015v1_76X_mcRun2_asymptotic_v12_ext3-v1/00000/00DF0A73-17C2-E511-B086-E41D2D08DE30.root"
      5 ds = UprootDataset(dataset_opendata, "events")
----> 6 jet_pt_query = ds.Where(lambda e: e.met_e > 25).Select(lambda e: e.jet_pt)
      7 print(jet_pt_query.value())

File /opt/conda/lib/python3.8/site-packages/func_adl/object_stream.py:163, in ObjectStream.Where(self, filter)
    145 r"""
    146 Filter the object stream, allowing only items for which `filter` evaluates as true through.
    147 
   (...)
    158       contains a lambda definition, or a python `ast` of type `ast.Lambda`.
    159 """
    160 from func_adl.type_based_replacement import remap_from_lambda
    162 n_stream, n_ast, rtn_type = remap_from_lambda(
--> 163     self, _local_simplification(parse_as_ast(filter))
    164 )
    165 if rtn_type != bool:
    166     raise ValueError(f"The Where filter must return a boolean (not {rtn_type})")

File /opt/conda/lib/python3.8/site-packages/func_adl/util_ast.py:683, in parse_as_ast(ast_source, caller_name)
    664 r"""Return an AST for a lambda function from several sources.
    665 
    666 We are handed one of several things:
   (...)
    680     An ast starting from the Lambda AST node.
    681 """
    682 if callable(ast_source):
--> 683     src_ast = _parse_source_for_lambda(ast_source, caller_name)
    684     if not src_ast:
    685         # This most often happens in a notebook when the lambda is defined in a funny place
    686         # and can't be recovered.
    687         raise ValueError(f"Unable to recover source for function {ast_source}.")

File /opt/conda/lib/python3.8/site-packages/func_adl/util_ast.py:649, in _parse_source_for_lambda(ast_source, caller_name)
    644         raise ValueError(
    645             f"Internal Error - Found no lambda in source with the arguments {caller_arg_list}"
    646         )
    648     if len(good_lambdas) > 1:
--> 649         raise ValueError(
    650             "Found multiple calls to on same line"
    651             + ("" if caller_name is None else f" for {caller_name}")
    652             + " - split the calls across "
    653             "lines or change lambda argument names so they are different."
    654         )
    656     lda = good_lambdas[0]
    658 return lda

ValueError: Found multiple calls to on same line - split the calls across lines or change lambda argument names so they are different.
gordonwatts commented 1 year ago

Easy to repro this bug...