working with typestubs in python

satya - 3/9/2024, 11:53:57 AM

These are now called type hints

These are now called type hints

satya - 3/9/2024, 11:54:05 AM

Type hints and python

Type hints and python

Search for: Type hints and python

satya - 3/9/2024, 11:54:48 AM

Setting up vscode for typing

  1. Install the ubiquitous MS python extension
  2. Go to command: Ctrl-shift-p
  3. Search for "Preferences: work space settings"
  4. Then there search for python.analysis.typeCheckingMode
  5. Set it to "strict"

satya - 3/9/2024, 11:57:04 AM

Between strict and basic

  1. First, do enable them
  2. Basic is ok
  3. I now prefer strict
  4. I recommend start with strict
  5. I have to go back and fix a number of files due to "basic" setting before.
  6. It is a necessary evil
  7. You can work around in a few places by choosing to ignore a line in a file by putting comment to do so
  8. 8. You can also ignore a file as well, if you don't want to spend time fixing it.

satya - 3/9/2024, 12:10:35 PM

Here is how the settings file entry for strict typing based on a project (not workspace)


# in file 
# project/.vscode/settings.json
{
    "python.analysis.typeCheckingMode": "strict"
}

satya - 3/9/2024, 12:12:14 PM

Sometimes pylance grows crazy over types

  1. As you start using libraries, all of them may not specify type hints to their code
  2. This causes problems when you start using strict typing
  3. One example is say you have a dictionary of strings and objects and you are passing to a function that has no type hints
  4. This seem to throw off pylance pretty badly
  5. You can turn this off by typing #type:ignore on that line

satya - 3/9/2024, 12:13:50 PM

An example


def _getFlattenedDictionary(tomlConfigFilename: str) -> dict[str, Any]:
    # Read and parse the toml file
    toml_str = fileutils.read_text_file(tomlConfigFilename)
    parsed_toml: tomlkit.TOMLDocument = tomlkit.parse(toml_str)
    # convert it to json
    json_str: str = json.dumps(parsed_toml,indent=4)
    dict = json.loads(json_str)
    new_dict = _process_dict_for_aliases(dict)


    flat_dict = flatten(new_dict, reducer="dot") #type:ignore
    return flat_dict #type:ignore

satya - 3/9/2024, 12:14:34 PM

In brief: #type:ignore


your line #type:ignore

satya - 3/9/2024, 12:38:13 PM

Some type hints and initialization


# All imports needed for the type hints
from typing import Optional, Union

# Type hint for a list of integers
numbers: list[int] = [1, 2, 3]

# Type hint for a dictionary with string keys and float values
prices: dict[str, float] = {'apple': 0.99, 'banana': 0.59}

# Type hint for a set of strings
fruits: set[str] = {'apple', 'banana', 'cherry'}

satya - 3/9/2024, 12:39:21 PM

Nested collections


# Type hint for a list of dictionaries, 
# each with string keys and integer values

scores: list[dict[str, int]] = 
  [{'math': 90, 'science': 85}, {'math': 92, 'science': 88}]

# Type hint for a dictionary with string keys 
# and lists of floats as values

student_grades: dict[str, list[float]] = 
  {'Alice': [88.5, 92.3, 85.0], 'Bob': [72.5, 81.0, 78.9]}

satya - 3/9/2024, 12:40:39 PM

Some necessary imports


# This is still the case in new python
from typing import Optional, Union

satya - 3/9/2024, 12:40:53 PM

Using them


# Type hint for an optional string (can be a string or None)
optional_name: Optional[str] = None

# Type hint for a variable that can be either an int or a string
mixed_type: Union[int, str] = 42
mixed_type = "forty-two"

satya - 3/9/2024, 12:41:41 PM

Complex examples


# Type hint for a complex nested structure:
# A list of dictionaries with:
# - string keys
# - values that are either a list of integers or a single string

complex_structure: 
   list[dict[str, Union[list[int], str]]] = 

[
    {'numbers': [1, 2, 3], 'name': 'first'},
    {'numbers': [4, 5, 6], 'name': 'second'}
]

satya - 3/9/2024, 11:10:26 PM

Type: The special key word from typing


from typing import Any, Type

var1 = Type[Any]

satya - 3/9/2024, 11:12:10 PM

Observations

  1. The "var1" is of type "Type"
  2. very similar to somelist = list[str] is a "list"
  3. The "Any" is a generic argument to types
  4. This means the type "Type" is generic and that it produces when instantiated an object of type "Any" in this case