| 827 | return (expr for expr in self.walk() if isinstance(expr, operation)) |
| 828 | |
| 829 | def __getattr__(self, key): |
| 830 | try: |
| 831 | return object.__getattribute__(self, key) |
| 832 | except AttributeError as err: |
| 833 | if key.startswith("_meta"): |
| 834 | # Avoid a recursive loop if/when `self._meta*` |
| 835 | # produces an `AttributeError` |
| 836 | raise RuntimeError( |
| 837 | f"Failed to generate metadata for {self}. " |
| 838 | "This operation may not be supported by the current backend." |
| 839 | ) |
| 840 | |
| 841 | # Allow operands to be accessed as attributes |
| 842 | # as long as the keys are not already reserved |
| 843 | # by existing methods/properties |
| 844 | _parameters = type(self)._parameters |
| 845 | if key in _parameters: |
| 846 | idx = _parameters.index(key) |
| 847 | return self.operands[idx] |
| 848 | |
| 849 | raise AttributeError( |
| 850 | f"{err}\n\n" |
| 851 | "This often means that you are attempting to use an unsupported " |
| 852 | f"API function.." |
| 853 | ) |
| 854 | |
| 855 | |
| 856 | class SingletonExpr(Expr): |