Changeset 1100
- Timestamp:
- 03/01/08 21:38:44 (9 months ago)
- Location:
- pyamf/branches/logging-173/pyamf
- Files:
-
- 8 modified
-
__init__.py (modified) (2 diffs)
-
amf0.py (modified) (6 diffs)
-
amf3.py (modified) (7 diffs)
-
remoting/__init__.py (modified) (8 diffs)
-
tests/gateway/test_twisted.py (modified) (3 diffs)
-
tests/test_amf0.py (modified) (3 diffs)
-
tests/test_amf3.py (modified) (3 diffs)
-
util.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
pyamf/branches/logging-173/pyamf/__init__.py
r1089 r1100 191 191 """ 192 192 This class represents a Flash Actionscript Object (typed or untyped). 193 193 194 194 I supply a C{__builtin__.dict} interface to support get/setattr calls. 195 195 """ … … 362 362 @return: Instance of C{self.klass}. 363 363 """ 364 if hasattr(self.klass, '__setstate__') or hasattr(self.klass, '__getstate__'): 365 if type(self.klass) is types.TypeType: # new-style class 366 return self.klass.__new__(self.klass) 367 elif type(self.klass) is types.ClassType: # classic class 368 return util.make_classic_instance(self.klass) 369 370 raise TypeError, 'invalid class type %r' % self.klass 371 364 372 return self.klass(*args, **kwargs) 365 373 -
pyamf/branches/logging-173/pyamf/amf0.py
r1089 r1100 20 20 """ 21 21 22 import datetime, types 22 import datetime, types, logging 23 23 24 24 import pyamf 25 25 from pyamf import util 26 27 logger = logging.getLogger(__name__) 26 28 27 29 class ASTypes: … … 51 53 #: 1 single byte, C{0Ã06} indicates null. 52 54 UNDEFINED = 0x06 53 #: When an ActionScript object refers to itself, such C{this.self = this}, or54 #: when objects are repeated within the same scope (for example, as the two55 #: parameters of the same function called), a code of C{0Ã07} and an C{int},56 #: the reference number, are written.55 #: When an ActionScript object refers to itself, such C{this.self = this}, 56 #: or when objects are repeated within the same scope (for example, as the 57 #: two parameters of the same function called), a code of C{0Ã07} and an 58 #: C{int}, the reference number, are written. 57 59 REFERENCE = 0x07 58 60 #: A MixedArray is indicated by code C{0Ã08}, then a Long representing the 59 #: highest numeric index in the array, or 0 if there are none or they are all60 #: negative. After that follow the elements in key : value pairs.61 #: highest numeric index in the array, or 0 if there are none or they are 62 #: all negative. After that follow the elements in key : value pairs. 61 63 MIXEDARRAY = 0x08 62 64 #: @see: L{OBJECT} 63 65 OBJECTTERM = 0x09 64 66 #: An array is indicated by C{0x0A}, then a Long for array length, then the 65 #: array elements themselves. Arrays are always sparse; values for inexistant66 #: keys are set to null (C{0Ã06}) to maintain sparsity.67 #: array elements themselves. Arrays are always sparse; values for 68 #: inexistant keys are set to null (C{0Ã06}) to maintain sparsity. 67 69 ARRAY = 0x0a 68 70 #: Date is represented as C{00x0B}, then a double, then an C{int}. The double … … 348 350 attrs = alias.getAttrs(obj) 349 351 350 if attrs is None:351 alias = None352 353 352 key = self.readString() 354 353 355 354 ot = chr(ASTypes.OBJECTTERM) 355 obj_attrs = dict() 356 356 357 357 while self.stream.peek() != ot: 358 if alias: 359 if key not in attrs: 360 self.readElement() 361 key = self.readString() 362 continue 363 364 if isinstance(obj, (list, dict)): 365 obj[key] = self.readElement() 366 else: 367 value = self.readElement() 368 369 try: 370 setattr(obj, key, value) 371 except AttributeError: 372 obj.__dict__[key] = value 373 358 obj_attrs[key] = self.readElement() 374 359 key = self.readString() 375 360 376 361 # discard the end marker (ASTypes.OBJECTTERM) 377 362 self.stream.read(len(ot)) 363 364 if attrs is None: 365 attrs = obj_attrs.keys() 366 367 if alias: 368 if hasattr(obj, '__setstate__'): 369 obj.__setstate__(obj_attrs) 370 371 return 372 373 for key in filter(lambda x: x in attrs, obj_attrs.keys()): 374 obj.__setattr__(key, obj_attrs[key]) 375 else: 376 f = obj.__setattr__ 377 378 if isinstance(obj, (list, dict)): 379 f = obj.__setitem__ 380 381 for key, value in obj_attrs.iteritems(): 382 f(key, value) 383 384 return 378 385 379 386 def readObject(self): … … 600 607 @param writeType: Write data type. 601 608 """ 602 if not isinstance(s, basestring): 603 s = str(s) 604 605 if not isinstance(s, unicode): 606 s = unicode(s) 607 608 s = s.encode('utf8') 609 if isinstance(s, unicode): 610 s = s.encode('utf8') 611 elif not isinstance(s, basestring): 612 s = unicode(s).encode('utf8') 609 613 610 614 if len(s) > 0xffff: … … 707 711 self.writeString(alias.alias, False) 708 712 709 if alias is not None: 713 if hasattr(o, '__getstate__'): 714 for key, value in o.__getstate__().iteritems(): 715 self.writeString(key, False) 716 self.writeElement(value) 717 elif alias is not None: 710 718 it = alias.getAttrs(o) 711 719 … … 716 724 for key in it: 717 725 self.writeString(key, False) 718 self.writeElement( util.get_attr(o, key))726 self.writeElement(getattr(o, key)) 719 727 elif hasattr(o, 'iteritems'): 720 728 for k, v in o.iteritems(): -
pyamf/branches/logging-173/pyamf/amf3.py
r1089 r1100 622 622 attrs = None 623 623 624 if hasattr(obj, 'keys'): 624 if hasattr(obj, '__getstate__'): 625 attrs = set([unicode(k) for k in obj.__getstate__()]) 626 elif hasattr(obj, 'keys'): 625 627 attrs = set([unicode(k) for k in obj.keys()]) 626 628 elif hasattr(obj, 'iteritems'): … … 1094 1096 raise pyamf.EncodeError, "Decoding an object in amf3 tagged as amf0 only is not allowed" 1095 1097 1096 klass = class_def.getClass() 1097 1098 obj = klass() 1098 if class_def.alias: 1099 obj = class_def.alias() 1100 else: 1101 klass = class_def.getClass() 1102 obj = klass() 1103 1104 obj_attrs = pyamf.ASObject() 1099 1105 self.context.addObject(obj) 1100 1106 … … 1102 1108 obj.__readamf__(DataInput(self)) 1103 1109 elif class_def.encoding == ObjectEncoding.DYNAMIC: 1104 readStatic(class_ref, class_def, obj , num_attrs)1105 readDynamic(class_ref, class_def, obj )1110 readStatic(class_ref, class_def, obj_attrs, num_attrs) 1111 readDynamic(class_ref, class_def, obj_attrs) 1106 1112 elif class_def.encoding == ObjectEncoding.STATIC: 1107 readStatic(class_ref, class_def, obj , num_attrs)1113 readStatic(class_ref, class_def, obj_attrs, num_attrs) 1108 1114 else: 1109 1115 raise pyamf.DecodeError, "Unknown object encoding" 1116 1117 if hasattr(obj, '__setstate__'): 1118 obj.__setstate__(obj_attrs) 1119 else: 1120 for k, v in obj_attrs.iteritems(): 1121 obj.__setattr__(k, v) 1110 1122 1111 1123 return obj … … 1325 1337 """ 1326 1338 if not isinstance(n, basestring): 1327 raise TypeError, "str or unicode expected" 1328 1329 if not isinstance(n, unicode): 1330 try: 1331 n = unicode(n) 1332 except UnicodeError: 1333 raise pyamf.EncodeError, "error converting str to unicode" 1334 1335 if len(n) == 0: 1339 bytes = unicode(n).encode('utf8') 1340 n = bytes 1341 elif isinstance(n, unicode): 1342 bytes = n.encode('utf8') 1343 else: 1344 bytes = n 1345 1346 if len(bytes) == 0: 1336 1347 self._writeInteger(REFERENCE_BIT) 1337 1348 … … 1347 1358 self.context.addString(n) 1348 1359 1349 bytes = n.encode('utf8')1350 1360 self._writeInteger((len(bytes) << 1) | REFERENCE_BIT) 1351 1352 1361 self.stream.write(bytes) 1353 1362 … … 1555 1564 [self._writeString(attr) for attr in attrs] 1556 1565 1557 [self.writeElement( util.get_attr(obj, attr)) for attr in attrs]1566 [self.writeElement(obj[attr]) for attr in attrs] 1558 1567 1559 1568 self.writeType(ASTypes.OBJECT) … … 1591 1600 class_def = self._getClassDefinition(obj) 1592 1601 1602 if hasattr(obj, '__getstate__'): 1603 obj_attrs = obj.__getstate__() 1604 elif hasattr(obj, 'iteritems'): 1605 obj_attrs = {} 1606 1607 for k, v in obj.iteritems(): 1608 obj_attrs[k] = v 1609 elif hasattr(obj, '__dict__'): 1610 obj_attrs = obj.__dict__ 1611 1593 1612 if class_def.encoding in (ObjectEncoding.EXTERNAL, ObjectEncoding.PROXY): 1594 1613 obj.__writeamf__(DataOutput(self)) 1595 el if class_def.encoding == ObjectEncoding.DYNAMIC:1614 else: 1596 1615 static_attrs, dynamic_attrs = class_def.getAttrs(obj) 1597 1616 1598 1617 if static_attrs is not None: 1599 writeStatic(obj , static_attrs, class_ref)1600 1601 if dynamic_attrs is not None:1618 writeStatic(obj_attrs, static_attrs, class_ref) 1619 1620 if class_def.encoding == ObjectEncoding.DYNAMIC and dynamic_attrs is not None: 1602 1621 for attr in dynamic_attrs: 1603 1622 self._writeString(attr) 1604 self.writeElement( util.get_attr(obj, attr))1623 self.writeElement(obj_attrs[attr]) 1605 1624 1606 1625 self._writeString("") 1607 elif class_def.encoding == ObjectEncoding.STATIC:1608 static_attrs, dynamic_attrs = class_def.getAttrs(obj)1609 1610 if static_attrs is not None:1611 writeStatic(obj, static_attrs, class_ref)1612 else:1613 raise pyamf.EncodeError, "Unknown object encoding"1614 1626 1615 1627 def writeByteArray(self, n, use_references=True): -
pyamf/branches/logging-173/pyamf/remoting/__init__.py
r1089 r1100 18 18 19 19 @see: U{Remoting Envelope on OSFlash (external) 20 <http://osflash.org/documentation/amf/envelopes/remoting>}20 <http://osflash.org/documentation/amf/envelopes/remoting>} 21 21 @see: U{Remoting Headers on OSFlash (external) 22 <http://osflash.org/amf/envelopes/remoting/headers>}22 <http://osflash.org/amf/envelopes/remoting/headers>} 23 23 @see: U{Remoting Debug Headers on OSFlash (external) 24 <http://osflash.org/documentation/amf/envelopes/remoting/debuginfo>} 25 24 <http://osflash.org/documentation/amf/envelopes/remoting/debuginfo>} 26 25 @author: U{Nick Joyce<mailto:nick@boxdesign.co.uk>} 27 28 26 @since: 0.1.0 29 27 """ 30 28 29 import logging 30 31 31 import pyamf 32 32 from pyamf import util 33 33 34 34 __all__ = ['Envelope', 'Request', 'Response', 'decode', 'encode'] 35 36 logger = logging.getLogger(__name__) 35 37 36 38 #: Succesful call. … … 492 494 @param stream: AMF data. 493 495 @type context: L{amf0.Context<pyamf.amf0.Context>} or 494 L{amf3.Context<pyamf.amf3.Context>}496 L{amf3.Context<pyamf.amf3.Context>} 495 497 @param context: Context. 496 498 @type strict: C{bool} 497 499 @param strict: Enforce strict encoding. 498 500 499 @raise DecodeError: Malformed stream.500 @raise RuntimeError: Decoder is unable to fully consume the501 stream buffer.502 503 501 @return: Message envelope. 504 502 @rtype: L{Envelope} 505 503 """ 504 logger.debug("decode - begin (stream=%r, context=%r, strict=%r)" % ( 505 stream, context, strict)) 506 506 507 if not isinstance(stream, util.BufferedByteStream): 507 508 stream = util.BufferedByteStream(stream) … … 525 526 header_count = stream.read_ushort() 526 527 528 logger.debug("header count=%d" % header_count) 527 529 for i in xrange(header_count): 528 530 name, required, data = _read_header(stream, decoder, strict) … … 533 535 534 536 body_count = stream.read_short() 537 logger.debug("body count=%d" % body_count) 535 538 context.clear() 536 539 … … 540 543 541 544 if strict and stream.remaining() > 0: 542 raise RuntimeError, "Unable to fully consume the buffer" 545 raise RuntimeError, "Unable to fully consume the buffer (remaining:%d)" % stream.remaining() 546 547 logger.debug("decode - end (msg=%r)" % msg) 543 548 544 549 return msg … … 560 565 @return: File object. 561 566 """ 567 logger.debug("encode - begin (msg=%r, old_context=%r, strict=%r)" % ( 568 msg, old_context, strict)) 569 562 570 def getNewContext(): 563 571 if old_context: … … 587 595 encoder.context = getNewContext() 588 596 _write_body(name, message, stream, encoder, strict) 597 598 logger.debug("encode - end (stream=%r)" % stream) 589 599 590 600 return stream … … 595 605 return pyamf.ERROR_CLASS_MAP[fault.code] 596 606 except KeyError: 597 # default to RemotingError598 607 return RemotingError -
pyamf/branches/logging-173/pyamf/tests/gateway/test_twisted.py
r1089 r1100 350 350 self.assertTrue(isinstance(response.body, remoting.ErrorFault)) 351 351 self.assertEquals(response.body.code, 'IndexError') 352 352 353 353 def test_auth_fail(self): 354 354 def auth(u, p): … … 611 611 d2 = defer.Deferred() 612 612 reactor.callLater(0, lambda: d2.callback(None)) 613 613 614 614 return d2 615 615 … … 658 658 self.assertTrue(result) 659 659 except: 660 d.errback() 660 d.errback() 661 661 else: 662 662 d.callback(None) -
pyamf/branches/logging-173/pyamf/tests/test_amf0.py
r1089 r1100 163 163 self._run(data) 164 164 165 def test_bytestring(self): 166 class UnicodeObject: 167 def __unicode__(self): 168 return u'MÃötley CrÃÃÂŒe' 169 170 class StrObject: 171 def __str__(self): 172 return u'MÃötley CrÃÃÂŒe' 173 174 class ReprObject: 175 def __repr__(self): 176 return u'MÃötley CrÃÃÂŒe' 177 178 self.encoder.writeString(UnicodeObject()) 179 self.assertEquals(self.buf.getvalue(), '\x02\x00\x15M\xc3\x83\xc3\x82' 180 '\xc2\xb6tley Cr\xc3\x83\xc3\x82\xc2\xbce') 181 self.buf.truncate() 182 183 self.encoder.writeString(StrObject()) 184 self.assertEquals(self.buf.getvalue(), '\x02\x00\x15M\xc3\x83\xc3\x82' 185 '\xc2\xb6tley Cr\xc3\x83\xc3\x82\xc2\xbce') 186 self.buf.truncate() 187 188 self.encoder.writeString(ReprObject()) 189 self.assertEquals(self.buf.getvalue(), '\x02\x00\x15M\xc3\x83\xc3\x82' 190 '\xc2\xb6tley Cr\xc3\x83\xc3\x82\xc2\xbce') 191 self.buf.truncate() 192 193 self.encoder.writeString('M\xc3\x83\xc3\x82\xc2\xb6tley Cr\xc3\x83\xc3\x82\xc2\xbce') 194 self.assertEquals(self.buf.getvalue(), '\x02\x00\x15M\xc3\x83\xc3\x82' 195 '\xc2\xb6tley Cr\xc3\x83\xc3\x82\xc2\xbce') 196 165 197 def test_null(self): 166 198 self._run([(None, '\x05')]) … … 380 412 381 413 pyamf.unregister_class(Person) 414 415 def test_getstate(self): 416 tc = self 417 tc.executed = False 418 419 class Foo(object): 420 def __getstate__(self): 421 tc.executed = True 422 return {'spam': 'hello', 'eggs': True} 423 424 pyamf.register_class(Foo, 'foo') 425 426 foo = Foo() 427 self.encoder.writeElement(foo) 428 429 self.assertEquals(self.buf.getvalue(), '\x10\x00\x03\x66\x6f\x6f\x00' 430 '\x04\x65\x67\x67\x73\x01\x01\x00\x04\x73\x70\x61\x6d\x02\x00\x05' 431 '\x68\x65\x6c\x6c\x6f\x00\x00\x09') 432 self.assertTrue(self.executed) 433 434 pyamf.unregister_class(Foo) 382 435 383 436 class DecoderTestCase(unittest.TestCase): … … 612 665 pyamf.unregister_class(Foo) 613 666 667 def test_setstate_newstyle(self): 668 self.executed = False 669 670 class Foo(object): 671 tc = self 672 673 def __init__(self, *args, **kwargs): 674 self.tc.fail("__init__ called") 675 676 def __setstate__(self, state): 677 self.tc.executed = True 678 self.__dict__.update(state) 679 680 pyamf.register_class(Foo, 'foo') 681 682 self.buf.write('\x10\x00\x03\x66\x6f\x6f\x00\x04\x65\x67\x67\x73\x01\x01\x00\x04') 683 self.buf.write('\x73\x70\x61\x6d\x02\x00\x05\x68\x65\x6c\x6c\x6f\x00\x00\x09') 684 self.buf.seek(0) 685 686 foo = self.decoder.readElement() 687 688 self.assertEquals(foo.spam, 'hello') 689 self.assertEquals(foo.eggs, True) 690 self.assertTrue(self.executed) 691 692 pyamf.unregister_class(Foo) 693 694 def test_setstate_classic(self): 695 self.executed = False 696 697 class Foo: 698 tc = self 699 700 def __init__(self, *args, **kwargs): 701 self.tc.fail("__init__ called") 702 703 def __setstate__(self, state): 704 self.tc.executed = True 705 self.__dict__.update(state) 706 707 pyamf.register_class(Foo, 'foo') 708 709 self.buf.write('\x10\x00\x03\x66\x6f\x6f\x00\x04\x65\x67\x67\x73\x01\x01\x00\x04') 710 self.buf.write('\x73\x70\x61\x6d\x02\x00\x05\x68\x65\x6c\x6c\x6f\x00\x00\x09') 711 self.buf.seek(0) 712 713 foo = self.decoder.readElement() 714 715 self.assertTrue(self.executed) 716 self.assertTrue(isinstance(foo, Foo)) 717 self.assertEquals(foo.spam, 'hello') 718 self.assertEquals(foo.eggs, True) 719 720 pyamf.unregister_class(Foo) 721 614 722 class HelperTestCase(unittest.TestCase): 615 723 def test_encode(self): -
pyamf/branches/logging-173/pyamf/tests/test_amf3.py
r1089 r1100 317 317 (u'á áá»', '\x06\x13\xe1\x9a\xa0\xe1\x9b\x87\xe1\x9a\xbb')]) 318 318 319 def test_bytestring(self): 320 class UnicodeObject: 321 def __unicode__(self): 322 return u'MÃötley CrÃÃÂŒe' 323 324 class StrObject: 325 def __str__(self): 326 return u'MÃötley CrÃÃÂŒe' 327 328 class ReprObject: 329 def __repr__(self): 330 return u'MÃötley CrÃÃÂŒe' 331 332 self.encoder.writeString(UnicodeObject()) 333 self.assertEquals(self.buf.getvalue(), '\x06+M\xc3\x83\xc3\x82\xc2\xb6tley Cr\xc3\x83\xc3\x82\xc2\xbce') 334 self.buf.truncate() 335 self.context.clear() 336 337 self.encoder.writeString(StrObject()) 338 self.assertEquals(self.buf.getvalue(), '\x06+M\xc3\x83\xc3\x82\xc2\xb6tley Cr\xc3\x83\xc3\x82\xc2\xbce') 339 self.buf.truncate() 340 self.context.clear() 341 342 self.encoder.writeString(ReprObject()) 343 self.assertEquals(self.buf.getvalue(), '\x06+M\xc3\x83\xc3\x82\xc2\xb6tley Cr\xc3\x83\xc3\x82\xc2\xbce') 344 self.buf.truncate() 345 self.context.clear() 346 347 self.encoder.writeString('M\xc3\x83\xc3\x82\xc2\xb6tley Cr\xc3\x83\xc3\x82\xc2\xbce') 348 self.assertEquals(self.buf.getvalue(), '\x06+M\xc3\x83\xc3\x82\xc2\xb6tley Cr\xc3\x83\xc3\x82\xc2\xbce') 349 350 319 351 def test_string_references(self): 320 352 self._run([ … … 524 556 525 557 pyamf.unregister_class(Person) 558 559 def test_getstate(self): 560 self.executed = False 561 562 class Foo(object): 563 tc = self 564 565 def __getstate__(self): 566 self.tc.executed = True 567 return {'spam': 'hello', 'eggs': True} 568 569 pyamf.register_class(Foo, 'foo') 570 571 foo = Foo() 572 self.encoder.writeElement(foo) 573 574 self.assertEquals(self.buf.getvalue(), '\x0a\x0b\x07\x66\x6f\x6f\x09' 575 '\x65\x67\x67\x73\x03\x09\x73\x70\x61\x6d\x06\x0b\x68\x65\x6c\x6c' 576 '\x6f\x01') 577 self.assertTrue(self.executed) 578 579 pyamf.unregister_class(Foo) 526 580 527 581 class DecoderTestCase(unittest.TestCase): … … 768 822 pyamf.unregister_class(Spam) 769 823 824 def test_setstate_newstyle(self): 825 self.executed = False 826 827 class Foo(object): 828 tc = self 829 830 def __init__(self, *args, **kwargs): 831 self.tc.fail("__init__ called") 832 833 def __setstate__(self, state): 834 self.tc.executed = True 835 self.__dict__.update(state) 836 837 pyamf.register_class(Foo, 'foo') 838 839 self.buf.write('\x0a\x0b\x07\x66\x6f\x6f\x09\x65\x67\x67\x73' + \ 840 '\x03\x09\x73\x70\x61\x6d\x06\x0b\x68\x65\x6c\x6c\x6f\x01') 841 self.buf.seek(0) 842 843 foo = self.decoder.readElement() 844 845 self.assertEquals(foo.spam, 'hello') 846 self.assertEquals(foo.eggs, True) 847 self.assertTrue(self.executed) 848 849 pyamf.unregister_class(Foo) 850 851 def test_setstate_classic(self): 852 self.executed = False
