Kodestandard for Cerebrum-utvikling

Informasjon om hvordan vi skal kode Python for Cerebrum.

Merk: Denne filen er utdatert, se heller CONTRIBUTING.md i kode-repoet.

1   Python standard

1.1   Generelt

Generell Python-utvikling bør følge de generelle rettningslinjene beskrevet i this-modulen:

import this

I tillegg skal PEP8 og PEP257 brukes som utgangspunkt for Python-utvikling i Cerebrum.

All nyutviklet kode bør kunne passere den offisielle PEP8 validatoren:

yum install python-pep8
pep8 min_kode.py

I tillegg er det flere Cerebrum-spesifiske standarder for utvikling av Python-kode.

1.2   Blanke linjer

1.2.1   Klasser og metoder

  1. Klasser skal separeres med 2 blanke linjer.
  2. Metoder skal separeres med én blank linje.
  3. Det bør ikke være blanke linjer i metoder.

1.2.2   Funksjoner

  1. Funksjoner skal separeres med 2 blanke linjer.

1.2.3   import

  1. import <x>-linjer skal komme før from <x> import <y> linjer.

  2. import-er grupperes som i PEP-8 (stdlib, 3rd pty, internal)

  3. Det bør være èn blank linje mellom hver gruppe. Eks.:

    import os
    from collections import defaultdict
    
    import requests
    
    import Cerebrum.Errors
    from Cerebrum.Utils import Factory
    

1.3   Variabler (names)

Metodenavn og funksjonsnavn skal følge den anbefalte PEP8 konvensjonen. Eks.:

obj.delete_group()  # Riktig
obj.deleteGroup()  # IKKE riktig

1.4   Indentering

Indenteringen skal følge alle PEP8 standarder. I tillegg bør en sørge for at indenteringen ikke brytes opp. Eks.:

a_long_and_expected_result = my_func(this_is_a_very_long_var_name,
                                     this_is_another_long_var_name)  # Riktig
a_long_and_expected_result = my_func(
    this_is_a_very_long_var_name,
    this_is_another_long_var_name,
    we_can_continue_with_longer_and_longer_var_names)  # Riktig

a_long_and_expected_result = my_func(this_is_a_very_long_var_name,
                                     this_is_another_long_var_name
)  # IKKE riktig
a_long_and_expected_result = my_func(
    this_is_a_very_long_var_name,
    this_is_another_long_var_name,
    we_can_continue_with_longer_and_longer_var_names
)  # IKKE riktig

1.5   Lange linjer

1.5.1   Separator

Lange linjer skal separeres ved hjelp av paranteser og ikke ved hjelp av \ - backslash (når dette lar seg gjøre).

1.5.2   Elementer

I sekvenser (sequences) skal det være kun ett element per linje.:

# riktig
from Cerebrum.modules.bofhd.auth import (BofhdAuthOpSet,
                                         BofhdAuthOpTarget,
                                         BofhdAuthRole)
# IKKE riktig
from Cerebrum.modules.bofhd.auth import (BofhdAuthOpSet, BofhdAuthOpTarget,
                                         BofhdAuthRole)
# IKKE riktig
from Cerebrum.modules.bofhd.auth import BofhdAuthOpSet, \
                                        BofhdAuthOpTarget, \
                                        BofhdAuthRole

1.6   Kommentarer

Eksempler:

# riktig
# CONST1 - Description 1
# CONST2 - Description 2
my_tuple = (
    CONST1,
    CONST2,
    CONST3,
)

# IKKE riktig
my_tuple = (
    CONST1,  # Description 1
    CONST2,  # Description 2
    CONST3,
)


# riktig
# my very useful conditional
my_conditional = my_func()
if my_conditional:
    # handles the True conditional
    return foo

# OK
my_conditional = my_func()  # assigning my very useful conditional
if my_conditional:  # checking if the conditional is True
    return foo

# IKKE riktig
my_conditional = my_func()  # my very useful conditional as described by a
                            # very long description
if my_conditional:  # handles the True conditional
    return foo

1.7   Attributter

Attributtnavn starter med _ dersom attributtet ikke er en del av klassens API og/eller er intern for denne klassen (protected).

Attrubuttnavn starter med __ dersom attrubuttet ikke skal være tilgjengelig utenfor klassen (private).

1.8   Python 3

All kode skal designes og skrives med tanke på at den skal kjøre på Python 3 i fremtiden.

1.8.1   Unicode

Strenger som defineres eksplisitt til å være unicode-strenger i Python 2, skal defineres slikt:

my_str = u'The value of the string'  # riktig
my_str = unicode('The value of the string')  # IKKE riktig

Alle strenger bør være unicode-strenger der det lar seg gjøre.

1.8.2   Formatering av strenger

Strenger bør formateres ved hjelp av format metoden:

# riktig
composite_str = '{name} is {location}'.format(name=name, location=where)

# bør unngåes
composite_str = '%s is %s' % (name, where)

1.8.3   print

I Python 2 skal print brukes som funksjon for å gjøre migrering enklere:

from __future__ import print_function

print('This is a test')  # riktig
print 'This is a test'  # IKKE riktig

1.8.4   properties

properties og data descriptors bør brukes istedenfor get_<attribute> og set_<attribute>

1.8.5   context managers

Bruk av context managers bør vurderes hver gang en havner i try / finally situasjon (PEP343).

1.9   Strenger

  • Bruk ' over " det det lar seg gjøre. Kun bruk " dersom det er nødvending for å håndtere escapes.
  • Bruk """ for docstrings/here-strings ("""Text.""")
  • Bruk r'' dersom du trenger å bruke f.eks. backslash: r'C:\Documents\')

Eksempler:

# ' vs. "
my_str = 'This is a string'  # Foretrukket
my_str = "This is a string"  # Bør unngåes
my_str = 'That\'s another thing'  # Bør unngåes
my_str = "That's another thing"   # Foretrukket

# formatering
my_str = '{} - {}'.format(a, b)  # Bør unngåes
my_str = '{0} - {1}'.format(a, b)  # OK
my_str = '{name} - {location}'.format(name=a, location=b)  # Foretrukket

# splitte lange strenger over flere linjer (uten å bruke raw string)
my_str = ('All right... but apart from a large standard library, high '
          'readability, true high level object orientation and '
          'exception handling... what has Python ever done for us?')
Av sgs
Publisert 1. sep. 2019 07:43 - Sist endret 2. des. 2022 10:57