Inconsistent Type Interpretation

So, I have an object with the member `monitor_df`, and it is typed through the parameter that is assigned to it during the `__init__()`

It is typed as `Optional[pd.DataFrame]`, so it can be either `None` (the default) or be a `pd.DataFrame`.

Later I have this code:

Notice that the code interpreter can not resolve the `to_html()` method.  When I put my cursor on the that method, the problem reported in the message bar on the bottom left of PyCharm is "Cannot find reference 'to_html' in 'None'."

So, ok, the interpreter is using the `None` instead of the `pd.DataFrame` interpretation of the type of the variable.

However,  in the line above it, a parallel construct calls `self.monitor_df.to_string()` without complaint, a method I believe is not implemented on `None` but implemented on `pd.DataFrame`.

Why is the `self.monitor_df` being interpreted to having one type on the first line and a different one on the following line of code?

Any guesses?



Hi, could you provide textual code sample to reproduce the issue?


I will provide almost the same example that I gave you a screen shot of before.  Of course, this example will not be designed to run, as the problem is in the type interpretation in PyCharm.  The example I will upload looks like this in the editor:

Note that the `to_html()` only reports an issue in its use at line 27.  It's use in line 20 causes no such complaints.   The member variable `self.monitor_df` should be interpreted the same no matter what, yes?

Also note, that this demo program has never been run, nor is it designed to be run.  Simply an example to show how the editor is implying types inconsistently.  

I can't find a way to attach the python file to this issue.  Please advise and I will upload the file.  





Here is the text of the example for you:




__author__ = 'eb'

from typing import Tuple

import pandas as pd

class DemoTypeInterpretationBug(object):

def __init__(self, monitor_df: pd.DataFrame) -> None:
self.monitor_df = monitor_df

def example(self):
label1 = "Test" if False else self.monitor_df.to_string()
label2 = "Test" if False else self.monitor_df.to_html().replace("foo", "bar")
print(f"{label1} {label2}")

def get_message(self, host_name: str, signatory: str, now: pd.Timestamp) -> Tuple[str, str]:
table = f" - No Nominal Statistics Available -" \
if self.monitor_df is None else self.monitor_df.to_string()
table_html = f"<I>No Nominal Statistics Available</I>" \
if self.monitor_df is None else self.monitor_df.to_html().replace('<table', '<table id="indicators"')

return table, table_html



Hi, thank you for the example. I have simplified it and created a bug report:

Please follow the issue for updates. If you think the minimal example doesn't describe the issue well enough, let me know.


Bug report looks perfect.  Thanks.


Please sign in to leave a comment.