IDE allow you to refactor code, Baron allows you to write refactoring code.

Overview

Introduction

Baron is a Full Syntax Tree (FST) library for Python. By opposition to an AST which drops some syntax information in the process of its creation (like empty lines, comments, formatting), a FST keeps everything and guarantees the operation fst_to_code(code_to_fst(source_code)) == source_code.

Roadmap

Current roadmap is as boring as needed:

  • bug fixs
  • new small features (walker pattern, maybe code generation) and performance improvement.

Installation

pip install baron

Basic Usage

from baron import parse, dumps

fst = parse(source_code_string)
source_code_string == dumps(fst)

Unless you want to do low level things, use RedBaron instead of using Baron directly. Think of Baron as the "bytecode of python source code" and RedBaron as some sort of usable layer on top of it.

If you don't know what Baron is or don't understand yet why it might be useful for you, read the « Why is this important? » section.

Documentation

Baron documentation is available on Read The Docs.

Contributing

If you want to implement new grammar elements for newer python versions, here are the documented steps for that: https://github.com/PyCQA/redbaron/blob/master/add_new_grammar.md

Also note that reviewing most grammar modifications takes several hours of advanced focusing (we can't really afford bugs here) so don't despair if you PR seems to be hanging around, sorry for that :/

And thanks in advance for your work!

Financial support

Baron and RedBaron are a very advanced piece of engineering that requires a lot of time of concentration to work on. Until the end of 2018, the development has been a full volunteer work mostly done by Bram, but now, to reach the next level and bring those projects to the stability and quality you expect, we need your support.

You can join our contributors and sponsors on our transparent OpenCollective, every contribution will count and will be mainly used to work on the projects stability and quality but also on continuing, on the side, the R&D side of those projects.

Our supporters

badge with number of supporters at tier I like this, keep going! badge with number of supporters at tier it looks cool! badge with number of supporters at tier Oh god, that saved me so much time!

Why is this important?

The usage of a FST might not be obvious at first sight so let's consider a series of problems to illustrate it. Let's say that you want to write a program that will:

  • rename a variable in a source file... without clashing with things that are not a variable (example: stuff inside a string)
  • inline a function/method
  • extract a function/method from a series of line of code
  • split a class into several classes
  • split a file into several modules
  • convert your whole code base from one ORM to another
  • do custom refactoring operation not implemented by IDE/rope
  • implement the class browser of smalltalk for python (the whole one where you can edit the code of the methods, not just showing code)

It is very likely that you will end up with the awkward feeling of writing clumpsy weak code that is very likely to break because you didn't thought about all the annoying special cases and the formatting keeps bothering you. You may end up playing with ast.py until you realize that it removes too much information to be suitable for those situations. You will probably ditch this task as simply too complicated and really not worth the effort. You are missing a good abstraction that will take care of all of the code structure and formatting for you so you can concentrate on your task.

The FST tries to be this abstraction. With it you can now work on a tree which represents your code with its formatting. Moreover, since it is the exact representation of your code, modifying it and converting it back to a string will give you back your code only modified where you have modified the tree.

Said in another way, what I'm trying to achieve with Baron is a paradigm change in which writing code that will modify code is now a realist task that is worth the price (I'm not saying a simple task, but a realistic one: it's still a complex task).

Other

Having a FST (or at least a good abstraction build on it) also makes it easier to do code generation and code analysis while those two operations are already quite feasible (using ast.py and a templating engine for example).

Some technical details

Baron produces a FST in the form of JSON (and by JSON I mean Python lists and dicts that can be dumped into JSON) for maximum interoperability.

Baron FST is quite similar to Python AST with some modifications to be more intuitive to humans, since Python AST has been made for CPython interpreter.

Since playing directly with JSON is a bit raw I'm going to build an abstraction on top of it that will looks like BeautifulSoup/jQuery.

State of the project

Currently, Baron has been tested on the top 100 projects and the FST converts back exactly into the original source code. So, it can be considered quite stable, but it is far away from having been battle tested.

Since the project is very young and no one is already using it except my project, I'm open to changes of the FST nodes but I will quickly become conservative once it gets some adoption and will probably accept to modify it only once or twice in the future with clear indications on how to migrate.

Baron is supporting python 2 grammar and up to python 3.7 grammar.

Tests

Run either py.test tests/ or nosetests in the baron directory.

Community

You can reach us on irc.freenode.net#baron or irc.freenode.net##python-code-quality.

Code of Conduct

As a member of PyCQA, Baron follows its Code of Conduct.

Misc

Old blog post announcing the project. Not that much up to date.

Comments
  • inconsistency for comment at start of file

    inconsistency for comment at start of file

    Hello,

    Little unconsistency when parsing comment at start of file.

    If it starts with a newline, we alternate endl/comment:

    parse('\n#foo\n#bar\n')
    Out[7]: 
    [{'formatting': [], 'indent': '', 'type': 'endl', 'value': '\n'},
     {'formatting': [], 'type': 'comment', 'value': '#foo'},
     {'formatting': [], 'indent': '', 'type': 'endl', 'value': '\n'},
     {'formatting': [], 'type': 'comment', 'value': '#bar'},
     {'formatting': [], 'indent': '', 'type': 'endl', 'value': '\n'}]
    

    If it starts with a comment, we get a endl that includes the comment as formatting.

    parse('#foo\n#bar\n')
    [{'formatting': [{'formatting': [], 'type': 'comment', 'value': '#foo'}],
      'indent': '',
      'type': 'endl',
      'value': '\n'},
     {'formatting': [], 'type': 'comment', 'value': '#bar'},
     {'formatting': [], 'indent': '', 'type': 'endl', 'value': '\n'}]
    

    Not too sure what the proper behaviour is supposed to be, but I guess it should be something similar in both cases.

    bug 
    opened by ze42 10
  • Expanding commit rights? (Re. unmerged PRs)

    Expanding commit rights? (Re. unmerged PRs)

    Thanks for your work on this project! A question/suggestion: would you consider granting commit rights to more people to help the project move forward? There are quite a few PRs for Python 3 support that have been open for ~9 months without activity (#108, #113, #114 #115, #116, #118, #119, #120, #126) and it would be great to have support for some of these features in a release.

    @odcinek seems like a good person for the job if he's willing, seeing how most of the PRs are his...

    /ping @Psycojoker [With apologies to psychoJoker who I pinged by accident before editing...]

    opened by msegado 8
  • add support for typed function parameters

    add support for typed function parameters

    Resolves https://github.com/PyCQA/baron/issues/127

    Please let me know what you think.

    This should allow for typed parameters like def foo(x: int) and def foo(x: List[int]). I didn't try testing when parameters like *args or **kwargs are typed. I think that would be good to add in the future but it just wasn't as necessary for me at the moment.

    This does not add support for typed variables or function return types, but I hope to add support for the later in the near future assuming this is accepted.

    opened by scottbelden 6
  • [fix] remediate race when creating cache file

    [fix] remediate race when creating cache file

    If another process writes the cache file while we were generating the grammar, we'll fail to run os.open(cache_file, os.O_RDWR | os.O_CREAT | os.O_EXCL, 0o0600) because the file (now) exists.

    opened by benjaminp 5
  • Recover from corrupted cache file

    Recover from corrupted cache file

    This allows baron to recover in case the cache file has invalid JSON by deleting and recreating it. Before, it would fail with an exception on initialization.

    opened by ryu2 4
  • Add missing comma in Python string list

    Add missing comma in Python string list

    In Python, two adjacent strings get concatenated implicitly. Missing commas in multi-line string lists is a common source of bugs causing unwanted string concatenation. In this case, it is clear that this comma is missing by mistake and there should not be a concatenation.

    opened by EhsanKia 2
  • Return annotations

    Return annotations

    Hi guys, I ran into a problem where Baron interprets the "-" in the "->" of a function's return annotation as a minus instead of as part of an arrow.

    def foo() -> int: return 3

    baron.parser.ParsingError: Error, got an unexpected token MINUS here: 1 def foo() -<---- here The token MINUS should be one of those: COLON

    Very cool project by the way; would be nice to use something like RB in combination with support for annotations to enable some proper static analysis of functions, maybe even hijack some ideas from Haskell.

    opened by RedKhan 2
  • Python 3: support f-strings

    Python 3: support f-strings

    Python 3 has a wonderful feature called f-strings, which allows in-string interpolation. E.g.:

    from baron import parse
    parse("f'{a}'")
    

    These are not currently parsed by baron.

    opened by PythonNut 2
  • Convert readthedocs links for their .org -> .io migration for hosted projects

    Convert readthedocs links for their .org -> .io migration for hosted projects

    As per their blog post of the 27th April ‘Securing subdomains’:

    Starting today, Read the Docs will start hosting projects from subdomains on the domain readthedocs.io, instead of on readthedocs.org. This change addresses some security concerns around site cookies while hosting user generated data on the same domain as our dashboard.

    Test Plan: Manually visited all the links I’ve modified.

    opened by adamchainz 2
  • Parsing assignment to literal

    Parsing assignment to literal

    Baron fails to see an error here:

    >>> a = 1 = 2
      File "<stdin>", line 1
    SyntaxError: can't assign to literal
    
    >>> RedBaron('a = 1 = 2')
    0   a = 1 = 2
    

    I know baron has a relaxed syntax, so I don't know if this is really an error. But it should at least be documented.

    opened by ibizaman 2
  • baron failed to parse dict/list expansion

    baron failed to parse dict/list expansion

    example:

    core_topic_set = {
                    *flattenUnhashableList(
                        [value for key, value in getMetatopic[dog_or_cat].items()]
                    )
                }
    
    opened by James4Ever0 0
  • baron raise exception when unicode is in code

    baron raise exception when unicode is in code

    example:

    the unicode below are just attributes inside a class.

    orders=[
            BSP.all.order.最多点击,
            BSP.all.order.最多收藏,
            BSP.all.order.最新发布,
            BSP.all.order.最多弹幕,
            BSP.all.order.综合排序,
        ]
    

    exception:

    Traceback (most recent call last):
      File "/media/root/parrot/pyjom/tests/skipexception_code_and_continue_resurrection_time_travel_debugging/codemod_redbaron/redbaron_test.py", line 6, in <module>
        r=redbaron.RedBaron(t)
      File "/usr/local/lib/python3.9/dist-packages/redbaron/redbaron.py", line 36, in __init__
        self.node_list = base_nodes.NodeList.from_fst(baron.parse(source_code), parent=self, on_attribute="root")
      File "/usr/local/lib/python3.9/dist-packages/baron/baron.py", line 49, in parse
        tokens = tokenize(source_code, False)
      File "/usr/local/lib/python3.9/dist-packages/baron/baron.py", line 70, in tokenize
        splitted = split(pouet)
      File "/usr/local/lib/python3.9/dist-packages/baron/spliter.py", line 6, in split
        return list(split_generator(sequence))
      File "/usr/local/lib/python3.9/dist-packages/baron/spliter.py", line 76, in split_generator
        raise UntreatedError("Untreated elements: %s" % iterator.rest_of_the_sequence().__repr__()[:50])
    baron.spliter.UntreatedError: Untreated elements: '最多点击,\n        BSP.all.order.最多收藏,\n        BSP.a
    
    opened by James4Ever0 0
  • Mishandling of print function

    Mishandling of print function

    The following code...

    import redbaron
    rb = redbaron.RedBaron('func = print if True else print')
    print(rb.dumps())
    

    ...produces the following output:

    func = printif True else print
    

    Note that the space between the print and the if has been removed.

    This bug does not occur if the the word print is replaced with foo.

    opened by shindavid 0
  • blank line causes ParsingError

    blank line causes ParsingError

    The following code fails with a ParsingError:

    from redbaron import RedBaron
    
    text = '''
    if True:
        pass
    elif True: pass
    
    else:
        pass
    '''
    
    RedBaron(text)
    

    The python interpreter parses text without any syntax error.

    Deleting the blank line between the elif and the else fixes the ParsingError.

    Expand to view traceback
    Traceback (most recent call last):
      File ".../site-packages/baron/baron.py", line 20, in _parse
        return parser(tokens)
      File ".../site-packages/baron/grammator.py", line 836, in parse
        return parser.parse(iter(tokens))
      File ".../site-packages/baron/parser.py", line 165, in parse
        raise ParsingError(debug_output)
    baron.parser.ParsingError: Error, got an unexpected token ELSE here:
    
       1
       2 if True:
       3     pass
       4 elif True: pass
       5
       6 else<---- here
    
    The token ELSE should be one of those: $end, ASSERT, AT, BACKQUOTE, BINARY, BINARY_RAW_STRING, BINARY_STRING, BREAK, CLASS, COMMENT, COMPLEX, CONTINUE, DEF, DEL, ELLIPSIS, ENDL, ENDMARKER, EXEC, FLOAT, FLOAT_EXPONANT, FLOAT_EXPONANT_COMPLEX, FOR, FROM, GLOBAL, HEXA, IF, IMPORT, INT, INTERPOLATED_RAW_STRING, INTERPOLATED_STRING, LAMBDA, LEFT_BRACKET, LEFT_PARENTHESIS, LEFT_SQUARE_BRACKET, LONG, MINUS, NAME, NONLOCAL, NOT, OCTA, PASS, PLUS, PRINT, RAISE, RAW_STRING, RETURN, STAR, STRING, TILDE, TRY, UNICODE_RAW_STRING, UNICODE_STRING, WHILE, WITH, YIELD
    
    Baron has failed to parse this input. If this is valid python code (and by that I mean that the python binary successfully parse this code without any syntax error) (also consider that baron does not yet parse python 3 code integrally) it would be kind if you can extract a snippet of your code that make Baron fails and open a bug here: https://github.com/PyCQA/baron/issues
    
    Sorry for the inconvenience.
    
    opened by shindavid 0
  • Support for PEP-570: positional-only arguments

    Support for PEP-570: positional-only arguments

    PEP-570 adds support for positional-only arguments. Baron seem to support keyword-only arguments, as shown in test_case_1 below, which is represented by a kwargs_only_marker node. Following this convention i propose creating a posargs_only_marker node for the test_case_2 example.

    Testcase:

    from redbaron import RedBaron
    import ast, json
    
    test_case_1 = "def foo(a, *, b, c): pass"  # kwarg only
    test_case_2 = "def foo(a, /, b, c): pass"  # pos only
    
    print(ast.dump(ast.parse(test_case_1), indent=4))        # dump python ast
    print("=" * 60)
    print(json.dumps(RedBaron(test_case_1).fst(), indent=4)) # dump redbaron ast
    print("=" * 60)
    print(ast.dump(ast.parse(test_case_2), indent=4))        # dump python ast
    print("=" * 60)
    print(json.dumps(RedBaron(test_case_2).fst(), indent=4)) # dump redbaron ast
    
    Expand this to view output
    Module(
        body=[
            FunctionDef(
                name='foo',
                args=arguments(
                    posonlyargs=[],
                    args=[
                        arg(arg='a')],
                    kwonlyargs=[
                        arg(arg='b'),
                        arg(arg='c')],
                    kw_defaults=[
                        None,
                        None],
                    defaults=[]),
                body=[
                    Pass()],
                decorator_list=[])],
        type_ignores=[])
    ============================================================
    [
        {
            "type": "def",
            "async": false,
            "name": "foo",
            "decorators": [],
            "async_formatting": [],
            "first_formatting": [
                {
                    "type": "space",
                    "value": " "
                }
            ],
            "second_formatting": [],
            "third_formatting": [],
            "arguments": [
                {
                    "type": "def_argument",
                    "annotation_first_formatting": [],
                    "annotation_second_formatting": [],
                    "first_formatting": [],
                    "second_formatting": [],
                    "target": {
                        "type": "name",
                        "value": "a"
                    },
                    "annotation": {},
                    "value": {}
                },
                {
                    "type": "comma",
                    "first_formatting": [],
                    "second_formatting": [
                        {
                            "type": "space",
                            "value": " "
                        }
                    ]
                },
                {
                    "type": "kwargs_only_marker",
                    "formatting": []
                },
                {
                    "type": "comma",
                    "first_formatting": [],
                    "second_formatting": [
                        {
                            "type": "space",
                            "value": " "
                        }
                    ]
                },
                {
                    "type": "def_argument",
                    "annotation_first_formatting": [],
                    "annotation_second_formatting": [],
                    "first_formatting": [],
                    "second_formatting": [],
                    "target": {
                        "type": "name",
                        "value": "b"
                    },
                    "annotation": {},
                    "value": {}
                },
                {
                    "type": "comma",
                    "first_formatting": [],
                    "second_formatting": [
                        {
                            "type": "space",
                            "value": " "
                        }
                    ]
                },
                {
                    "type": "def_argument",
                    "annotation_first_formatting": [],
                    "annotation_second_formatting": [],
                    "first_formatting": [],
                    "second_formatting": [],
                    "target": {
                        "type": "name",
                        "value": "c"
                    },
                    "annotation": {},
                    "value": {}
                }
            ],
            "fourth_formatting": [],
            "return_annotation_first_formatting": [],
            "return_annotation_second_formatting": [],
            "fifth_formatting": [],
            "sixth_formatting": [
                {
                    "type": "space",
                    "value": " "
                }
            ],
            "value": [
                {
                    "type": "pass"
                },
                {
                    "type": "endl",
                    "value": "\n",
                    "indent": "",
                    "formatting": []
                }
            ],
            "return_annotation": {}
        }
    ]
    ============================================================
    Module(
        body=[
            FunctionDef(
                name='foo',
                args=arguments(
                    posonlyargs=[
                        arg(arg='a')],
                    args=[
                        arg(arg='b'),
                        arg(arg='c')],
                    kwonlyargs=[],
                    kw_defaults=[],
                    defaults=[]),
                body=[
                    Pass()],
                decorator_list=[])],
        type_ignores=[])
    ============================================================
    Traceback (most recent call last):
      File "/home/pbsds/.cache/pypoetry/virtualenvs/fix-my-functions-Moge_7ev-py3.9/lib/python3.9/site-packages/baron/baron.py", line 20, in _parse
        return parser(tokens)
      File "/home/pbsds/.cache/pypoetry/virtualenvs/fix-my-functions-Moge_7ev-py3.9/lib/python3.9/site-packages/baron/grammator.py", line 836, in parse
        return parser.parse(iter(tokens))
      File "/home/pbsds/.cache/pypoetry/virtualenvs/fix-my-functions-Moge_7ev-py3.9/lib/python3.9/site-packages/baron/parser.py", line 165, in parse
        raise ParsingError(debug_output)
    baron.parser.ParsingError: Error, got an unexpected token SLASH here:
    
       1 def foo(a, /<---- here
    
    The token SLASH should be one of those: COMMA, DOUBLE_STAR, LEFT_PARENTHESIS, NAME, RIGHT_PARENTHESIS, STAR
    
    opened by pbsds 0
Releases(0.9)
  • 0.9(Feb 25, 2019)

    First version of full python 3.7 grammar support.

    • BREAKING CHANGE: annotations are now member of {def,list,dict}_argument to flatten the data structure
    • add support for ... in from import by bram
    • add support for return annotation by bram
    • add support for exec function by bram
    • add support for variable annotation https://github.com/PyCQA/baron/pull/145 by scottbelden and additional work by bram
    • add support for *var expressions in tuple assignment by bram
    • add support for raise from https://github.com/PyCQA/baron/pull/120 by odcinek with additional work by bram
    • add support for arglist usage in class definition inheritence by bram
    • bug fix by https://github.com/PyCQA/baron/pull/126/commits/91e839a228293698cc755a7f28afeca2669cb66e kyleatmakrs
    Source code(tar.gz)
    Source code(zip)
  • 0.8(Feb 25, 2019)

  • 0.7(Aug 21, 2018)

    • fix line continuation https://github.com/PyCQA/baron/pull/92 by ibizaman
    • handle corrupt cache file situation https://github.com/PyCQA/baron/pull/76 by ryu2
    • fix special crashing edge case in indentation marker https://github.com/PyCQA/bar by Ahuge
    • fixed incorrect tokenization case "d*e-1". Fixes #85 https://github.com/PyCQA/baron/pull/107 by boxed
    • fix endl handling inside groupings by kyleatmakrs (extracted from https://github.com/PyCQA/baron/pull/126)

    Python 3:

    • python 3 parsing extracted from https://github.com/PyCQA/baron/pull/126
    • support ellipsis https://github.com/PyCQA/baron/pull/121 by odcinek
    • support matrix operator https://github.com/PyCQA/baron/pull/117 by odcinek
    • support f-strings https://github.com/PyCQA/baron/pull/110 by odcinek
    • support numeric literals https://github.com/PyCQA/baron/pull/111 by odcinek
    • support nonlocal statement https://github.com/PyCQA/baron/pull/112 by odcinek
    • support keyword only markers https://github.com/PyCQA/baron/pull/108 by boxed
    • support yield from statement https://github.com/PyCQA/baron/pull/113 by odcinek and additional work by bram
    • support async/await statements https://github.com/PyCQA/baron/pull/114 by odcinek and additional work by bram
    Source code(tar.gz)
    Source code(zip)
  • 0.6.6(Jun 12, 2017)

    • fix situation where a deindented comment between a if and elif/else broken parsing, see https://github.com/PyCQA/baron/issues/87
    • around 35-40% to 75% parsing speed improvment on big files by duncf https://github.com/PyCQA/baron/pull/99
    Source code(tar.gz)
    Source code(zip)
  • 0.6.5(Jun 12, 2017)

  • 0.6.4(Jun 12, 2017)

  • 0.6.3(Jun 12, 2017)

  • 0.6.2(Jun 12, 2017)

    • fix race condition when generating parser cache file
    • make all user-facing errors inherit from the same BaronError class
    • fix: dotted_name and float_exponant_complex were missing from nodes_rendering_order
    Source code(tar.gz)
    Source code(zip)
  • 0.6.1(Jun 12, 2017)

    • fix: the string was having a greedy behavior on grouping the string tokens surrounding it (for string chains), this ends up creating an inconsistancy in the way string was grouped in general
    • fix: better number parsing handling, everything isn't fixed yet
    • make all (expected) errors inherit from the same BaronError class
    • fix: parsing fails correctly if a quoted string is not closed
    Source code(tar.gz)
    Source code(zip)
  • 0.6(Jun 12, 2017)

    • FST structure modification: def_argument_tuple is no more and all arguments now have a coherent structure:
      • def_argument node name attribute has been renamed to target, like in assign
      • target attribute now points to a dict, not to a string
      • old name -> string are now target -> name_node
      • def_argument_tuple is now a def_argument where target points to a tuple
      • this specific tuple will only has name and comma and tuple members (no more def_argument for name)
    • new node: long, before int and long where merged but that was causing problems
    Source code(tar.gz)
    Source code(zip)
  • 0.5(Jun 12, 2017)

  • 0.4(Jun 12, 2017)

    • new rendering type in the nodes_rendering_order dictionary: string. This remove an ambiguity where a key could be pointing to a dict or a string, thus forcing third party tools to do guessing.
    Source code(tar.gz)
    Source code(zip)
Owner
Python Code Quality Authority
Organization for code quality tools (and plugins) for the Python programming language
Python Code Quality Authority
Simple, hassle-free, dependency-free, AST based source code refactoring toolkit.

refactor is an end-to-end refactoring framework that is built on top of the 'simple but effective refactorings' assumption. It is much easier to write a simple script with it rather than trying to figure out what sort of a regex you need in order to replace a pattern (if it is even matchable with regexes).

Batuhan Taskaya 385 Jan 6, 2023
Awesome autocompletion, static analysis and refactoring library for python

Jedi - an awesome autocompletion, static analysis and refactoring library for Python Jedi is a static analysis tool for Python that is typically used

Dave Halter 5.3k Dec 29, 2022
a python refactoring library

rope, a python refactoring library ... Overview Rope is a python refactoring library. Notes Nick Smith <[email protected]> takes over maintaining rope

null 1.5k Dec 30, 2022
Bottom-up approach to refactoring in python

Introduction RedBaron is a python library and tool powerful enough to be used into IPython solely that intent to make the process of writing code that

Python Code Quality Authority 653 Dec 30, 2022
AST based refactoring tool for Python.

breakfast AST based refactoring tool. (Very early days, not usable yet.) Why 'breakfast'? I don't know about the most important, but it's a good meal.

eric casteleijn 0 Feb 22, 2022
Refactoring Python Applications for Simplicity

Python Refactoring Refactoring Python Applications for Simplicity. You can open and read project files or use this summary ?? Concatenate String my_st

Mohammad Dori 3 Jul 15, 2022
Turn your C++/Java code into a Python-like format for extra style points and to make everyone hates you

Turn your C++/Java code into a Python-like format for extra style points and to make everyone hates you

Tô Đức (Watson) 4 Feb 7, 2022
Code generation and code search for Python and Javascript.

Codeon Code generation and code search for Python and Javascript. Similar to GitHub Copilot with one major difference: Code search is leveraged to mak

null 51 Dec 8, 2022
Find dead Python code

Vulture - Find dead code Vulture finds unused code in Python programs. This is useful for cleaning up and finding errors in large code bases. If you r

Jendrik Seipp 2.4k Dec 27, 2022
Removes commented-out code from Python files

eradicate eradicate removes commented-out code from Python files. Introduction With modern revision control available, there is no reason to save comm

Steven Myint 146 Dec 13, 2022
A library that modifies python source code to conform to pep8.

Pep8ify: Clean your code with ease Pep8ify is a library that modifies python source code to conform to pep8. Installation This library currently works

Steve Pulec 117 Jan 3, 2023
{Ninja-IDE Is Not Just Another IDE}

Ninja-IDE Is Not Just Another IDE Ninja-IDE is a cross-platform integrated development environment (IDE) that allows developers to create applications

ninja-ide 919 Dec 14, 2022
Sudo Baron Samedit Exploit

CVE-2021-3156 (Sudo Baron Samedit) This repository is CVE-2021-3156 exploit targeting Linux x64. For writeup, please visit https://datafarm-cybersecur

Worawit Wang 559 Jan 3, 2023
VSCode extension to sort and refactor python imports using reorder-python-imports.

reorder-python-imports VSCode extension to sort and refactor python imports using reorder-python-imports. Unlike other import organizers, reorder-pyth

Ryan Butler 3 Aug 26, 2022
The refactoring tutorial I wrote for PyConDE 2022. You can also work through the exercises on your own.

Refactoring 101 planet images by Justin Nichol on opengameart.org CC-BY 3.0 Goal of this Tutorial In this tutorial, you will refactor a space travel t

Kristian Rother 9 Jun 10, 2022
🧮A simple calculator written in python allows you to make simple calculations, write charts, calculate the dates, and exchange currency.

Calculator ?? A simple calculator written in python allows you to make simple calculations, write charts, calculate the dates, and exchange currency.

Jan Kupczyk 1 Jan 15, 2022
Safe code refactoring for modern Python.

Safe code refactoring for modern Python projects. Overview Bowler is a refactoring tool for manipulating Python at the syntax tree level. It enables s

Facebook Incubator 1.4k Jan 4, 2023