From 14574f7bb96f1769bfcee658a23a1f9e8cc88001 Mon Sep 17 00:00:00 2001 From: gahjelle Date: Wed, 20 Sep 2023 08:56:27 +0200 Subject: [PATCH 1/8] Add 3.12 examples from the typing preview --- python-312/README.md | 35 +++++++++++- python-312/typing/alias.py | 3 ++ python-312/typing/alias_311.py | 7 +++ python-312/typing/concatenation.py | 2 + python-312/typing/concatenation_311.py | 7 +++ python-312/typing/deck.py | 6 +++ python-312/typing/deck_311.py | 8 +++ python-312/typing/generic_queue.py | 12 +++++ python-312/typing/generic_queue_311.py | 15 ++++++ python-312/typing/inspect_string.py | 8 +++ python-312/typing/inspect_string_311.py | 13 +++++ python-312/typing/list_helpers.py | 3 ++ python-312/typing/list_helpers_311.py | 8 +++ python-312/typing/options.py | 34 ++++++++++++ python-312/typing/oslo.question | 5 ++ python-312/typing/pyproject.toml | 2 + python-312/typing/quiz.py | 72 +++++++++++++++++++++++++ python-312/typing/typed_queue.py | 23 ++++++++ 18 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 python-312/typing/alias.py create mode 100644 python-312/typing/alias_311.py create mode 100644 python-312/typing/concatenation.py create mode 100644 python-312/typing/concatenation_311.py create mode 100644 python-312/typing/deck.py create mode 100644 python-312/typing/deck_311.py create mode 100644 python-312/typing/generic_queue.py create mode 100644 python-312/typing/generic_queue_311.py create mode 100644 python-312/typing/inspect_string.py create mode 100644 python-312/typing/inspect_string_311.py create mode 100644 python-312/typing/list_helpers.py create mode 100644 python-312/typing/list_helpers_311.py create mode 100644 python-312/typing/options.py create mode 100644 python-312/typing/oslo.question create mode 100644 python-312/typing/pyproject.toml create mode 100644 python-312/typing/quiz.py create mode 100644 python-312/typing/typed_queue.py diff --git a/python-312/README.md b/python-312/README.md index 3e63d19905..3a1fef5d52 100644 --- a/python-312/README.md +++ b/python-312/README.md @@ -15,8 +15,10 @@ You can learn more about Python 3.12's new features in the following Real Python - [Python 3.12 Preview: Ever Better Error Messages](https://realpython.com/python312-error-messages/) - [Python 3.12 Preview: Support For the Linux `perf` Profiler](https://realpython.com/python312-perf-profiler/) - [Python 3.12 Preview: More Intuitive and Consistent F-Strings](https://realpython.com/python312-f-strings/) +- [Python 3.12 Preview: Subinterpreters](https://realpython.com/python312-subinterpreters/) +- [Python 3.12 Preview: Static Typing Improvements](https://realpython.com/python312-typing/) -You'll find examples from all these tutorials in this repository. +You'll find examples from these tutorials in this repository. ## Examples @@ -136,6 +138,37 @@ Pythonista! In this example, you can see how the new implementation of f-strings allows you to include backslashes in embedded expressions. This wasn't possible with f-strings in earlier versions of Python. +### Static Typing Improvements + +You'll find all static typing examples inside the [`typing/`](typing/) directory. You should install the Pyright type checker for PyPI: + +```console +$ python -m pip install pyright +``` + +You can then run type checks by running `pyright`. For some features you need to specify `--pythonversion 3.12`. + +#### Type Variables and Generic Classes, Functions, and Type Aliases + +You can find comparisons between the old and the new syntax for type variables in the following files: + +- [`generic_queue.py`](typing/generic_queue.py) and [`generic_queue_311.py`](typing/generic_queue_311.py) +- [`list_helpers.py`](typing/list_helpers.py) and [`list_helpers_311.py`](typing/list_helpers_311.py) +- [`concatenation.py`](typing/concatenation.py) and [`concatenation_311.py`](typing/concatenation_311.py) +- [`inspect_string.py`](typing/inspect_string.py) and [`inspect_string_311.py`](typing/inspect_string_311.py) +- [`deck.py`](typing/deck.py) and [`deck_311.py`](typing/deck_311.py) +- [`alias.py`](typing/alias.py) and [`alias_311.py`](typing/alias_311.py) + +Additionally, [`typed_queue.py`](typing/typed_queue.py) shows the implementation of typed queues without using type variables. + +#### Modeling Inheritance With `@override` + +The file [`quiz.py`](typing/quiz.py) shows how to use the new `@override` decorator. In addition to the code in the tutorial, this file includes support for reading questions from files. This is done to show that `@override` works well together with other decorators like `@classmethod`. + +#### Annotating `**kwargs` With Typed Dictionaries + +The file [`options.py`](typing/options.py) shows how you can use a typed dictionary to annotate variable keyword arguments. + ## Authors - **Martin Breuss**, E-mail: [martin@realpython.com](martin@realpython.com) diff --git a/python-312/typing/alias.py b/python-312/typing/alias.py new file mode 100644 index 0000000000..6e1d21e37c --- /dev/null +++ b/python-312/typing/alias.py @@ -0,0 +1,3 @@ +type Ordered[T] = list[T] | tuple[T, ...] + +numbers: Ordered[int] = (1, 2, 3) diff --git a/python-312/typing/alias_311.py b/python-312/typing/alias_311.py new file mode 100644 index 0000000000..05a8860e7b --- /dev/null +++ b/python-312/typing/alias_311.py @@ -0,0 +1,7 @@ +from typing import TypeAlias, TypeVar + +T = TypeVar("T") + +Ordered: TypeAlias = list[T] | tuple[T, ...] + +numbers: Ordered[int] = (1, 2, 3) diff --git a/python-312/typing/concatenation.py b/python-312/typing/concatenation.py new file mode 100644 index 0000000000..a1176fe6e9 --- /dev/null +++ b/python-312/typing/concatenation.py @@ -0,0 +1,2 @@ +def concatenate[T: (str, bytes)](first: T, second: T) -> T: + return first + second diff --git a/python-312/typing/concatenation_311.py b/python-312/typing/concatenation_311.py new file mode 100644 index 0000000000..bad958a167 --- /dev/null +++ b/python-312/typing/concatenation_311.py @@ -0,0 +1,7 @@ +from typing import TypeVar + +T = TypeVar("T", str, bytes) + + +def concatenate(first: T, second: T) -> T: + return first + second diff --git a/python-312/typing/deck.py b/python-312/typing/deck.py new file mode 100644 index 0000000000..db044e776d --- /dev/null +++ b/python-312/typing/deck.py @@ -0,0 +1,6 @@ +import random + +type CardDeck = list[tuple[str, int]] + +def shuffle(deck: CardDeck) -> CardDeck: + return random.sample(deck, k=len(deck)) diff --git a/python-312/typing/deck_311.py b/python-312/typing/deck_311.py new file mode 100644 index 0000000000..e1c20499b5 --- /dev/null +++ b/python-312/typing/deck_311.py @@ -0,0 +1,8 @@ +import random +from typing import TypeAlias + +CardDeck: TypeAlias = list[tuple[str, int]] + + +def shuffle(deck: CardDeck) -> CardDeck: + return random.sample(deck, k=len(deck)) diff --git a/python-312/typing/generic_queue.py b/python-312/typing/generic_queue.py new file mode 100644 index 0000000000..8bc33e263e --- /dev/null +++ b/python-312/typing/generic_queue.py @@ -0,0 +1,12 @@ +from collections import deque + + +class Queue[T]: + def __init__(self) -> None: + self.elements: deque[T] = deque() + + def push(self, element: T) -> None: + self.elements.append(element) + + def pop(self) -> T: + return self.elements.popleft() diff --git a/python-312/typing/generic_queue_311.py b/python-312/typing/generic_queue_311.py new file mode 100644 index 0000000000..15a4ac8248 --- /dev/null +++ b/python-312/typing/generic_queue_311.py @@ -0,0 +1,15 @@ +from collections import deque +from typing import Generic, TypeVar + +T = TypeVar("T") + + +class Queue(Generic[T]): + def __init__(self) -> None: + self.elements: deque[T] = deque() + + def push(self, element: T) -> None: + self.elements.append(element) + + def pop(self) -> T: + return self.elements.popleft() diff --git a/python-312/typing/inspect_string.py b/python-312/typing/inspect_string.py new file mode 100644 index 0000000000..5478eeb307 --- /dev/null +++ b/python-312/typing/inspect_string.py @@ -0,0 +1,8 @@ +class Words(str): + def __len__(self): + return len(self.split()) + + +def inspect[S: str](text: S) -> S: + print(f"'{text.upper()}' has length {len(text)}") + return text diff --git a/python-312/typing/inspect_string_311.py b/python-312/typing/inspect_string_311.py new file mode 100644 index 0000000000..368eb1df7b --- /dev/null +++ b/python-312/typing/inspect_string_311.py @@ -0,0 +1,13 @@ +from typing import TypeVar + +S = TypeVar("S", bound=str) + + +class Words(str): + def __len__(self): + return len(self.split()) + + +def inspect(text: S) -> S: + print(f"'{text.upper()}' has length {len(text)}") + return text diff --git a/python-312/typing/list_helpers.py b/python-312/typing/list_helpers.py new file mode 100644 index 0000000000..356251b95b --- /dev/null +++ b/python-312/typing/list_helpers.py @@ -0,0 +1,3 @@ +def push_and_pop[T](elements: list[T], element: T) -> T: + elements.append(element) + return elements.pop(0) diff --git a/python-312/typing/list_helpers_311.py b/python-312/typing/list_helpers_311.py new file mode 100644 index 0000000000..c5422fad7a --- /dev/null +++ b/python-312/typing/list_helpers_311.py @@ -0,0 +1,8 @@ +from typing import TypeVar + +T = TypeVar("T") + + +def push_and_pop(elements: list[T], element: T) -> T: + elements.append(element) + return elements.pop(0) diff --git a/python-312/typing/options.py b/python-312/typing/options.py new file mode 100644 index 0000000000..9086adfd6c --- /dev/null +++ b/python-312/typing/options.py @@ -0,0 +1,34 @@ +from typing import Required, TypedDict, Unpack + + +class Options(TypedDict, total=False): + line_width: int + level: Required[str] + propagate: bool + + +def show_options(program_name: str, **kwargs: Unpack[Options]) -> None: + print(program_name.upper()) + for option, value in kwargs.items(): + print(f"{option:<15} {value}") + + +def show_options_explicit( + program_name: str, + *, + level: str, + line_width: int | None = None, + propagate: bool | None = None, +) -> None: + options = { + "line_width": line_width, + "level": level, + "propagate": propagate, + } + print(program_name.upper()) + for option, value in options.items(): + if value is not None: + print(f"{option:<15} {value}") + + +show_options("logger", line_width=80, level="INFO", propagate=False) diff --git a/python-312/typing/oslo.question b/python-312/typing/oslo.question new file mode 100644 index 0000000000..a021f6f7df --- /dev/null +++ b/python-312/typing/oslo.question @@ -0,0 +1,5 @@ +In which country is Oslo the capital? +Norway +Sweden +Ireland +Canada diff --git a/python-312/typing/pyproject.toml b/python-312/typing/pyproject.toml new file mode 100644 index 0000000000..d8321d405f --- /dev/null +++ b/python-312/typing/pyproject.toml @@ -0,0 +1,2 @@ +[tool.pyright] +# reportImplicitOverride = true diff --git a/python-312/typing/quiz.py b/python-312/typing/quiz.py new file mode 100644 index 0000000000..8719033c2a --- /dev/null +++ b/python-312/typing/quiz.py @@ -0,0 +1,72 @@ +import pathlib +import random +from dataclasses import dataclass +from string import ascii_lowercase +from typing import Self, override + + +@dataclass +class Question: + question: str + answer: str + + @classmethod + def from_file(cls, path: pathlib.Path) -> Self: + question, answer, *_ = path.read_text(encoding="utf-8").split("\n") + return cls(question, answer) + + def ask(self) -> bool: + answer = input(f"\n{self.question} ") + return answer == self.answer + + +@dataclass +class MultipleChoiceQuestion(Question): + distractors: list[str] + + @classmethod + @override + def from_file(cls, path: pathlib.Path) -> Self: + question, answer, *distractors = ( + path.read_text(encoding="utf-8").strip().split("\n") + ) + return cls(question, answer, distractors) + + @override + def ask(self) -> bool: + print(f"\n{self.question}") + + alternatives = random.sample( + self.distractors + [self.answer], k=len(self.distractors) + 1 + ) + labeled_alternatives = dict(zip(ascii_lowercase, alternatives)) + for label, alternative in labeled_alternatives.items(): + print(f" {label}) {alternative}", end="") + + answer = input("\n\nChoice? ") + return labeled_alternatives.get(answer) == self.answer + + +questions = [ + Question("Who created Python?", "Guido van Rossum"), + MultipleChoiceQuestion( + "What's a PEP?", + "A Python Enhancement Proposal", + distractors=[ + "A Pretty Exciting Policy", + "A Preciously Evolved Python", + "A Potentially Epic Prize", + ], + ), + MultipleChoiceQuestion.from_file(pathlib.Path("oslo.question")), +] + +score = 0 +for question in random.sample(questions, k=len(questions)): + if question.ask(): + score += 1 + print("Yes, that's correct!") + else: + print(f"No, the answer is '{question.answer}'") + +print(f"\nYou got {score} out of {len(questions)} correct") diff --git a/python-312/typing/typed_queue.py b/python-312/typing/typed_queue.py new file mode 100644 index 0000000000..99fede6982 --- /dev/null +++ b/python-312/typing/typed_queue.py @@ -0,0 +1,23 @@ +from collections import deque + + +class IntegerQueue: + def __init__(self) -> None: + self.elements: deque[int] = deque() + + def push(self, element: int) -> None: + self.elements.append(element) + + def pop(self) -> int: + return self.elements.popleft() + + +class StringQueue: + def __init__(self) -> None: + self.elements: deque[str] = deque() + + def push(self, element: str) -> None: + self.elements.append(element) + + def pop(self) -> str: + return self.elements.popleft() From 21ac77b2f3ba6f6e49edcc34ebe8ce0498aaf9f7 Mon Sep 17 00:00:00 2001 From: gahjelle Date: Wed, 20 Sep 2023 12:54:11 +0200 Subject: [PATCH 2/8] Use Python 3.12 for linting --- .github/workflows/linters.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index b51144d493..49bb7108bd 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: include: - - {name: Linux311, python: '3.11.0-rc.1', os: ubuntu-latest} + - {name: Linux312, python: '3.12.0-rc.3', os: ubuntu-latest} steps: - name: Check out repository uses: actions/checkout@v2 From 2ee15899823cb03ebdf0db500cdbbf63ed91e6b1 Mon Sep 17 00:00:00 2001 From: gahjelle Date: Wed, 20 Sep 2023 13:02:56 +0200 Subject: [PATCH 3/8] Upgrade Flake8 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ceddbc5f57..ed52968a38 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ black[jupyter]==22.6.0 -flake8==5.0.4 +flake8==6.1.0 From 8c5ab2b4a4faef1002cf46874c1c2705f24e9ec5 Mon Sep 17 00:00:00 2001 From: gahjelle Date: Wed, 20 Sep 2023 13:15:42 +0200 Subject: [PATCH 4/8] Downgrade back to Python 3.11 for linting --- .github/workflows/linters.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 49bb7108bd..33b0bcadf7 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: include: - - {name: Linux312, python: '3.12.0-rc.3', os: ubuntu-latest} + - {name: Linux311, python: '3.11.5', os: ubuntu-latest} steps: - name: Check out repository uses: actions/checkout@v2 From 46e0103a0a3a794ba80d174f2231d24a459af18a Mon Sep 17 00:00:00 2001 From: gahjelle Date: Wed, 20 Sep 2023 13:18:06 +0200 Subject: [PATCH 5/8] Reset cache --- .github/workflows/linters.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 33b0bcadf7..2983f1f14c 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -33,9 +33,9 @@ jobs: uses: actions/cache@v3 with: path: ./venv - key: ${{ matrix.name }}-pip-${{ hashFiles('requirements.txt') }} + key: ${{ matrix.name }}-v1-pip-${{ hashFiles('requirements.txt') }} restore-keys: | - ${{ matrix.name }}-pip- + ${{ matrix.name }}-v1-pip- - name: Install dependencies if: steps.cache.outputs.cache-hit != 'true' From 5e74e0760b14d6baf54d17397268a3f048fe567e Mon Sep 17 00:00:00 2001 From: gahjelle Date: Wed, 20 Sep 2023 13:27:43 +0200 Subject: [PATCH 6/8] Combine 3.11 and 3.12 code in the same file --- python-312/typing/alias.py | 13 ++++++++++++- python-312/typing/alias_311.py | 7 ------- python-312/typing/concatenation.py | 13 ++++++++++++- python-312/typing/concatenation_311.py | 7 ------- python-312/typing/deck.py | 14 +++++++++++++- python-312/typing/deck_311.py | 8 -------- python-312/typing/generic_queue.py | 21 ++++++++++++++++++++- python-312/typing/generic_queue_311.py | 15 --------------- python-312/typing/inspect_string.py | 19 ++++++++++++++++++- python-312/typing/inspect_string_311.py | 13 ------------- python-312/typing/list_helpers.py | 14 +++++++++++++- python-312/typing/list_helpers_311.py | 8 -------- 12 files changed, 88 insertions(+), 64 deletions(-) delete mode 100644 python-312/typing/alias_311.py delete mode 100644 python-312/typing/concatenation_311.py delete mode 100644 python-312/typing/deck_311.py delete mode 100644 python-312/typing/generic_queue_311.py delete mode 100644 python-312/typing/inspect_string_311.py delete mode 100644 python-312/typing/list_helpers_311.py diff --git a/python-312/typing/alias.py b/python-312/typing/alias.py index 6e1d21e37c..0b203b37e2 100644 --- a/python-312/typing/alias.py +++ b/python-312/typing/alias.py @@ -1,3 +1,14 @@ -type Ordered[T] = list[T] | tuple[T, ...] +from typing import TypeAlias, TypeVar + +T = TypeVar("T") + +Ordered: TypeAlias = list[T] | tuple[T, ...] numbers: Ordered[int] = (1, 2, 3) + + +# %% Python 3.12 + +# type Ordered[T] = list[T] | tuple[T, ...] +# +# numbers: Ordered[int] = (1, 2, 3) diff --git a/python-312/typing/alias_311.py b/python-312/typing/alias_311.py deleted file mode 100644 index 05a8860e7b..0000000000 --- a/python-312/typing/alias_311.py +++ /dev/null @@ -1,7 +0,0 @@ -from typing import TypeAlias, TypeVar - -T = TypeVar("T") - -Ordered: TypeAlias = list[T] | tuple[T, ...] - -numbers: Ordered[int] = (1, 2, 3) diff --git a/python-312/typing/concatenation.py b/python-312/typing/concatenation.py index a1176fe6e9..fe429f6433 100644 --- a/python-312/typing/concatenation.py +++ b/python-312/typing/concatenation.py @@ -1,2 +1,13 @@ -def concatenate[T: (str, bytes)](first: T, second: T) -> T: +from typing import TypeVar + +T = TypeVar("T", str, bytes) + + +def concatenate(first: T, second: T) -> T: return first + second + + +# %% Python 3.12 + +# def concatenate[T: (str, bytes)](first: T, second: T) -> T: +# return first + second diff --git a/python-312/typing/concatenation_311.py b/python-312/typing/concatenation_311.py deleted file mode 100644 index bad958a167..0000000000 --- a/python-312/typing/concatenation_311.py +++ /dev/null @@ -1,7 +0,0 @@ -from typing import TypeVar - -T = TypeVar("T", str, bytes) - - -def concatenate(first: T, second: T) -> T: - return first + second diff --git a/python-312/typing/deck.py b/python-312/typing/deck.py index db044e776d..1b4644a547 100644 --- a/python-312/typing/deck.py +++ b/python-312/typing/deck.py @@ -1,6 +1,18 @@ import random +from typing import TypeAlias + +CardDeck: TypeAlias = list[tuple[str, int]] -type CardDeck = list[tuple[str, int]] def shuffle(deck: CardDeck) -> CardDeck: return random.sample(deck, k=len(deck)) + + +# %% Python 3.12 + +# import random +# +# type CardDeck = list[tuple[str, int]] +# +# def shuffle(deck: CardDeck) -> CardDeck: +# return random.sample(deck, k=len(deck)) diff --git a/python-312/typing/deck_311.py b/python-312/typing/deck_311.py deleted file mode 100644 index e1c20499b5..0000000000 --- a/python-312/typing/deck_311.py +++ /dev/null @@ -1,8 +0,0 @@ -import random -from typing import TypeAlias - -CardDeck: TypeAlias = list[tuple[str, int]] - - -def shuffle(deck: CardDeck) -> CardDeck: - return random.sample(deck, k=len(deck)) diff --git a/python-312/typing/generic_queue.py b/python-312/typing/generic_queue.py index 8bc33e263e..3ebbe6b635 100644 --- a/python-312/typing/generic_queue.py +++ b/python-312/typing/generic_queue.py @@ -1,7 +1,10 @@ from collections import deque +from typing import Generic, TypeVar +T = TypeVar("T") -class Queue[T]: + +class Queue(Generic[T]): def __init__(self) -> None: self.elements: deque[T] = deque() @@ -10,3 +13,19 @@ def push(self, element: T) -> None: def pop(self) -> T: return self.elements.popleft() + + +# %% Python 3.12 + +# from collections import deque +# +# +# class Queue[T]: +# def __init__(self) -> None: +# self.elements: deque[T] = deque() +# +# def push(self, element: T) -> None: +# self.elements.append(element) +# +# def pop(self) -> T: +# return self.elements.popleft() diff --git a/python-312/typing/generic_queue_311.py b/python-312/typing/generic_queue_311.py deleted file mode 100644 index 15a4ac8248..0000000000 --- a/python-312/typing/generic_queue_311.py +++ /dev/null @@ -1,15 +0,0 @@ -from collections import deque -from typing import Generic, TypeVar - -T = TypeVar("T") - - -class Queue(Generic[T]): - def __init__(self) -> None: - self.elements: deque[T] = deque() - - def push(self, element: T) -> None: - self.elements.append(element) - - def pop(self) -> T: - return self.elements.popleft() diff --git a/python-312/typing/inspect_string.py b/python-312/typing/inspect_string.py index 5478eeb307..f7767d6269 100644 --- a/python-312/typing/inspect_string.py +++ b/python-312/typing/inspect_string.py @@ -1,8 +1,25 @@ +from typing import TypeVar + +S = TypeVar("S", bound=str) + + class Words(str): def __len__(self): return len(self.split()) -def inspect[S: str](text: S) -> S: +def inspect(text: S) -> S: print(f"'{text.upper()}' has length {len(text)}") return text + + +# %% Python 3.12 + +# class Words(str): +# def __len__(self): +# return len(self.split()) +# +# +# def inspect[S: str](text: S) -> S: +# print(f"'{text.upper()}' has length {len(text)}") +# return text diff --git a/python-312/typing/inspect_string_311.py b/python-312/typing/inspect_string_311.py deleted file mode 100644 index 368eb1df7b..0000000000 --- a/python-312/typing/inspect_string_311.py +++ /dev/null @@ -1,13 +0,0 @@ -from typing import TypeVar - -S = TypeVar("S", bound=str) - - -class Words(str): - def __len__(self): - return len(self.split()) - - -def inspect(text: S) -> S: - print(f"'{text.upper()}' has length {len(text)}") - return text diff --git a/python-312/typing/list_helpers.py b/python-312/typing/list_helpers.py index 356251b95b..61a399b2ec 100644 --- a/python-312/typing/list_helpers.py +++ b/python-312/typing/list_helpers.py @@ -1,3 +1,15 @@ -def push_and_pop[T](elements: list[T], element: T) -> T: +from typing import TypeVar + +T = TypeVar("T") + + +def push_and_pop(elements: list[T], element: T) -> T: elements.append(element) return elements.pop(0) + + +# %% Python 3.12 + +# def push_and_pop[T](elements: list[T], element: T) -> T: +# elements.append(element) +# return elements.pop(0) diff --git a/python-312/typing/list_helpers_311.py b/python-312/typing/list_helpers_311.py deleted file mode 100644 index c5422fad7a..0000000000 --- a/python-312/typing/list_helpers_311.py +++ /dev/null @@ -1,8 +0,0 @@ -from typing import TypeVar - -T = TypeVar("T") - - -def push_and_pop(elements: list[T], element: T) -> T: - elements.append(element) - return elements.pop(0) From 6835f4738cc556543b87da624d07312fedb471ac Mon Sep 17 00:00:00 2001 From: gahjelle Date: Wed, 20 Sep 2023 14:57:39 +0200 Subject: [PATCH 7/8] Update README --- python-312/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/python-312/README.md b/python-312/README.md index 3a1fef5d52..22f84c9fe6 100644 --- a/python-312/README.md +++ b/python-312/README.md @@ -140,7 +140,7 @@ In this example, you can see how the new implementation of f-strings allows you ### Static Typing Improvements -You'll find all static typing examples inside the [`typing/`](typing/) directory. You should install the Pyright type checker for PyPI: +You'll find all static typing examples inside the [`typing/`](typing/) directory. You should install the Pyright type checker from PyPI: ```console $ python -m pip install pyright @@ -150,14 +150,14 @@ You can then run type checks by running `pyright`. For some features you need to #### Type Variables and Generic Classes, Functions, and Type Aliases -You can find comparisons between the old and the new syntax for type variables in the following files: +You can find comparisons between the old and the new syntax for type variables in the following files. The new 3.12 syntax is shown in the commented part of the code. -- [`generic_queue.py`](typing/generic_queue.py) and [`generic_queue_311.py`](typing/generic_queue_311.py) -- [`list_helpers.py`](typing/list_helpers.py) and [`list_helpers_311.py`](typing/list_helpers_311.py) -- [`concatenation.py`](typing/concatenation.py) and [`concatenation_311.py`](typing/concatenation_311.py) -- [`inspect_string.py`](typing/inspect_string.py) and [`inspect_string_311.py`](typing/inspect_string_311.py) -- [`deck.py`](typing/deck.py) and [`deck_311.py`](typing/deck_311.py) -- [`alias.py`](typing/alias.py) and [`alias_311.py`](typing/alias_311.py) +- [`generic_queue.py`](typing/generic_queue.py) +- [`list_helpers.py`](typing/list_helpers.py) +- [`concatenation.py`](typing/concatenation.py) +- [`inspect_string.py`](typing/inspect_string.py) +- [`deck.py`](typing/deck.py) +- [`alias.py`](typing/alias.py) Additionally, [`typed_queue.py`](typing/typed_queue.py) shows the implementation of typed queues without using type variables. From dada278e2adad1a91dc635322198cb4b0bdc7f91 Mon Sep 17 00:00:00 2001 From: KateFinegan <95366190+KateFinegan@users.noreply.github.com> Date: Fri, 22 Sep 2023 14:19:10 -0600 Subject: [PATCH 8/8] README LE Static Typing --- python-312/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python-312/README.md b/python-312/README.md index 22f84c9fe6..ea8679a4be 100644 --- a/python-312/README.md +++ b/python-312/README.md @@ -146,11 +146,11 @@ You'll find all static typing examples inside the [`typing/`](typing/) directory $ python -m pip install pyright ``` -You can then run type checks by running `pyright`. For some features you need to specify `--pythonversion 3.12`. +You can then run type checks by running `pyright`. For some features, you need to specify `--pythonversion 3.12`. #### Type Variables and Generic Classes, Functions, and Type Aliases -You can find comparisons between the old and the new syntax for type variables in the following files. The new 3.12 syntax is shown in the commented part of the code. +You can find comparisons between the old and the new syntax for type variables in the following files, with the new 3.12 syntax shown in the commented part of the code: - [`generic_queue.py`](typing/generic_queue.py) - [`list_helpers.py`](typing/list_helpers.py)