P4Python - Python OO interface to the Perforce SCM System.
import p4
p4c = p4.P4() p4c.port = "1666" p4c.user = "fred" p4c.client = "fred-ws" try: p4c.connect() info = p4c.run("info") p4c.run("edit", "file.txt") p4c.disconnect() except p4.P4Error: for e in p4c.errors: print e
Don't forget to also look at the test harness which demonstrates lots of commands being run the output being parsed and checked.
Create and update a client workspace from a template.
import p4 template = "my-client-template" client_root = r"c:\work\my-root" p4c = p4.P4() p4c.parse_forms() # This call is important to make handling specs objects like clients easier try: p4c.connect() # Run a "p4 client -t template -o" and convert it into a Python dictionary spec = p4c.fetch_client("-t", template) spec["Root"] = client_root p4c.save_client(spec) p4c.run_sync() except p4.P4Error: # If any errors occur, we'll jump in here. Just log them # and raise the exception up to the higher level for e in p4.errors: print e
We create a changelist using the "p4 change -o" command, modify it and then do the submission ("p4 submit -i"). Error handling left to default exceptions being raised:
import p4 p4c = p4.P4() p4c.parse_forms() # This call is important to make handling specs objects like clients easier p4c.connect() change = p4c.fetch_change() # Let us assume that files were opened elsewhere and we only want to submit a subset that we # already know about myfiles = ['//depot/some/path/file1.c', '//depot/some/path/file1.h'] change["Description"] = "My changelist\nSubmitted from P4Python\n" change["Files"] = myfiles # This attribute takes a python list result = p4c.save_submit(change) # May do some parsing of result to ensure it all worked although by default an exception # will be raised on an error.
May need to login to Perforce first:
import p4 p4c = p4.P4() p4c.user = "Robert" p4c.connect() p4c.login("Mypassword") opened = p4c.run_opened() etc...
This module provides an OO interface to the Perforce SCM system that is designed to be intuitive to Python users. Data is returned in Python arrays and dictionaries (hashes) and input can also be supplied in these formats.
Each P4 object represents a connection to the Perforce Server, and multiple commands may be executed (serially) over a single connection (which of itself can result in substantially improved performance if executing lots of perforce commands).
myp4 = p4.P4()
1. Value from file specified by P4CONFIG 2. Value from $ENV{P4CLIENT} 3. Hostname
Connect()
and before the Run().
1. Value from file specified by P4CONFIG 2. Value from $ENV{P4PORT} 3. perforce:1666
p4.errors
.
Results are returned as an array of results.
Through the magic of the getattr(), you can also treat the Perforce commands as methods, so:
p4.run_edit("filename.txt")
is equivalent to
p4.run("edit", "filename.txt")
Note that the format of the array results you get depends on (a) whether you're using tagged (or form parsing) mode (b) the command you've executed (c) the arguments you supplied and (d) your Perforce server version.
In tagged or form parsing mode, ideally each result element will be a dictionary, but this is dependent on the command you ran and your server version.
In non-tagged mode (the default), the each result element will be a string. In this case, also note that as the Perforce server sometimes asks the client to write a blank line between result elements, some of these result elements can be empty.
Mostly you will want to use form parsing (and hence tagged) mode. See parse_forms().
Note that the return values of individual Perforce commands are not documented because they may vary between server releases.
If you want to be correlate the results returned by the P4 interface with those sent to the command line client try running your command with RPC tracing enabled. For example:
Tagged mode: p4 -Ztag -vrpc=1 describe -s 4321 Non-Tagged mode: p4 -vrpc=1 describe -s 4321
Pay attention to the calls to client-FstatInfo(), client-OutputText(),
client-OutputData() and client-HandleError(). Each call to one of these
functions results in either a result element, or an error element.
p4.translate(P4.NOCONV)
1. Value from file specified by P4CONFIG 2. Value from P4USER in environment 3. OS username
p4.warnings
p4c.api("57") # Lock to 2005.1 format p4c.connect() etc.
The following methods are simply wrappers around the base methods designed to make common actions easy to code.
SetProtocol( "tag", "" )
. Responses from commands that
support tagged output will be in the form of a hash ref rather than plain
text. Must be called prior to calling Connect()
.
p4.fetch_change()
, or
p4.run_client("-o")
be parsed and returned as a hash reference for easy
manipulation. Equivalent to calling SetProtocol( "tag", "" )
and
SetProtocol( "specstring", "" )
. Must be called prior to calling
c
onnect()
.
pr.run("cmd", "-o")
and returning
the first item from results array. eg.
label = myp4.fetch_label(labelname) change = myp4.fetch_change(changeno) clientspec = myp4.fetch_client(clientname)are equivalent to:
label = myp4.run("label", "-o", labelname)[0] change = myp4.run("change", "-o", changeno)[0] clientspec = myp4.run("client", "-o", clientname)[0]
myp4.login("mypassword")
myp4.input = "password" myp4.run("login")
myp4.passwd("mynewpassword")
myp4.input = "mynewpassword" myp4.run("passwd")
myp4.input = spec myp4.run("cmd", "-i") e.g.
myp4.save_label(label) myp4.save_change(changeno) myp4.save_client(clientspec) change = myp4.fetch_change() change["Description"] = "some text..."; myp4.save_submit(change)
This version of P4 is largely backwards compatible with previous versions with the following exceptions:
In 0.6 a new P4Error exception class has been introduced. This exception will be thrown instead of P4Client.error (which should now never be thrown).
See LICENSE.txt
Robert Cowham, Vaccaperna Systems Ltd (robert at vaccaperna dot co dot uk)
Thanks to Tony Smith for the documentation for P4Perl on which this is based.
Perforce API documentation.
$Id: //guest/robert_cowham/perforce/API/python/main/P4.html#6 $