1.. _styleguide: 2 3Translate Styleguide 4==================== 5 6The Translate styleguide is the styleguide for all Translate projects, 7including Translate Toolkit, Pootle, Virtaal and others. Patches are required 8to follow these guidelines. 9 10This Styleguide follows :pep:`8` with some clarifications. It is based almost 11verbatim on the `Flask Styleguide`_. 12 13pre-commit hooks 14---------------- 15 16The Translate styleguide can be checked by `pre-commit`_. The Translate toolkit 17repository repository contains configuration for it to verify the committed 18files are sane. After installing it (it is already included in the 19:file:`requirements/dev.txt`) turn it on by running ``pre-commit install`` in 20Translate toolkit checkout. This way all your changes will be automatically 21checked. 22 23You can also trigger check manually, to check all files run: 24 25.. code-block:: sh 26 27 pre-commit run --all 28 29.. _pre-commit: https://pre-commit.com/ 30 31.. _styleguide-python: 32 33Python 34------ 35 36These are the Translate conventions for Python coding style. 37 38.. _styleguide-general: 39 40General 41^^^^^^^ 42 43Indentation 44~~~~~~~~~~~ 45 464 real spaces, no tabs. Exceptions: modules that have been copied into the 47source that don't follow this guideline. 48 49 50Maximum line length 51~~~~~~~~~~~~~~~~~~~ 52 5379 characters with a soft limit for 84 if absolutely necessary. Try to avoid 54too nested code by cleverly placing `break`, `continue` and `return` 55statements. 56 57 58Continuing long statements 59~~~~~~~~~~~~~~~~~~~~~~~~~~ 60 61To continue a statement you can use backslashes (preceded by a space) in which 62case you should align the next line with the last dot or equal sign, or indent 63four spaces: 64 65.. code-block:: python 66 67 MyModel.query.filter(MyModel.scalar > 120) \ 68 .order_by(MyModel.name.desc()) \ 69 .limit(10) 70 71 my_long_assignment = MyModel.query.filter(MyModel.scalar > 120) \ 72 .order_by(MyModel.name.desc()) \ 73 .limit(10) 74 75 this_is_a_very_long(function_call, 'with many parameters') \ 76 .that_returns_an_object_with_an_attribute 77 78 79If you break in a statement with parentheses or braces, align to the braces: 80 81.. code-block:: python 82 83 this_is_a_very_long(function_call, 'with many parameters', 84 23, 42, 'and even more') 85 86 87If you need to break long strings, on function calls or when assigning to 88variables, try to use implicit string continuation: 89 90.. code-block:: python 91 92 this_holds_a_very_long_string("Very long string with a lot of characters " 93 "and words on it, so many that it is " 94 "necessary to break it in several lines to " 95 "improve readability.") 96 long_string_var = ("Very long string with a lot of characters and words on " 97 "it, so many that it is necessary to break it in " 98 "several lines to improve readability.") 99 100 101For lists or tuples with many items, break immediately after the opening brace: 102 103.. code-block:: python 104 105 items = [ 106 'this is the first', 'set of items', 'with more items', 107 'to come in this line', 'like this' 108 ] 109 110 111Blank lines 112~~~~~~~~~~~ 113 114Top level functions and classes are separated by two lines, everything else 115by one. Do not use too many blank lines to separate logical segments in code. 116Example: 117 118.. code-block:: python 119 120 def hello(name): 121 print('Hello %s!' % name) 122 123 124 def goodbye(name): 125 print('See you %s.' % name) 126 127 128 class MyClass: 129 """This is a simple docstring""" 130 131 def __init__(self, name): 132 self.name = name 133 134 @property 135 def annoying_name(self): 136 return self.name.upper() + '!!!!111' 137 138 139Strings 140~~~~~~~ 141 142- Double quotes are suggested over single quotes, but always try to respect the 143 surrounding coding style. This is overruled by escaping which you should always 144 try to avoid. 145 146 .. code-block:: python 147 148 # Good. 149 str1 = "Sauron's eye" 150 str2 = 'Its name is "Virtaal".' 151 152 153 # Bad. 154 str3 = 'Sauron\'s eye' 155 str4 = "Its name is \"Virtaal\"." 156 157 158String formatting 159~~~~~~~~~~~~~~~~~ 160 161While str.format() is more powerful than %-formatting, the latter has been the 162canonical way of formatting strings in Python for a long time and the Python 163core team has shown no desire to settle on one syntax over the other. 164For simple, serial positional cases (non-translatable strings), the old "%s" 165way of formatting is preferred. 166For anything more complex, including translatable strings, str.format is 167preferred as it is significantly more powerful and often cleaner. 168 169.. code-block:: python 170 171 # Good 172 print("Hello, {thing}".format(thing="world")) 173 print("Hello, {}".format("world")) 174 print("%s=%r" % ("hello", "world")) # non-translatable strings 175 176 # Bad 177 print("%s, %s" % ("Hello", "world")) # Translatable string. 178 print("Hello, %(thing)s" % {"thing": "world"}) # Use {thing}. 179 180 181.. _styleguide-imports: 182 183Imports 184~~~~~~~ 185 186Like in :pep:`8`, but: 187 188- Imports should be grouped in the following order: 189 190 1) __future__ library imports 191 2) Python standard library imports 192 3) Third party libraries imports 193 4) Translate Toolkit imports 194 5) Current package imports, using explicit relative imports (See `PEP 328 195 <http://www.python.org/dev/peps/pep-0328/#guido-s-decision>`_) 196 197- A blank line must be present between each group of imports (like in PEP8). 198- Imports on each group must be arranged alphabetically by module name: 199 200 - Shortest module names must be before longer ones: 201 ``from django.db import ...`` before ``from django.db.models import ...``. 202 203- ``import ...`` calls must precede ``from ... import`` ones on each group: 204 205 - On each of these subgroups the entries should be alphabetically arranged. 206 - No blank lines between subgroups. 207 208- On ``from ... import`` 209 210 - Use a ``CONSTANT``, ``Class``, ``function`` order, where the constants, 211 classes and functions are in alphabetical order inside of its respective 212 groups. 213 - If the import line exceeds the 80 chars, then split it using parentheses to 214 continue the import on the next line (aligning the imported items with the 215 opening parenthesis). 216 217.. code-block:: python 218 219 from __future__ import absolute_import 220 221 import re 222 import sys.path as sys_path 223 import time 224 from datetime import timedelta 225 from os import path 226 227 from lxml.html import fromstring 228 229 from translate.filters import checks 230 from translate.storage import base 231 from translate.storage.aresource import (EOF, WHITESPACE, AndroidFile, 232 AndroidUnit, android_decode, 233 android_encode) 234 235 from . import php2po 236 237 238Properties 239~~~~~~~~~~ 240 241- Never use ``lambda`` functions: 242 243 .. code-block:: python 244 245 # Good. 246 @property 247 def stores(self): 248 return self.child.stores 249 250 251 # Bad. 252 stores = property(lambda self: self.child.stores) 253 254 255- Try to use ``@property`` instead of ``get_*`` or ``is_*`` methods that don't 256 require passing any parameter: 257 258 .. code-block:: python 259 260 # Good. 261 @property 262 def terminology(self): 263 ... 264 265 @property 266 def is_monolingual(self): 267 ... 268 269 270 # Also good. 271 def get_stores_for_language(self, language): 272 ... 273 274 275 # Bad. 276 def get_terminology(self): 277 ... 278 279 def is_monolingual(self): 280 ... 281 282 283- Always use ``@property`` instead of ``property(...)``, even for properties 284 that also have a setter or a deleter: 285 286 .. code-block:: python 287 288 # Good. 289 @property 290 def units(self): 291 ... 292 293 294 # Also good. 295 @property 296 def x(self): 297 """I'm the 'x' property.""" 298 return self._x 299 300 @x.setter 301 def x(self, value): # Note: Method must be named 'x' too. 302 self._x = value 303 304 @x.deleter 305 def x(self): # Note: Method must be named 'x' too. 306 del self._x 307 308 309 # Bad. 310 def _get_units(self): 311 ... 312 units = property(_get_units) 313 314 315 # Also bad. 316 def getx(self): 317 return self._x 318 def setx(self, value): 319 self._x = value 320 def delx(self): 321 del self._x 322 x = property(getx, setx, delx, "I'm the 'x' property.") 323 324 325Expressions and Statements 326^^^^^^^^^^^^^^^^^^^^^^^^^^ 327 328General whitespace rules 329~~~~~~~~~~~~~~~~~~~~~~~~ 330 331- No whitespace for unary operators that are not words (e.g.: ``-``, ``~`` 332 etc.) as well on the inner side of parentheses. 333- Whitespace is placed between binary operators. 334 335.. code-block:: python 336 337 # Good. 338 exp = -1.05 339 value = (item_value / item_count) * offset / exp 340 value = my_list[index] 341 value = my_dict['key'] 342 343 344 # Bad. 345 exp = - 1.05 346 value = ( item_value / item_count ) * offset / exp 347 value = (item_value/item_count)*offset/exp 348 value=( item_value/item_count ) * offset/exp 349 value = my_list[ index ] 350 value = my_dict ['key'] 351 352 353Slice notation 354~~~~~~~~~~~~~~ 355 356While :pep:`8` calls for spaces around operators ``a = b + c`` this results in 357flags when you use ``a[b+1:c-1]`` but would allow the rather unreadable 358``a[b + 1:c - 1]`` to pass. :pep:`8` is rather quiet on slice notation. 359 360- Don't use spaces with simple variables or numbers 361- Use brackets for expressions with spaces between binary operators 362 363 .. code-block:: python 364 365 # Good. 366 a[1:2] 367 a[start:end] 368 a[(start - 1):(end + var + 2)] # Brackets help group things and don't hide the slice 369 a[-1:(end + 1)] 370 371 372 # Bad. 373 a[start: end] # No spaces around : 374 a[start-1:end+var+2] # Insanely hard to read, especially when your expressions are more complex 375 a[start - 1:end + 2] # You lose sight of the fact that it is a slice 376 a[- 1:end] # -1 is unary, no space 377 378 379.. note:: 380 381 String slice formatting is still under discussion. 382 383Comparisons 384~~~~~~~~~~~ 385 386- Against arbitrary types: ``==`` and ``!=`` 387- Against singletons with ``is`` and ``is not`` (e.g.: ``foo is not None``) 388- Never compare something with `True` or `False` (for example never do ``foo == 389 False``, do ``not foo`` instead) 390 391 392Negated containment checks 393~~~~~~~~~~~~~~~~~~~~~~~~~~ 394 395- Use ``foo not in bar`` instead of ``not foo in bar`` 396 397 398Instance checks 399~~~~~~~~~~~~~~~ 400 401- ``isinstance(a, C)`` instead of ``type(A) is C``, but try to avoid instance 402 checks in general. Check for features. 403 404 405If statements 406~~~~~~~~~~~~~ 407 408- Use ``()`` brackets around complex if statements to allow easy wrapping, 409 don't use backslash to wrap an if statement. 410- Wrap between ``and``, ``or``, etc. 411- Keep ``not`` with the expression 412- Use ``()`` alignment between expressions 413- Use extra ``()`` to eliminate ambiguity, don't rely on an understanding of 414 Python operator precedence rules. 415 416 .. code-block:: python 417 418 # Good. 419 if length >= (upper + 2): 420 ... 421 422 if (length >= 25 and 423 string != "Something" and 424 not careful): 425 do_something() 426 427 428 # Bad. 429 if length >= upper + 2: 430 ... 431 432 if (length... 433 and string !=... 434 435 436Naming Conventions 437^^^^^^^^^^^^^^^^^^ 438 439.. note:: 440 441 This has not been implemented or discussed. The Translate code 442 is not at all consistent with these conventions. 443 444 445- Class names: ``CamelCase``, with acronyms kept uppercase (``HTTPWriter`` and 446 not ``HttpWriter``) 447- Variable names: ``lowercase_with_underscores`` 448- Method and function names: ``lowercase_with_underscores`` 449- Constants: ``UPPERCASE_WITH_UNDERSCORES`` 450- precompiled regular expressions: ``name_re`` 451 452Protected members are prefixed with a single underscore. Double underscores 453are reserved for mixin classes. 454 455To prevent name clashes with keywords, one trailing underscore may be appended. 456Clashes with builtins are allowed and **must not** be resolved by appending an 457underline to the name. If your code needs to access a shadowed builtin, rebind 458the builtin to a different name instead. Consider using a different name to 459avoid having to deal with either type of name clash, but don't complicate names 460with prefixes or suffixes. 461 462 463Function and method arguments 464~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 465 466- Class methods: ``cls`` as first parameter 467- Instance methods: ``self`` as first parameter 468 469 470.. _styleguide-docs: 471 472Documentation 473============= 474 475We use Sphinx_ to generate our API and user documentation. Read the 476`reStructuredText primer`_ and `Sphinx documentation`_ as needed. 477 478 479Special roles 480------------- 481 482We introduce a number of special roles for documentation: 483 484* ``:issue:`` -- links to a toolkit issue Github. 485 486 * ``:issue:`234``` gives: :issue:`234` 487 * ``:issue:`broken <234>``` gives: :issue:`broken <234>` 488 489* ``:opt:`` -- mark command options and command values. 490 491 * ``:opt:`-P``` gives :opt:`-P` 492 * ``:opt:`--progress=dots``` gives :opt:`--progress=dots` 493 * ``:opt:`dots``` gives :opt:`dots` 494 495* ``:man:`` -- link to a Linux man page. 496 497 * ``:man:`msgfmt``` gives :man:`msgfmt` 498 499 500Code and command line highlighting 501---------------------------------- 502 503All code examples and format snippets should be highlighted to make them easier 504to read. By default Sphinx uses Python highlighting of code snippets (but it 505doesn't always work). You will want to change that in these situations: 506 507.. highlight:: rest 508 509* The examples are not Python e.g. talking about INI file parsing. In which 510 case set the file level highlighting using:: 511 512 .. highlight:: ini 513 514* There are multiple different code examples in the document, then use:: 515 516 .. code-block:: ruby 517 518 before each code block. 519 520* Python code highlighting isn't working, then force Python highlighting using:: 521 522 .. code-block:: python 523 524.. note:: Generally we prefer explicit markup as this makes it easier for those 525 following you to know what you intended. So use ``.. code-block:: python`` 526 even though in some cases this is not required. 527 528With *command line examples*, to improve readability use:: 529 530 .. code-block:: console 531 532Add ``$`` command prompt markers and ``#`` comments as required, as shown in 533this example: 534 535.. code-block:: console 536 537 $ cd docs 538 $ make html # Build all Sphinx documentation 539 $ make linkcheck # Report broken links 540 541 542.. highlight:: python 543 544 545User documentation 546------------------ 547 548This is documentation found in ``docs/`` and that is published on Read the 549Docs. The target is the end user so our primary objective is to make accessible, 550readable and beautiful documents for them. 551 552 553Docstrings 554---------- 555 556Docstring conventions: 557 All docstrings are formatted with reStructuredText as understood by 558 Sphinx. Depending on the number of lines in the docstring, they are 559 laid out differently. If it's just one line, the closing triple 560 quote is on the same line as the opening, otherwise the text is on 561 the same line as the opening quote and the triple quote that closes 562 the string on its own line: 563 564 .. code-block:: python 565 566 def foo(): 567 """This is a simple docstring.""" 568 569 570 def bar(): 571 """This is a longer docstring with so much information in there 572 that it spans three lines. In this case the closing triple quote 573 is on its own line. 574 """ 575 576 577Please read :pep:`257` (Docstring Conventions) for a general overview, 578the important parts though are: 579 580- A docstring should have a brief one-line summary, ending with a period. Use 581 ``Do this``, ``Return that`` rather than ``Does ...``, ``Returns ...``. 582- If there are more details there should be a blank line between the one-line 583 summary and the rest of the text. Use paragraphs and formatting as needed. 584- Use `reST field lists`_ to describe the input parameters and/or return types 585 as the last part of the docstring. 586- Use proper capitalisation and punctuation. 587- Don't restate things that would appear in parameter descriptions. 588 589.. code-block:: python 590 591 def addunit(self, unit): 592 """Append the given unit to the object's list of units. 593 594 This method should always be used rather than trying to modify the 595 list manually. 596 597 :param Unit unit: Any object that inherits from :class:`Unit`. 598 """ 599 self.units.append(unit) 600 601 602Parameter documentation: 603 Document parameters using `reST field lists`_ as follows: 604 605 .. code-block:: python 606 607 def foo(bar): 608 """Simple docstring. 609 610 :param SomeType bar: Something 611 :return: Returns something 612 :rtype: Return type 613 """ 614 615 616Cross referencing code: 617 When talking about other objects, methods, functions and variables 618 it is good practice to cross-reference them with Sphinx's `Python 619 cross-referencing`_. 620 621Other directives: 622 Use `paragraph-level markup`_ when needed. 623 624.. note:: 625 626 We still need to gather the useful ones that we want you to use and how to use 627 them. E.g. how to talk about a parameter in the docstring. How to reference 628 classes in the module. How to reference other modules, etc. 629 630 631Module header: 632 The module header consists of a utf-8 encoding declaration, copyright 633 attribution, license block and a standard docstring: 634 635 .. code-block:: python 636 637 # 638 ... LICENSE BLOCK... 639 640 """A brief description""" 641 642.. """ 643 package.module 644 ~~~~~~~~~~~~~~ 645 646.. A brief description goes here. 647 648.. :copyright: (c) YEAR by AUTHOR. 649 :license: LICENSE_NAME, see LICENSE_FILE for more details. 650 """ 651 652Deprecation: 653 Document the deprecation and version when deprecating features: 654 655 .. code-block:: python 656 657 from translate.misc.deprecation import deprecated 658 659 660 @deprecated("Use util.run_fast() instead.") 661 def run_slow(): 662 """Run fast 663 664 .. deprecated:: 1.5 665 Use :func:`run_fast` instead. 666 """ 667 run_fast() 668 669 670 671Comments 672-------- 673 674General: 675 - The ``#`` symbol (pound or hash) is used to start comments. 676 - A space must follow the ``#`` between any written text. 677 - Line length must be observed. 678 - Inline comments are preceded by two spaces. 679 - Write sentences correctly: proper capitalisation and punctuation. 680 681 .. code-block:: python 682 683 # Good comment with space before and full sentence. 684 statement # Good comment with two spaces 685 686 687 #Bad comment no space before 688 statement # Bad comment, needs two spaces 689 690 691Docstring comments: 692 Rules for comments are similar to docstrings. Both are formatted with 693 reStructuredText. If a comment is used to document an attribute, put a 694 colon after the opening pound sign (``#``): 695 696 .. code-block:: python 697 698 class User: 699 #: the name of the user as unicode string 700 name = Column(String) 701 #: the sha1 hash of the password + inline salt 702 pw_hash = Column(String) 703 704 705.. _Flask Styleguide: http://flask.pocoo.org/docs/styleguide/ 706.. _reST field lists: http://sphinx-doc.org/domains.html#info-field-lists 707.. _Python cross-referencing: http://sphinx-doc.org/domains.html#cross-referencing-python-objects 708.. _Sphinx: http://sphinx-doc.org/ 709.. _reStructuredText primer: http://sphinx-doc.org/rest.html 710.. _Sphinx documentation: http://sphinx-doc.org/contents.html 711.. _paragraph-level markup: http://sphinx-doc.org/markup/para.html#paragraph-level-markup 712