pax_global_header 0000666 0000000 0000000 00000000064 11665215263 0014521 g ustar 00root root 0000000 0000000 52 comment=7b2e6089ff9182776b5cb5420e24536ab7479a34
pyjavaproperties-0.6/ 0000775 0000000 0000000 00000000000 11665215263 0014775 5 ustar 00root root 0000000 0000000 pyjavaproperties-0.6/MANIFEST.in 0000664 0000000 0000000 00000000104 11665215263 0016526 0 ustar 00root root 0000000 0000000 include TODO
include README
recursive-include testdata *.properties
pyjavaproperties-0.6/PKG-INFO 0000664 0000000 0000000 00000010271 11665215263 0016073 0 ustar 00root root 0000000 0000000 Metadata-Version: 1.0
Name: pyjavaproperties
Version: 0.6
Summary: Python replacement for java.util.Properties.
Home-page: http://pypi.python.org/pypi/pyjavaproperties
Author: Jesse Noller
Author-email: jnoller@gmail.com
License: PSF License
Description: ================
pyjavaproperties
================
* Project hosting:
.. contents::
About
------------------
This is a "fork" of the "python replacement for java.util.Properties" recipe
on ASPN: and uploaded by
Anand Balachandran Pillai.
The project is maintained by Jesse Noller , Anand Pilla
.
License
------------------
As with all ASPN recipes not otherwise licensed prior to July 15, 2008 on
aspn.activestate.com, the original recipe is under PSF License. For more
information, see the ASPN terms of service here:
While the licensing under the PSF license is sub-optimal, it is what it is. See
for more information about the PSF
license.
What this is
------------------
This module is designed to be a python equivalent to the `java.util.Properties `_ class.
Currently, the basic input/output methods are supported, and there are plans
to add the XML input/output methods found in J2SE 5.0.
Fundamentally, this module is designed so that users can easily parse and
manipulate Java Properties files - that's it. There's a fair number of us
pythonistas who work in multi-language shops, and constantly writing your own
parsing mechanism is just painful. Not to mention Java guys are notoriously
unwilling to use anything which is cross-language for configuration, unless
it's XML, which is a form of self-punishment. :)
Plans
------------------
Here is a rough plan of features:
- Keep/maintain blank lines and comments found in the original file
- Make the module compatible with the new methods in J2SE 5.0
- Switch to/add python property access rather than direct dictionary get/set
- Add unit tests
- Add unicode support
- When-Pigs-Fly: If running within Jython, switch to java.util.Properties
under the hood
- Coercion/conversion to python types for values
Usage
------------------
This is the easy part::
from pyjavaproperties import Properties
p = Properties()
p.load(open('test2.properties'))
p.list()
print p
print p.items()
print p['name3']
p['name3'] = 'changed = value'
print p['name3']
p['new key'] = 'new value'
p.store(open('test2.properties','w'))
See also the Properties.list() method, which will return an iterator over the
property keys
Changes & News
--------------
0.4:
- Patch from Pepper Lebeck-Jobe for handling ! style comments.
0.3:
- Keys that are added which were not part of the original file
are simply appended to the index. Shenanigans.
0.2:
- Added an internal list (self._keyorder) to keep an ordered index of keys
as they are encountered, so the file can we written-back out in the
same order.
0.1:
- Initial release/fork.
- Added setup/packaging and doc
- added in {foo} style references for previous properties, thanks to N B
on ASPN.
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
pyjavaproperties-0.6/README 0000664 0000000 0000000 00000006024 11665215263 0015657 0 ustar 00root root 0000000 0000000 ================
pyjavaproperties
================
* Project hosting:
.. contents::
About
------------------
This is a "fork" of the "python replacement for java.util.Properties" recipe
on ASPN: and uploaded by
Anand Balachandran Pillai.
The project is maintained by Jesse Noller , Anand Pilla
.
License
------------------
As with all ASPN recipes not otherwise licensed prior to July 15, 2008 on
aspn.activestate.com, the original recipe is under PSF License. For more
information, see the ASPN terms of service here:
While the licensing under the PSF license is sub-optimal, it is what it is. See
for more information about the PSF
license.
What this is
------------------
This module is designed to be a python equivalent to the `java.util.Properties `_ class.
Currently, the basic input/output methods are supported, and there are plans
to add the XML input/output methods found in J2SE 5.0.
Fundamentally, this module is designed so that users can easily parse and
manipulate Java Properties files - that's it. There's a fair number of us
pythonistas who work in multi-language shops, and constantly writing your own
parsing mechanism is just painful. Not to mention Java guys are notoriously
unwilling to use anything which is cross-language for configuration, unless
it's XML, which is a form of self-punishment. :)
Plans
------------------
Here is a rough plan of features:
- Keep/maintain blank lines and comments found in the original file
- Make the module compatible with the new methods in J2SE 5.0
- Switch to/add python property access rather than direct dictionary get/set
- Add unit tests
- Add unicode support
- When-Pigs-Fly: If running within Jython, switch to java.util.Properties
under the hood
- Coercion/conversion to python types for values
Usage
------------------
This is the easy part::
from pyjavaproperties import Properties
p = Properties()
p.load(open('test2.properties'))
p.list()
print p
print p.items()
print p['name3']
p['name3'] = 'changed = value'
print p['name3']
p['new key'] = 'new value'
p.store(open('test2.properties','w'))
See also the Properties.list() method, which will return an iterator over the
property keys
Changes & News
--------------
0.4:
- Patch from Pepper Lebeck-Jobe for handling ! style comments.
0.3:
- Keys that are added which were not part of the original file
are simply appended to the index. Shenanigans.
0.2:
- Added an internal list (self._keyorder) to keep an ordered index of keys
as they are encountered, so the file can we written-back out in the
same order.
0.1:
- Initial release/fork.
- Added setup/packaging and doc
- added in {foo} style references for previous properties, thanks to N B
on ASPN.
pyjavaproperties-0.6/TODO 0000664 0000000 0000000 00000000320 11665215263 0015460 0 ustar 00root root 0000000 0000000 * Add PEP 8 interface, python properties.
* Add in unit tests
- Have to find some really offensive .properties files
* Switch to returning Unicode values
* Possible coercion to python types (on ints/etc)
pyjavaproperties-0.6/pyjavaproperties.egg-info/ 0000775 0000000 0000000 00000000000 11665215263 0022076 5 ustar 00root root 0000000 0000000 pyjavaproperties-0.6/pyjavaproperties.egg-info/PKG-INFO 0000664 0000000 0000000 00000010271 11665215263 0023174 0 ustar 00root root 0000000 0000000 Metadata-Version: 1.0
Name: pyjavaproperties
Version: 0.6
Summary: Python replacement for java.util.Properties.
Home-page: http://pypi.python.org/pypi/pyjavaproperties
Author: Jesse Noller
Author-email: jnoller@gmail.com
License: PSF License
Description: ================
pyjavaproperties
================
* Project hosting:
.. contents::
About
------------------
This is a "fork" of the "python replacement for java.util.Properties" recipe
on ASPN: and uploaded by
Anand Balachandran Pillai.
The project is maintained by Jesse Noller , Anand Pilla
.
License
------------------
As with all ASPN recipes not otherwise licensed prior to July 15, 2008 on
aspn.activestate.com, the original recipe is under PSF License. For more
information, see the ASPN terms of service here:
While the licensing under the PSF license is sub-optimal, it is what it is. See
for more information about the PSF
license.
What this is
------------------
This module is designed to be a python equivalent to the `java.util.Properties `_ class.
Currently, the basic input/output methods are supported, and there are plans
to add the XML input/output methods found in J2SE 5.0.
Fundamentally, this module is designed so that users can easily parse and
manipulate Java Properties files - that's it. There's a fair number of us
pythonistas who work in multi-language shops, and constantly writing your own
parsing mechanism is just painful. Not to mention Java guys are notoriously
unwilling to use anything which is cross-language for configuration, unless
it's XML, which is a form of self-punishment. :)
Plans
------------------
Here is a rough plan of features:
- Keep/maintain blank lines and comments found in the original file
- Make the module compatible with the new methods in J2SE 5.0
- Switch to/add python property access rather than direct dictionary get/set
- Add unit tests
- Add unicode support
- When-Pigs-Fly: If running within Jython, switch to java.util.Properties
under the hood
- Coercion/conversion to python types for values
Usage
------------------
This is the easy part::
from pyjavaproperties import Properties
p = Properties()
p.load(open('test2.properties'))
p.list()
print p
print p.items()
print p['name3']
p['name3'] = 'changed = value'
print p['name3']
p['new key'] = 'new value'
p.store(open('test2.properties','w'))
See also the Properties.list() method, which will return an iterator over the
property keys
Changes & News
--------------
0.4:
- Patch from Pepper Lebeck-Jobe for handling ! style comments.
0.3:
- Keys that are added which were not part of the original file
are simply appended to the index. Shenanigans.
0.2:
- Added an internal list (self._keyorder) to keep an ordered index of keys
as they are encountered, so the file can we written-back out in the
same order.
0.1:
- Initial release/fork.
- Added setup/packaging and doc
- added in {foo} style references for previous properties, thanks to N B
on ASPN.
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
pyjavaproperties-0.6/pyjavaproperties.egg-info/SOURCES.txt 0000664 0000000 0000000 00000000415 11665215263 0023762 0 ustar 00root root 0000000 0000000 MANIFEST.in
README
TODO
setup.py
./pyjavaproperties.py
./pyjavaproperties_test.py
pyjavaproperties.egg-info/PKG-INFO
pyjavaproperties.egg-info/SOURCES.txt
pyjavaproperties.egg-info/dependency_links.txt
pyjavaproperties.egg-info/top_level.txt
testdata/complex.properties pyjavaproperties-0.6/pyjavaproperties.egg-info/dependency_links.txt 0000664 0000000 0000000 00000000001 11665215263 0026144 0 ustar 00root root 0000000 0000000
pyjavaproperties-0.6/pyjavaproperties.egg-info/top_level.txt 0000664 0000000 0000000 00000000022 11665215263 0024622 0 ustar 00root root 0000000 0000000
pyjavaproperties
pyjavaproperties-0.6/pyjavaproperties.py 0000664 0000000 0000000 00000024477 11665215263 0020774 0 ustar 00root root 0000000 0000000 #! /usr/bin/env python
"""
A Python replacement for java.util.Properties class
This is modelled as closely as possible to the Java original.
Created - Anand B Pillai
"""
import sys,os
import re
import time
class IllegalArgumentException(Exception):
def __init__(self, lineno, msg):
self.lineno = lineno
self.msg = msg
def __str__(self):
s='Exception at line number %d => %s' % (self.lineno, self.msg)
return s
class Properties(object):
""" A Python replacement for java.util.Properties """
def __init__(self, props=None):
# Note: We don't take a default properties object
# as argument yet
# Dictionary of properties.
self._props = {}
# Dictionary of properties with 'pristine' keys
# This is used for dumping the properties to a file
# using the 'store' method
self._origprops = {}
self._keyorder = []
# Dictionary mapping keys from property
# dictionary to pristine dictionary
self._keymap = {}
self.othercharre = re.compile(r'(?',line
# Means we need to split by space.
first, last = m2.span()
sepidx = first
elif m:
# print 'Other match=>',line
# No matching wspace char found, need
# to split by either '=' or ':'
first, last = m.span()
sepidx = last - 1
# print line[sepidx]
# If the last character is a backslash
# it has to be preceded by a space in which
# case the next line is read as part of the
# same property
while line[-1] == '\\':
# Read next line
nextline = i.next()
nextline = nextline.strip()
lineno += 1
# This line will become part of the value
line = line[:-1] + nextline
# Now split to key,value according to separation char
if sepidx != -1:
key, value = line[:sepidx], line[sepidx+1:]
else:
key,value = line,''
self._keyorder.append(key)
self.processPair(key, value)
def processPair(self, key, value):
""" Process a (key, value) pair """
oldkey = key
oldvalue = value
# Create key intelligently
keyparts = self.bspacere.split(key)
# print keyparts
strippable = False
lastpart = keyparts[-1]
if lastpart.find('\\ ') != -1:
keyparts[-1] = lastpart.replace('\\','')
# If no backspace is found at the end, but empty
# space is found, strip it
elif lastpart and lastpart[-1] == ' ':
strippable = True
key = ''.join(keyparts)
if strippable:
key = key.strip()
oldkey = oldkey.strip()
oldvalue = self.unescape(oldvalue)
value = self.unescape(value)
# Patch from N B @ ActiveState
curlies = re.compile("{.+?}")
found = curlies.findall(value)
for f in found:
srcKey = f[1:-1]
if self._props.has_key(srcKey):
value = value.replace(f, self._props[srcKey], 1)
self._props[key] = value.strip()
# Check if an entry exists in pristine keys
if self._keymap.has_key(key):
oldkey = self._keymap.get(key)
self._origprops[oldkey] = oldvalue.strip()
else:
self._origprops[oldkey] = oldvalue.strip()
# Store entry in keymap
self._keymap[key] = oldkey
if key not in self._keyorder:
self._keyorder.append(key)
def escape(self, value):
# Java escapes the '=' and ':' in the value
# string with backslashes in the store method.
# So let us do the same.
newvalue = value.replace(':','\:')
newvalue = newvalue.replace('=','\=')
return newvalue
def unescape(self, value):
# Reverse of escape
newvalue = value.replace('\:',':')
newvalue = newvalue.replace('\=','=')
return newvalue
def load(self, stream):
""" Load properties from an open file stream """
# For the time being only accept file input streams
if type(stream) is not file:
raise TypeError,'Argument should be a file object!'
# Check for the opened mode
if stream.mode != 'r':
raise ValueError,'Stream should be opened in read-only mode!'
try:
lines = stream.readlines()
self.__parse(lines)
except IOError, e:
raise
def getProperty(self, key):
""" Return a property for the given key """
return self._props.get(key,'')
def setProperty(self, key, value):
""" Set the property for the given key """
if type(key) is str and type(value) is str:
self.processPair(key, value)
else:
raise TypeError,'both key and value should be strings!'
def propertyNames(self):
""" Return an iterator over all the keys of the property
dictionary, i.e the names of the properties """
return self._props.keys()
def list(self, out=sys.stdout):
""" Prints a listing of the properties to the
stream 'out' which defaults to the standard output """
out.write('-- listing properties --\n')
for key,value in self._props.items():
out.write(''.join((key,'=',value,'\n')))
def store(self, out, header=""):
""" Write the properties list to the stream 'out' along
with the optional 'header' """
if out.mode[0] != 'w':
raise ValueError,'Steam should be opened in write mode!'
try:
out.write(''.join(('#',header,'\n')))
# Write timestamp
tstamp = time.strftime('%a %b %d %H:%M:%S %Z %Y', time.localtime())
out.write(''.join(('#',tstamp,'\n')))
# Write properties from the pristine dictionary
for prop in self._keyorder:
if prop in self._origprops:
val = self._origprops[prop]
out.write(''.join((prop,'=',self.escape(val),'\n')))
out.close()
except IOError, e:
raise
def getPropertyDict(self):
return self._props
def __getitem__(self, name):
""" To support direct dictionary like access """
return self.getProperty(name)
def __setitem__(self, name, value):
""" To support direct dictionary like access """
self.setProperty(name, value)
def __getattr__(self, name):
""" For attributes not found in self, redirect
to the properties dictionary """
try:
return self.__dict__[name]
except KeyError:
if hasattr(self._props,name):
return getattr(self._props, name)
if __name__=="__main__":
p = Properties()
p.load(open('test2.properties'))
p.list()
print p
print p.items()
print p['name3']
p['name3'] = 'changed = value'
print p['name3']
p['new key'] = 'new value'
p.store(open('test2.properties','w'))
pyjavaproperties-0.6/pyjavaproperties_test.py 0000664 0000000 0000000 00000004355 11665215263 0022024 0 ustar 00root root 0000000 0000000 #! /usr/bin/env python
"""Basic tests to ensure pyjavaproperties behaves like java.util.Properties.
Created - Pepper Lebeck-Jobe (eljobe@gmail.com)
"""
import os
import unittest
from pyjavaproperties import Properties
class PyJavaPropertiesTest(unittest.TestCase):
"""Tests pyjavaproperties complies to java.util.Properties contract."""
def setUp(self):
test_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'testdata')
self.properties_file = os.path.join(test_dir, 'complex.properties')
def testParsePropertiesInput(self):
properties = Properties()
properties.load(open(self.properties_file))
self.assertEquals(23, len(properties.items()))
self.assertEquals('Value00', properties['Key00'])
self.assertEquals('Value01', properties['Key01'])
self.assertEquals('Value02', properties['Key02'])
self.assertEquals('Value03', properties['Key03'])
self.assertEquals('Value04', properties['Key04'])
self.assertEquals('Value05a, Value05b, Value05c', properties['Key05'])
self.assertEquals('Value06a, Value06b, Value06c', properties['Key06'])
self.assertEquals('Value07b', properties['Key07'])
self.assertEquals(
'Value08a, Value08b, Value08c, Value08d, Value08e, Value08f',
properties['Key08'])
self.assertEquals(
'Value09a, Value09b, Value09c, Value09d, Value09e, Value09f',
properties['Key09'])
self.assertEquals('Value10', properties['Key10'])
self.assertEquals('', properties['Key11'])
self.assertEquals('Value12a, Value12b, Value12c', properties['Key12'])
self.assertEquals('Value13 With Spaces', properties['Key13'])
self.assertEquals('Value14 With Spaces', properties['Key14'])
self.assertEquals('Value15 With Spaces', properties['Key15'])
self.assertEquals('Value16', properties['Key16 With Spaces'])
self.assertEquals('Value17', properties['Key17 With Spaces'])
self.assertEquals('Value18 # Not a comment.', properties['Key18'])
self.assertEquals('Value19 ! Not a comment.', properties['Key19'])
self.assertEquals('Value20', properties['Key20=WithEquals'])
self.assertEquals('Value21', properties['Key21:WithColon'])
self.assertEquals('Value22', properties['Key22'])
if __name__ == '__main__':
unittest.main()
pyjavaproperties-0.6/setup.cfg 0000664 0000000 0000000 00000000073 11665215263 0016616 0 ustar 00root root 0000000 0000000 [egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
pyjavaproperties-0.6/setup.py 0000664 0000000 0000000 00000002063 11665215263 0016510 0 ustar 00root root 0000000 0000000 import os
import sys
try:
import ez_setup
ez_setup.use_setuptools()
except ImportError:
pass
from setuptools import setup
# Use a cute trick to include the rest-style docs as the long_description
# therefore having it self-doc'ed and hosted on pypi
f = open(os.path.join(os.path.dirname(__file__), 'README'))
long_description = f.read().strip()
f.close()
setup(
name='pyjavaproperties',
version='0.6',
author='Jesse Noller',
author_email = 'jnoller@gmail.com',
description = 'Python replacement for java.util.Properties.',
long_description = long_description,
url='http://pypi.python.org/pypi/pyjavaproperties',
license = 'PSF License',
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'License :: OSI Approved :: Apache Software License',
'Topic :: Software Development :: Libraries',
'Topic :: Software Development :: Libraries :: Python Modules',
],
py_modules=['pyjavaproperties'],
packages=[''],
package_dir={'': '.'},
)
pyjavaproperties-0.6/testdata/ 0000775 0000000 0000000 00000000000 11665215263 0016606 5 ustar 00root root 0000000 0000000 pyjavaproperties-0.6/testdata/complex.properties 0000664 0000000 0000000 00000002030 11665215263 0022366 0 ustar 00root root 0000000 0000000 # notKey00:notValue00 This is a comment and ignored.
! notKey01:notValue01 This is a comment and ignored.
# notKey02=notValue02 This is a comment and ignored.
! notKey03=notValue03 This is a comment and ignored.
Key00:Value00
Key01=Value01
Key02:Value02
Key03 : Value03
Key04 = Value04
Key05: Value05a, Value05b, Value05c
Key06 = Value06a, Value06b, Value06c
Key07 = Value07a
Key07 = Value07b
Key08: Value08a, Value08b, \
Value08c, Value08d, \
Value08e, Value08f
Key09 = Value09a, Value09b, \
Value09c, Value09d, \
Value09e, Value09f
# notKey04=notValue04 This is a comment and ignored.
Key10 Value10
! notKey05=notValue05 This is a comment and ignored.
Key11
Key12 Value12a, Value12b, Value12c
Key13:Value13 With Spaces
Key14=Value14 With Spaces
Key15 Value15 With Spaces
Key16\ With\ Spaces:Value16
Key17\ With\ Spaces=Value17
Key18 = Value18 # Not a comment.
Key19 : Value19 ! Not a comment.
Key20\=WithEquals = Value20
Key21\:WithColon : Value21
Key22 Value22