if hasattr(obj, ‘foo’):
does that get caught or not? if hasattr(obj, ‘foo’):
does that get caught or not? attr = "foo" if conditionA else "bar"
obj = A() if conditionB else B()
if hasattr(obj, attr):
...
Because of this, Bowler is focused on being more practical, and leans on the expectation that an engineer will be in the loop and validate the resulting diff, run unit tests, etc. if ConditionA:
attr = "foo"
else:
attr = "bar"
if ConditionB:
obj = A()
else:
obj = B()
if hasattr(attr, obj):
do_magic()
I haven't tested Bowler yet but I would think something that refactors code would handle that pretty easily? hasattr = lambda *args: False`
or something equally insane and difficult to statically analyse> Eg if I rename a method and elsewhere have `if hasattr(obj, ‘foo’):`
Further, even in the absence of insane dynamic code, it probably isn't possible to automatically make a correct decision without knowing the intent of the original code.
For example, maybe we're renaming the `foo` method of `Fizz` class to `barr`, and currently the program is written such that `is hasattr(obj, 'foo'):` only happens to be called on `Fizz` instances. Is it the case that the programmer only ever intended that code to be called on `Fizz` instances, or did the programmer intend it should operate on all types that have a `foo` attribute, including old-style `Fizz` instances and new types that might be encountered in future? In the former case, we should rewrite the logic to `hasattr(obj, 'barr')`, in the latter case perhaps we should leave it unchanged, so it will no longer trigger after the refactor.
i do agree it should be possible to automatically flag this as "here be something interesting to consider! please intervene and make a manual decision!"
Nope. Something that refactors code could potentially identify that as an ambiguous case reliably, but it's impossible to statically refactor code of that sort in the general case. Without external/runtime behavior verification/specification, that is.
That was Python syntax.
Python 3.6.6 (tags/v3.6.6:4cf1f54eb7, Jul 6 2018, 15:35:19)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> conditionA = True
>>> attr = "foo" if conditionA else "bar"
>>> print(attr)
foo
>>> conditionA = False
>>> attr = "foo" if conditionA else "bar"
>>> print(attr)
bar
>>>