Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion asyncio-walkthrough/areq.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ async def parse(url: str, session: ClientSession, **kwargs) -> set:
try:
# Ensure we return an absolute path.
abslink = urllib.parse.urljoin(url, link)
except urllib.error.URLError, ValueError:
except (urllib.error.URLError, ValueError):
logger.exception("Error parsing URL: %s", link)
pass
else:
Expand Down
2 changes: 0 additions & 2 deletions cursor-vs-windsurf-python/prompts.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ Type this into a file and let each editor complete it:
@dataclass
class RetryMetadata:
attempts_made: int


# ...
```

Expand Down
1 change: 1 addition & 0 deletions django-pagination/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Add the Python keywords to your database:
>>> for kw in keyword.kwlist:
... k = Keyword(name=kw)
... k.save()
...
```

Verify that the keywords were added to your database:
Expand Down
1 change: 1 addition & 0 deletions flask-connexion-rest-part-2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Navigate inside the `rp_flask_api/`, enter the [Python interactive shell](https:
>>> for person_data in people:
... insert_cmd = f"INSERT INTO person VALUES ({person_data})"
... conn.execute(insert_cmd)
...
<sqlite3.Cursor object at 0x104ac4dc0>
<sqlite3.Cursor object at 0x104ac4f40>
<sqlite3.Cursor object at 0x104ac4fc0>
Expand Down
2 changes: 1 addition & 1 deletion flush-print/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ SLIGHTLY_TOO_LARGE_FOR_BUFFER = 80_000
# Script paused at 10919

bufsize = 80_000 - 10919
print(bufsize) # 69081 <-- Your buffer size approximation
print(bufsize) # 69081 <-- Your buffer size approximation
```

You can divide the number you get by `1000` to get an estimation of your buffer size for stdout in kilobytes. In the example above, on a macOS system with a M1 chip, the buffer size of stdout when interacting with it through Python's `print()` would therefore be approximately 69 kilobytes.
Expand Down
2 changes: 1 addition & 1 deletion python-copy/benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def benchmark(container, executions):
def sliceable(instance):
try:
instance[0:1]
except TypeError, KeyError:
except (TypeError, KeyError):
return False
else:
return True
Expand Down
2 changes: 1 addition & 1 deletion python-eval-mathrepl/mathrepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def main():
# Read user's input
try:
expression = input(f"{PS1} ")
except KeyboardInterrupt, EOFError:
except (KeyboardInterrupt, EOFError):
raise SystemExit()

# Handle special commands
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def get_serializer(format):
try:
module = importlib.import_module(f"serializers.{format}")
serializer = getattr(module, f"{format.title()}Serializer")
except ImportError, AttributeError:
except (ImportError, AttributeError):
raise ValueError(f"Unknown format {format!r}") from None

return serializer()
Expand Down
2 changes: 1 addition & 1 deletion python-import/population_quiz/population_quiz.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def run_quiz(population, num_questions, num_countries):
try:
guess_idx = int(guess_str) - 1
guess = countries[guess_idx]
except ValueError, IndexError:
except (ValueError, IndexError):
print(f"Please answer between 1 and {num_countries}")
else:
break
Expand Down
2 changes: 1 addition & 1 deletion python-multiple-exceptions/exception_pass.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
try:
with open("file.txt", mode="rt") as f:
print(f.readlines())
except FileNotFoundError, PermissionError:
except (FileNotFoundError, PermissionError):
pass
2 changes: 1 addition & 1 deletion python-multiple-exceptions/multiple_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
first = float(input("What is your first number? "))
second = float(input("What is your second number? "))
print(f"{first} divided by {second} is {first / second}")
except ZeroDivisionError, ValueError:
except (ZeroDivisionError, ValueError):
print("There was an error")
2 changes: 1 addition & 1 deletion python-type-checking/hearts.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def play_card(self, played: List[Card], hearts_broken: bool) -> Card:
try:
card_num = int(input(f" {self.name}, choose card: "))
card = playable[card_num]
except ValueError, IndexError:
except (ValueError, IndexError):
pass
else:
break
Expand Down
2 changes: 1 addition & 1 deletion structural-pattern-matching/guessing_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ def bye():
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt, EOFError:
except (KeyboardInterrupt, EOFError):
print()
bye()
68 changes: 35 additions & 33 deletions wordcount/tests/realpython/HOWTO.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@ Inside each task file, create a class decorated with the `@task()` decorator:
```python
from realpython import task


@task(
number=1,
name="Run the wordcount Command",
url="https://realpython.com/lessons/run-the-wordcount-command-task/",
)
class Test:
def test_one(self): ...

def test_two(self): ...
def test_one(self):
...

def test_two(self):
...

def test_three(self): ...
def test_three(self):
...
```

This class can be named anything, e.g., `Test`, and you can reuse this name across different files if you want to.
Expand All @@ -55,15 +57,15 @@ You can associate resources common to all test methods by placing the correspond
```python
from realpython import task, tutorial, course, podcast


@task(
number=1,
name="Run the wordcount Command",
url="https://realpython.com/lessons/run-the-wordcount-command-task/",
)
@tutorial("python-comments-guide")
@course("writing-comments-python", "Writing Comments in Python")
class Test: ...
class Test:
...
```

This will cascade down to the individual test methods, meaning that if one of them fails, then we'll include that resource on the list of hints.
Expand All @@ -73,20 +75,23 @@ In contrast, decorating the individual test methods will let you associate resou
```python
from realpython import task, tutorial, course, podcast


@task(
number=1,
name="Run the wordcount Command",
url="https://realpython.com/lessons/run-the-wordcount-command-task/",
)
class Test:
def test_one(self): ...


def test_one(self):
...

@course("writing-comments-python", "Writing Comments in Python")
def test_two(self): ...

def test_two(self):
...

@tutorial("python-comments-guide")
def test_three(self): ...
def test_three(self):
...
```

These decorators expect the **slug** to identify a resource in the CMS. If you don't provide a title, which is an optional parameter, then the slug will be automatically prettified and used as a link label.
Expand All @@ -96,7 +101,8 @@ These decorators expect the **slug** to identify a resource in the CMS. If you d
By default, the plugin will try to prettify the acceptance criteria shown in the report based on the name of the corresponding test method, e.g.:

```python
def test_reports_zeros_on_an_empty_stream(self): ...
def test_reports_zeros_on_an_empty_stream(self):
...
```

...becomes "_Reports zeros on an empty stream_."
Expand All @@ -115,18 +121,15 @@ pytest allows you to run the same test method against different parameters (data
```python
import pytest


@pytest.mark.parametrize(
"flags",
[
[],
["-l"],
["-w"],
["-c"],
["-l", "-w", "-c"],
],
)
def test_always_displays_counts_in_the_same_order(self, flags): ...
@pytest.mark.parametrize("flags", [
[],
["-l"],
["-w"],
["-c"],
["-l", "-w", "-c"],
])
def test_always_displays_counts_in_the_same_order(self, flags):
...
```

The resulting report will append the values of the parameters to the name of the acceptance criteria. This will work regardless of whether you provde a docstring or not.
Expand All @@ -138,11 +141,11 @@ By default, each test method will time out after a predefined number of seconds.
```python
import pytest


@task(...)
class Test:
@pytest.mark.timeout(3.5)
def test_one(self): ...
def test_one(self):
...
```

## Running Tests in DEBUG Mode
Expand Down Expand Up @@ -184,12 +187,13 @@ However, it sill won't show the **expected vs. actual**. If you want to do that,
```python
from realpython import task, assert_equals


@task(...)
class Test:
def test_one(self):
assert_equals(
"expected", function(), "Your function should return XYZ"
"expected",
function(),
"Your function should return XYZ"
)
```

Expand All @@ -198,14 +202,13 @@ Note that the order of these arguments matters! The _expected_ value always come
```python
from realpython import task, assert_equals


@task(...)
class Test:
def test_one(self):
assert_equals(
expected="expected",
actual=function(),
message="Your function should return XYZ",
message="Your function should return XYZ"
)
```

Expand All @@ -214,7 +217,6 @@ If you just want to show the expected vs actual without any extra message, then
```python
from realpython import task, assert_equals


@task(...)
class Test:
def test_one(self):
Expand Down
Loading