pytype

About_work·2023년 3월 3일
0

python clean code

목록 보기
8/11

설명

  • 코드의 type을 확인하고(type annotation이 있는경우), 추론하기도 한다.
  • misspelled attribute name이나 잘못된 function calls 등도(더 많은 기능의 Error Classess: https://google.github.io/pytype/errors.html) 잡아낸다.
  • pytype을 돌린 결과로 pyi files 파일이 생성되고(type annotation을 추론한 결과), 이 파일은 merge-pyi라는 tool을 이용하여 Python source 코드에 반영될 수 있다!
$ merge-pyi -i <filepath>.py .pytype/pyi/<filename>.pyi

사용법

설치

  • Linux에서 지원
  • MacOSX에서 설치하려면, OSX 10.7 이상, Xcode v8 이상이 요구된다.
  • pip install pytype

명령어

usage: pytype [options] input [input ...]
positional arguments:
  input                 file or directory to process
  • 예시: pytype file_or_directory
  • options
    • -V, --python-version: Python version (major.minor) of the target code. Defaults to the version that pytype is running under.
    • -o, --output: The directory into which all pytype output goes, including generated .pyi files. Defaults to .pytype.
    • -d, --disable: 무시할 에러 이름의 리스트(comma나 space로 구분)
      • pytype's error에 대한 자세한 설명은 해당 문서 참조.

패키지에 적용

  • pytype을 abc패키지에 셋업하려면, abc 패키지 바로 상위 패키지에 pyproject.toml 파일을 만들고 아래와 같이 내용을 작성하라.
# pyproject.toml
[tool.pytype]
inputs = ['package_name']
  • 이렇게 하면, argument 없는 커멘드 pytype으로 패키지를 검사할 수 있다.

github Action을 통한 자동화

pre-commit 이용해서 돌리기

  • dev -> current HEAD
$ pre-commit run --hook-stage manual --from-ref dev --to-ref HEAD pytype
  • 특정 sub-directory만 확인하고 싶을 떄
$ git ls-files -- <sub-directory> xargs pre-commit run --hook-stage manual pytype --files

Config File

  • config file은 2가지 스타일이 될 수 있다.
    • (선호)[tool.pytype]섹션이 들어있는 TOML-style
    • [pytype] 색션이 들어있는, INI-style file
  • 명백한 config 파일이 제공되지 않으면, pytype은 현재 디렉토리부터 올라가면서, 첫번재 pyproject.toml이나 setup.cfg를 찾는다.
# .pytype.cfg
# NOTE: All relative paths are relative to the location of this file.
# Generated by pytype --generate-config=pytype.toml

[pytype]

# Space-separated list of files or directories to exclude.
exclude =
    **/*_test.py
    **/test_*.py

# Space-separated list of files or directories to process.
inputs =
    .

# Keep going past errors to analyze as many files as possible.
keep_going = False

# Run N jobs in parallel. When 'auto' is used, this will be equivalent to the
# number of CPUs on the host system.
jobs = auto

# All pytype output goes here.
output = .pytype

# Platform (e.g., "linux", "win32") that the target code runs on.
platform = linux

# Paths to source code directories, separated by ':'.
pythonpath = .

# Python version (major.minor) of the target code.
python_version = 3.8

# Always use function return type annotations. This flag is temporary and will
# be removed once this behavior is enabled by default.
always_use_return_annotations = False

# Enable parameter count checks for overriding methods. This flag is temporary
# and will be removed once this behavior is enabled by default.
overriding_parameter_count_checks = False

# Use the enum overlay for more precise enum checking. This flag is temporary
# and will be removed once this behavior is enabled by default.
use_enum_overlay = False

# Opt-in: Do not allow Any as a return type.
no_return_any = False

# Experimental: Support pyglib's @cached.property.
enable_cached_property = False

# Experimental: Infer precise return types even for invalid function calls.
precise_return = False

# Experimental: Solve unknown types to label with structural types.
protocols = False

# Experimental: Only load submodules that are explicitly imported.
strict_import = False

# Experimental: Enable exhaustive checking of function parameter types.
strict_parameter_checks = False

# Experimental: Emit errors for comparisons between incompatible primitive
# types.
strict_primitive_comparisons = False

# Space-separated list of error names to ignore.
disable =
    pyi-error
    import-error

# Don't report errors.
report_errors = True

pre-commit-config.yaml 에 추가?

  • pre-commit-config.yaml
- repo: https://github.com/google/pytype
  rev: '2023.02.17'
  hooks:
  - id: pytype
    name: pytype
    args:
    - --config=.pytype.cfg
    # NOTE(hyunseok.kil): Because pytype is too heavy to run on every commits,
    # manually run it by
    # 'pre-commit run --hook-stage manual' after git add <modified files>
    stages:
    - manual

Error 무시하기

import socket
class Server:

  def __init__(self, port):
    self.port = port

  def listen(self):
    self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.socket.bind((socket.gethostname(), self.port))
    self.socket.listen(backlog=5)

  def accept(self):
    return self.socket.accept()

>>>
File "t.py", line 13, in accept: No attribute 'socket' on Server [attribute-error]
  • 수정 1
return self.socket.accept()  # pytype: disable=attribute-error
  • 수정 2
    • variable에도 type annotation을 할 수 있는데, 심지어 미래에 생성될 variable에 대해서도 아래와 같이 작성 가능하다.
class Server:
  socket: socket.socket
profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글