Skip to content

December of 2021

Life Management

Music Management

  • New: Introduce how I manage my music library.


  • New: How to contribute to MusicBrainz.

    MusicBrainz is an open music encyclopedia that collects music metadata and makes it available to the public.

    MusicBrainz aims to be:

    • The ultimate source of music information by allowing anyone to contribute and releasing the data under open licenses.
    • The universal lingua franca for music by providing a reliable and unambiguous form of music identification, enabling both people and machines to have meaningful conversations about music.

    Like Wikipedia, MusicBrainz is maintained by a global community of users and we want everyone — including you — to participate and contribute.


Generic Coding Practices

Program Versioning

Keep a Changelog

  • New: Introduce the Changelog practice.

    A changelog is a file which contains a curated, chronologically ordered list of notable changes for each version of a project.

    It's purpose is to make it easier for users and contributors to see precisely what notable changes have been made between each release (or version) of the project.

    In the article we added:

  • New: Introduce Semantic Versioning.

    Semantic Versioning is a way to define your program's version based on the type of changes you've introduced. It's defined as a three-number string (separated with a period) in the format of MAJOR.MINOR.PATCH.

    Also included in the article is:

Calendar Versioning

  • New: Introduce Calendar Versioning.

    Calendar Versioning is a versioning convention based on your project's release calendar, instead of arbitrary numbers.

    CalVer suggests version number to be in format of: YEAR.MONTH.sequence. For example, 20.1 indicates a release in 2020 January, while 20.5.2 indicates a release that occurred in 2020 May, while the 2 indicates this is the third release of the month.


Pydantic Field Types

  • New: Using constrained strings in list attributes.

    import re
    import pydantic
    from pydantic import Field
    from typing import List
    class Regex(pydantic.ConstrainedStr):
        regex = re.compile("^[0-9a-z_]*$")
    class Data(pydantic.BaseModel):
        regex: List[Regex]
    data = Data(**{"regex": ["abc", "123", "asdf"]})


  • New: Introduce the pipenv package manager.

    Pipenv is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world.



  • New: Test programs that use sh.

    sh can be patched in your tests the typical way, with unittest.mock.patch():

    from unittest.mock import patch
    import sh
    def get_something():
        return sh.pwd()
    @patch("sh.pwd", create=True)
    def test_something(pwd):
        pwd.return_value = "/"
        assert get_something() == "/"

Code Styling

  • New: Introduce the awesome, life saving library pydantic_factories.

    Pydantic factories is a library offers powerful mock data generation capabilities for pydantic based models and dataclasses. It automatically creates FactoryBoy factories from a pydantic model.

    from datetime import date, datetime
    from typing import List, Union
    from pydantic import BaseModel, UUID4
    from pydantic_factories import ModelFactory
    class Person(BaseModel):
        id: UUID4
        name: str
        hobbies: List[str]
        age: Union[float, int]
        birthday: Union[datetime, date]
    class PersonFactory(ModelFactory):
        __model__ = Person
    result =
  • Reorganization: Moved the semantic versioning commit guidelines to the semver article.

Package Management

  • New: Compare Poetry, Pipenv and PDM package management tools.

    Pipenv has broad support. It is an official project of the Python Packaging Authority, alongside pip. It's also supported by the Heroku Python buildpack, which is useful for anyone with Heroku or Dokku-based deployment strategies.

    Poetry is a one-stop shop for dependency management and package management. It simplifies creating a package, managing its dependencies, and publishing it. Compared to Pipenv, Poetry's separate add and install commands are more explicit, and it's faster for everything except for a full dependency install.

    I liked Poetry most, and in the end I didn't analyze pdm.

  • New: Describe what a dependency solver does.

    A Solver tries to find a working set of dependencies that all agree with each other. By looking back in time, it’s happy to solve very old versions of packages if newer ones are supposed to be incompatible. This can be helpful, but is slow, and also means you can easily get a very ancient set of packages when you thought you were getting the latest versions.

    In the section we compare Pip's and Poetry's solver.

  • New: Add downsides of Poetry.

    It does upper version capping by default, which is becoming a big problem in the Python environment.

    This is specially useless when you add dependencies that follow CalVer. poetry add packaging will still do ^21 for the version it adds. You shouldn’t be capping versions, but you really shouldn’t be capping CalVer.

    It's equally troublesome that it upper pins the python version.



  • New: Introduce goodconf the pyndantic YAML friendly configuration management.

    goodconf is a thin wrapper over Pydantic's settings management. Allows you to define configuration variables and load them from environment or JSON/YAML file. Also generates initial configuration files and documentation for your defined configuration.

  • New: Capture deprecation warnings.

    Python and its ecosystem does not have an assumption of strict SemVer, and has a tradition of providing deprecation warnings. If you have good CI, you should be able to catch warnings even before your users see them. Try the following pytest configuration:

    filterwarnings = ["error"]

    This will turn warnings into errors and allow your CI to break before users break.

    Other sections added are:

Python Snippets



  • New: Conditionally skip questions.

    Sometimes it is helpful to be able to skip a question based on a condition. To avoid the need for an if around the question, you can pass the condition when you create the question:

    import questionary
    DISABLED = True
    response = questionary.confirm("Are you amazed?").skip_if(DISABLED, default=True).ask()
  • New: Don't highlight the selected option by default.

    If you don't want to highlight the default choice in the select question use the next style:

    from questionary import Style
    choice = select(
        "Question title: ",
        choices=['a', 'b', 'c'],
        style=Style([("selected", "noreverse")]),



Continuous Integration

Dependency managers

  • Correction: Deprecate in favour of Poetry.

Automating Processes