diff options
author | CoprDistGit <infra@openeuler.org> | 2023-05-10 08:30:50 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-05-10 08:30:50 +0000 |
commit | fe3f283539bfa6c97d0b9cdcc0b5dc2ca3b10b8f (patch) | |
tree | e67bd1f0481e12689d421b9dd632b007fa399c39 | |
parent | ccea522f7434c600f13e86a97b43b865adaeab57 (diff) |
automatic import of python-func-adl
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-func-adl.spec | 414 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 416 insertions, 0 deletions
@@ -0,0 +1 @@ +/func_adl-3.2.4.tar.gz diff --git a/python-func-adl.spec b/python-func-adl.spec new file mode 100644 index 0000000..531459d --- /dev/null +++ b/python-func-adl.spec @@ -0,0 +1,414 @@ +%global _empty_manifest_terminate_build 0 +Name: python-func-adl +Version: 3.2.4 +Release: 1 +Summary: Functional Analysis Description Language Base Package +License: MIT +URL: https://github.com/iris-hep/func_adl +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/aa/19/25d76b27b00eb979aca9b829ff75efc1045b9349ee98ce2e1fb1ebb4674f/func_adl-3.2.4.tar.gz +BuildArch: noarch + +Requires: python3-make-it-sync +Requires: python3-astunparse +Requires: python3-black +Requires: python3-coverage +Requires: python3-flake8 +Requires: python3-isort +Requires: python3-pytest +Requires: python3-pytest-asyncio +Requires: python3-pytest-cov +Requires: python3-twine +Requires: python3-wheel +Requires: python3-pytest +Requires: python3-pytest-asyncio +Requires: python3-pytest-cov +Requires: python3-flake8 +Requires: python3-coverage +Requires: python3-twine +Requires: python3-wheel +Requires: python3-astunparse +Requires: python3-black +Requires: python3-isort + +%description +|List Comprehension | `[j.pt() for j in jets]` | `jets.Select(lambda j: j.pt())` | +|List Comprehension | `[j.pt() for j in jets if abs(j.eta()) < 2.4]` | `jets.Where(lambda j: abs(j.eta()) < 2.4).Select(lambda j: j.pt())` | +|List Comprehension | `[j.pt()+e.pt() for j in jets for e in electrons]` | `jets.Select(lambda j: electrons.Select(lambda e: j.pt()+e.pt())` | +Note: Everything that goes for a list comprehension also goes for a generator expression. +## Extensibility +There are two several extensibility points: +- `EventDataset` should be sub-classed to provide an executor. +- `EventDataset` can use Python's type hinting system to allow for editors and other intelligent typing systems to type check expressions. The more type data present, the more the system can help. +- Define a function that can be called inside a LINQ expression +- Define new stream methods +- It is possible to insert a call back at a function or method call site that will allow for modification of the `ObjectStream` or the call site's `ast`. +### EventDataSet +An example `EventDataSet`: +```python +class events(EventDataset): + async def execute_result_async(self, a: ast.AST, title: Optional[str] = None): + await asyncio.sleep(0.01) + return a +``` +and some `func_adl` code that uses it: +```python +r = (events() + .SelectMany(lambda e: e.Jets('jets')) + .Select(lambda j: j.eta()) + .value()) +``` +- When the `.value()` method is invoked, the `execute_result_async` with a complete `ast` representing the query is called. This is the point that one would send it to the backend to actually be processed. +- Normally, the constructor of `events` would take in the name of the dataset to be processed, which could then be used in `execute_result_async`. +### Typing EventDataset +A minor change to the declaration above, and no change to the query: +```python +class dd_jet: + def pt(self) -> float: + def eta(self) -> float: +class dd_event: + def Jets(self, bank: str) -> Iterable[dd_jet]: + def EventNumber(self, bank='default') -> int +class events(EventDataset[dd_event]): + async def execute_result_async(self, a: ast.AST, title: Optional[str] = None): + await asyncio.sleep(0.01) + return a +``` +This is not required, but when this is done: +- Editors that use types to give one a list of options/guesses will now light up as long as they have reasonable type-checking built in. +- If a required argument is missed, an error will be generated +- If a default argument is missed, it will be automatically filled in. +It should be noted that the type and expression follower is not very sophisticated! While it can follow method calls, it won't follow much else! +The code should work find in python 3.11 or if `from __future__ import annotations` is used. +### Type-based callbacks +By adding a function and a reference in the type system, arbitrary code can be executed during the traversing of the `func_adl`. Keeping the query the same and the `events` definition the same, we can add the info directly to the python type declarations using a decorator for a class definition: +```python +from func_adl import ObjectStream +from typing import TypeVar +# Generic type is required in order to preserve type checkers ability to see +# changes in the type +T = TypeVar('T') +def add_md_for_type(s: ObjectStream[T], a: ast.Call) -> Tuple[ObjectStream[T], ast.AST]: + return s.MetaData({'hi': 'there'}), a +@func_adl_callback(add_md_for_type) +class dd_event: + def Jets(self, bank: str) -> Iterable[dd_jet]: +``` +- When the `.Jets()` method is processed, the `add_md_for_type` is called with the current object stream and the ast. +- `add_md_for_type` here adds metadata and returns the updated stream and ast. +- Nothing prevents the function from parsing the AST, removing or adding arguments, adding more complex metadata, or doing any of this depending on the arguments in the call site. +### Parameterized method calls +These are a very special form of callback that were implemented to support things like inter-op for templates in C++. It allows you to write something like: +```python +result = (ds + .SelectMany(lambda e: e.Jets()) + .Select(lambda j: j.getAttribute[float]('moment0')) + .AsAwkward('moment0') +) +``` +Note the `[float]` in the call to `getAttribute`. This can only happen if the property `getAttribute` in the `Jet` class is marked with the decorator `func_adl_parameterized_call`: +```python +T = TypeVar('T') +def my_callback(s: ObjectStream[T], a: ast.Call, param_1) -> Tuple[ObjectStream[T], ast.AST, Type]: +class Jet: + @func_adl_parameterized_call() + @property + def getAttribute(self): +``` +Here, `param_1` will be called with set to `float`. Note that this means at the time when this is called the parameterized values must resolve to an actual value - they aren't converted to C++. In this case, the `my_callback` could inject `MetaData` to build a templated call to `getAttribute`. The tuple that `my_callback` returns is the same as for `add_md_for_type` above - except that the third parameter must return the return type of the call. +If more than one argument is used (`j.getAttribute['float','int'])['moment0']`), then `param_1` is a tuple with two items. +### Function Definitions +It is useful to have functions that can be called in the backend directly - or use a function call to artificially insert something into the `func_adl` query stream (like `MetaData`). For example, the C++ backend +uses this to insert inline-C++ code. The `func_adl_callable` decorator is used to do this: +```python +def MySqrtProcessor(s: ObjectStream[T], a: ast.Call) -> Tuple[ObjectStream[T], ast.Call]: + 'Can add items to the object stream' + new_s = s.MetaData({'j': 'func_stuff'}) + return new_s, a +# Declare the typing and name of the function to func_adl +@func_adl_callable(MySqrtProcessor) +def MySqrt(x: float) -> float: +r = (events() + .SelectMany(lambda e: e.Jets('jets')) + .Select(lambda j: MySqrt(j.eta())) + .value()) +``` +In the above sample, the call to `MySqrt` will be passed back to the backend. However, the `MetaData` will be inserted into the stream before the call. One can use C++ do define the `MySqrt` function (or similar). +Note that if `MySqrt` is defined always in the backend with no additional data needed, one can skip the `MySqrtProcessor` in the decorator call. +### Adding new Collection API's +Functions like `First` should not be present in `ObjectStream` as that is the top level set of definitions. However, inside the event context, they make a lot of sense. The type following code needs a way to track these (the type hint system needs no modification, just declare your collections in your `Event` object appropriately). +For examples, see the `test_type_based_replacement` file. The class-level decorator is called `register_func_adl_os_collection`. +## Development +After a new release has been built and passes the tests you can release it by creating a new release on `github`. An action that runs when a release is "created" will send it to `pypi`. + +%package -n python3-func-adl +Summary: Functional Analysis Description Language Base Package +Provides: python-func-adl +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-func-adl +|List Comprehension | `[j.pt() for j in jets]` | `jets.Select(lambda j: j.pt())` | +|List Comprehension | `[j.pt() for j in jets if abs(j.eta()) < 2.4]` | `jets.Where(lambda j: abs(j.eta()) < 2.4).Select(lambda j: j.pt())` | +|List Comprehension | `[j.pt()+e.pt() for j in jets for e in electrons]` | `jets.Select(lambda j: electrons.Select(lambda e: j.pt()+e.pt())` | +Note: Everything that goes for a list comprehension also goes for a generator expression. +## Extensibility +There are two several extensibility points: +- `EventDataset` should be sub-classed to provide an executor. +- `EventDataset` can use Python's type hinting system to allow for editors and other intelligent typing systems to type check expressions. The more type data present, the more the system can help. +- Define a function that can be called inside a LINQ expression +- Define new stream methods +- It is possible to insert a call back at a function or method call site that will allow for modification of the `ObjectStream` or the call site's `ast`. +### EventDataSet +An example `EventDataSet`: +```python +class events(EventDataset): + async def execute_result_async(self, a: ast.AST, title: Optional[str] = None): + await asyncio.sleep(0.01) + return a +``` +and some `func_adl` code that uses it: +```python +r = (events() + .SelectMany(lambda e: e.Jets('jets')) + .Select(lambda j: j.eta()) + .value()) +``` +- When the `.value()` method is invoked, the `execute_result_async` with a complete `ast` representing the query is called. This is the point that one would send it to the backend to actually be processed. +- Normally, the constructor of `events` would take in the name of the dataset to be processed, which could then be used in `execute_result_async`. +### Typing EventDataset +A minor change to the declaration above, and no change to the query: +```python +class dd_jet: + def pt(self) -> float: + def eta(self) -> float: +class dd_event: + def Jets(self, bank: str) -> Iterable[dd_jet]: + def EventNumber(self, bank='default') -> int +class events(EventDataset[dd_event]): + async def execute_result_async(self, a: ast.AST, title: Optional[str] = None): + await asyncio.sleep(0.01) + return a +``` +This is not required, but when this is done: +- Editors that use types to give one a list of options/guesses will now light up as long as they have reasonable type-checking built in. +- If a required argument is missed, an error will be generated +- If a default argument is missed, it will be automatically filled in. +It should be noted that the type and expression follower is not very sophisticated! While it can follow method calls, it won't follow much else! +The code should work find in python 3.11 or if `from __future__ import annotations` is used. +### Type-based callbacks +By adding a function and a reference in the type system, arbitrary code can be executed during the traversing of the `func_adl`. Keeping the query the same and the `events` definition the same, we can add the info directly to the python type declarations using a decorator for a class definition: +```python +from func_adl import ObjectStream +from typing import TypeVar +# Generic type is required in order to preserve type checkers ability to see +# changes in the type +T = TypeVar('T') +def add_md_for_type(s: ObjectStream[T], a: ast.Call) -> Tuple[ObjectStream[T], ast.AST]: + return s.MetaData({'hi': 'there'}), a +@func_adl_callback(add_md_for_type) +class dd_event: + def Jets(self, bank: str) -> Iterable[dd_jet]: +``` +- When the `.Jets()` method is processed, the `add_md_for_type` is called with the current object stream and the ast. +- `add_md_for_type` here adds metadata and returns the updated stream and ast. +- Nothing prevents the function from parsing the AST, removing or adding arguments, adding more complex metadata, or doing any of this depending on the arguments in the call site. +### Parameterized method calls +These are a very special form of callback that were implemented to support things like inter-op for templates in C++. It allows you to write something like: +```python +result = (ds + .SelectMany(lambda e: e.Jets()) + .Select(lambda j: j.getAttribute[float]('moment0')) + .AsAwkward('moment0') +) +``` +Note the `[float]` in the call to `getAttribute`. This can only happen if the property `getAttribute` in the `Jet` class is marked with the decorator `func_adl_parameterized_call`: +```python +T = TypeVar('T') +def my_callback(s: ObjectStream[T], a: ast.Call, param_1) -> Tuple[ObjectStream[T], ast.AST, Type]: +class Jet: + @func_adl_parameterized_call() + @property + def getAttribute(self): +``` +Here, `param_1` will be called with set to `float`. Note that this means at the time when this is called the parameterized values must resolve to an actual value - they aren't converted to C++. In this case, the `my_callback` could inject `MetaData` to build a templated call to `getAttribute`. The tuple that `my_callback` returns is the same as for `add_md_for_type` above - except that the third parameter must return the return type of the call. +If more than one argument is used (`j.getAttribute['float','int'])['moment0']`), then `param_1` is a tuple with two items. +### Function Definitions +It is useful to have functions that can be called in the backend directly - or use a function call to artificially insert something into the `func_adl` query stream (like `MetaData`). For example, the C++ backend +uses this to insert inline-C++ code. The `func_adl_callable` decorator is used to do this: +```python +def MySqrtProcessor(s: ObjectStream[T], a: ast.Call) -> Tuple[ObjectStream[T], ast.Call]: + 'Can add items to the object stream' + new_s = s.MetaData({'j': 'func_stuff'}) + return new_s, a +# Declare the typing and name of the function to func_adl +@func_adl_callable(MySqrtProcessor) +def MySqrt(x: float) -> float: +r = (events() + .SelectMany(lambda e: e.Jets('jets')) + .Select(lambda j: MySqrt(j.eta())) + .value()) +``` +In the above sample, the call to `MySqrt` will be passed back to the backend. However, the `MetaData` will be inserted into the stream before the call. One can use C++ do define the `MySqrt` function (or similar). +Note that if `MySqrt` is defined always in the backend with no additional data needed, one can skip the `MySqrtProcessor` in the decorator call. +### Adding new Collection API's +Functions like `First` should not be present in `ObjectStream` as that is the top level set of definitions. However, inside the event context, they make a lot of sense. The type following code needs a way to track these (the type hint system needs no modification, just declare your collections in your `Event` object appropriately). +For examples, see the `test_type_based_replacement` file. The class-level decorator is called `register_func_adl_os_collection`. +## Development +After a new release has been built and passes the tests you can release it by creating a new release on `github`. An action that runs when a release is "created" will send it to `pypi`. + +%package help +Summary: Development documents and examples for func-adl +Provides: python3-func-adl-doc +%description help +|List Comprehension | `[j.pt() for j in jets]` | `jets.Select(lambda j: j.pt())` | +|List Comprehension | `[j.pt() for j in jets if abs(j.eta()) < 2.4]` | `jets.Where(lambda j: abs(j.eta()) < 2.4).Select(lambda j: j.pt())` | +|List Comprehension | `[j.pt()+e.pt() for j in jets for e in electrons]` | `jets.Select(lambda j: electrons.Select(lambda e: j.pt()+e.pt())` | +Note: Everything that goes for a list comprehension also goes for a generator expression. +## Extensibility +There are two several extensibility points: +- `EventDataset` should be sub-classed to provide an executor. +- `EventDataset` can use Python's type hinting system to allow for editors and other intelligent typing systems to type check expressions. The more type data present, the more the system can help. +- Define a function that can be called inside a LINQ expression +- Define new stream methods +- It is possible to insert a call back at a function or method call site that will allow for modification of the `ObjectStream` or the call site's `ast`. +### EventDataSet +An example `EventDataSet`: +```python +class events(EventDataset): + async def execute_result_async(self, a: ast.AST, title: Optional[str] = None): + await asyncio.sleep(0.01) + return a +``` +and some `func_adl` code that uses it: +```python +r = (events() + .SelectMany(lambda e: e.Jets('jets')) + .Select(lambda j: j.eta()) + .value()) +``` +- When the `.value()` method is invoked, the `execute_result_async` with a complete `ast` representing the query is called. This is the point that one would send it to the backend to actually be processed. +- Normally, the constructor of `events` would take in the name of the dataset to be processed, which could then be used in `execute_result_async`. +### Typing EventDataset +A minor change to the declaration above, and no change to the query: +```python +class dd_jet: + def pt(self) -> float: + def eta(self) -> float: +class dd_event: + def Jets(self, bank: str) -> Iterable[dd_jet]: + def EventNumber(self, bank='default') -> int +class events(EventDataset[dd_event]): + async def execute_result_async(self, a: ast.AST, title: Optional[str] = None): + await asyncio.sleep(0.01) + return a +``` +This is not required, but when this is done: +- Editors that use types to give one a list of options/guesses will now light up as long as they have reasonable type-checking built in. +- If a required argument is missed, an error will be generated +- If a default argument is missed, it will be automatically filled in. +It should be noted that the type and expression follower is not very sophisticated! While it can follow method calls, it won't follow much else! +The code should work find in python 3.11 or if `from __future__ import annotations` is used. +### Type-based callbacks +By adding a function and a reference in the type system, arbitrary code can be executed during the traversing of the `func_adl`. Keeping the query the same and the `events` definition the same, we can add the info directly to the python type declarations using a decorator for a class definition: +```python +from func_adl import ObjectStream +from typing import TypeVar +# Generic type is required in order to preserve type checkers ability to see +# changes in the type +T = TypeVar('T') +def add_md_for_type(s: ObjectStream[T], a: ast.Call) -> Tuple[ObjectStream[T], ast.AST]: + return s.MetaData({'hi': 'there'}), a +@func_adl_callback(add_md_for_type) +class dd_event: + def Jets(self, bank: str) -> Iterable[dd_jet]: +``` +- When the `.Jets()` method is processed, the `add_md_for_type` is called with the current object stream and the ast. +- `add_md_for_type` here adds metadata and returns the updated stream and ast. +- Nothing prevents the function from parsing the AST, removing or adding arguments, adding more complex metadata, or doing any of this depending on the arguments in the call site. +### Parameterized method calls +These are a very special form of callback that were implemented to support things like inter-op for templates in C++. It allows you to write something like: +```python +result = (ds + .SelectMany(lambda e: e.Jets()) + .Select(lambda j: j.getAttribute[float]('moment0')) + .AsAwkward('moment0') +) +``` +Note the `[float]` in the call to `getAttribute`. This can only happen if the property `getAttribute` in the `Jet` class is marked with the decorator `func_adl_parameterized_call`: +```python +T = TypeVar('T') +def my_callback(s: ObjectStream[T], a: ast.Call, param_1) -> Tuple[ObjectStream[T], ast.AST, Type]: +class Jet: + @func_adl_parameterized_call() + @property + def getAttribute(self): +``` +Here, `param_1` will be called with set to `float`. Note that this means at the time when this is called the parameterized values must resolve to an actual value - they aren't converted to C++. In this case, the `my_callback` could inject `MetaData` to build a templated call to `getAttribute`. The tuple that `my_callback` returns is the same as for `add_md_for_type` above - except that the third parameter must return the return type of the call. +If more than one argument is used (`j.getAttribute['float','int'])['moment0']`), then `param_1` is a tuple with two items. +### Function Definitions +It is useful to have functions that can be called in the backend directly - or use a function call to artificially insert something into the `func_adl` query stream (like `MetaData`). For example, the C++ backend +uses this to insert inline-C++ code. The `func_adl_callable` decorator is used to do this: +```python +def MySqrtProcessor(s: ObjectStream[T], a: ast.Call) -> Tuple[ObjectStream[T], ast.Call]: + 'Can add items to the object stream' + new_s = s.MetaData({'j': 'func_stuff'}) + return new_s, a +# Declare the typing and name of the function to func_adl +@func_adl_callable(MySqrtProcessor) +def MySqrt(x: float) -> float: +r = (events() + .SelectMany(lambda e: e.Jets('jets')) + .Select(lambda j: MySqrt(j.eta())) + .value()) +``` +In the above sample, the call to `MySqrt` will be passed back to the backend. However, the `MetaData` will be inserted into the stream before the call. One can use C++ do define the `MySqrt` function (or similar). +Note that if `MySqrt` is defined always in the backend with no additional data needed, one can skip the `MySqrtProcessor` in the decorator call. +### Adding new Collection API's +Functions like `First` should not be present in `ObjectStream` as that is the top level set of definitions. However, inside the event context, they make a lot of sense. The type following code needs a way to track these (the type hint system needs no modification, just declare your collections in your `Event` object appropriately). +For examples, see the `test_type_based_replacement` file. The class-level decorator is called `register_func_adl_os_collection`. +## Development +After a new release has been built and passes the tests you can release it by creating a new release on `github`. An action that runs when a release is "created" will send it to `pypi`. + +%prep +%autosetup -n func-adl-3.2.4 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-func-adl -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Wed May 10 2023 Python_Bot <Python_Bot@openeuler.org> - 3.2.4-1 +- Package Spec generated @@ -0,0 +1 @@ +f77bc11d51a2ddce5db74dcbc7915ace func_adl-3.2.4.tar.gz |