Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STYLE use pandas-dev-flaker #40906

Merged
merged 10 commits into from
Apr 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 9 additions & 95 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ repos:
rev: 3.9.0
hooks:
- id: flake8
additional_dependencies: [flake8-comprehensions>=3.1.0, flake8-bugbear>=21.3.2]
additional_dependencies:
- flake8-comprehensions==3.1.0
- flake8-bugbear==21.3.2
- pandas-dev-flaker==0.2.0
- id: flake8
name: flake8 (cython)
types: [cython]
Expand Down Expand Up @@ -71,7 +74,11 @@ repos:
rev: v1.2.2
hooks:
- id: yesqa
additional_dependencies: [flake8==3.9.0]
additional_dependencies:
- flake8==3.9.0
- flake8-comprehensions==3.1.0
- flake8-bugbear==21.3.2
- pandas-dev-flaker==0.2.0
- repo: local
hooks:
- id: flake8-rst
Expand All @@ -82,28 +89,6 @@ repos:
types: [rst]
args: [--filename=*.rst]
additional_dependencies: [flake8-rst==0.7.0, flake8==3.7.9]
- id: frame-or-series-union
name: Check for use of Union[Series, DataFrame] instead of FrameOrSeriesUnion alias
entry: Union\[.*(Series,.*DataFrame|DataFrame,.*Series).*\]
language: pygrep
types: [python]
exclude: ^pandas/_typing\.py$
- id: inconsistent-namespace-usage
name: 'Check for inconsistent use of pandas namespace'
entry: python scripts/check_for_inconsistent_pandas_namespace.py
language: python
types: [python]
- id: no-os-remove
name: Check code for instances of os.remove
entry: os\.remove
language: pygrep
types: [python]
files: ^pandas/tests/
exclude: |
(?x)^
pandas/tests/io/excel/test_writers\.py
|pandas/tests/io/pytables/common\.py
|pandas/tests/io/pytables/test_store\.py$
- id: unwanted-patterns
name: Unwanted patterns
language: pygrep
Expand All @@ -113,52 +98,10 @@ repos:
\#\ type:\ (?!ignore)
|\#\ type:\s?ignore(?!\[)

# foo._class__ instead of type(foo)
|\.__class__

# np.bool/np.object instead of np.bool_/np.object_
|np\.bool[^_8]
|np\.object[^_8]

# imports from pandas.core.common instead of `import pandas.core.common as com`
|from\ pandas\.core\.common\ import
|from\ pandas\.core\ import\ common

# imports from collections.abc instead of `from collections import abc`
|from\ collections\.abc\ import

# Numpy
|from\ numpy\ import\ random
|from\ numpy\.random\ import

# Incorrect code-block / IPython directives
|\.\.\ code-block\ ::
|\.\.\ ipython\ ::
types_or: [python, cython, rst]
exclude: ^doc/source/development/code_style\.rst # contains examples of patterns to avoid
- id: unwanted-patterns-in-tests
name: Unwanted patterns in tests
language: pygrep
entry: |
(?x)
# pytest.xfail instead of pytest.mark.xfail
pytest\.xfail

# imports from pandas._testing instead of `import pandas._testing as tm`
|from\ pandas\._testing\ import
|from\ pandas\ import\ _testing\ as\ tm

# No direct imports from conftest
|conftest\ import
|import\ conftest

# pandas.testing instead of tm
|pd\.testing\.

# pd.api.types instead of from pandas.api.types import ...
|(pd|pandas)\.api\.types\.
files: ^pandas/tests/
types_or: [python, cython, rst]
- id: pip-to-conda
name: Generate pip dependency from conda
description: This hook checks if the conda environment.yml and requirements-dev.txt are equal
Expand All @@ -180,35 +123,6 @@ repos:
language: python
types: [rst]
files: ^doc/source/(development|reference)/
- id: unwanted-patterns-bare-pytest-raises
name: Check for use of bare pytest raises
language: python
entry: python scripts/validate_unwanted_patterns.py --validation-type="bare_pytest_raises"
types: [python]
files: ^pandas/tests/
exclude: ^pandas/tests/extension/
- id: unwanted-patterns-private-function-across-module
name: Check for use of private functions across modules
language: python
entry: python scripts/validate_unwanted_patterns.py --validation-type="private_function_across_module"
types: [python]
exclude: ^(asv_bench|pandas/tests|doc)/
- id: unwanted-patterns-private-import-across-module
name: Check for import of private attributes across modules
language: python
entry: python scripts/validate_unwanted_patterns.py --validation-type="private_import_across_module"
types: [python]
exclude: ^(asv_bench|pandas/tests|doc)/
- id: unwanted-patterns-strings-to-concatenate
name: Check for use of not concatenated strings
language: python
entry: python scripts/validate_unwanted_patterns.py --validation-type="strings_to_concatenate"
types_or: [python, cython]
- id: unwanted-patterns-strings-with-wrong-placed-whitespace
name: Check for strings with wrong placed spaces
language: python
entry: python scripts/validate_unwanted_patterns.py --validation-type="strings_with_wrong_placed_whitespace"
types_or: [python, cython]
- id: use-pd_array-in-core
name: Import pandas.array as pd_array in core
language: python
Expand Down
2 changes: 1 addition & 1 deletion asv_bench/benchmarks/gil.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
except ImportError:
from pandas import algos
try:
from pandas._testing import test_parallel
from pandas._testing import test_parallel # noqa: PDF014

have_real_test_parallel = True
except ImportError:
Expand Down
2 changes: 1 addition & 1 deletion asv_bench/benchmarks/pandas_vb_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class BaseIO:
def remove(self, f):
"""Remove created files"""
try:
os.remove(f)
os.remove(f) # noqa: PDF008
except OSError:
# On Windows, attempting to remove a file that is in use
# causes an exception to be raised
Expand Down
30 changes: 0 additions & 30 deletions ci/code_checks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,6 @@ fi
### PATTERNS ###
if [[ -z "$CHECK" || "$CHECK" == "patterns" ]]; then

MSG='Check for use of exec' ; echo $MSG
invgrep -R --include="*.py*" -E "[^a-zA-Z0-9_]exec\(" pandas
RET=$(($RET + $?)) ; echo $MSG "DONE"

MSG='Check for pytest warns' ; echo $MSG
invgrep -r -E --include '*.py' 'pytest\.warns' pandas/tests/
RET=$(($RET + $?)) ; echo $MSG "DONE"

MSG='Check for pytest raises without context' ; echo $MSG
invgrep -r -E --include '*.py' "[[:space:]] pytest.raises" pandas/tests/
RET=$(($RET + $?)) ; echo $MSG "DONE"

MSG='Check for use of builtin filter function' ; echo $MSG
invgrep -R --include="*.py" -P '(?<!def)[\(\s]filter\(' pandas
RET=$(($RET + $?)) ; echo $MSG "DONE"

# Check for the following code in testing: `np.testing` and `np.array_equal`
MSG='Check for invalid testing' ; echo $MSG
invgrep -r -E --include '*.py' --exclude testing.py '(numpy|np)(\.testing|\.array_equal)' pandas/tests/
RET=$(($RET + $?)) ; echo $MSG "DONE"

# Check for the following code in the extension array base tests: `tm.assert_frame_equal` and `tm.assert_series_equal`
MSG='Check for invalid EA testing' ; echo $MSG
invgrep -r -E --include '*.py' --exclude base.py 'tm.assert_(series|frame)_equal' pandas/tests/extension/base
Expand All @@ -98,15 +77,6 @@ if [[ -z "$CHECK" || "$CHECK" == "patterns" ]]; then
invgrep -R --include="*.rst" -E "[a-zA-Z0-9]\`\`?[a-zA-Z0-9]" doc/source/
RET=$(($RET + $?)) ; echo $MSG "DONE"

# Check for the following code in testing: `unittest.mock`, `mock.Mock()` or `mock.patch`
MSG='Check that unittest.mock is not used (pytest builtin monkeypatch fixture should be used instead)' ; echo $MSG
invgrep -r -E --include '*.py' '(unittest(\.| import )mock|mock\.Mock\(\)|mock\.patch)' pandas/tests/
RET=$(($RET + $?)) ; echo $MSG "DONE"

MSG='Check for use of {foo!r} instead of {repr(foo)}' ; echo $MSG
invgrep -R --include=*.{py,pyx} '!r}' pandas
RET=$(($RET + $?)) ; echo $MSG "DONE"
echo $MSG "DONE"
fi

### CODE ###
Expand Down
143 changes: 2 additions & 141 deletions doc/source/development/code_style.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,147 +19,8 @@ consistent code format throughout the project. We encourage you to use
Patterns
========

Using foo.__class__
-------------------


pandas uses 'type(foo)' instead 'foo.__class__' as it is making the code more
readable.
For example:

**Good:**

.. code-block:: python

foo = "bar"
type(foo)

**Bad:**

.. code-block:: python

foo = "bar"
foo.__class__


String formatting
=================

Concatenated strings
--------------------

Using f-strings
~~~~~~~~~~~~~~~

pandas uses f-strings formatting instead of '%' and '.format()' string formatters.

The convention of using f-strings on a string that is concatenated over several lines,
is to prefix only the lines containing values which need to be interpreted.

For example:

**Good:**

.. code-block:: python

foo = "old_function"
bar = "new_function"

my_warning_message = (
f"Warning, {foo} is deprecated, "
"please use the new and way better "
f"{bar}"
)

**Bad:**

.. code-block:: python

foo = "old_function"
bar = "new_function"

my_warning_message = (
f"Warning, {foo} is deprecated, "
f"please use the new and way better "
f"{bar}"
)

White spaces
~~~~~~~~~~~~

Only put white space at the end of the previous line, so
there is no whitespace at the beginning of the concatenated string.

For example:

**Good:**

.. code-block:: python

example_string = (
"Some long concatenated string, "
"with good placement of the "
"whitespaces"
)

**Bad:**

.. code-block:: python

example_string = (
"Some long concatenated string,"
" with bad placement of the"
" whitespaces"
)

Representation function (aka 'repr()')
--------------------------------------

pandas uses 'repr()' instead of '%r' and '!r'.

The use of 'repr()' will only happen when the value is not an obvious string.

For example:

**Good:**

.. code-block:: python

value = str
f"Unknown received value, got: {repr(value)}"

**Good:**

.. code-block:: python

value = str
f"Unknown received type, got: '{type(value).__name__}'"


Imports (aim for absolute)
==========================

In Python 3, absolute imports are recommended. Using absolute imports, doing something
like ``import string`` will import the string module rather than ``string.py``
in the same directory. As much as possible, you should try to write out
absolute imports that show the whole import chain from top-level pandas.

Explicit relative imports are also supported in Python 3 but it is not
recommended to use them. Implicit relative imports should never be used
and are removed in Python 3.

For example:

::

# preferred
import pandas.core.common as com

# not preferred
from .common import test_base

# wrong
from common import test_base
We use a ``flake8`` plugin, `pandas-dev-flaker <https://github.com/pandas-dev/pandas-dev-flaker>`_, to
check our codebase for unwanted patterns. See its ``README`` for the up-to-date list of rules we enforce.

Testing
=======
Expand Down
5 changes: 3 additions & 2 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ dependencies:
- black=20.8b1
- cpplint
- flake8=3.9.0
- flake8-bugbear>=21.3.2 # used by flake8, find likely bugs
- flake8-comprehensions>=3.1.0 # used by flake8, linting of unnecessary comprehensions
- flake8-bugbear=21.3.2 # used by flake8, find likely bugs
- flake8-comprehensions=3.1.0 # used by flake8, linting of unnecessary comprehensions
- isort>=5.2.1 # check that imports are in the right order
- mypy=0.812
- pre-commit>=2.9.2
Expand Down Expand Up @@ -117,3 +117,4 @@ dependencies:
- pip:
- git+https://github.com/pydata/pydata-sphinx-theme.git@master
- numpydoc < 1.2 # 2021-02-09 1.2dev breaking CI
- pandas-dev-flaker==0.2.0
2 changes: 1 addition & 1 deletion pandas/_testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ def external_error_raised(expected_exception: type[Exception]) -> ContextManager
"""
import pytest

return pytest.raises(expected_exception, match=None)
return pytest.raises(expected_exception, match=None) # noqa: PDF010


cython_table = pd.core.common._cython_table.items()
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/window/ewm.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from pandas.core.dtypes.common import is_datetime64_ns_dtype
from pandas.core.dtypes.missing import isna

import pandas.core.common as common
import pandas.core.common as common # noqa: PDF018
from pandas.core.util.numba_ import maybe_use_numba
from pandas.core.window.common import zsqrt
from pandas.core.window.doc import (
Expand Down
Loading