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