-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeError: getattr() got an unexpected keyword argument 'class_context' #7109
Comments
Thanks for the report. I can reproduce with import holoviews as hv
selection_linker = (
hv.selection.link_selections.instance()
)
selection_linker()
(Pdb) self
<Instance of param.parameterized.ParameterizedFunction at 0x4534040464>
(Pdb) self._proxied
<Instance of param.parameterized.ParameterizedFunction at 0x4534039552>
(Pdb) self._proxied._proxied
<ClassDef.ParameterizedFunction l.3613 at 0x102dabd30> This trivial diff fixes it, but I don't know whether it's papering over a deeper failure with chained diff --git a/astroid/bases.py b/astroid/bases.py
index a3f2017f..644bb4ed 100644
--- a/astroid/bases.py
+++ b/astroid/bases.py
@@ -303,7 +303,10 @@ class Instance(BaseInstance):
def callable(self):
try:
- self._proxied.getattr("__call__", class_context=False)
+ proxied = self._proxied
+ while isinstance(proxied, Instance):
+ proxied = proxied._proxied
+ proxied.getattr("__call__", class_context=False)
return True
except AttributeInferenceError:
return False Holoviews source: https://github.com/holoviz/holoviews/blob/5ce1e1d774a977f709670def5304bef7213ea6fe/holoviews/selection.py#L296 |
Although that seems to fix the issue I don't think that is the actual fix. class A:
...
A.__new__(A()) The above code will raise a
The following diff --git a/astroid/bases.py b/astroid/bases.py
index a3f2017f3..3d20ba832 100644
--- a/astroid/bases.py
+++ b/astroid/bases.py
@@ -434,6 +434,8 @@ class UnboundMethod(Proxy):
return
node_context = context.extra_context.get(caller.args[0])
+ if caller.lineno == 3644:
+ print(list(caller.args[0].infer(context=node_context)))
infer = caller.args[0].infer(context=node_context)
yield from (Instance(x) if x is not Uninferable else x for x in infer) # type: ignore[misc,arg-type] [<Instance of param.parameterized.ParameterizedFunction at 0x4409978064>] However, by adding <class 'holoviews.core.util.Config'>
<class 'holoviews.core.util.sanitize_identifier_fn'>
<class 'holoviews.core.util.sanitize_identifier_fn'>
<class 'holoviews.core.util.sanitize_identifier_fn'>
<class 'holoviews.core.util.sanitize_identifier_fn'>
<class 'holoviews.selection.link_selections'> This follows the normal assumption that TLDR: Chained As for the fix itself, I have no idea yet and it will likely need to happen somewhere within |
Thank you for digging into the source! 🚀
Sounds like the situation will be improved when we land pylint-dev/astroid#1189, and we can start filtering out inferred values based on constraints (here, the That said, there's still a problem here, right? Because Extending your example: class A:
...
invalid = A.__new__(A())
invalid()
Given that, do you have thoughts about alternatives? |
diff --git a/astroid/bases.py b/astroid/bases.py
index a3f2017f3..2d3d04559 100644
--- a/astroid/bases.py
+++ b/astroid/bases.py
@@ -436,7 +436,7 @@ class UnboundMethod(Proxy):
node_context = context.extra_context.get(caller.args[0])
infer = caller.args[0].infer(context=node_context)
- yield from (Instance(x) if x is not Uninferable else x for x in infer) # type: ignore[misc,arg-type]
+ yield from (Instance(x) if isinstance(x, nodes.ClassDef) else x for x in infer) # type: ignore[misc,arg-type]
def bool_value(self, context=None):
return True This should be a good first start. Not sure if we should also allow |
Yeah, I just came to that conclusion but with |
I'll give it a go. |
Btw, wouldn't it be better to iterate over In both our solutions, if for some reason we end up with |
But correct inference is important -- in my example, the user wrote invalid code, and there's no reason astroid can't infer that correctly. |
Yeah, but shouldn't |
Duh, I forgot we were inside |
I think other paths in the function to return |
I think failing locally and letting callers decide what to do is what we do elsewhere: I'm looking at this diff, and it passes the astroid suite (will check pylint next) diff --git a/astroid/bases.py b/astroid/bases.py
index a3f2017f..91762ef7 100644
--- a/astroid/bases.py
+++ b/astroid/bases.py
@@ -436,7 +436,12 @@ class UnboundMethod(Proxy):
node_context = context.extra_context.get(caller.args[0])
infer = caller.args[0].infer(context=node_context)
- yield from (Instance(x) if x is not Uninferable else x for x in infer) # type: ignore[misc,arg-type]
+ for inferred in infer:
+ if isinstance(inferred, type(Uninferable)): # isinstance helps mypy
+ yield inferred
+ if isinstance(inferred, (nodes.ClassDef, nodes.Lambda, Proxy)):
+ yield Instance(inferred)
+ raise InferenceError
def bool_value(self, context=None):
return True |
Bug description
Linting the below
script.py
file raises an exception.Configuration
Command used
Pylint output
Expected behavior
No error would be raised
Pylint version
OS / Environment
Windows
Additional dependencies
pip install pandas==1.4.2 holoviews==1.14.9 hvplot==0.8.0 pylint==2.14.3 astroid==2.11.6
The text was updated successfully, but these errors were encountered: