増加するPythonコードの改良


写真Matěj Baťha / CC-BY-SA 2.5
私たちの多くは、コードの品質を改善するためのツールを採用している
  • コードフォーマッタ
  • プリンタとプリンタ
  • テストカバレッジ測定
  • Pythonでは、このようなツールには次のようなものがあります.

  • Black (コードの書式設定)

  • isort (インポートのソートとフォーマット)

  • Pylint (コード品質)

  • Flake8 (コード形式)

  • Mypy (静的タイピング)

  • coverage.py (テストカバレッジ)
  • 新しいプロジェクトと小さなプロジェクトでは、そのような自動コード変更とコード全体の品質チェックを実施するのは簡単です.これは、ローカルのgitフックだけでなく、CIパイプラインで行うことができます.
    しかし、あなたが大きな既存のコードベースを持っているか、オープンソースプロジェクトに貢献しているならば、1つの試みですべてのチェック緑を回すのは可能でないかもしれません.
    一つの試みでコードベースを再フォーマットしない1つの良い理由は、すべての再フォーマットされた線のために作者情報が失われるということです.中git --ignore-rev この問題の1つの解決策を提供してください、このブログ柱はもう一つの選択肢を提示します.

    導入Darker – 適用Black 徐々にフォーマット
    背後にある考えDarker コードを再フォーマットするBlackisort ), しかし、開発者によって変更された領域に新しい書式を適用するだけです.
    Darkerによって提案された変更だけを適用することによって、CodeBaseは徐々に、すべてのコードがBlack 規則
    Darker また、品質チェックを実行することができます.あなたが新しく修正された地域に触れるものを見るように違反は濾過されます.
    最後にpytest-darker プラグインは、このすべてを統合Pytest それで、再フォーマットとチェックは単位テストとともに実行されます.

    私は販売しているDarker ?
    次の例では、まず何を表示しますかDarker コマンドラインで手動で使用したとき、一般的なオープンソースプロジェクトの現実世界の状況で行われたでしょう.
    また、テストスイートとの統合方法を示しますpytest-darker プラグイン.

    事例研究
    クローンを始めましょうdateutil パッケージ
    $ git clone https://github.com/dateutil/dateutil.git
    $ cd dateutil
    
    2020年1月にはモルモットとして使える小さな特徴の枝があったDarker (参照)dateutil/dateutil#993 ):
    $ export GIT_PAGER=cat
    
    $ git log --graph --oneline a332879..6edfecd
    * 6edfecd Update documentation links
    *   110a09b Merge pull request #993 from pganssle/parsererror_repr
    |\  
    | * ea7f441 Fix custom repr for ParserError
    |/  
    * 21fe6e9 Merge pull request #987 from eastface/issue_981
    
    我々は今、その前に状況を再現することができます pganssle/parsererror_repr 枝はリセットされたmaster 枝の前に戻る.
    $ git reset --hard 21fe6e9
    HEAD is now at 21fe6e9 Merge pull request #987 from eastface/issue_981
    
    ...そして、 pganssle/parsererror_repr マージが完了する前の時点で分岐します.
    $ git checkout -b pganssle/parsererror_repr ea7f441
    Switched to a new branch 'pganssle/parsererror_repr'
    
    我々の倉庫は、ブランチが合併される前に、同様の状態にあります:
    $ git log --graph --oneline master^..
    * ea7f441 (HEAD -> pganssle/parsererror_repr) Fix custom repr for ParserError
    * 21fe6e9 (master) Merge pull request #987 from eastface/issue_981
    * a332879 Added Mark Bailey to AUTHORS file
    * 79d2e48 Fix TypeError in parser wrapper logic
    
    によって導入された変更点 pganssle/parsererror_repr 枝は
    $ git diff -U0 master
    diff --git a/changelog.d/991.bugfix.rst b/changelog.d/991.bugfix.rst
    new file mode 100644
    index 0000000..473082e
    --- /dev/null
    +++ b/changelog.d/991.bugfix.rst
    @@ -0,0 +1 @@
    +Fixed the custom ``repr`` for ``dateutil.parser.ParserError``, which was not defined due to an indentation error. (gh issue #991, gh pr #993)
    diff --git a/dateutil/parser/_parser.py b/dateutil/parser/_parser.py
    index 7fcfa54..8d67584 100644
    --- a/dateutil/parser/_parser.py
    +++ b/dateutil/parser/_parser.py
    @@ -1603,2 +1603,3 @@ class ParserError(ValueError):
    -        def __repr__(self):
    -            return "%s(%s)" % (self.__class__.__name__, str(self))
    +    def __repr__(self):
    +        args = ", ".join("'%s'" % arg for arg in self.args)
    +        return "%s(%s)" % (self.__class__.__name__, args)
    diff --git a/dateutil/test/test_parser.py b/dateutil/test/test_parser.py
    index 605705e..cfa4bbb 100644
    --- a/dateutil/test/test_parser.py
    +++ b/dateutil/test/test_parser.py
    @@ -945,0 +946,9 @@ def test_decimal_error(value):
    +
    +def test_parsererror_repr():
    +    # GH 991 — the __repr__ was not properly indented and so was never defined.
    +    # This tests the current behavior of the ParserError __repr__, but the
    +    # precise format is not guaranteed to be stable and may change even in
    +    # minor versions. This test exists to avoid regressions.
    +    s = repr(ParserError("Problem with string: %s", "2019-01-01"))
    +
    +    assert s == "ParserError('Problem with string: %s', '2019-01-01')"
    
    表面にはすべての変化が見えるBlack 準拠.を返します.master 既にBlack フォーマットされて、我々は単に走ることができましたBlack 我々が何かを逃したかどうか見るために pganssle/parsererror_repr 枝.でもああ
    $ pip install -q black
    
    $ black --diff .
    ### ... LOTS of output redacted ...
    All done! ✨ 🍰 ✨
    35 files would be reformatted, 3 files would be left unchanged.
    
    ありがとうBlack , しかし、このブランチの変更がうまくフォーマットされているかどうかだけに興味があります.
    残念ながらBlack ボックスのこの機能を提供しません.代わりに、我々は使用しますDarker :
    $ pip install -q darker
    
    $ darker --diff --revision master... .
    --- dateutil/test/test_parser.py
    +++ dateutil/test/test_parser.py
    @@ -944,6 +944,7 @@
         with pytest.raises(ParserError):
             parse(value)
    
    +
     def test_parsererror_repr():
         # GH 991 — the __repr__ was not properly indented and so was never defined.
         # This tests the current behavior of the ParserError __repr__, but the
    
    ハ!それで、我々は機能定義の前に1つの改行を逃しました!
    我々は今ちょうど実行することができますDarker without the --diff フラグを指定すると、実際にソースコードに変更が書き込まれます.
    $ darker --revision master... . 
    
    $ git diff -U1
    diff --git a/dateutil/test/test_parser.py b/dateutil/test/test_parser.py
    index cfa4bbb..53a02de 100644
    --- a/dateutil/test/test_parser.py
    +++ b/dateutil/test/test_parser.py
    @@ -946,2 +946,3 @@ def test_decimal_error(value):
    
    +
     def test_parsererror_repr():
    

    走るDarker テストスイートの一部として
    これでインストールできますpytest-darker :
    $ pip install -q pytest-darker
    
    設定しますDarker したがって、常にチェックしますが、ソースファイルを変更しません.これはpyproject.toml ファイル
    [tool.darker]
    src = [
        "."
    ]
    check = true
    diff = true
    revision = "master..."
    
    テストスイートを実行し、機能分岐の書式を確認することもできます.
    $ pip install --quiet --requirement requirement-dev.txt
    $ pytest --darker
    ====================== test session starts =======================
    # ... lots of output ...
    dateutil/test/test_parser.py F............................ [ 38%]
    .......................................................... [ 40%]
    .......................................................... [ 43%]
    .......................................................... [ 46%]
    ...................xxxxxxxxxxxxx..........                 [ 48%]
    # ... more output ...
    ============================ FAILURES ============================
    ______________________ Darker format check _______________________
    Edited lines are not Black formatted
    ---------------------- Captured stdout call ----------------------
    --- dateutil/test/test_parser.py
    +++ dateutil/test/test_parser.py
    @@ -944,6 +944,7 @@
         with pytest.raises(ParserError):
             parse(value)
    
    +
     def test_parsererror_repr():
         # GH 991 — the __repr__ was not properly indented and so was never defined.
         # This tests the current behavior of the ParserError __repr__, but the
    ==================== short test summary info =====================
    FAILED dateutil/test/test_parser.py::DARKER
    ===== 1 failed, 2012 passed, 84 skipped, 19 xfailed in 7.12s =====
    

    より多くのグッズ
    私は走る方法を示したDarker コマンドラインだけでなく、テストスイートに統合.将来のブログ記事で、私は計画します
  • 統合ガイドDarker IDEで
  • 持ち方を見せるTravis CI ギタブランDarker , and
  • 謎を説明する--revision master... コマンドラインオプション.
  • インポートの並べ替え方法とコードのリンギングを行う方法Darker

  • 貢献!
    我々は、貢献する開発者の小さな幸せな束ですDarker on its GitHub repository – ドロップで言って、こんにちはと言うとあなたの手の見直しとプル要求を提出し、バグ報告を作る!また、時々virtual meetups スパンニングの大陸とタイムゾーン、そして我々もそこにあなたを参照してください!