Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ported to python 3, compatible with python 2 #41

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5d8b31a
fixed many syntax & reference errors; broke compatibility with python…
simonzack Jan 23, 2015
163c41b
hashing doesn't work here, since strings & bytes hash to the same val…
simonzack Jan 22, 2015
c7aa208
fixed next issues
simonzack Jan 23, 2015
7e96377
fixed bool issues
simonzack Jan 23, 2015
275fdad
more portable dict check
simonzack Jan 22, 2015
ff0dd2d
use sorted
simonzack Jan 22, 2015
fa9785f
fixed encoding issues
simonzack Jan 22, 2015
0932f31
use __eq__ instead
simonzack Jan 22, 2015
b15041f
fixed _join
simonzack Jan 23, 2015
06b98bc
type fixes, everything is an object in python
simonzack Jan 23, 2015
11894e6
more type fixes
simonzack Jan 23, 2015
13d7422
use unittest.TestCase instead as the name of the builtins module diff…
simonzack Jan 23, 2015
bbbb38d
store exc_info as it will change on the second sys.exc_info() invocat…
simonzack Jan 23, 2015
9a50898
convert to a local variable
simonzack Jan 23, 2015
2c5fe67
convert to list first
simonzack Jan 23, 2015
f01e6e7
use ModuleType instead
simonzack Jan 23, 2015
5f5dfe9
use `.data` instead
simonzack Jan 23, 2015
771fff1
use the `'b'` array type for testing
simonzack Jan 23, 2015
9aa1210
check whether the class is a classic class, i.e. if we are in python 2
simonzack Jan 23, 2015
045968e
fix python 3 `datetime.utcfromtimestamp` microsecond rounding
simonzack Jan 23, 2015
534bfda
sort object keys so encoding is deterministic, and so tests always pass
simonzack Jan 23, 2015
3e30198
skip classic tests on python 3
simonzack Jan 23, 2015
a4805e5
fixed repr issues
simonzack Jan 23, 2015
3992abb
Merge branch 'master' into python3
simonzack Jan 23, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cpyamf/util.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,8 @@ cdef class cBufferedByteStream(object):
def __nonzero__(self):
return self.length > 0

__bool__ = __nonzero__


cdef class BufferedByteStream(cBufferedByteStream):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"""

from datetime import datetime
from six import iteritems

import pyamf

Expand Down Expand Up @@ -59,13 +60,13 @@ def insertDefaultData(self):
user.first_name = 'Bill'
user.last_name = 'Lumbergh'
user.created = datetime.utcnow()
for label, email in {'personal': '[email protected]', 'work': '[email protected]'}.iteritems():
for label, email in iteritems({'personal': '[email protected]', 'work': '[email protected]'}):
email_obj = models.Email()
email_obj.label = label
email_obj.email = email
user.emails.append(email_obj)

for label, number in {'personal': '1-800-555-5555', 'work': '1-555-555-5555'}.iteritems():
for label, number in iteritems({'personal': '1-800-555-5555', 'work': '1-555-555-5555'}):
phone_obj = models.PhoneNumber()
phone_obj.label = label
phone_obj.number = number
Expand Down
30 changes: 15 additions & 15 deletions doc/tutorials/examples/actionscript/guestbook/python/guestbook.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"""


from datetime import datetime
from urlparse import urlparse
import re
from urlparse import urlparse
from six import string_types

try:
from genshi.input import HTML
Expand All @@ -33,12 +33,12 @@
# This is MySQL specific, make sure that if you use a different database server
# this is updated to ensure sql injection attacks don't occur
def sql_safe(value):
if isinstance(value, basestring):
if isinstance(value, string_types):
return value.replace("'", "\\'")
elif isinstance(type(value), (int, float)):
return value

raise TypeError, 'basestring, int or float expected'
raise TypeError('basestring, int or float expected')


def is_valid_url(url):
Expand Down Expand Up @@ -93,8 +93,8 @@ def __init__(self, pool):
self.conn_pool = pool
LoopingCall(self._keepAlive).start(3600, False)

def _keepAlive():
print 'Running Keep Alive...'
def _keepAlive(self):
print('Running Keep Alive...')
self.conn_pool.runOperation('SELECT 1')

def getMessages(self):
Expand Down Expand Up @@ -135,35 +135,35 @@ def addMessage(self, request, msg):
email = msg._amf_object.email
message = msg._amf_object.message

if not isinstance(name, basestring):
if not isinstance(name, string_types):
name = str(name)

if len(name) > 50:
raise IOError, "Name exceeds maximum length (50 chars max)"
raise IOError("Name exceeds maximum length (50 chars max)")

if not isinstance(url, basestring):
if not isinstance(url, string_types):
url = str(url)

if len(url) > 255:
raise IOError, "Website url exceeds maximum length (255 chars max)"
raise IOError("Website url exceeds maximum length (255 chars max)")

if len(url) > 0:
valid_url, reason = is_valid_url(url)

if not valid_url:
raise ValueError, "Website url not valid"
raise ValueError("Website url not valid")

if not isinstance(email, basestring):
if not isinstance(email, string_types):
email = str(email)

if not is_valid_email(email):
raise ValueError, "Email address is not valid"
raise ValueError("Email address is not valid")

if not isinstance(message, basestring):
if not isinstance(message, string_types):
message = str(message)

if len(message) == 0:
raise ValueError, "Message is required"
raise ValueError("Message is required")

message = strip_message(message)
response_deferred = defer.Deferred()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
import re
import sys
from six import text_type

from simplejson.scanner import Scanner, pattern
try:
Expand Down Expand Up @@ -92,8 +93,8 @@ def scanstring(s, end, encoding=None, _b=BACKSLASH, _m=STRINGCHUNK.match):
end = chunk.end()
content, terminator = chunk.groups()
if content:
if not isinstance(content, unicode):
content = unicode(content, encoding)
if not isinstance(content, text_type):
content = content.decode(encoding)
_append(content)
if terminator == '"':
break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Implementation of JSONEncoder
"""
import re
from six import iteritems
try:
from simplejson import _speedups
except ImportError:
Expand Down Expand Up @@ -233,7 +234,7 @@ def _iterencode_dict(self, dct, markers=None):
keys.sort()
items = [(k, dct[k]) for k in keys]
else:
items = dct.iteritems()
items = iteritems(dct)
_encoding = self.encoding
_do_decode = (_encoding is not None
and not (_need_utf8 and _encoding == 'utf-8'))
Expand Down
15 changes: 9 additions & 6 deletions pyamf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import types
import inspect
from six import iteritems

from pyamf import util, _version
from pyamf.adapters import register_adapters
Expand Down Expand Up @@ -89,6 +90,8 @@ def __repr__(self):
def __nonzero__(self):
return False

__bool__ = __nonzero__


#: Represents the C{undefined} value in the Adobe Flash Player client.
Undefined = UndefinedType()
Expand Down Expand Up @@ -607,7 +610,7 @@ def _check_type(type_):
if type_ in TYPE_MAP:
raise KeyError('Type %r already exists' % (type_,))

if isinstance(type_, types.TupleType):
if isinstance(type_, tuple):
for x in type_:
_check_type(x)
else:
Expand All @@ -626,7 +629,7 @@ def get_type(type_):
if isinstance(type_, list):
type_ = tuple(type_)

for k, v in TYPE_MAP.iteritems():
for k, v in iteritems(TYPE_MAP):
if k == type_:
return v

Expand Down Expand Up @@ -717,11 +720,11 @@ def remove_error_class(klass):
if klass not in ERROR_CLASS_MAP:
raise ValueError('Code %s is not registered' % (klass,))
elif isinstance(klass, python.class_types):
classes = ERROR_CLASS_MAP.values()
classes = list(ERROR_CLASS_MAP.values())
if klass not in classes:
raise ValueError('Class %s is not registered' % (klass,))

klass = ERROR_CLASS_MAP.keys()[classes.index(klass)]
klass = list(ERROR_CLASS_MAP.keys())[classes.index(klass)]
else:
raise TypeError("Invalid type, expected class or string")

Expand Down Expand Up @@ -753,7 +756,7 @@ def register_alias_type(klass, *args):
- At least one type must be supplied
"""
def check_type_registered(arg):
for k, v in ALIAS_TYPES.iteritems():
for k, v in iteritems(ALIAS_TYPES):
for kl in v:
if arg is kl:
raise RuntimeError('%r is already registered under %r' % (
Expand Down Expand Up @@ -781,7 +784,7 @@ def check_type_registered(arg):

ALIAS_TYPES[klass] = args

for k, v in CLASS_CACHE.copy().iteritems():
for k, v in iteritems(CLASS_CACHE.copy()):
new_alias = util.get_class_alias(v.klass)

if new_alias is klass:
Expand Down
7 changes: 4 additions & 3 deletions pyamf/adapters/_django_db_models_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from django.db.models.fields import related, files

import datetime
from six import iteritems

import pyamf

Expand Down Expand Up @@ -172,7 +173,7 @@ def getEncodableAttributes(self, obj, **kwargs):
if not attrs:
attrs = {}

for name, prop in self.fields.iteritems():
for name, prop in iteritems(self.fields):
if name not in attrs.keys():
continue

Expand All @@ -184,7 +185,7 @@ def getEncodableAttributes(self, obj, **kwargs):
if key.startswith('_'):
del attrs[key]

for name, relation in self.relations.iteritems():
for name, relation in iteritems(self.relations):
if '_%s_cache' % name in obj.__dict__:
attrs[name] = getattr(obj, name)

Expand Down Expand Up @@ -235,7 +236,7 @@ def getDecodableAttributes(self, obj, attrs, **kwargs):
pass

if not getattr(obj, pk_attr):
for name, relation in self.relations.iteritems():
for name, relation in iteritems(self.relations):
if isinstance(relation, related.ManyToManyField):
try:
if len(attrs[name]) == 0:
Expand Down
6 changes: 3 additions & 3 deletions pyamf/adapters/_django_utils_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
def convert_lazy(l, encoder=None):
try:
if l.__class__._delegate_text:
return unicode(l)
return u'l'
except AttributeError:
if l.__class__._delegate_unicode:
return unicode(l)
return u'l'

if l.__class__._delegate_str:
return str(l)
return b'1'

raise ValueError('Don\'t know how to convert lazy value %s' % (repr(l),))

Expand Down
13 changes: 7 additions & 6 deletions pyamf/adapters/_google_appengine_ext_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from google.appengine.ext import db
from google.appengine.ext.db import polymodel
import datetime
from six import integer_types, iteritems, string_types

import pyamf
from pyamf.adapters import util
Expand Down Expand Up @@ -112,7 +113,7 @@ def getCustomProperties(self):
self.properties = {}
reverse_props = []

for name, prop in self.klass.properties().iteritems():
for name, prop in iteritems(self.klass.properties()):
self.properties[name] = prop

props.append(name)
Expand All @@ -127,7 +128,7 @@ def getCustomProperties(self):
# check if the property is a defined as a collection_name. These types
# of properties are read-only and the datastore freaks out if you
# attempt to meddle with it. We delete the attribute entirely ..
for name, value in self.klass.__dict__.iteritems():
for name, value in iteritems(self.klass.__dict__):
if isinstance(value, db._ReverseReferenceProperty):
reverse_props.append(name)

Expand All @@ -149,7 +150,7 @@ def getEncodableAttributes(self, obj, codec=None):
gae_objects = getGAEObjects(codec.context) if codec else None

if self.reference_properties and gae_objects:
for name, prop in self.reference_properties.iteritems():
for name, prop in iteritems(self.reference_properties):
klass = prop.reference_class
key = prop.get_value_for_datastore(obj)

Expand Down Expand Up @@ -210,11 +211,11 @@ def getDecodableAttributes(self, obj, attrs, codec=None):
v = attrs[k]

if isinstance(prop, db.FloatProperty) and \
isinstance(v, (int, long)):
isinstance(v, integer_types):
attrs[k] = float(v)
elif isinstance(prop, db.IntegerProperty) and \
isinstance(v, float):
x = long(v)
x = int(v)

# only convert the type if there is no mantissa - otherwise
# let the chips fall where they may
Expand Down Expand Up @@ -280,7 +281,7 @@ def loadInstanceFromDatastore(klass, key, codec=None):
'expected db.Model/db.Expando class, got %s' % (klass,)
)

if not isinstance(key, basestring):
if not isinstance(key, string_types):
raise TypeError('string expected for key, got %s', (repr(key),))

key = str(key)
Expand Down
5 changes: 1 addition & 4 deletions pyamf/adapters/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
@since: 0.4
"""

import __builtin__

if not hasattr(__builtin__, 'set'):
from sets import Set as set
from six.moves import builtins


def to_list(obj, encoder):
Expand Down
11 changes: 6 additions & 5 deletions pyamf/alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"""

import inspect
from six import iteritems, string_types

import pyamf
from pyamf import python, util
Expand Down Expand Up @@ -123,7 +124,7 @@ def compile(self):
self.decodable_properties.update(self.klass.__slots__)
self.encodable_properties.update(self.klass.__slots__)

for k, v in self.klass.__dict__.iteritems():
for k, v in iteritems(self.klass.__dict__):
if not isinstance(v, property):
continue

Expand Down Expand Up @@ -313,7 +314,7 @@ def __repr__(self):
)

def __eq__(self, other):
if isinstance(other, basestring):
if isinstance(other, string_types):
return self.alias == other
elif isinstance(other, self.__class__):
return self.klass == other.klass
Expand Down Expand Up @@ -421,14 +422,14 @@ def getEncodableAttributes(self, obj, codec=None):
if self.proxy_attrs is not None and attrs and codec:
context = codec.context

for k, v in attrs.copy().iteritems():
for k, v in iteritems(attrs.copy()):
if k in self.proxy_attrs:
attrs[k] = context.getProxyForObject(v)

if self.synonym_attrs:
missing = object()

for k, v in self.synonym_attrs.iteritems():
for k, v in iteritems(self.synonym_attrs):
value = attrs.pop(k, missing)

if value is missing:
Expand Down Expand Up @@ -510,7 +511,7 @@ def getDecodableAttributes(self, obj, attrs, codec=None):
if self.synonym_attrs:
missing = object()

for k, v in self.synonym_attrs.iteritems():
for k, v in iteritems(self.synonym_attrs):
value = attrs.pop(v, missing)

if value is missing:
Expand Down
Loading