Skip to main content

Tool for fixing trivial problems with your code.

Project description

pybetter

PyPI PyPI - Python Version GitHub Code style: black

Tool for fixing trivial problems with your code.

Originally intended as an example for my PyCon Belarus 2020 talk about LibCST.

Usage

Simply provide a valid Python source code file as one of the argument and it will try to fix any issues it could find.

Usage: pybetter [OPTIONS] [SOURCES]...

Options:
  --noop  Do not make any changes to the source files.
  --help  Show this message and exit.

Example

# cat test.py
def f():
    return (42, "Hello, world")

# pybetter test.py
--> Processing 'test.py'...
  [+] (B003) Remove parentheses from the tuple in 'return' statement.
All done!

# cat test.py
def f():
    return 42, "Hello, world"

Available fixers

  • B001: Replace 'not A in B' with 'A not in B'

    Usage of A not in B over not A in B is recommended both by Google and PEP-8. Both of those forms are compiled to the same bytecode, but second form has some potential of confusion for the reader.

    # BEFORE:
    if not 42 in counts:
        sys.exit(-1)
    
    # AFTER:
    if 42 not in counts:
        sys.exit(-1)
    
  • B002: Default values for kwargs are mutable.

    As described in [Common Gotchas] (https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments) section of "The Hitchhiker's Guide to Python", mutable arguments can be a tricky thing.

    This fixer replaces any default values that happen to be lists or dicts with None value, moving initialization from function definition into function body.

    # BEFORE
    def p(a=[]):
        print(a)
      
    # AFTER
    def p(a=None):
        if a is None:
            a = []
        
        print(a)
    

    Be warned, that this fix may break code which intentionally uses mutable default arguments (e.g. caching).

  • B003: Remove parentheses from the tuple in 'return' statement.

    If you are returning a tuple from the function by implicitly constructing it, then additional parentheses around it are redundant.

    # BEFORE:
    def hello():
        return ("World", 42)
    
    # AFTER:
    def hello():
        return "World", 42
    
  • B004: __all__ attribute is missing.

    Regenerate missing __all__ attribute, filling it with the list of top-level function and class names.

    NB: It will ignore any names starting with _ to prevent any private members from ending up in the list.

    # BEFORE:
    def hello():
        return ("World", 42)
    
    class F:
        pass
    
    # AFTER:
    def hello():
        return "World", 42
    
    class F:
        pass
    
    __all__ = [
      "F",
      "hello",
    ]
    
  • B005: Replace "A == None" with "A is None"

    "Comparisons to singletons like None should always be done with is or is not, never the equality operators." (PEP8)

    # BEFORE:
    
    if a == None:
        pass
      
    # AFTER:
    
    if a is None:
        pass
    
  • B006: Remove comparisons with either 'False' or 'True'.

    PEP8 recommends that conditions should be evaluated without explicit equality comparison with True/False singletons. In Python, every non-empty value is treated as True and vice versa,

    so in most cases those comparisons can be safely eliminated.

    NB: is True and is False checks are not affected, since they can be used to explicitly check for equality with a specific singleton, instead of using abovementioned "non-empty" heuristic.

    # BEFORE:
    
    if a == False or b == True or c == False == True:
        pass
      
    # AFTER:
    
    if a or b or c:
        pass
    
  • B007: Convert f-strings without expressions into regular strings.

    It is wasteful to use f-string mechanism if there are no expressions to be extrapolated.

    # BEFORE:
    a = f"Hello, world"
    
    # AFTER:
    a = "Hello, world"
    

Installation

# pip install pybetter

Getting started with development

# git clone https://github.com/lensvol/pybetter
# poetry install

License

This project is licensed under the MIT License - see the LICENSE file for details

Authors

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for pybetter, version 0.2.1
Filename, size File type Python version Upload date Hashes
Filename, size pybetter-0.2.1-py3-none-any.whl (12.1 kB) File type Wheel Python version py3 Upload date Hashes View hashes
Filename, size pybetter-0.2.1.tar.gz (10.3 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page