473,770 Members | 2,143 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Code: Rolling a Container Into a String

I want to convert a dict into string form, then back again. After
discovering that eval is insecure, I wrote some code to roll a Python
object, dict, tuple, or list into a string. I've posted it below. Does
anyone know an easier way to accomplish this? Essentially, I want to
avoid doing an 'eval' on a string to get it back into dict form... but
still allow nested structures. (My current code doesn't handle nested
structures.)

I conked out before writing the 'unroll' code. I'm going to go watch
some boob tube with my husband, instead, and leave that code for
another day. If you know of a better way, or feel like writing the
'unroll' code and posting it, by all means, do so! :-D I'll check
Google newsgroups before I tackle the job, to see if some kind soul
took pity on me.

--Kamilche

import types

SimpleTypes = [types.BooleanTy pe, types.FloatType , types.IntType, \
types.LongType, types.NoneType, types.StringTyp e]

_dictdelim1 = "{"
_dictdelim2 = "}"
_listdelim1 = "["
_listdelim2 = "]"
_tupledelim1 = "("
_tupledelim2 = ")"

def roll(item):
"Return a string representation of an object, dict, tuple, or
list."
return _roll2(item, [], {})
def unroll(s):
"Unrolls a string back into a dict, tuple, or list."
if type(s) != types.StringTyp e:
raise Exception("You may only pass strings to this function!")
err = "Error occurred when parsing " + s + "!"
state = 0
container = None
for c in s:
if c == _dictdelim1:
lookfor = _dictdelim2
elif c == _listdelim1:
lookfor = _listdelim2
elif c == _tupledelim1:
lookfor = _tupledelim2
else:
raise Exception(err)
state = 1

def _quoted(s):
' Return a stringized value'
if type(s) != types.StringTyp e:
return str(s)
else:
l = []
s = s.replace("'", "\'")
l.append("'")
l.append(s)
l.append("'")
return ''.join(l)

def _roll2(d, lst, r):
' Function that does the work.'
# Start of _roll2
t = type(d)
if t == types.DictType:
theid = id(d)
if theid in r:
raise Exception("Recu rsion detected! Stopping now.")
r[theid] = theid
cnt = 0
lst.append(_dic tdelim1)
for key in d.keys():
if key[0] != '_':
lst.append(_quo ted(key))
lst.append(': ')
t = type(d[key])
if t in SimpleTypes:
lst.append(_quo ted(d[key]))
else:
_roll2(d[key], lst, r)
lst.append(", ")
cnt += 1
if cnt > 0:
del lst[-1]
lst.append(_dic tdelim2)
elif t in (types.ListType , types.TupleType ):
theid = id(d)
if theid in r:
raise Exception("Recu rsion detected! Stopping now.")
r[theid] = theid
cnt = 0
if t == types.ListType:
lst.append(_lis tdelim1)
else:
lst.append(_tup ledelim1)
for item in d:
if type(item) in SimpleTypes:
lst.append(_quo ted(item))
else:
_roll2(item, lst, r)
lst.append(", ")
cnt += 1
if cnt > 0:
del lst[-1]
if t == types.ListType:
lst.append(_lis tdelim2)
else:
lst.append(_tup ledelim2)
elif hasattr(d, '__dict__'):
_roll2(d.__dict __, lst, r)
else:
raise Exception("Unha ndled type " + str(t) + \
"! You may only pass dicts, tuples, lists, and
" + \
"objects with a __dict__ to this function!")
return ''.join(lst)


class simple:
pass

def main():
l = ['List1', 'List2', 'List3']
d = {'Dict1': 'd1', 'Dict2': 'd2', 'list': l}
t = ('Tuple1', d, 'Tuple2')

print "It handles dicts, lists, and tuples."
print roll(t), "\n"

o = simple()
o.name = 'the name'
o.password = 'the password'
o.list = ['ol1', 'ol2']
o.dict = {'od1': None, 'od2': 2}
o.tuple = ('tuple1', 'tuple2')
o.float = 1.5
o.long = 123456789012345 67890
o.bool = True
o.int = 1

print "It handles objects."
print roll(o), "\n"

print "It won't roll attributes whose name starts with '_'"
o._recursion = o.tuple
print roll(o), "\n"

print "It will raise an exception if it detects recursion."
print "This next one will cause recursion."
o.recursion = o.tuple
print roll(o), "\n"

print "You can't roll simple types."
print roll('a'), "\n"

if __name__ == "__main__":
main()
Jul 18 '05 #1
7 1691

"Kamilche" <kl*******@home .com> wrote in message
news:88******** *************** ***@posting.goo gle.com...
I want to convert a dict into string form, then back again. After
discovering that eval is insecure,
With arbitrary code from an arbitrary source, yes.
If you *know* that you are eval-ing your own safe strings, then no problem.
I wrote some code to roll a Python
object, dict, tuple, or list into a string.


repr(object) already does that for you. Why duplicate the work?

You only need custom a eval function, which might check that string is safe
(no function calls, no list comps) and then eval, or which might do parsing
and construction itself.

Terry J. Reedy
Jul 18 '05 #2
Terry Reedy wrote:
"Kamilche" <kl*******@home .com> wrote in message
news:88******** *************** ***@posting.goo gle.com...
I want to convert a dict into string form, then back again. After
discovering that eval is insecure,

With arbitrary code from an arbitrary source, yes.
If you *know* that you are eval-ing your own safe strings, then no problem.

I wrote some code to roll a Python
object, dict, tuple, or list into a string.

repr(object) already does that for you. Why duplicate the work?

You only need custom a eval function, which might check that string is safe
(no function calls, no list comps) and then eval, or which might do parsing
and construction itself.

Terry J. Reedy

Or use the pprint module which does nice pretty-printing

David
Jul 18 '05 #3
"Kamilche" <kl*******@home .com> wrote in message
news:88******** *************** ***@posting.goo gle.com...
I want to convert a dict into string form, then back again. After
discovering that eval is insecure, I wrote some code to roll a Python
object, dict, tuple, or list into a string. I've posted it below. Does
anyone know an easier way to accomplish this? Essentially, I want to
avoid doing an 'eval' on a string to get it back into dict form... but
still allow nested structures. (My current code doesn't handle nested
structures.)

unroll is just repr().

Here is a pyparsing routine to "roll up" your data structures, a mere 60
lines or so. It's fairly tolerant of some odd cases, and fully handles
nested data. (Extension to include remaining items, such as boolean data
and scientific notation, is left as an exercise for the reader.) I hope
this is fairly easy to follow - I've dropped in a few comments.

For those of you who've been living in a cave, you can download pyparsing at
http://pyparsing.sourceforge.net.

-- Paul
from pyparsing import Word, ZeroOrMore, OneOrMore, Suppress, Forward, \
quotedString,nu ms,Combine,Opti onal,delimitedL ist,Group

# create a dictionary of ugly data, complete with nested lists, tuples
# and dictionaries, even imaginary numbers!
d1 = {}
d1['a'] = [1,2,3,[4,5,6]]
d1['b'] = (7,8,(9,10),'a' ,"",'')
d1['c'] = { 'aa' : 1, 'bb' : "lskdj'slkd jf", 'cc':1.232, 'dd':(('z',),) }
d1[('d','e')] = 5+10j

print repr(d1)

testdata = repr(d1)
"""
looks like this:
{'a': [1, 2, 3, [4, 5, 6]], ('d', 'e'): (5+10j), 'c': {'aa': 1, 'cc': 1.232,
'dd': (('z',),), 'bb': "lskdj'slkdjf"} , 'b': (7, 8, (9, 10), 'a', '', '')}
"""

#define low-level data elements
intNum = Word( nums+"+-", nums )
realNum = Combine(intNum + "." + Optional(Word(n ums)))
number = realNum | intNum
imagNum = Combine( "(" + number + "+" + number + "j" + ")" )

item = Forward() # set up for recursive grammar definition
tupleDef = Suppress("(") + ( delimitedList( item ) ^
( item + Suppress(",") ) ) + Suppress(")")
listDef = Suppress("[") + delimitedList( item ) + Suppress("]")
keyDef = tupleDef | quotedString | imagNum | number
keyVal = Group( keyDef + Suppress(":") + item )
dictDef = Suppress("{") + delimitedList( keyVal ) + Suppress("}")

item << ( quotedString | number | imagNum |
tupleDef | listDef | dictDef )

# define low-level conversion routines
intNum.setParse Action( lambda s,loc,toks: int(toks[0]) )
realNum.setPars eAction( lambda s,loc,toks: float(toks[0]) )
imagNum.setPars eAction( lambda s,loc,toks: eval(toks[0]) ) # no built-in to
convert imaginaries?

# strip leading and trailing character from parsed quoted string
quotedString.se tParseAction( lambda s,loc,toks: toks[0][1:-1] )

# define list-to-list/tuple/dict routines
evalTuple = lambda s,loc,toks: [ tuple(toks) ]
evalList = lambda s,loc,toks: [ toks.asList() ]
evalDict = lambda s,loc,toks: [ dict([tuple(kv) for kv in toks]) ]

tupleDef.setPar seAction( evalTuple )
listDef.setPars eAction( evalList )
dictDef.setPars eAction( evalDict )

# first element of returned tokens list is the reconstructed list/tuple/dict
results = item.parseStrin g( testdata )[0]
print results

if repr(results) == repr(d1):
print "Eureka!"
else:
print "Compare results for mismatch"
print repr(results)
print repr(d1)
Jul 18 '05 #4

Use YAML

import yaml

then from your code:

yaml.dump( whatever ) =>

then yaml.loadstring (str)...

It handles objects.
{'name': 'the name', 'tuple': ('tuple1', 'tuple2'), 'int': 1, 'float':
1.5, 'list': ['ol1', 'ol2'], 'long': 123456789012345 67890,
'dict': {'od1': None, 'od2': 2}, 'bool': True, 'password': 'the password'}

--- !!__main__.simp le # instanciates class for you
bool: True
dict:
od1: ~
od2: 2
float: 1.5
int: 1
list:
- ol1
- ol2
long: 123456789012345 67890
name: the name
password: the password
tuple:
- tuple1
- tuple2

It won't roll attributes whose name starts with '_'
{'name': 'the name', 'tuple': ('tuple1', 'tuple2'), 'int': 1, 'float':
1.5, 'list': ['ol1', 'ol2'], 'long': 123456789012345 67890,
'dict': {'od1': None, 'od2': 2}, 'bool': True, 'password': 'the password'}

--- !!__main__.simp le
_recursion: # yaml does not handle recursion (I have an old version)
- tuple1
- tuple2
bool: True
dict:
od1: ~
od2: 2
float: 1.5
int: 1
list:
- ol1
- ol2
long: 123456789012345 67890
name: the name
password: the password
tuple:
- tuple1
- tuple2

It will raise an exception if it detects recursion.
This next one will cause recursion.
--- !!__main__.simp le
_recursion:
- tuple1
- tuple2
bool: True
dict:
od1: ~
od2: 2
float: 1.5
int: 1
list:
- ol1
- ol2
long: 123456789012345 67890
name: the name
password: the password
recursion:
- tuple1
- tuple2
tuple:
- tuple1
- tuple2
Jul 18 '05 #5
> I want to convert a dict into string form, then back again.

Since you probably don't want to do this just for the joy of
converting something to string an back ...

Maybe the pickle (and cPickle) module does what you are looking for.

Oliver
Jul 18 '05 #6
Pierre-Frédéric Caillaud <pe****@free.fr > wrote in message news:<opr941cav 01v4ijd@musicbo x>...
Use YAML

It looked interesting, so I downloaded it... and was confronted with
dozens of files, and the need to compile before use... when I was
looking for a simple cross-platform 2 function solution that didn't
take any DLL's. Dang.

Well, it's a new day, maybe I'll be inspired.
Jul 18 '05 #7

did you download syck or the pure python yaml parser ?
on Linux the pure python module is just a matter of typing "emerge sync"
but I don't know about Syck...

On 25 Jun 2004 13:36:31 -0700, Kamilche <kl*******@home .com> wrote:
Pierre-Frédéric Caillaud <pe****@free.fr > wrote in message
news:<opr941cav 01v4ijd@musicbo x>...
Use YAML

It looked interesting, so I downloaded it... and was confronted with
dozens of files, and the need to compile before use... when I was
looking for a simple cross-platform 2 function solution that didn't
take any DLL's. Dang.

Well, it's a new day, maybe I'll be inspired.


--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 18 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
1556
by: Maitre Bart | last post by:
What I want to perform is calling a member function of container 1 (CRunner), using as argument the value of a container 2 (CNames). The purpose is to transfer values from C2 into C1 using a specific C1 member function. Both containers contains the same number of elements (or at least, C1 is larger than C2). As suggested by S. Meyers (and others), I would like to use an STL algorithm instead of a custom loop. Let say I have the...
6
1820
by: Dan McCollick | last post by:
Hi All, I have a very small screen scrape application, that has a small problem. when I run the app and I have fiddler(an http tool to view what is being sent by the requests/responses, http://www.fiddlertool.com) the app works, and I am able to login to the (intranet)website. If do not run the app while fiddler is running, it does not work(the app returns html of the login page, instead of the target page). Here is the code, thanks...
6
3373
by: cpnet | last post by:
I've authored a custom web component (a non-ui component kinda like a DataSet) and so far it's working. When my web component is added to the web form in the designer from the toolbox, the namespace for my component is automatically added to the using directive of the codebehind. And, the appropriate assembly is added to the "References" for the Web form's project. However, my custom component has a field (initialized to null, and...
6
5516
by: Paolo Pignatelli | last post by:
I have an aspx code behind page that goes something like this in the HTML view: <asp:HyperLink id=HyperLink1 runat="server" NavigateUrl='<%#"mailto:" &amp; DataBinder.Eval(Container.DataItem,"StoreEmail") &amp; "&amp;Subject=" &amp; DataBinder.Eval(Container.DataItem,"ProductName") ....
4
5043
by: Larry Grady | last post by:
Anyone up for a challenge? I've been struggling with this for a few days and was hoping someone could help me. Pouring through all the messageboards I just can't find the solution. We have a GridView that needs to be dynamically designed, depending on what collection of fields our uses want to edit for their product data. We have 400+ fields of information per product so they're selecting a subset of those fields to edit.
1
1601
by: Neo Geshel | last post by:
I am having conflicting results with two pieces of identical code. One is an insert, the other is an update to a db. The first code, which works, is this: Sub Add3_Click(sender As Object, e As EventArgs) Dim imgStream as Stream = Add3Image.PostedFile.InputStream Dim imgLen as Integer = Add3Image.PostedFile.ContentLength Dim imgType as String = Add3Image.PostedFile.ContentType If Not imgStream Is Nothing And imgLen > 0 And (imgType =
2
3550
by: mikepolitowski | last post by:
Hi folks, I am have been trying to solve this problem for quite some time now and would appreciate any advice. I have been trying to call a code-behind function that is defined in my aspx.cs from within a DataList <ItemTemplate> block using the <%# %> syntax. I would not have written here if I had not spent over 6 hours trying to find a solution to this problem again any advice is greatly appreciated. I have included a code snippet...
2
2458
by: MrCrool | last post by:
Hi I need to be able to handle the following ASP programming in pure C# code: <asp:TemplateColumn HeaderText="Customer Information"> <ItemTemplate> <table border="0"> <tr> <td align="right"><b>Name:</b></td> <td><%# DataBinder.Eval(Container.DataItem, "name") %></td>
3
5834
by: peterhall | last post by:
In VBA an Access module has a find method - works perfectly to find a string inside a module. i'm working in A97 (legacy) systems (large ones) and want to write code that searches all modules so that I can check on the possible effects of a change. But the 97 modules collection is open modules only. Access 97 doesn't have an allmodules collection - 2000+ does - so I can move the app up for this purpose. But now I find that a module in...
0
9454
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10260
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10102
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8933
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7460
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6712
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5354
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5482
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4007
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.