From dbf6e8060b9d91b0c92a13473a12474eee5a63f2 Mon Sep 17 00:00:00 2001 From: Alan Aguiar Date: Mon, 11 Nov 2013 21:16:05 +0000 Subject: sugar not work --- diff --git a/Gambiarra/__init__.py b/Gambiarra/__init__.py deleted file mode 100644 index 424bcbd..0000000 --- a/Gambiarra/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python -# -*- coding: UTF-8 -*- -# -# Copyright (C) 2007 by ULPM: Alexandre Yukio Harano -# Fábio Cassarotti Parronchi Navarro -# Gabriel Geraldo França Marcondes -# Luiz Carlos Irber Júnior -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - diff --git a/Gambiarra/gambiarra.py b/Gambiarra/gambiarra.py deleted file mode 100644 index 0daeee2..0000000 --- a/Gambiarra/gambiarra.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env python -# -*- coding: UTF-8 -*- -# -# Copyright (C) 2007 by ULPM: Alexandre Yukio Harano -# Fábio Cassarotti Parronchi Navarro -# Gabriel Geraldo França Marcondes -# Luiz Carlos Irber Júnior -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import sys -import os -import gtk -import pygame - -from Gambiarra.command import Play, Help, Quit -from Gambiarra.gamemenu import GameMenu -import Gambiarra.levels as Levels - -from Gambiarra.objects import Esteira, check_collision - -class Game(object): - # controle do jogo - fps = 30 - playing = None - running = None - clock = None - level = 0 - levels = [] - selected_element = None - _showed_help = None - count = None - play_sounds = None - - # elementos do jogo - screen = None - menu = None - congrats = None - congrats_snd = None - - def __init__(self, play_sounds=True): - self.play_sounds = play_sounds - self.running = True - self.playing = False - self._showed_help = False - self.count = 0 - - def load_all(self): - pygame.init() - if self.play_sounds: - pygame.mixer.init() - #self.screen = pygame.display.set_mode((1200, 900)) - self.screen = pygame.display.get_surface() - pygame.display.flip() - pygame.display.set_caption("Gambiarra") - self.clock = pygame.time.Clock() - self.levels = Levels.init_levels() - self.menu = GameMenu() - self.congrats = pygame.image.load(os.path.join("data","images", - "fim_fase.png")) - if self.play_sounds: - snd_file = os.path.join("data", "snd", "Congrats.wav") - self.congrats_snd = pygame.mixer.Sound(snd_file) - - def run(self): - self.load_all() - #inicia o loop - self.main_loop() - - def event_handler(self): - #GTK events - while gtk.events_pending(): - gtk.main_iteration() - for event in pygame.event.get(): - if event.type == pygame.MOUSEBUTTONDOWN: - self.mouse_event( pygame.mouse.get_pos() ) - - def update_screen(self, fps): - #update dos elementos da tela - if self.playing: - - # executa a simulacao - objs = check_collision(self.levels[self.level].simulator.objects, - self.levels[self.level].simulator.static_objs) - self.levels[self.level].simulator.objects = objs - for obj in self.levels[self.level].simulator.objects: - obj.update() - else: - if self.selected_element: - if self.selected_element.editable: - self.selected_element.rect.center = pygame.mouse.get_pos() - - def mouse_event(self, mouse_pos): - if not self.selected_element: - mouse_move = (0, 0) - mouse_move = pygame.mouse.get_rel() - - for element in self.levels[self.level].simulator.objects: - if element.rect.collidepoint(mouse_pos): - self.selected_element = element - break - - if not self.selected_element: - for element in self.levels[self.level].simulator.static_objs: - if element.rect.collidepoint(mouse_pos): - self.selected_element = element - - if isinstance(element, Esteira) and element.editable: - self.count += 1 - if self.count == 1: - element.sentido = -element.sentido - self.count = 0 - break - - if not self.selected_element: #se nao encontrou no for anterior - for element in self.levels[self.level].objbar.objects: - if element.rect.collidepoint(mouse_pos): - element.remove(self.levels[self.level].objbar.objects) - self.levels[self.level].simulator.add(element) - self.selected_element = element - break - - if not self.selected_element: #se nao encontrou no for anterior - for element in self.levels[self.level].cmdbar.commands: - if element.rect.collidepoint(mouse_pos): - if isinstance(element, Play): - element.image = pygame.transform.flip(element.image, - True, False) - self.playing = not self.playing - if not self.playing: - objs = self.levels[self.level].simulator.objects - for obj in objs: - obj.speed = [0, 0] - obj.rect.topleft = obj.initial_pos - elif isinstance(element, Help): - self.levels[self.level].show_help(self.screen) - elif isinstance(element, Quit): - sys.exit() - break - - else: - if self.selected_element.editable and not self.playing: - mouse_move = pygame.mouse.get_rel() - if mouse_move != (0, 0): - self.count -= 1 - self.selected_element.rect.center = pygame.mouse.get_pos() - new_pos = self.selected_element.rect.topleft - self.selected_element.initial_pos = new_pos - self.selected_element = None - - def show_congratulations(self): - if self.play_sounds: - pygame.mixer.stop() - self.congrats_snd.play() - - self.screen.blit(self.congrats, (600 - self.congrats.get_width()/2, - 450 - self.congrats.get_height()/2) ) - pygame.display.flip() - - while True: - #GTK events - while gtk.events_pending(): - gtk.main_iteration() - for event in pygame.event.get(): - if event.type == pygame.MOUSEBUTTONDOWN: - return - - def main_loop(self): - self.menu.run() - while self.running and self.level < len(self.levels): - while not self.levels[self.level].goal_reached(): - self.event_handler() - self.clock.tick(self.fps) - self.update_screen(self.fps) - self.levels[self.level].draw() - - if not self._showed_help: - self.levels[self.level].show_help(self.screen) - self._showed_help = True - - pygame.display.flip() - - self.playing = False - self._showed_help = False - self.level += 1 - self.show_congratulations() - if (len(self.levels) == self.level) : - self.running = False - diff --git a/Gambiarra/objects/__init__.py b/Gambiarra/objects/__init__.py deleted file mode 100644 index f4e303c..0000000 --- a/Gambiarra/objects/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -from Gambiarra.objects.animals import Penguin -from Gambiarra.objects.balls import SoccerBall, BowlingBall, BeachBall -from Gambiarra.objects.elastica import Elastica -from Gambiarra.objects.esteira import Esteira -from Gambiarra.objects.target import Target -from Gambiarra.objects.things import Thing, check_collision -from Gambiarra.objects.wall import UpWall, DownWall, LeftWall, RightWall - -# namespace cleanup -del animals -del balls -del elastica -del esteira -del target -del things -del wall diff --git a/activity.py b/activity.py index 5134d06..3089696 100644 --- a/activity.py +++ b/activity.py @@ -29,26 +29,20 @@ from sugar.graphics.toolbarbox import ToolbarBox from sugar.activity.widgets import ActivityToolbarButton from sugar.graphics.toolbutton import ToolButton from sugar.activity.widgets import StopButton - import sugargame.canvas from gettext import gettext as _ -# add the libs subdir to the path -basedir = os.path.abspath(os.curdir) -libdir = os.path.join(basedir, "libs") - -sys.path.insert(0, libdir) - -from Gambiarra.gambiarra import Game +from gambiarra import Game class GambiarraActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle) + self.max_participants = 1 self.game = Game() - self.build_toolbar() + #self.build_toolbar() self._pygamecanvas = sugargame.canvas.PygameCanvas(self) self.set_canvas(self._pygamecanvas) self._pygamecanvas.grab_focus() diff --git a/activity/activity.info b/activity/activity.info index 8486357..5638b0d 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -2,6 +2,6 @@ name = Gambiarra activity_version = 1 bundle_id = org.laptop.community.Gambiarra -icon = activity-gambiarra +icon = gambiarra exec = sugar-activity activity.GambiarraActivity diff --git a/activity/activity-gambiarra.svg b/activity/gambiarra.svg index e8528dd..e8528dd 100644 --- a/activity/activity-gambiarra.svg +++ b/activity/gambiarra.svg diff --git a/Gambiarra/command.py b/command.py index b2db177..b2db177 100644 --- a/Gambiarra/command.py +++ b/command.py diff --git a/gambiarra.py b/gambiarra.py index 8996dc1..2c23a36 100644..100755 --- a/gambiarra.py +++ b/gambiarra.py @@ -2,9 +2,9 @@ # -*- coding: UTF-8 -*- # # Copyright (C) 2007 by ULPM: Alexandre Yukio Harano -# Fábio Cassarotti Parronchi Navarro -# Gabriel Geraldo França Marcondes -# Luiz Carlos Irber Júnior +# Fábio Cassarotti Parronchi Navarro +# Gabriel Geraldo França Marcondes +# Luiz Carlos Irber Júnior # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -21,34 +21,189 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import sys -import os.path -from optparse import OptionParser +import os +import gtk +import pygame -# add the libs subdir to the path -basedir = os.path.abspath(os.curdir) -libdir = os.path.join(basedir, "libs") +from command import Play, Help, Quit +from gamemenu import GameMenu +import levels as Levels -if not libdir in sys.path: - sys.path.insert(0, libdir) +from objects import Esteira, check_collision -from Gambiarra.gambiarra import Game +class Game(object): + # controle do jogo + fps = 30 + playing = None + running = None + clock = None + level = 0 + levels = [] + selected_element = None + _showed_help = None + count = None + play_sounds = None -def main(play_sounds=True): - game = Game(play_sounds) - game.run() + # elementos do jogo + screen = None + menu = None + congrats = None + congrats_snd = None + + def __init__(self, play_sounds=True, running_sugar=True): + self.play_sounds = play_sounds + self.running_sugar = running_sugar + self.running = True + self.playing = False + self._showed_help = False + self.count = 0 + + def load_all(self): + pygame.init() + if self.play_sounds: + pygame.mixer.init() + self.screen = pygame.display.get_surface() + if self.screen is None: + self.screen = pygame.display.set_mode((1200, 900)) + pygame.display.flip() + pygame.display.set_caption("Gambiarra") + self.clock = pygame.time.Clock() + self.levels = Levels.init_levels() + self.menu = GameMenu() + self.congrats = pygame.image.load(os.path.join("data","images", + "fim_fase.png")) + if self.play_sounds: + snd_file = os.path.join("data", "snd", "Congrats.wav") + self.congrats_snd = pygame.mixer.Sound(snd_file) + + def run(self): + self.load_all() + self.main_loop() + + def event_handler(self): + #GTK events + while gtk.events_pending(): + gtk.main_iteration() + for event in pygame.event.get(): + if event.type == pygame.MOUSEBUTTONDOWN: + self.mouse_event( pygame.mouse.get_pos() ) + elif (event.type == pygame.QUIT) and not self.running_sugar: + self.running = False + + def update_screen(self, fps): + #update dos elementos da tela + if self.playing: + + # executa a simulacao + objs = check_collision(self.levels[self.level].simulator.objects, + self.levels[self.level].simulator.static_objs) + self.levels[self.level].simulator.objects = objs + for obj in self.levels[self.level].simulator.objects: + obj.update() + else: + if self.selected_element: + if self.selected_element.editable: + self.selected_element.rect.center = pygame.mouse.get_pos() + + def mouse_event(self, mouse_pos): + if not self.selected_element: + mouse_move = (0, 0) + mouse_move = pygame.mouse.get_rel() + + for element in self.levels[self.level].simulator.objects: + if element.rect.collidepoint(mouse_pos): + self.selected_element = element + break + + if not self.selected_element: + for element in self.levels[self.level].simulator.static_objs: + if element.rect.collidepoint(mouse_pos): + self.selected_element = element + + if isinstance(element, Esteira) and element.editable: + self.count += 1 + if self.count == 1: + element.sentido = -element.sentido + self.count = 0 + break + + if not self.selected_element: #se nao encontrou no for anterior + for element in self.levels[self.level].objbar.objects: + if element.rect.collidepoint(mouse_pos): + element.remove(self.levels[self.level].objbar.objects) + self.levels[self.level].simulator.add(element) + self.selected_element = element + break + + if not self.selected_element: #se nao encontrou no for anterior + for element in self.levels[self.level].cmdbar.commands: + if element.rect.collidepoint(mouse_pos): + if isinstance(element, Play): + element.image = pygame.transform.flip(element.image, + True, False) + self.playing = not self.playing + if not self.playing: + objs = self.levels[self.level].simulator.objects + for obj in objs: + obj.speed = [0, 0] + obj.rect.topleft = obj.initial_pos + elif isinstance(element, Help): + self.levels[self.level].show_help(self.screen) + elif isinstance(element, Quit): + sys.exit() + break + + else: + if self.selected_element.editable and not self.playing: + mouse_move = pygame.mouse.get_rel() + if mouse_move != (0, 0): + self.count -= 1 + self.selected_element.rect.center = pygame.mouse.get_pos() + new_pos = self.selected_element.rect.topleft + self.selected_element.initial_pos = new_pos + self.selected_element = None + + def show_congratulations(self): + if self.play_sounds: + pygame.mixer.stop() + self.congrats_snd.play() + + self.screen.blit(self.congrats, (600 - self.congrats.get_width()/2, + 450 - self.congrats.get_height()/2) ) + pygame.display.flip() + + while True: + #GTK events + while gtk.events_pending(): + gtk.main_iteration() + for event in pygame.event.get(): + if event.type == pygame.MOUSEBUTTONDOWN: + return + + def main_loop(self): + self.menu.run() + while self.running and self.level < len(self.levels): + while not self.levels[self.level].goal_reached() and self.running: + self.event_handler() + self.clock.tick(self.fps) + self.update_screen(self.fps) + self.levels[self.level].draw() + + if not self._showed_help: + self.levels[self.level].show_help(self.screen) + self._showed_help = True + + pygame.display.flip() + + if self.running: + self.playing = False + self._showed_help = False + self.level += 1 + self.show_congratulations() + if (len(self.levels) == self.level) : + self.running = False if __name__ == "__main__": - parser = OptionParser() - parser.add_option('-p', '--profile', action='store_true', - dest='profile', default=False, - help='run in profiling mode [default: %default]') - parser.add_option('-s', '--no-sound', action='store_true', - dest='sound', default=False, - help='disable sounds [default: %default]') - options, args = parser.parse_args() - - if options.profile: - import cProfile - cProfile.run('main()', filename='gambiarra.cprof') - else: - main(options.sound) + g = Game(running_sugar=False) + g.run() + diff --git a/Gambiarra/gamemenu.py b/gamemenu.py index 55d838e..55d838e 100644 --- a/Gambiarra/gamemenu.py +++ b/gamemenu.py diff --git a/Gambiarra/levels.py b/levels.py index 9d16bd2..79bf675 100644 --- a/Gambiarra/levels.py +++ b/levels.py @@ -25,9 +25,9 @@ import os import simplejson as json -from Gambiarra.objects import * +from objects import * -from Gambiarra.command import Play, Help, Quit +from command import Play, Help, Quit class SimulationView(object): """ This widget holds the objects being simulated. """ @@ -149,6 +149,9 @@ class Level(object): 450 - self.help_img.get_height()/2) ) pygame.display.flip() while True: + #GTK events + while gtk.events_pending(): + gtk.main_iteration() for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONDOWN: return diff --git a/objects/__init__.py b/objects/__init__.py new file mode 100644 index 0000000..f10dcdb --- /dev/null +++ b/objects/__init__.py @@ -0,0 +1,16 @@ +from objects.animals import Penguin +from objects.balls import SoccerBall, BowlingBall, BeachBall +from objects.elastica import Elastica +from objects.esteira import Esteira +from objects.target import Target +from objects.things import Thing, check_collision +from objects.wall import UpWall, DownWall, LeftWall, RightWall + +# namespace cleanup +del animals +del balls +del elastica +del esteira +del target +del things +del wall diff --git a/Gambiarra/objects/animals.py b/objects/animals.py index 9b3114a..9b3114a 100644 --- a/Gambiarra/objects/animals.py +++ b/objects/animals.py diff --git a/Gambiarra/objects/balls.py b/objects/balls.py index 3546d34..3546d34 100644 --- a/Gambiarra/objects/balls.py +++ b/objects/balls.py diff --git a/Gambiarra/objects/elastica.py b/objects/elastica.py index 01dd9d8..01dd9d8 100644 --- a/Gambiarra/objects/elastica.py +++ b/objects/elastica.py diff --git a/Gambiarra/objects/esteira.py b/objects/esteira.py index f17fe59..f17fe59 100644 --- a/Gambiarra/objects/esteira.py +++ b/objects/esteira.py diff --git a/Gambiarra/objects/target.py b/objects/target.py index 69bbca5..69bbca5 100644 --- a/Gambiarra/objects/target.py +++ b/objects/target.py diff --git a/Gambiarra/objects/things.py b/objects/things.py index 7d8ac79..7d8ac79 100644 --- a/Gambiarra/objects/things.py +++ b/objects/things.py diff --git a/Gambiarra/objects/wall.py b/objects/wall.py index ec6c1de..ec6c1de 100644 --- a/Gambiarra/objects/wall.py +++ b/objects/wall.py diff --git a/simplejson/__init__.py b/simplejson/__init__.py deleted file mode 100644 index be9e87a..0000000 --- a/simplejson/__init__.py +++ /dev/null @@ -1,389 +0,0 @@ -r""" -A simple, fast, extensible JSON encoder and decoder - -JSON (JavaScript Object Notation) is a subset of -JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data -interchange format. - -simplejson exposes an API familiar to uses of the standard library -marshal and pickle modules. - -Encoding basic Python object hierarchies:: - - >>> import simplejson - >>> simplejson.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) - '["foo", {"bar": ["baz", null, 1.0, 2]}]' - >>> print simplejson.dumps("\"foo\bar") - "\"foo\bar" - >>> print simplejson.dumps(u'\u1234') - "\u1234" - >>> print simplejson.dumps('\\') - "\\" - >>> print simplejson.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True) - {"a": 0, "b": 0, "c": 0} - >>> from StringIO import StringIO - >>> io = StringIO() - >>> simplejson.dump(['streaming API'], io) - >>> io.getvalue() - '["streaming API"]' - -Compact encoding:: - - >>> import simplejson - >>> simplejson.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':')) - '[1,2,3,{"4":5,"6":7}]' - -Pretty printing:: - - >>> import simplejson - >>> print simplejson.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4) - { - "4": 5, - "6": 7 - } - -Decoding JSON:: - - >>> import simplejson - >>> simplejson.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') - [u'foo', {u'bar': [u'baz', None, 1.0, 2]}] - >>> simplejson.loads('"\\"foo\\bar"') - u'"foo\x08ar' - >>> from StringIO import StringIO - >>> io = StringIO('["streaming API"]') - >>> simplejson.load(io) - [u'streaming API'] - -Specializing JSON object decoding:: - - >>> import simplejson - >>> def as_complex(dct): - ... if '__complex__' in dct: - ... return complex(dct['real'], dct['imag']) - ... return dct - ... - >>> simplejson.loads('{"__complex__": true, "real": 1, "imag": 2}', - ... object_hook=as_complex) - (1+2j) - >>> import decimal - >>> simplejson.loads('1.1', parse_float=decimal.Decimal) - decimal.Decimal(1.1) - -Extending JSONEncoder:: - - >>> import simplejson - >>> class ComplexEncoder(simplejson.JSONEncoder): - ... def default(self, obj): - ... if isinstance(obj, complex): - ... return [obj.real, obj.imag] - ... return simplejson.JSONEncoder.default(self, obj) - ... - >>> dumps(2 + 1j, cls=ComplexEncoder) - '[2.0, 1.0]' - >>> ComplexEncoder().encode(2 + 1j) - '[2.0, 1.0]' - >>> list(ComplexEncoder().iterencode(2 + 1j)) - ['[', '2.0', ', ', '1.0', ']'] - - -Using simplejson from the shell to validate and -pretty-print:: - - $ echo '{"json":"obj"}' | python -msimplejson - { - "json": "obj" - } - $ echo '{ 1.2:3.4}' | python -msimplejson - Expecting property name: line 1 column 2 (char 2) - -Note that the JSON produced by this module's default settings -is a subset of YAML, so it may be used as a serializer for that as well. -""" -__version__ = '1.8.1' -__all__ = [ - 'dump', 'dumps', 'load', 'loads', - 'JSONDecoder', 'JSONEncoder', -] - -if __name__ == '__main__': - from simplejson.decoder import JSONDecoder - from simplejson.encoder import JSONEncoder -else: - from decoder import JSONDecoder - from encoder import JSONEncoder - -_default_encoder = JSONEncoder( - skipkeys=False, - ensure_ascii=True, - check_circular=True, - allow_nan=True, - indent=None, - separators=None, - encoding='utf-8', - default=None, -) - -def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, - allow_nan=True, cls=None, indent=None, separators=None, - encoding='utf-8', default=None, **kw): - """ - Serialize ``obj`` as a JSON formatted stream to ``fp`` (a - ``.write()``-supporting file-like object). - - If ``skipkeys`` is ``True`` then ``dict`` keys that are not basic types - (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) - will be skipped instead of raising a ``TypeError``. - - If ``ensure_ascii`` is ``False``, then the some chunks written to ``fp`` - may be ``unicode`` instances, subject to normal Python ``str`` to - ``unicode`` coercion rules. Unless ``fp.write()`` explicitly - understands ``unicode`` (as in ``codecs.getwriter()``) this is likely - to cause an error. - - If ``check_circular`` is ``False``, then the circular reference check - for container types will be skipped and a circular reference will - result in an ``OverflowError`` (or worse). - - If ``allow_nan`` is ``False``, then it will be a ``ValueError`` to - serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) - in strict compliance of the JSON specification, instead of using the - JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). - - If ``indent`` is a non-negative integer, then JSON array elements and object - members will be pretty-printed with that indent level. An indent level - of 0 will only insert newlines. ``None`` is the most compact representation. - - If ``separators`` is an ``(item_separator, dict_separator)`` tuple - then it will be used instead of the default ``(', ', ': ')`` separators. - ``(',', ':')`` is the most compact JSON representation. - - ``encoding`` is the character encoding for str instances, default is UTF-8. - - ``default(obj)`` is a function that should return a serializable version - of obj or raise TypeError. The default simply raises TypeError. - - To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the - ``.default()`` method to serialize additional types), specify it with - the ``cls`` kwarg. - """ - # cached encoder - if (skipkeys is False and ensure_ascii is True and - check_circular is True and allow_nan is True and - cls is None and indent is None and separators is None and - encoding == 'utf-8' and default is None and not kw): - iterable = _default_encoder.iterencode(obj) - else: - if cls is None: - cls = JSONEncoder - iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, - check_circular=check_circular, allow_nan=allow_nan, indent=indent, - separators=separators, encoding=encoding, - default=default, **kw).iterencode(obj) - # could accelerate with writelines in some versions of Python, at - # a debuggability cost - for chunk in iterable: - fp.write(chunk) - - -def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, - allow_nan=True, cls=None, indent=None, separators=None, - encoding='utf-8', default=None, **kw): - """ - Serialize ``obj`` to a JSON formatted ``str``. - - If ``skipkeys`` is ``True`` then ``dict`` keys that are not basic types - (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) - will be skipped instead of raising a ``TypeError``. - - If ``ensure_ascii`` is ``False``, then the return value will be a - ``unicode`` instance subject to normal Python ``str`` to ``unicode`` - coercion rules instead of being escaped to an ASCII ``str``. - - If ``check_circular`` is ``False``, then the circular reference check - for container types will be skipped and a circular reference will - result in an ``OverflowError`` (or worse). - - If ``allow_nan`` is ``False``, then it will be a ``ValueError`` to - serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in - strict compliance of the JSON specification, instead of using the - JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). - - If ``indent`` is a non-negative integer, then JSON array elements and - object members will be pretty-printed with that indent level. An indent - level of 0 will only insert newlines. ``None`` is the most compact - representation. - - If ``separators`` is an ``(item_separator, dict_separator)`` tuple - then it will be used instead of the default ``(', ', ': ')`` separators. - ``(',', ':')`` is the most compact JSON representation. - - ``encoding`` is the character encoding for str instances, default is UTF-8. - - ``default(obj)`` is a function that should return a serializable version - of obj or raise TypeError. The default simply raises TypeError. - - To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the - ``.default()`` method to serialize additional types), specify it with - the ``cls`` kwarg. - """ - # cached encoder - if (skipkeys is False and ensure_ascii is True and - check_circular is True and allow_nan is True and - cls is None and indent is None and separators is None and - encoding == 'utf-8' and default is None and not kw): - return _default_encoder.encode(obj) - if cls is None: - cls = JSONEncoder - return cls( - skipkeys=skipkeys, ensure_ascii=ensure_ascii, - check_circular=check_circular, allow_nan=allow_nan, indent=indent, - separators=separators, encoding=encoding, default=default, - **kw).encode(obj) - -_default_decoder = JSONDecoder(encoding=None, object_hook=None) - -def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, **kw): - """ - Deserialize ``fp`` (a ``.read()``-supporting file-like object containing - a JSON document) to a Python object. - - If the contents of ``fp`` is encoded with an ASCII based encoding other - than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must - be specified. Encodings that are not ASCII based (such as UCS-2) are - not allowed, and should be wrapped with - ``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode`` - object and passed to ``loads()`` - - ``object_hook`` is an optional function that will be called with the - result of any object literal decode (a ``dict``). The return value of - ``object_hook`` will be used instead of the ``dict``. This feature - can be used to implement custom decoders (e.g. JSON-RPC class hinting). - - To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` - kwarg. - """ - return loads(fp.read(), - encoding=encoding, cls=cls, object_hook=object_hook, - parse_float=parse_float, parse_int=parse_int, - parse_constant=parse_constant, **kw) - -def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, **kw): - """ - Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON - document) to a Python object. - - If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding - other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name - must be specified. Encodings that are not ASCII based (such as UCS-2) - are not allowed and should be decoded to ``unicode`` first. - - ``object_hook`` is an optional function that will be called with the - result of any object literal decode (a ``dict``). The return value of - ``object_hook`` will be used instead of the ``dict``. This feature - can be used to implement custom decoders (e.g. JSON-RPC class hinting). - - ``parse_float``, if specified, will be called with the string - of every JSON float to be decoded. By default this is equivalent to - float(num_str). This can be used to use another datatype or parser - for JSON floats (e.g. decimal.Decimal). - - ``parse_int``, if specified, will be called with the string - of every JSON int to be decoded. By default this is equivalent to - int(num_str). This can be used to use another datatype or parser - for JSON integers (e.g. float). - - ``parse_constant``, if specified, will be called with one of the - following strings: -Infinity, Infinity, NaN, null, true, false. - This can be used to raise an exception if invalid JSON numbers - are encountered. - - To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` - kwarg. - """ - if (cls is None and encoding is None and object_hook is None and - parse_int is None and parse_float is None and - parse_constant is None and not kw): - return _default_decoder.decode(s) - if cls is None: - cls = JSONDecoder - if object_hook is not None: - kw['object_hook'] = object_hook - if parse_float is not None: - kw['parse_float'] = parse_float - if parse_int is not None: - kw['parse_int'] = parse_int - if parse_constant is not None: - kw['parse_constant'] = parse_constant - return cls(encoding=encoding, **kw).decode(s) - -# -# Compatibility cruft from other libraries -# - -def decode(s): - """ - demjson, python-cjson API compatibility hook. Use loads(s) instead. - """ - import warnings - warnings.warn("simplejson.loads(s) should be used instead of decode(s)", - DeprecationWarning) - return loads(s) - -def encode(obj): - """ - demjson, python-cjson compatibility hook. Use dumps(s) instead. - """ - import warnings - warnings.warn("simplejson.dumps(s) should be used instead of encode(s)", - DeprecationWarning) - return dumps(obj) - -def read(s): - """ - jsonlib, JsonUtils, python-json, json-py API compatibility hook. - Use loads(s) instead. - """ - import warnings - warnings.warn("simplejson.loads(s) should be used instead of read(s)", - DeprecationWarning) - return loads(s) - -def write(obj): - """ - jsonlib, JsonUtils, python-json, json-py API compatibility hook. - Use dumps(s) instead. - """ - import warnings - warnings.warn("simplejson.dumps(s) should be used instead of write(s)", - DeprecationWarning) - return dumps(obj) - -# -# Pretty printer: -# curl http://mochikit.com/examples/ajax_tables/domains.json | python -msimplejson -# - -def main(): - import sys - if len(sys.argv) == 1: - infile = sys.stdin - outfile = sys.stdout - elif len(sys.argv) == 2: - infile = open(sys.argv[1], 'rb') - outfile = sys.stdout - elif len(sys.argv) == 3: - infile = open(sys.argv[1], 'rb') - outfile = open(sys.argv[2], 'wb') - else: - raise SystemExit("%s [infile [outfile]]" % (sys.argv[0],)) - try: - obj = load(infile) - except ValueError, e: - raise SystemExit(e) - dump(obj, outfile, sort_keys=True, indent=4) - outfile.write('\n') - -if __name__ == '__main__': - main() diff --git a/simplejson/decoder.py b/simplejson/decoder.py deleted file mode 100644 index 6a73e9a..0000000 --- a/simplejson/decoder.py +++ /dev/null @@ -1,322 +0,0 @@ -""" -Implementation of JSONDecoder -""" -import re -import sys - -from simplejson.scanner import Scanner, pattern -try: - from simplejson import _speedups -except: - _speedups = None - -FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL - -def _floatconstants(): - import struct - import sys - _BYTES = '7FF80000000000007FF0000000000000'.decode('hex') - if sys.byteorder != 'big': - _BYTES = _BYTES[:8][::-1] + _BYTES[8:][::-1] - nan, inf = struct.unpack('dd', _BYTES) - return nan, inf, -inf - -NaN, PosInf, NegInf = _floatconstants() - -def linecol(doc, pos): - lineno = doc.count('\n', 0, pos) + 1 - if lineno == 1: - colno = pos - else: - colno = pos - doc.rindex('\n', 0, pos) - return lineno, colno - -def errmsg(msg, doc, pos, end=None): - lineno, colno = linecol(doc, pos) - if end is None: - return '%s: line %d column %d (char %d)' % (msg, lineno, colno, pos) - endlineno, endcolno = linecol(doc, end) - return '%s: line %d column %d - line %d column %d (char %d - %d)' % ( - msg, lineno, colno, endlineno, endcolno, pos, end) - -_CONSTANTS = { - '-Infinity': NegInf, - 'Infinity': PosInf, - 'NaN': NaN, - 'true': True, - 'false': False, - 'null': None, -} - -def JSONConstant(match, context, c=_CONSTANTS): - s = match.group(0) - fn = getattr(context, 'parse_constant', None) - if fn is None: - rval = c[s] - else: - rval = fn(s) - return rval, None -pattern('(-?Infinity|NaN|true|false|null)')(JSONConstant) - -def JSONNumber(match, context): - match = JSONNumber.regex.match(match.string, *match.span()) - integer, frac, exp = match.groups() - if frac or exp: - fn = getattr(context, 'parse_float', None) or float - res = fn(integer + (frac or '') + (exp or '')) - else: - fn = getattr(context, 'parse_int', None) or int - res = fn(integer) - return res, None -pattern(r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?')(JSONNumber) - -STRINGCHUNK = re.compile(r'(.*?)(["\\])', FLAGS) -BACKSLASH = { - '"': u'"', '\\': u'\\', '/': u'/', - 'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t', -} - -DEFAULT_ENCODING = "utf-8" - -def scanstring(s, end, encoding=None, _b=BACKSLASH, _m=STRINGCHUNK.match): - if encoding is None: - encoding = DEFAULT_ENCODING - chunks = [] - _append = chunks.append - begin = end - 1 - while 1: - chunk = _m(s, end) - if chunk is None: - raise ValueError( - errmsg("Unterminated string starting at", s, begin)) - end = chunk.end() - content, terminator = chunk.groups() - if content: - if not isinstance(content, unicode): - content = unicode(content, encoding) - _append(content) - if terminator == '"': - break - try: - esc = s[end] - except IndexError: - raise ValueError( - errmsg("Unterminated string starting at", s, begin)) - if esc != 'u': - try: - m = _b[esc] - except KeyError: - raise ValueError( - errmsg("Invalid \\escape: %r" % (esc,), s, end)) - end += 1 - else: - esc = s[end + 1:end + 5] - next_end = end + 5 - msg = "Invalid \\uXXXX escape" - try: - if len(esc) != 4: - raise ValueError - uni = int(esc, 16) - if 0xd800 <= uni <= 0xdbff and sys.maxunicode > 65535: - msg = "Invalid \\uXXXX\\uXXXX surrogate pair" - if not s[end + 5:end + 7] == '\\u': - raise ValueError - esc2 = s[end + 7:end + 11] - if len(esc2) != 4: - raise ValueError - uni2 = int(esc2, 16) - uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00)) - next_end += 6 - m = unichr(uni) - except ValueError: - raise ValueError(errmsg(msg, s, end)) - end = next_end - _append(m) - return u''.join(chunks), end - -# Use speedup -if _speedups is not None: - scanstring = _speedups.scanstring - -def JSONString(match, context): - encoding = getattr(context, 'encoding', None) - return scanstring(match.string, match.end(), encoding) -pattern(r'"')(JSONString) - -WHITESPACE = re.compile(r'\s*', FLAGS) - -def JSONObject(match, context, _w=WHITESPACE.match): - pairs = {} - s = match.string - end = _w(s, match.end()).end() - nextchar = s[end:end + 1] - # trivial empty object - if nextchar == '}': - return pairs, end + 1 - if nextchar != '"': - raise ValueError(errmsg("Expecting property name", s, end)) - end += 1 - encoding = getattr(context, 'encoding', None) - iterscan = JSONScanner.iterscan - while True: - key, end = scanstring(s, end, encoding) - end = _w(s, end).end() - if s[end:end + 1] != ':': - raise ValueError(errmsg("Expecting : delimiter", s, end)) - end = _w(s, end + 1).end() - try: - value, end = iterscan(s, idx=end, context=context).next() - except StopIteration: - raise ValueError(errmsg("Expecting object", s, end)) - pairs[key] = value - end = _w(s, end).end() - nextchar = s[end:end + 1] - end += 1 - if nextchar == '}': - break - if nextchar != ',': - raise ValueError(errmsg("Expecting , delimiter", s, end - 1)) - end = _w(s, end).end() - nextchar = s[end:end + 1] - end += 1 - if nextchar != '"': - raise ValueError(errmsg("Expecting property name", s, end - 1)) - object_hook = getattr(context, 'object_hook', None) - if object_hook is not None: - pairs = object_hook(pairs) - return pairs, end -pattern(r'{')(JSONObject) - -def JSONArray(match, context, _w=WHITESPACE.match): - values = [] - s = match.string - end = _w(s, match.end()).end() - # look-ahead for trivial empty array - nextchar = s[end:end + 1] - if nextchar == ']': - return values, end + 1 - iterscan = JSONScanner.iterscan - while True: - try: - value, end = iterscan(s, idx=end, context=context).next() - except StopIteration: - raise ValueError(errmsg("Expecting object", s, end)) - values.append(value) - end = _w(s, end).end() - nextchar = s[end:end + 1] - end += 1 - if nextchar == ']': - break - if nextchar != ',': - raise ValueError(errmsg("Expecting , delimiter", s, end)) - end = _w(s, end).end() - return values, end -pattern(r'\[')(JSONArray) - -ANYTHING = [ - JSONObject, - JSONArray, - JSONString, - JSONConstant, - JSONNumber, -] - -JSONScanner = Scanner(ANYTHING) - -class JSONDecoder(object): - """ - Simple JSON decoder - - Performs the following translations in decoding by default: - - +---------------+-------------------+ - | JSON | Python | - +===============+===================+ - | object | dict | - +---------------+-------------------+ - | array | list | - +---------------+-------------------+ - | string | unicode | - +---------------+-------------------+ - | number (int) | int, long | - +---------------+-------------------+ - | number (real) | float | - +---------------+-------------------+ - | true | True | - +---------------+-------------------+ - | false | False | - +---------------+-------------------+ - | null | None | - +---------------+-------------------+ - - It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as - their corresponding ``float`` values, which is outside the JSON spec. - """ - - _scanner = Scanner(ANYTHING) - __all__ = ['__init__', 'decode', 'raw_decode'] - - def __init__(self, encoding=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None): - """ - ``encoding`` determines the encoding used to interpret any ``str`` - objects decoded by this instance (utf-8 by default). It has no - effect when decoding ``unicode`` objects. - - Note that currently only encodings that are a superset of ASCII work, - strings of other encodings should be passed in as ``unicode``. - - ``object_hook``, if specified, will be called with the result - of every JSON object decoded and its return value will be used in - place of the given ``dict``. This can be used to provide custom - deserializations (e.g. to support JSON-RPC class hinting). - - ``parse_float``, if specified, will be called with the string - of every JSON float to be decoded. By default this is equivalent to - float(num_str). This can be used to use another datatype or parser - for JSON floats (e.g. decimal.Decimal). - - ``parse_int``, if specified, will be called with the string - of every JSON int to be decoded. By default this is equivalent to - int(num_str). This can be used to use another datatype or parser - for JSON integers (e.g. float). - - ``parse_constant``, if specified, will be called with one of the - following strings: -Infinity, Infinity, NaN, null, true, false. - This can be used to raise an exception if invalid JSON numbers - are encountered. - """ - self.encoding = encoding - self.object_hook = object_hook - self.parse_float = parse_float - self.parse_int = parse_int - self.parse_constant = parse_constant - - def decode(self, s, _w=WHITESPACE.match): - """ - Return the Python representation of ``s`` (a ``str`` or ``unicode`` - instance containing a JSON document) - """ - obj, end = self.raw_decode(s, idx=_w(s, 0).end()) - end = _w(s, end).end() - if end != len(s): - raise ValueError(errmsg("Extra data", s, end, len(s))) - return obj - - def raw_decode(self, s, **kw): - """ - Decode a JSON document from ``s`` (a ``str`` or ``unicode`` beginning - with a JSON document) and return a 2-tuple of the Python - representation and the index in ``s`` where the document ended. - - This can be used to decode a JSON document from a string that may - have extraneous data at the end. - """ - kw.setdefault('context', self) - try: - obj, end = self._scanner.iterscan(s, **kw).next() - except StopIteration: - raise ValueError("No JSON object could be decoded") - return obj, end - -__all__ = ['JSONDecoder'] diff --git a/simplejson/encoder.py b/simplejson/encoder.py deleted file mode 100644 index 1c69b02..0000000 --- a/simplejson/encoder.py +++ /dev/null @@ -1,376 +0,0 @@ -""" -Implementation of JSONEncoder -""" -import re -try: - from simplejson import _speedups -except ImportError: - _speedups = None - -ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]') -ESCAPE_ASCII = re.compile(r'([\\"/]|[^\ -~])') -ESCAPE_DCT = { - '\\': '\\\\', - '"': '\\"', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', -} -for i in range(0x20): - ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,)) - -# assume this produces an infinity on all machines (probably not guaranteed) -INFINITY = float('1e66666') -FLOAT_REPR = repr - -def floatstr(o, allow_nan=True): - # Check for specials. Note that this type of test is processor- and/or - # platform-specific, so do tests which don't depend on the internals. - - if o != o: - text = 'NaN' - elif o == INFINITY: - text = 'Infinity' - elif o == -INFINITY: - text = '-Infinity' - else: - return FLOAT_REPR(o) - - if not allow_nan: - raise ValueError("Out of range float values are not JSON compliant: %r" - % (o,)) - - return text - - -def encode_basestring(s): - """ - Return a JSON representation of a Python string - """ - def replace(match): - return ESCAPE_DCT[match.group(0)] - return '"' + ESCAPE.sub(replace, s) + '"' - -def encode_basestring_ascii(s): - def replace(match): - s = match.group(0) - try: - return ESCAPE_DCT[s] - except KeyError: - n = ord(s) - if n < 0x10000: - return '\\u%04x' % (n,) - else: - # surrogate pair - n -= 0x10000 - s1 = 0xd800 | ((n >> 10) & 0x3ff) - s2 = 0xdc00 | (n & 0x3ff) - return '\\u%04x\\u%04x' % (s1, s2) - return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"' - -try: - encode_basestring_ascii = _speedups.encode_basestring_ascii - _need_utf8 = True -except AttributeError: - _need_utf8 = False - -class JSONEncoder(object): - """ - Extensible JSON encoder for Python data structures. - - Supports the following objects and types by default: - - +-------------------+---------------+ - | Python | JSON | - +===================+===============+ - | dict | object | - +-------------------+---------------+ - | list, tuple | array | - +-------------------+---------------+ - | str, unicode | string | - +-------------------+---------------+ - | int, long, float | number | - +-------------------+---------------+ - | True | true | - +-------------------+---------------+ - | False | false | - +-------------------+---------------+ - | None | null | - +-------------------+---------------+ - - To extend this to recognize other objects, subclass and implement a - ``.default()`` method with another method that returns a serializable - object for ``o`` if possible, otherwise it should call the superclass - implementation (to raise ``TypeError``). - """ - __all__ = ['__init__', 'default', 'encode', 'iterencode'] - item_separator = ', ' - key_separator = ': ' - def __init__(self, skipkeys=False, ensure_ascii=True, - check_circular=True, allow_nan=True, sort_keys=False, - indent=None, separators=None, encoding='utf-8', default=None): - """ - Constructor for JSONEncoder, with sensible defaults. - - If skipkeys is False, then it is a TypeError to attempt - encoding of keys that are not str, int, long, float or None. If - skipkeys is True, such items are simply skipped. - - If ensure_ascii is True, the output is guaranteed to be str - objects with all incoming unicode characters escaped. If - ensure_ascii is false, the output will be unicode object. - - If check_circular is True, then lists, dicts, and custom encoded - objects will be checked for circular references during encoding to - prevent an infinite recursion (which would cause an OverflowError). - Otherwise, no such check takes place. - - If allow_nan is True, then NaN, Infinity, and -Infinity will be - encoded as such. This behavior is not JSON specification compliant, - but is consistent with most JavaScript based encoders and decoders. - Otherwise, it will be a ValueError to encode such floats. - - If sort_keys is True, then the output of dictionaries will be - sorted by key; this is useful for regression tests to ensure - that JSON serializations can be compared on a day-to-day basis. - - If indent is a non-negative integer, then JSON array - elements and object members will be pretty-printed with that - indent level. An indent level of 0 will only insert newlines. - None is the most compact representation. - - If specified, separators should be a (item_separator, key_separator) - tuple. The default is (', ', ': '). To get the most compact JSON - representation you should specify (',', ':') to eliminate whitespace. - - If specified, default is a function that gets called for objects - that can't otherwise be serialized. It should return a JSON encodable - version of the object or raise a ``TypeError``. - - If encoding is not None, then all input strings will be - transformed into unicode using that encoding prior to JSON-encoding. - The default is UTF-8. - """ - - self.skipkeys = skipkeys - self.ensure_ascii = ensure_ascii - self.check_circular = check_circular - self.allow_nan = allow_nan - self.sort_keys = sort_keys - self.indent = indent - self.current_indent_level = 0 - if separators is not None: - self.item_separator, self.key_separator = separators - if default is not None: - self.default = default - self.encoding = encoding - - def _newline_indent(self): - return '\n' + (' ' * (self.indent * self.current_indent_level)) - - def _iterencode_list(self, lst, markers=None): - if not lst: - yield '[]' - return - if markers is not None: - markerid = id(lst) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = lst - yield '[' - if self.indent is not None: - self.current_indent_level += 1 - newline_indent = self._newline_indent() - separator = self.item_separator + newline_indent - yield newline_indent - else: - newline_indent = None - separator = self.item_separator - first = True - for value in lst: - if first: - first = False - else: - yield separator - for chunk in self._iterencode(value, markers): - yield chunk - if newline_indent is not None: - self.current_indent_level -= 1 - yield self._newline_indent() - yield ']' - if markers is not None: - del markers[markerid] - - def _iterencode_dict(self, dct, markers=None): - if not dct: - yield '{}' - return - if markers is not None: - markerid = id(dct) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = dct - yield '{' - key_separator = self.key_separator - if self.indent is not None: - self.current_indent_level += 1 - newline_indent = self._newline_indent() - item_separator = self.item_separator + newline_indent - yield newline_indent - else: - newline_indent = None - item_separator = self.item_separator - first = True - if self.ensure_ascii: - encoder = encode_basestring_ascii - else: - encoder = encode_basestring - allow_nan = self.allow_nan - if self.sort_keys: - keys = dct.keys() - keys.sort() - items = [(k, dct[k]) for k in keys] - else: - items = dct.iteritems() - _encoding = self.encoding - _do_decode = (_encoding is not None - and not (_need_utf8 and _encoding == 'utf-8')) - for key, value in items: - if isinstance(key, str): - if _do_decode: - key = key.decode(_encoding) - elif isinstance(key, basestring): - pass - # JavaScript is weakly typed for these, so it makes sense to - # also allow them. Many encoders seem to do something like this. - elif isinstance(key, float): - key = floatstr(key, allow_nan) - elif isinstance(key, (int, long)): - key = str(key) - elif key is True: - key = 'true' - elif key is False: - key = 'false' - elif key is None: - key = 'null' - elif self.skipkeys: - continue - else: - raise TypeError("key %r is not a string" % (key,)) - if first: - first = False - else: - yield item_separator - yield encoder(key) - yield key_separator - for chunk in self._iterencode(value, markers): - yield chunk - if newline_indent is not None: - self.current_indent_level -= 1 - yield self._newline_indent() - yield '}' - if markers is not None: - del markers[markerid] - - def _iterencode(self, o, markers=None): - if isinstance(o, basestring): - if self.ensure_ascii: - encoder = encode_basestring_ascii - else: - encoder = encode_basestring - _encoding = self.encoding - if (_encoding is not None and isinstance(o, str) - and not (_need_utf8 and _encoding == 'utf-8')): - o = o.decode(_encoding) - yield encoder(o) - elif o is None: - yield 'null' - elif o is True: - yield 'true' - elif o is False: - yield 'false' - elif isinstance(o, (int, long)): - yield str(o) - elif isinstance(o, float): - yield floatstr(o, self.allow_nan) - elif isinstance(o, (list, tuple)): - for chunk in self._iterencode_list(o, markers): - yield chunk - elif isinstance(o, dict): - for chunk in self._iterencode_dict(o, markers): - yield chunk - else: - if markers is not None: - markerid = id(o) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = o - for chunk in self._iterencode_default(o, markers): - yield chunk - if markers is not None: - del markers[markerid] - - def _iterencode_default(self, o, markers=None): - newobj = self.default(o) - return self._iterencode(newobj, markers) - - def default(self, o): - """ - Implement this method in a subclass such that it returns - a serializable object for ``o``, or calls the base implementation - (to raise a ``TypeError``). - - For example, to support arbitrary iterators, you could - implement default like this:: - - def default(self, o): - try: - iterable = iter(o) - except TypeError: - pass - else: - return list(iterable) - return JSONEncoder.default(self, o) - """ - raise TypeError("%r is not JSON serializable" % (o,)) - - def encode(self, o): - """ - Return a JSON string representation of a Python data structure. - - >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) - '{"foo":["bar", "baz"]}' - """ - # This is for extremely simple cases and benchmarks... - if isinstance(o, basestring): - if isinstance(o, str): - _encoding = self.encoding - if (_encoding is not None - and not (_encoding == 'utf-8' and _need_utf8)): - o = o.decode(_encoding) - return encode_basestring_ascii(o) - # This doesn't pass the iterator directly to ''.join() because it - # sucks at reporting exceptions. It's going to do this internally - # anyway because it uses PySequence_Fast or similar. - chunks = list(self.iterencode(o)) - return ''.join(chunks) - - def iterencode(self, o): - """ - Encode the given object and yield each string - representation as available. - - For example:: - - for chunk in JSONEncoder().iterencode(bigobject): - mysocket.write(chunk) - """ - if self.check_circular: - markers = {} - else: - markers = None - return self._iterencode(o, markers) - -__all__ = ['JSONEncoder'] diff --git a/simplejson/jsonfilter.py b/simplejson/jsonfilter.py deleted file mode 100644 index 01ca21d..0000000 --- a/simplejson/jsonfilter.py +++ /dev/null @@ -1,40 +0,0 @@ -import simplejson -import cgi - -class JSONFilter(object): - def __init__(self, app, mime_type='text/x-json'): - self.app = app - self.mime_type = mime_type - - def __call__(self, environ, start_response): - # Read JSON POST input to jsonfilter.json if matching mime type - response = {'status': '200 OK', 'headers': []} - def json_start_response(status, headers): - response['status'] = status - response['headers'].extend(headers) - environ['jsonfilter.mime_type'] = self.mime_type - if environ.get('REQUEST_METHOD', '') == 'POST': - if environ.get('CONTENT_TYPE', '') == self.mime_type: - args = [_ for _ in [environ.get('CONTENT_LENGTH')] if _] - data = environ['wsgi.input'].read(*map(int, args)) - environ['jsonfilter.json'] = simplejson.loads(data) - res = simplejson.dumps(self.app(environ, json_start_response)) - jsonp = cgi.parse_qs(environ.get('QUERY_STRING', '')).get('jsonp') - if jsonp: - content_type = 'text/javascript' - res = ''.join(jsonp + ['(', res, ')']) - elif 'Opera' in environ.get('HTTP_USER_AGENT', ''): - # Opera has bunk XMLHttpRequest support for most mime types - content_type = 'text/plain' - else: - content_type = self.mime_type - headers = [ - ('Content-type', content_type), - ('Content-length', len(res)), - ] - headers.extend(response['headers']) - start_response(response['status'], headers) - return [res] - -def factory(app, global_conf, **kw): - return JSONFilter(app, **kw) diff --git a/simplejson/scanner.py b/simplejson/scanner.py deleted file mode 100644 index 0f4be10..0000000 --- a/simplejson/scanner.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -Iterator based sre token scanner -""" -import sre_parse, sre_compile, sre_constants -from sre_constants import BRANCH, SUBPATTERN -from re import VERBOSE, MULTILINE, DOTALL -import re - -__all__ = ['Scanner', 'pattern'] - -FLAGS = (VERBOSE | MULTILINE | DOTALL) -class Scanner(object): - def __init__(self, lexicon, flags=FLAGS): - self.actions = [None] - # combine phrases into a compound pattern - s = sre_parse.Pattern() - s.flags = flags - p = [] - for idx, token in enumerate(lexicon): - phrase = token.pattern - try: - subpattern = sre_parse.SubPattern(s, - [(SUBPATTERN, (idx + 1, sre_parse.parse(phrase, flags)))]) - except sre_constants.error: - raise - p.append(subpattern) - self.actions.append(token) - - s.groups = len(p)+1 # NOTE(guido): Added to make SRE validation work - p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) - self.scanner = sre_compile.compile(p) - - - def iterscan(self, string, idx=0, context=None): - """ - Yield match, end_idx for each match - """ - match = self.scanner.scanner(string, idx).match - actions = self.actions - lastend = idx - end = len(string) - while True: - m = match() - if m is None: - break - matchbegin, matchend = m.span() - if lastend == matchend: - break - action = actions[m.lastindex] - if action is not None: - rval, next_pos = action(m, context) - if next_pos is not None and next_pos != matchend: - # "fast forward" the scanner - matchend = next_pos - match = self.scanner.scanner(string, matchend).match - yield rval, matchend - lastend = matchend - -def pattern(pattern, flags=FLAGS): - def decorator(fn): - fn.pattern = pattern - fn.regex = re.compile(pattern, flags) - return fn - return decorator -- cgit v0.9.1