12th Week of 2022
Coding⚑
Python⚑
Type Hints⚑
-
New: Suggest to use
SequenceoverList.Because using
Listcould lead to some unexpected errors when combined with type inference. For example:class A: ... class B(A): ... lst = [A(), A()] # Inferred type is List[A] new_lst = [B(), B()] # inferred type is List[B] lst = new_lst # mypy will complain about this, because List is invariantPossible strategies in such situations are:
-
Use an explicit type annotation:
new_lst: List[A] = [B(), B()] lst = new_lst # OK -
Make a copy of the right hand side:
lst = list(new_lst) # Also OK -
Use immutable collections as annotations whenever possible:
def f_bad(x: List[A]) -> A: return x[0] f_bad(new_lst) # Fails def f_good(x: Sequence[A]) -> A: return x[0] f_good(new_lst) # OK
-
-
Sometimes the types of several variables are related, such as “if x is type A, y is type B, else y is type C”. Basic type hints cannot describe such relationships, making type checking cumbersome or inaccurate. We can instead use
@typing.overloadto represent type relationships properly.from __future__ import annotations from collections.abc import Sequence from typing import overload @overload def double(input_: int) -> int: ... @overload def double(input_: Sequence[int]) -> list[int]: ... def double(input_: int | Sequence[int]) -> int | list[int]: if isinstance(input_, Sequence): return [i * 2 for i in input_] return input_ * 2This looks a bit weird at first glance—we are defining double three times! Let’s take it apart.
The first two
@overloaddefinitions exist only for their type hints. Each definition represents an allowed combination of types. These definitions never run, so their bodies could contain anything, but it’s idiomatic to use Python’s...(ellipsis) literal.The third definition is the actual implementation. In this case, we need to provide type hints that union all the possible types for each variable. Without such hints, Mypy will skip type checking the function body.
When Mypy checks the file, it collects the
@overloaddefinitions as type hints. It then uses the first non-@overloaddefinition as the implementation. All@overloaddefinitions must come before the implementation, and multiple implementations are not allowed.When Python imports the file, the
@overloaddefinitions create temporary double functions, but each is overridden by the next definition. After importing, only the implementation exists. As a protection against accidentally missing implementations, attempting to call an@overloaddefinition will raise aNotImplementedError.@overloadcan represent arbitrarily complex scenarios. For a couple more examples, see the function overloading section of the Mypy docs. -
Correction: Debug the Start request repeated too quickly error.
Use
journalctl -eu dockerto debug
DevOps⚑
Automating Processes⚑
cruft⚑
-
New: Unable to interpret changes between current project and cookiecutter template as unicode.
Typically a result of hidden binary files in project folder. Maybe you have a hook that initializes the
.gitdirectory, don't do that.
Operative Systems⚑
Linux⚑
Linux Snippets⚑
-
Correction: Clean old kernels warning.
I don't recommend using this step, rely on
apt-get autoremove, it's safer.
ffmpeg⚑
-
New: Convert VOB to mkv.
-
Unify your VOBs
cat *.VOB > output.vob -
Identify the streams
ffmpeg -analyzeduration 100M -probesize 100M -i output.vobSelect the streams that you are interested in, imagine that is 1, 3, 4, 5 and 6.
-
Encoding
```bash ffmpeg \ -analyzeduration 100M -probesize 100M \ -i output.vob \ -map 0:1 -map 0:3 -map 0:4 -map 0:5 -map 0:6 \ -metadata:s:a:0 language=ita -metadata:s:a:0 title="Italian stereo" \ -metadata:s:a:1 language=eng -metadata:s:a:1 title="English stereo" \ -metadata:s:s:0 language=ita -metadata:s:s:0 title="Italian" \ -metadata:s:s:1 language=eng -metadata:s:s:1 title="English" \ -codec:v libx264 -crf 21 \ -codec:a libmp3lame -qscale:a 2 \ -codec:s copy \ output.mkv
-