Python Forum
meaning of -> syntax in function definition - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: meaning of -> syntax in function definition (/thread-36884.html)



meaning of -> syntax in function definition - DrakeSoft - Apr-08-2022

Hi,

I came across the following function:

def getWords(self) -> list[str]:
     with open(self.word_list_path, "r") as f:
        word_list = [line.strip() for line in f]
      return word_list

class Ui_MainWindow(QMainWindow):
 def __init__(self, word_list_path: str):
     super().__init__()
     self.word_list_path = word_list_path
     self.speller = SpellCheckWrapper(self.getWords(), self.addToDictionary)
     self.setupUi()

class SpellCheckWrapper:
    def __init__(
        self, personal_word_list: list[str], addToDictionary: Callable[[str], None]
    ):
        # Creating temporary file
        self.file = QTemporaryFile()
        self.file.open()
        self.dictionary = DictWithPWL(
            "en_US",
          .......
I am not familiar with the notation "def getWords(self) -> list[str]:" in the function definition. What does the -> mean?
Also when I invoke the file with python3 I get an error on the line:

self.speller = SpellCheckWrapper(self.getWords(), self.addToDictionary)
TypeError: 'type' object is not subscriptable

Could someone explain or provide some context for the use of -> and the error I see?


RE: meaning of -> syntax in function definition - deanhystad - Apr-08-2022

The "->" is part of the relatively new (version 3.5) Python type annotations. Think of type annotations as a way to document variable and function return types. An annotation standard allows development of code checking tools and documentation tools. Annotations do not change how Python runs the code. I would change "->list[str]" to "->List[str]", but this is not going to cause an errors.

Everything you 'd ever want to know about type annotations:
https://docs.python.org/3/library/typing.html
https://peps.python.org/pep-0484/
https://peps.python.org/pep-0483/

The annotations are not causing your error. I cannot help you because that is the only thing I know about your error. When you have an error please post the entire error message including the traceback. I would also like to see more complete code. This instruction is not correct for the code you have posed:
self.speller = SpellCheckWrapper(self.getWords(), self.addToDictionary)
According to this line, getWords() is a method of Ui_MainWindow, but it does not look like that in your posted code.


RE: meaning of -> syntax in function definition - Yoriz - Apr-08-2022

If you are using a version older than 3.9 you would need to import List from the typing module
from typing import List

def getWords(self) -> List[str]:
    ....

From version python 3.9 you can use the built-in list as a type hint.
def getWords(self) -> list[str]:
    ....
https://docs.python.org/3.9/whatsnew/3.9.html#type-hinting-generics-in-standard-collections Wrote:Type Hinting Generics in Standard Collections
In type annotations you can now use built-in collection types such as list and dict as generic types instead of importing the corresponding capitalized types (e.g. List or Dict) from typing. Some other types in the standard library are also now generic, for example queue.Queue.

Example:

def greet_all(names: list[str]) -> None:
    for name in names:
        print("Hello", name)
See PEP 585 for more details. (Contributed by Guido van Rossum, Ethan Smith, and Batuhan Taşkaya in bpo-39481.)



RE: meaning of -> syntax in function definition - DrakeSoft - Apr-08-2022

Thank you for your reply
I have included the complete code:



#example.py

import sys

from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget

from spellcheckwrapper import SpellCheckWrapper
from spelltextedit import SpellTextEdit


class Ui_MainWindow(QMainWindow):
    def __init__(self, word_list_path: str):
        super().__init__()
        self.word_list_path = word_list_path
        self.speller = SpellCheckWrapper(self.getWords(), self.addToDictionary)
        self.setupUi()

    def setupUi(self):
        self.resize(500, 500)
        self.setWindowTitle("Example app")

        self.centralWidget = QWidget(self)
        self.setCentralWidget(self.centralWidget)

        self.layout = QVBoxLayout(self.centralWidget)
        self.centralWidget.setLayout(self.layout)

        self.textEdit1 = SpellTextEdit(self.speller, self.centralWidget)
        self.layout.addWidget(self.textEdit1)

        self.textEdit2 = SpellTextEdit(self.speller, self.centralWidget)
        self.layout.addWidget(self.textEdit2)

    def getWords(self) -> list[str]:
        with open(self.word_list_path, "r") as f:
            word_list = [line.strip() for line in f]
        return word_list

    def addToDictionary(self, new_word: str):
        with open(self.word_list_path, "a") as f:
            f.write("\n" + new_word)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Ui_MainWindow("example_word_list.txt")
    window.show()
    sys.exit(app.exec_())
#------------------------

#spellcheckhighlighter.py

import re

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QSyntaxHighlighter, QTextCharFormat

from spellcheckwrapper import SpellCheckWrapper


class SpellCheckHighlighter(QSyntaxHighlighter):
    wordRegEx = re.compile(r"\b([A-Za-z]{2,})\b")

    def highlightBlock(self, text: str) -> None:
        if not hasattr(self, "speller"):
            return

        self.misspelledFormat = QTextCharFormat()
        self.misspelledFormat.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
        self.misspelledFormat.setUnderlineColor(Qt.red)

        for word_object in self.wordRegEx.finditer(text):
            if not self.speller.check(word_object.group()):
                self.setFormat(
                    word_object.start(),
                    word_object.end() - word_object.start(),
                    self.misspelledFormat,
                )

    def setSpeller(self, speller: SpellCheckWrapper):
        self.speller = speller

#------------------------------------


from typing import Callable
import enchant
from enchant import DictWithPWL
from PyQt5.QtCore import QTemporaryFile


class SpellCheckWrapper:
    def __init__(
        self, personal_word_list: list[str], addToDictionary: Callable[[str], None]
    ):
        # Creating temporary file
        self.file = QTemporaryFile()
        self.file.open()
        self.dictionary = DictWithPWL(
            "en_US",
            self.file.fileName(),
        )

        self.addToDictionary = addToDictionary

        self.word_list = set(personal_word_list)
        self.load_words()

    def load_words(self):
        for word in self.word_list:
            self.dictionary.add(word)

    def suggestions(self, word: str) -> list[str]:
        return self.dictionary.suggest(word)

    def correction(self, word: str) -> str:
        return self.dictionary.suggest(word)[0]

    def add(self, new_word: str) -> bool:
        if self.check(new_word):
            return False
        self.word_list.add(new_word)
        self.addToDictionary(new_word)
        self.dictionary.add(new_word)
        return True

    def check(self, word: str) -> bool:
        return self.dictionary.check(word)

    def getNewWords(self) -> set[str]:
        return self.word_list

#--------------------------------------------

# highlighter.py

import re

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QSyntaxHighlighter, QTextCharFormat

from spellcheckwrapper import SpellCheckWrapper


class SpellCheckHighlighter(QSyntaxHighlighter):
    wordRegEx = re.compile(r"\b([A-Za-z]{2,})\b")

    def highlightBlock(self, text: str) -> None:
        if not hasattr(self, "speller"):
            return

        self.misspelledFormat = QTextCharFormat()
        self.misspelledFormat.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
        self.misspelledFormat.setUnderlineColor(Qt.red)

        for word_object in self.wordRegEx.finditer(text):
            if not self.speller.check(word_object.group()):
                self.setFormat(
                    word_object.start(),
                    word_object.end() - word_object.start(),
                    self.misspelledFormat,
                )

    def setSpeller(self, speller: SpellCheckWrapper):
        self.speller = speller
#

# correction_action.py
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QAction


class SpecialAction(QAction):
    actionTriggered = pyqtSignal(str)

    def __init__(self, *args):
        super().__init__(*args)

        self.triggered.connect(self.emitTriggered)

    def emitTriggered(self):
        self.actionTriggered.emit(self.text())
The error message is

Error:
Traceback (most recent call last): File "/home/ProtoTyping/SpellChecker/pyqt-spellcheck/src/example.py", line 5, in <module> from spellcheckwrapper import SpellCheckWrapper File "/home/ProtoTyping/SpellChecker/pyqt-spellcheck/src/spellcheckwrapper.py", line 7, in <module> class SpellCheckWrapper: File "/home/ProtoTyping/SpellChecker/pyqt-spellcheck/src/spellcheckwrapper.py", line 9, in SpellCheckWrapper self, personal_word_list: list[str], addToDictionary: Callable[[str], None] TypeError: 'type' object is not subscriptable



RE: meaning of -> syntax in function definition - deanhystad - Apr-08-2022

As Yoriz mentioned, if you are using Python 3.9 or newer you can use list[str]. If you are using an older version of Python you need to use List[str] and in spellecheckwrapper.py modify the import.
from typing import Callable, List



RE: meaning of -> syntax in function definition - DrakeSoft - Apr-09-2022

Thanks guys,

When I did a python --version it was showing me Python 3.9.7, so the original code should have worked. But I was running the code in VScode, so I guess it was using an earlier version.

In the settings of VSCode, I changed the interpreter from Python3 (which was defaulting to /usr/bin/python3 --version Python 3.8.10) to Python 3.9.7 and then the code ran fine in vscode also.

again, thank you for your help, very much appreciated!