diff --git a/.gitignore b/.gitignore index 816aff376fc83..f4f64aac23905 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,7 @@ dist .coverage coverage.xml coverage_html_report +.mypy_cache *.pytest_cache # hypothesis test database .hypothesis/ diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6c30ec641f292..9b1b17b453af3 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -88,6 +88,13 @@ jobs: displayName: 'Docstring validation' condition: true + - script: | + export PATH=$HOME/miniconda3/bin:$PATH + source activate pandas-dev + ci/code_checks.sh typing + displayName: 'Typing validation' + condition: true + - script: | export PATH=$HOME/miniconda3/bin:$PATH source activate pandas-dev diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 658c2bc50e87b..9f3ded88b5e7d 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -16,9 +16,10 @@ # $ ./ci/code_checks.sh doctests # run doctests # $ ./ci/code_checks.sh docstrings # validate docstring errors # $ ./ci/code_checks.sh dependencies # check that dependencies are consistent +# $ ./ci/code_checks.sh typing # run static type analysis -[[ -z "$1" || "$1" == "lint" || "$1" == "patterns" || "$1" == "code" || "$1" == "doctests" || "$1" == "docstrings" || "$1" == "dependencies" ]] || \ - { echo "Unknown command $1. Usage: $0 [lint|patterns|code|doctests|docstrings|dependencies]"; exit 9999; } +[[ -z "$1" || "$1" == "lint" || "$1" == "patterns" || "$1" == "code" || "$1" == "doctests" || "$1" == "docstrings" || "$1" == "dependencies" || "$1" == "typing" ]] || \ + { echo "Unknown command $1. Usage: $0 [lint|patterns|code|doctests|docstrings|dependencies|typing]"; exit 9999; } BASE_DIR="$(dirname $0)/.." RET=0 @@ -256,4 +257,16 @@ if [[ -z "$CHECK" || "$CHECK" == "dependencies" ]]; then fi +### TYPING ### +if [[ -z "$CHECK" || "$CHECK" == "typing" ]]; then + + echo "mypy --version" + mypy --version + + MSG='Performing static analysis using mypy' ; echo $MSG + mypy pandas + RET=$(($RET + $?)) ; echo $MSG "DONE" +fi + + exit $RET diff --git a/environment.yml b/environment.yml index 41f013c52041c..1d7c8b96216e3 100644 --- a/environment.yml +++ b/environment.yml @@ -19,6 +19,7 @@ dependencies: - hypothesis>=3.82 - isort - moto + - mypy - pycodestyle - pytest>=4.0.2 - pytest-mock diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000000000..b7dbf390fa8c9 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,201 @@ +[mypy] +ignore_missing_imports=True +follow_imports=silent + +[mypy-pandas.conftest,pandas.tests.*] +ignore_errors=True + +[mypy-pandas._config.config] +ignore_errors=True + +[mypy-pandas._version] +ignore_errors=True + +[mypy-pandas.compat] +ignore_errors=True + +[mypy-pandas.compat.numpy.function] +ignore_errors=True + +[mypy-pandas.compat.pickle_compat] +ignore_errors=True + +[mypy-pandas.core.accessor] +ignore_errors=True + +[mypy-pandas.core.api] +ignore_errors=True + +[mypy-pandas.core.apply] +ignore_errors=True + +[mypy-pandas.core.arrays.array_] +ignore_errors=True + +[mypy-pandas.core.arrays.datetimelike] +ignore_errors=True + +[mypy-pandas.core.arrays.integer] +ignore_errors=True + +[mypy-pandas.core.arrays.interval] +ignore_errors=True + +[mypy-pandas.core.arrays.numpy_] +ignore_errors=True + +[mypy-pandas.core.arrays.period] +ignore_errors=True + +[mypy-pandas.core.arrays.sparse] +ignore_errors=True + +[mypy-pandas.core.arrays.timedeltas] +ignore_errors=True + +[mypy-pandas.core.base] +ignore_errors=True + +[mypy-pandas.core.computation.expr] +ignore_errors=True + +[mypy-pandas.core.computation.ops] +ignore_errors=True + +[mypy-pandas.core.computation.pytables] +ignore_errors=True + +[mypy-pandas.core.config] +ignore_errors=True + +[mypy-pandas.core.config_init] +ignore_errors=True + +[mypy-pandas.core.dtypes.dtypes] +ignore_errors=True + +[mypy-pandas.core.dtypes.missing] +ignore_errors=True + +[mypy-pandas.core.frame] +ignore_errors=True + +[mypy-pandas.core.generic] +ignore_errors=True + +[mypy-pandas.core.groupby.generic] +ignore_errors=True + +[mypy-pandas.core.groupby.groupby] +ignore_errors=True + +[mypy-pandas.core.groupby.ops] +ignore_errors=True + +[mypy-pandas.core.indexes.base] +ignore_errors=True + +[mypy-pandas.core.indexes.datetimelike] +ignore_errors=True + +[mypy-pandas.core.indexes.datetimes] +ignore_errors=True + +[mypy-pandas.core.indexes.period] +ignore_errors=True + +[mypy-pandas.core.indexes.timedeltas] +ignore_errors=True + +[mypy-pandas.core.indexing] +ignore_errors=True + +[mypy-pandas.core.internals.blocks] +ignore_errors=True + +[mypy-pandas.core.ops] +ignore_errors=True + +[mypy-pandas.core.panel] +ignore_errors=True + +[mypy-pandas.core.resample] +ignore_errors=True + +[mypy-pandas.core.reshape.concat] +ignore_errors=True + +[mypy-pandas.core.reshape.merge] +ignore_errors=True + +[mypy-pandas.core.reshape.reshape] +ignore_errors=True + +[mypy-pandas.core.reshape.tile] +ignore_errors=True + +[mypy-pandas.core.series] +ignore_errors=True + +[mypy-pandas.core.sparse.frame] +ignore_errors=True + +[mypy-pandas.core.strings] +ignore_errors=True + +[mypy-pandas.core.util.hashing] +ignore_errors=True + +[mypy-pandas.core.window] +ignore_errors=True + +[mypy-pandas.io.clipboards] +ignore_errors=True + +[mypy-pandas.io.feather_format] +ignore_errors=True + +[mypy-pandas.io.formats.css] +ignore_errors=True + +[mypy-pandas.io.html] +ignore_errors=True + +[mypy-pandas.io.json.json] +ignore_errors=True + +[mypy-pandas.io.json.normalize] +ignore_errors=True + +[mypy-pandas.io.json.table_schema] +ignore_errors=True + +[mypy-pandas.io.packers] +ignore_errors=True + +[mypy-pandas.io.parquet] +ignore_errors=True + +[mypy-pandas.io.pytables] +ignore_errors=True + +[mypy-pandas.io.stata] +ignore_errors=True + +[mypy-pandas.plotting._core] +ignore_errors=True + +[mypy-pandas.tseries.frequencies] +ignore_errors=True + +[mypy-pandas.tseries.holiday] +ignore_errors=True + +[mypy-pandas.tseries.offsets] +ignore_errors=True + +[mypy-pandas.util._doctools] +ignore_errors=True + +[mypy-pandas.util.testing] +ignore_errors=True diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index c1ba146ba0c9a..4c9ff0c7074d8 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1827,10 +1827,9 @@ def interpolate(self, method='pad', axis=0, inplace=False, limit=None, placement=self.mgr_locs) def shift(self, - periods, # type: int - axis=0, # type: libinternals.BlockPlacement - fill_value=None): # type: Any - # type: (...) -> List[ExtensionBlock] + periods: int, + axis: libinternals.BlockPlacement = 0, + fill_value: Any = None) -> List['ExtensionBlock']: """ Shift the block by `periods`. diff --git a/requirements-dev.txt b/requirements-dev.txt index ccf2301dad66b..e3034cb99ee80 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -10,6 +10,7 @@ gitpython hypothesis>=3.82 isort moto +mypy pycodestyle pytest>=4.0.2 pytest-mock