Sometimes as I'm using pdb, I would like to save the output to a file, pdbSaves.txt. For example I would want to do something like pp locals() >> pdbSaves.txt, which actually gives *** NameError: name 'pdbSaves' is not defined. What is the correct way to do this?
In Python 3 the ">>" symbol is no longer usable with the regular "print" for redirecting the output.
I had not before used it from inside the PDB, but, certainly, the support for it was removed at the same time.
What you have to do is to use the regular way of output to file with the new print function - or, if you want to do pretty print (pp does that), with the pprint.pprint function.
(Pdb) from pprint import pprint as ppr
(Pdb) file = open("x.txt", "wt")
(Pdb) ppr("mystuff", stream=file)
Or, for regular printing, the parameter name for the output file is file rather than stream (the advantage is that the import statement is not needed):
(Pdb) print ("mystuff", file=file)
Also, either these methods and the Python 2 >> way require the target to be an open file, not a string with the filename:
Related
I am using python and I am supposed to read a file from command line for further processing. My input file has a binary that should be read for further processing. Here is my input file sub.py:
CODE = " \x55\x48\x8b\x05\xb8\x13\x00\x00"
and my main file which should read this is like the following:
import pyvex
import archinfo
import fileinput
import sys
filename = sys.argv[-1]
f = open(sys.argv[-1],"r")
CODE = f.read()
f.close()
print CODE
#CODE = b"\x55\x48\x8b\x05\xb8\x13\x00\x00"
# translate an AMD64 basic block (of nops) at 0x400400 into VEX
irsb = pyvex.IRSB(CODE, 0x1000, archinfo.ArchAMD64())
# pretty-print the basic block
irsb.pp()
# this is the IR Expression of the jump target of the unconditional exit at the end of the basic block
print irsb.next
# this is the type of the unconditional exit (i.e., a call, ret, syscall, etc)
print irsb.jumpkind
# you can also pretty-print it
irsb.next.pp()
# iterate through each statement and print all the statements
for stmt in irsb.statements:
stmt.pp()
# pretty-print the IR expression representing the data, and the *type* of that IR expression written by every store statement
import pyvex
for stmt in irsb.statements:
if isinstance(stmt, pyvex.IRStmt.Store):
print "Data:",
stmt.data.pp()
print ""
print "Type:",
print stmt.data.result_type
print ""
# pretty-print the condition and jump target of every conditional exit from the basic block
for stmt in irsb.statements:
if isinstance(stmt, pyvex.IRStmt.Exit):
print "Condition:",
stmt.guard.pp()
print ""
print "Target:",
stmt.dst.pp()
print ""
# these are the types of every temp in the IRSB
print irsb.tyenv.types
# here is one way to get the type of temp 0
print irsb.tyenv.types[0]
The problem is that when I run "python maincode.py sub.py' it reads the code as content of the file but its output is completely different from when I directly add CODE into the statement irsb = pyvex.IRSB(CODE, 0x1000, archinfo.ArchAMD64()). Does anyone know what is the problem and how can I solve it? I even use importing from inputfile but it does not read a text.
Have you considered the __import__ way?
You could do
mod = __import__(sys.argv[-1])
print mod.CODE
and just pass the filename without the .py extension as your command line argument:
python maincode.py sub
EDIT: Apparently using __import__ is discouraged. Instead though you can use importlib module:
import sys,importlib
mod = importlib.import_module(sys.argv[-1])
print mod.CODE
..and it should work the same as using __import__
If you need to pass a path to the module, one way is if in each of the directories you added an empty file named
__init__.py
That will allow python to interpret the directories as module namespaces, and you can then pass the path in its module form: python maincode.py path.to.subfolder.sub
If for some reason you cannot or don't want to add the directories as namespaces, and don't want to add the init.py files everywhere, you could also use imp.find_module. Your maincode.py would instead look like this:
import sys, imp
mod = imp.find_module("sub","/path/to/subfolder/")
print mod.code
You'll have to write code which breaks apart your command line input into the module part "sub" and the folder path "/path/to/subfolder/" though. Does that make sense? Once its ready you'll call it like you expect, python maincode.py /path/to/subfolder/sub/
you're reading the code as text, while when reading as file you're likely reading as binary
you probably need to convert binary to text of vice-versa to make this work
Binary to String/Text in Python
I have two python modules: buildContent.py which contains code that results in output i want. buildRun.py which i run in order to redirect the output to a file.
I'm trying to save the output from buildContent.py to a file and I did something like this in the buildRun.py:
import buildContent
import sys
with open('out.xhtml', 'w') as f:
sys.stdout = f
print buildContent
I can see my output in the console but the file result is:
<module 'buildContent' from 'here's my path to the file'>
what to do?
the redirection is working properly.
if you replace your print statement with a string you will see that it has
worked.
The reason for that output is that you are not calling any functions within buildcontent, merely importing it.
The solution is to run the buildContent file from within the above where your print statement should be.
see this question for an example
Instead of printing buildContent, just execute that module with the required parameters. Not sure of the content of buildContent but something like this should work:
buildContent(data)
This way the code inside buildContent will run on the "data" and print the results (if the print statements are given in the module). If you did not include print statements in buildContent, collect the output into a variable and print that variable. Something like this:
var = buildContent(data)
print var
If you do not need any data atall to run buildContent, just run:
buildContent()
I really dont know how to word this.
I am creating a program that reads through another py file called code.py, it will find all VALID dictionary variable names and print them, easy enough? But the code im trying to run through is extremely tricky, purposely put in examples to trick the regex. The test code for code.py is here and my current code is:
import re
with open ("code.py", "r") as myfile:
data=myfile.read()
potato = re.findall(r' *(\w+)\W*{',data,re.M)
for i in range(len(potato)):
print(potato[i])
That regex doesnt work 100%, when used on the test code it will print variables that arent meant to be printed such as:
# z={}
z="z={}"
print('your mother = {}')
The expected output for the test file is
a0, a, b ,c d, e, etc all the way down to z, then it will be aa, ab , ac, ad, etc all the way down to aq
and anything really labeled z in the test code shouldnt print.
I realise that regex isn't amazing for doing this but i have to use regex and it can be done.
EDIT: Using the new regex (r'^ (\w+)\W{',data,re.M) the output fails on examples where there are variables assigned on one line such as,
d={
};e={
};
l should print but z shouldn't
potato = re.findall(r'^ *(\w+)\W*{',data,re.M)
This should fix it.
EDIT:
".*?(?<!\\)"|'.*?(?<!\\)'|\([^)(]*\)|#[^\n]*\n|[^\'\"\#(\w\n]*(\w+)[^\w]*?{
See demo.
https://regex101.com/r/gP5iH5/6
Trying to parse a Python file using a regular expression will usually be able to be fooled. I would suggest the following kind of approach. The dis library could be used to disassemble byte code from compiled source code. From this all of the dictionaries can be picked out.
So assuming a Python source file called code.py:
import code
source_module = code
source_py = "code.py"
import sys, dis, re
from contextlib import contextmanager
from StringIO import StringIO
#contextmanager
def captureStdOut(output):
stdout = sys.stdout
sys.stdout = output
yield
sys.stdout = stdout
with open(source_py) as f_source:
source_code = f_source.read()
byte_code = compile(source_code, source_py, "exec")
output = StringIO()
with captureStdOut(output):
dis.dis(byte_code)
dis.dis(source_module)
disassembly = output.getvalue()
dictionaries = re.findall("(?:BUILD_MAP|STORE_MAP).*?(?:STORE_FAST|STORE_NAME).*?\((.*?)\)", disassembly, re.M+re.S)
print dictionaries
As dis prints to stdout, you need to redirect the output. A regular expression can then be used to spot all of the entries. I do this twice, once by compiling the source to get the globals and once by importing the module to get the functions. There is probably a better way to do this but it seems to work.
Is it possible (not necessarly using python introspection) to print the source code of a script?
I want to execute a short python script that also print its source (so I can see which commands are executed).
The script is something like this:
command1()
#command2()
command3()
print some_variable_that_contain_src
The real application is that I want to run a script from IPython with the run -i magic and have as output the source (i.e. the commands executed). In this way I can check which commands are commented at every execution. Moreover, if executed in a Notebook I leave a trace of which commands have been used.
Solution
Using korylprince solution I end up with this one-liner to be put at the beginning of the script:
with open(__file__) as f: print '\n'.join(f.read().split('\n')[1:])
This will print the script source except the first line (that would be only noise). It's also easy to modify the slicing in order to print a different "slice" of the script.
If you want to print the whole file instead, the one-liner simplifies to:
with open(__file__) as f: print f.read()
As long as you're not doing anything crazy with packages, put this at the top of your script
with open(__file__) as f:
print f.read()
Which will read in the current file and print it out.
For python 3 make sure to use instead
print(f.read())
For the most simple answer:
import my_module
print open(my_module.__file__).read()
I also tried using the inspect package.
import inspect
import my_module
source_list = inspect.getsourcelines(my_module)
Will give you a list of strings with the source code defined in it
for line in source_list[0]:
print line
Will print out the entire source code in a readable manner
I've got a function meant to download a file from a URL and write it to a disk, along with imposing a particular file extension. At present, it looks something like this:
import requests
import os
def getpml(url,filename):
psc = requests.get(url)
outfile = os.path.join(os.getcwd(),filename+'.pml')
f = open(outfile,'w')
f.write(psc.content)
f.close()
try:
with open(outfile) as f:
print "File Successfully Written"
except IOError as e:
print "I/O Error, File Not Written"
return
When I try something like
getpml('http://www.mysite.com/data.txt','download') I get the appropriate file sitting in the current working directory, download.pml. But when I feed the function the same arguments without the ' symbol, Python says something to the effect of "NameError: name 'download' is not defined" (the URL produces a syntax error). This even occurs if, within the function itself, I use str(filename) or things like that.
I'd prefer not to have to input the arguments of the function in with quote characters - it just makes entering URLs and the like slightly more difficult. Any ideas? I presume there is a simple way to do this, but my Python skills are spotty.
No, that cannot be done. When you are typing Python source code you have to type quotes around strings. Otherwise Python can't tell where the string begins and ends.
It seems like you have a more general misunderstanding too. Calling getpml(http://www.mysite.com) without quotes isn't calling it with "the same argument without quotes". There simply isn't any argument there at all. It's not like there are "arguments with quotes" and "arguments without quotes". Python isn't like speaking a natural human language where you can make any sound and it's up to the listener to figure out what you mean. Python code can only be made up of certain building blocks (object names, strings, operators, etc.), and URLs aren't one of those.
You can call your function differently:
data = """\
http://www.mysite.com/data1.txt download1
http://www.mysite.com/data2.txt download2
http://www.mysite.com/data3.txt download3
"""
for line in data.splitlines():
url, filename = line.strip().split()
getpml(url, filename)