Skip to content

35th Week of 2022

Health

Sleep

  • New: How your brain generates sleep.

    Brainwave activity of REM sleep looks similar to the one you have when you're awake. They cycle (going up and down) at a fast frequency of thirty or forty times per second in an unreliable pattern. This behaviour is explained by the fact that different parts of your waking brain are processing different pieces of information at different moments in time and in different ways.

Coding

Languages

PDM

  • New: Supporting pre-releases.

    To help package maintainers, you can allow pre-releases to be validate candidates, that way you'll get the issues sooner. It will mean more time to maintain the broken CIs if you update your packages daily (as you should!), but it's the least you can do to help your downstream library maintainers

    By default, pdm's dependency resolver will ignore prereleases unless there are no stable versions for the given version range of a dependency. This behavior can be changed by setting allow_prereleases to true in [tool.pdm] table:

    [tool.pdm]
    allow_prereleases = true
    
  • New: Solve circular dependencies.

    Sometimes pdm is not able to locate the best package combination, or it does too many loops, so to help it you can update your version constrains so that it has the minimum number of candidates.

    To solve circular dependencies we first need to locate what are the conflicting packages, pdm doesn't make it easy to detect them. Locate all the outdated packages by doing pdm show on each package until this issue is solved and run pdm update {package} --unconstrained for each of them. If you're already on the latest version, update your pyproject.toml to match the latest state.

    Once you have everything to the latest compatible version, you can try to upgrade the rest of the packages one by one to the latest with --unconstrained.

    In the process of doing these steps you'll see some conflicts in the dependencies that can be manually solved by preventing those versions to be installed or maybe changing the python-requires.

Python Snippets

  • New: Fix R1728: Consider using a generator.

    Removing [] inside calls that can use containers or generators should be considered for performance reasons since a generator will have an upfront cost to pay. The performance will be better if you are working with long lists or sets.

    Problematic code:

    list([0 for y in list(range(10))])  # [consider-using-generator]
    tuple([0 for y in list(range(10))])  # [consider-using-generator]
    sum([y**2 for y in list(range(10))])  # [consider-using-generator]
    max([y**2 for y in list(range(10))])  # [consider-using-generator]
    min([y**2 for y in list(range(10))])  # [consider-using-generator]
    

    Correct code:

    list(0 for y in list(range(10)))
    tuple(0 for y in list(range(10)))
    sum(y**2 for y in list(range(10)))
    max(y**2 for y in list(range(10)))
    min(y**2 for y in list(range(10)))
    
  • New: Fix W1510: Using subprocess.run without explicitly set check is not recommended.

    The run call in the example will succeed whether the command is successful or not. This is a problem because we silently ignore errors.

    import subprocess
    def example():
        proc = subprocess.run("ls")
        return proc.stdout
    

    When we pass check=True, the behavior changes towards raising an exception when the return code of the command is non-zero.

  • New: Convert bytes to string.

    byte_var.decode('utf-8')
    
  • New: Use pipes with subprocess.

    To use pipes with subprocess you need to use the flag check=True which is a bad idea. Instead you should use two processes and link them together in python:

    ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
    +output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
    ps.wait()
    
  • New: Pass input to the stdin of a subprocess.

    import subprocess
    p = subprocess.run(['myapp'], input='data_to_write', text=True)
    
  • New: Copy and paste from clipboard.

    You can use many libraries to do it, but if you don't want to add any other dependencies you can use subprocess run.

    To copy from the selection clipboard, assuming you've got xclip installed, you could do:

    subprocess.run(
        ['xclip', '-selection', 'clipboard', '-i'],
        input='text to be copied',
        text=True,
        check=True,
    )
    

    To paste it:

    subprocess.check_output(
        ['xclip', '-o', '-selection', 'clipboard']
    ).decode('utf-8')
    

    Good luck testing that in the CI xD

Pydantic

  • New: Ignore a field when representing an object.

    Use repr=False. This is useful for properties that don't return a value quickly, for example if you save an sh background process.

    class Temp(BaseModel):
        foo: typing.Any
        boo: typing.Any = Field(..., repr=False)
    

sh

  • New: Avoid exception logging when killing a background process.

    In order to catch this exception execute your process with _bg_exec=False and execute p.wait() if you want to handle the exception. Otherwise don't use the p.wait().

    p = sh.sleep(100, _bg=True, _bg_exc=False)
    try:
        p.kill()
        p.wait()
    except sh.SignalException_SIGKILL as err:
        print("foo")
    
    foo
    

Generic Coding Practices

Use warnings to evolve your code

  • New: Use environmental variables to evolve your packages.

    A cleaner way to handle the package evolve is with environmental variables, that way you don't need to change the signature of the function twice. I've learned this from boto where they informed their users this way:

    • If you wish to test the new feature we have created a new environment variable BOTO_DISABLE_COMMONNAME. Setting this to true will suppress the warning and use the new functionality.
    • If you are concerned about this change causing disruptions, you can pin your version of botocore to <1.28.0 until you are ready to migrate.
    • If you are only concerned about silencing the warning in your logs, use warnings.filterwarnings when instantiating a new service client.

      import warnings
      warnings.filterwarnings('ignore', category=FutureWarning, module='botocore.client')
      

Abstract Syntax Trees

  • New: Introduce abstract syntax trees.

    Abstract syntax trees (AST) is a tree representation of the abstract syntactic structure of text (often source code) written in a formal language. Each node of the tree denotes a construct occurring in the text.

    The syntax is "abstract" in the sense that it does not represent every detail appearing in the real syntax, but rather just the structural or content-related details. For instance, grouping parentheses are implicit in the tree structure, so these do not have to be represented as separate nodes. Likewise, a syntactic construct like an if-condition-then statement may be denoted by means of a single node with three branches.

    This distinguishes abstract syntax trees from concrete syntax trees, traditionally designated parse trees. Parse trees are typically built by a parser during the source code translation and compiling process. Once built, additional information is added to the AST by means of subsequent processing, e.g., contextual analysis.

    Abstract syntax trees are also used in program analysis and program transformation systems.

    pyparsing looks to be a good candidate to construct an AST

Arts

Cooking

Cooking software

  • New: Finish the state of the art analysis.

    Review Cooklang, KookBook, RecipeSage, Mealie and Chowdown

Other

  • New: Bear with me or Bare with me.

    "Bear with me" is the correct form.