Skip to content
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

Suggestion: Creation of a dummy placeholder so that mypy doesn't return a "already defined" error when the re-definition is required. #3284

Closed
jcrmatos opened this issue Apr 29, 2017 · 10 comments

Comments

@jcrmatos
Copy link

Hello,

I would like to suggest the creation of a dummy placeholder (eg. AlreadyDefined or some symbol like ! or ...) so that mypy doesn't return a "already defined" error when the re-definition is required.

Here are 2 examples:

row = 0  # type: int
# do some processing with the row var
for row, event in enumerate(events_lst):  # type: int, List[str]
    # do some processing with row and event vars
row = 0  # type: int
# do some processing with the row var
row, event = some_func()  # type: int, List[str]

With the examples code above, mypy tells me that
data_processing.py:144: error: Name 'row' already defined
which is correct, but annoying, because to identify the type of event, I must re-identify row.

I know that I could disable the "already defined" errors with a command line flag, but I would like to receive them except when I have to re-identify some vars due to others, like in the examples above.

Thanks,

JM

@ilevkivskyi
Copy link
Member

Thanks for reporting!

For your case you can write

row = 0  # type: int
# do some processing with the row var
event = None  # type: List[str]
for row, event in enumerate(events_lst):
    # do some processing with row and event vars

For "throw away variables" there are already issues #465 and #1649

@jcrmatos
Copy link
Author

Hello,

Thanks for the solution.

I'll keep the suggestion open.

Best regards,

JM

@jcrmatos
Copy link
Author

Hello,

Tried your solution, but mypy returns this error

data_processing.py:154: error: Incompatible types in assignment (expression has
type None, variable has type List[str])

had to change it to
event = [] # type: List[str]

Thanks,

JM

@gvanrossum
Copy link
Member

@ilevkivskyi @ddfisher The failure from the last comment (presumably with strict optional) seems to be in violation of what PEP 484 says about this...

@ddfisher
Copy link
Collaborator

ddfisher commented May 3, 2017

Yeah, we decided to punt on the implementation of that until mypy had undefined checking. (We discussed this at the time, but that was a while ago now.)

@jcrmatos
Copy link
Author

Hello,

Maybe _ could be the placeholder?

row: int = 0
# do some processing with the row var
row, event = some_func()  # type: int, List[str]

would become this

row: int = 0
# do some processing with the row var
row, event = some_func()  # type: _, List[str]

Thanks,

JM

@thatrandomfrenchdude
Copy link

thatrandomfrenchdude commented Mar 9, 2023

Has there been any update on this issue to provide a placeholder value?

Im getting that same error ('"None" has no attribute cursor') when using a placeholder of None in my init() function that gets redefined in the the connect() function.

Not sure how I can resolve this. Thanks in advance for the help!

import sqlite3

class DB:
    def __init__(self, db_path: str) -> None:
        self.db_path = db_path
        self.conn = None
        self.cursor = None

    def connect(self) -> bool:
        try:
            self.conn = sqlite3.connect(self.db_path) # warning here
            self.conn.row_factory = sqlite3.Row # warning here
            self.cursor = self.conn.cursor() # warning here
            print(f"Connected to database at {self.db_path}")
            return True
        except sqlite3.Error as e:
            print(f"Error connecting to database: {e}")
            return False

@hauntsaninja
Copy link
Collaborator

Add a type hint in __init__, e.g. self.conn = Optional[<connection type>] = None

Closing the original issue since type comments are discouraged and there's no analogue for the above use case in PEP 526

@hauntsaninja hauntsaninja closed this as not planned Won't fix, can't repro, duplicate, stale Mar 9, 2023
@thatrandomfrenchdude
Copy link

Thanks @hauntsaninja !

@thatrandomfrenchdude
Copy link

For anyone coming across this later, this is what I did:

import sqlite3
from typing import Optional


class DB:
    def __init__(self, db_path: str) -> None:
        self.db_path = db_path
        self.conn: Optional[sqlite3.Connection] = None
        self.cursor: Optional[sqlite3.Cursor] = None

    def connect(self) -> bool:
        try:
            self.conn = sqlite3.connect(self.db_path)
            self.conn.row_factory = sqlite3.Row
            self.cursor = self.conn.cursor()
            print(f"Connected to database at {self.db_path}")
            return True
        except sqlite3.Error as e:
            print(f"Error connecting to database: {e}")
            return False

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants