Xaphanius
Xaphanius

Reputation: 629

How to type hint a class not exposed by a module

I am using a module called pyathena in my code, and I have a function that receives a pyathena connection:

import pyathena

def fn(conn) -> None:
    <DO SOMETHING>

conn = pyathena.connect(s3_staging_dir=f's3://<THE_BUCKET>/', region_name=<REGION>)

fn(conn)

I would like to type hint the conn parameter of fn.

I know that conn is of type pyathena.connection.Connection, but doing

def fn(conn: pyathena.connection.Connection) -> None:
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

doesn't work: AttributeError: module 'pyathena' has no attribute 'connection'.

Doing

from pyathena.connection import Connection

def fn(conn: Connection):
    ...

seems to work well, but I don't want to expose this Connection class in my code, other than to do the type hinting.

Q: Is there a way to type hint this unexposed class in my code without having to import as I did above?

Useful reference: https://github.com/laughingman7743/PyAthena/blob/master/pyathena/init.py

Upvotes: 0

Views: 880

Answers (2)

chepner
chepner

Reputation: 532218

Use deferred annotations:

from __future__ import annotations
import pyathena


def fn(conn: pyathena.connection.Connection) -> None:
    ...

The annotation is effectively treated as a string literal. If you feel like that compromises type safety too much (because you could misspell the type, for instance), you can use typing.TYPE_CHECKING instead.

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from pyathena.connection import Connection
else:
    Connection = '...'


def fn(conn: Connection) -> None:
    ...

Upvotes: 2

Lord Elrond
Lord Elrond

Reputation: 16062

How about an alias?

from pyathena.connection import Connection as _Con

def fn(conn: _Con):
    ...

Upvotes: 1

Related Questions