56
PYTHON REFACTORING WITH ROPE AND TRAAD Austin Bingham Sixty North AS 0

Austin Bingham. Python Refactoring. PyCon Belarus

Embed Size (px)

Citation preview

PYTHON REFACTORINGWITH ROPE AND TRAAD

Austin Bingham

Sixty North AS

0

HELLO!

PYTHON ISEVERYWHERE!

WHAT IS ROPE?

A PYTHON LIBRARY FOR DOINGPYTHON REFACTORINGS

ROPE HAS POWERFUL IDE-ORIENTED FEATURES

Code completionFinding definitions and occurrencesOrganizing importsLooking up docstrings

ELEMENTS OF ROPE

PROJECTRepresents the files and directories containing code that rope

will manipulate.

Project is the root object in rope

CREATE A PROJECTfrom rope.base.project import Projectproject = Project('project_dir')

RESOURCESThe files and directories in the project

server = project.get_resource('traad/server.py')print(server.name, server.path, server.is_folder())

c1 = project.get_resource('').get_children()[0]print(c1.name, c1.path, c1.is_folder())

WALK PROJECT RESOURCESdef get_all_resources(proj): todo = [''] while todo: res_path = todo[0] todo = todo[1:] res = proj.get_resource(res_path) yield(res.path, res.is_folder())

if res.is_folder(): todo.extend((child.path for child in res.get_children()))

Project.get_resource(path) finds a resource at arelative path

Resource.get_children() returns an iterable overchildren

MANAGE PREFERENCESprefs is a dict-like container of settings and preferences.for p in project.prefs.prefs: print(project.prefs.get(p))

prefs are stored in a file called .ropeproject/config.pyat the project's root directory.

ANATOMY OF AREFACTORING

CREATE THE REFACTORINGOBJECT

from rope.refactor.rename import Rename

ren = Rename(project, project.get_resource('traad/state.py'), offset=42)

This can fail if rope can't perform the refactoring

The refactoring is only partially bound

CALCULATE ACTUAL CHANGESchanges = ren.get_changes('TacoCopter')print(changes.description)print(changes.get_changed_resources())

changes represents a fully bound change

EXECUTE THE CHANGESproject.do(changes)

After this the changes are actually performed.

THE FULL PROCESSfrom rope.base.project import Projectfrom rope.refactor.rename import Rename

# Create the projectproj = Project('.')

# Create the partially-bound refactoringren = Rename(project, project.get_resource('traad/state.py'), offset=42)

# Calculate the changes for a fully-specified renamingchange = ren.get_changes('TacoCopter')

# Perform the changesproject.do(changes())

HISTORY

HISTORY OBJECTProject.history manages the history of changes that have

been made.

Also remembers what has been undone as well as changedependencies.

UNDOING CHANGESUndo the most recent changes

project.history.undo()

Or select more distance changes to undochange = project.history.undo_list[3]project.history.undo(change)

This will undo all dependent changes.

REDOING CHANGESYou can redo changes that you've previously undone.

change = project.history.redo_list[-2]project.history.redo(change)

MULTI-PROJECTREFACTORING

THE MULTI-PROJECTREFACTORING CLASS

First create a MultiProjectRefactoring instance.from rope.refactor import multiproject

mpr = multiproject.MultiProjectRefactoring( Rename, # type of refactoring to perform [other_project1, other_project2, other_project3])

Then call that with your main project and the refactoringinitializer arguments

ref = mpr(main_project, some_resource, offset=1337)

CREATE AND PERFORM THE CHANGE# Remember that ̀ref̀ is a renaming operationchanges = ref.get_all_changes( "EnterpriseProxyManagerImplementationFactoryFactory")

multiproject.perform(changes)

NON-REFACTORINGTOOLS

NOT INTENDED FOR"MANUAL" OPERATION

WHAT IS TRAAD?tråd - svært tynn snor av fibrer av silke, ull, el. f eks av metall

WHAT IS TRAAD?thread

TRAAD IS…An HTTP+JSON server for driving rope

TRAAD IS…Various clients for driving the server

WHY TRAAD?

SIMPLER INTEGRATION WITHEDITORS

Every corner of the programming universe knows how to speakHTTP+JSON

HTTP IS (WAY) MORE THAN FASTENOUGH FOR THIS WORK

The volume of data is low, and the response time only needs tobe good enough for humans

SUPPORT FOR MULTIPLE PYTHONVERSIONS

The client has zero depenencies on the version of Python thattraad is using

PROPER LEVEL OF ABSTRACTION

The problem domain of traad is Python refactoring, not Pythonintegration with other languages.

TRAAD ARCHITECTURE

Low-ceremony (sorta), powerful, and well-documented

PYKKA FOR MANAGINGCONCURRENCY

OVERALL ARCHITECTURE

TASK STATE{ 1: { 'status': 'pending', 'description': 'Renaming FOO to BAR', 'changed_resources': [. . .]},

2: { 'status': 'failure'},

3: { 'status': 'success', 'calltip': 'uuid1(node=None, clock_seq=None)' }}

Simple mapping of task-ids to dicts

State is an actor and thus threadsafe. Multiple asynchronoustasks could be accessing it at any time.

ASYNCHRONOUS OPERATIONS

SYNCHRONOUS OPERATIONS

ASYCHRONOUS VS.SYNCHRONOUS

AsynchronousRenameExtractOrganize importsSynchronousFind definitionGet historyCalltip

EMACSThe emacs lisp for renaming looks like this

; Starts new traad server on the specified directory(traad-open "~/projects/roid_rage")

; Renames whatever is a the point (i.e. under the cursor)(traad-rename "RagingRoid")

And the HTTP message looks like thisPOST /refactor/rename HTTP/1.1User-Agent: curl/7.30.0Host: 127.0.0.1:65172Accept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonContent-Length: 104

{"name":"RagingRoid", "path":"\/Users\/sixtynorth\/projects\/roid_rage\/roid_rage\/roid.py", "offset":102}

WHAT KIND OF AKEYNOTE IS THIS?

ROPE AND TRAAD ONLY EXISTBECAUSE OF CURIOUS

DEVELOPERS

IT CAN SEEM HOPELESS TO STARTA PROJECT LIKE THIS

FIND THE NICHE THAT REALLYINTERESTS YOU AND FILL IT

THERE IS NO FAME AND FORTUNEIN THIS KIND OF DEVELOPMENT

BUT IT IS IMMENSELY SATISFYINGAND ENJOYABLE

YOU WILL LEARN A GREAT DEAL

AND YOU REALLY WILL BEHELPING OTHERS

IT'S UP TO YOU, AND YOU CAN DOIT!

SUPPORT ROPE AND TRAAD

The success of rope and traad depend on users and developerslike you!

LINKSRope - Traad - Pykka - Bottle -

http://rope.sourceforge.net/http://github.com/abingham/traadhttp://www.pykka.org/http://bottlepy.org/

http://github.com/abingham/traad_rope_presentation