12th Week of 2022
Coding⚑
Python⚑
Type Hints⚑
-
New: Suggest to use
Sequence
overList
.Because using
List
could 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 invariant
Possible 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.overload
to 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_ * 2
This looks a bit weird at first glance—we are defining double three times! Let’s take it apart.
The first two
@overload
definitions 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
@overload
definitions as type hints. It then uses the first non-@overload
definition as the implementation. All@overload
definitions must come before the implementation, and multiple implementations are not allowed.When Python imports the file, the
@overload
definitions 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@overload
definition will raise aNotImplementedError
.@overload
can 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 docker
to 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
.git
directory, 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.vob
Select 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
-