[pypy-commit] pypy py3.5-fstring-pep498: Split the logic into its own file
Author: Armin Rigo Branch: py3.5-fstring-pep498 Changeset: r89721:9f329ca0b48f Date: 2017-01-24 08:50 +0100 http://bitbucket.org/pypy/pypy/changeset/9f329ca0b48f/ Log:Split the logic into its own file diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py --- a/pypy/interpreter/astcompiler/astbuilder.py +++ b/pypy/interpreter/astcompiler/astbuilder.py @@ -1,9 +1,9 @@ from pypy.interpreter.astcompiler import ast, consts, misc from pypy.interpreter.astcompiler import asthelpers # Side effects +from pypy.interpreter.astcompiler import fstring from pypy.interpreter import error from pypy.interpreter.pyparser.pygram import syms, tokens from pypy.interpreter.pyparser.error import SyntaxError -from pypy.interpreter.pyparser import parsestring from rpython.rlib.objectmodel import always_inline, we_are_translated @@ -1191,150 +1191,6 @@ i += 3 return (i,key,value) -def _add_constant_string(self, joined_pieces, w_string, atom_node): -space = self.space -is_unicode = space.isinstance_w(w_string, space.w_unicode) -# Implement implicit string concatenation. -if joined_pieces: -prev = joined_pieces[-1] -if is_unicode and isinstance(prev, ast.Str): -w_string = space.add(prev.s, w_string) -del joined_pieces[-1] -elif not is_unicode and isinstance(prev, ast.Bytes): -w_string = space.add(prev.s, w_string) -del joined_pieces[-1] -node = ast.Str if is_unicode else ast.Bytes -joined_pieces.append(node(w_string, atom_node.get_lineno(), -atom_node.get_column())) - -def _f_constant_string(self, joined_pieces, u, atom_node): -self._add_constant_string(joined_pieces, self.space.newunicode(u), - atom_node) - -def _f_string_compile(self, source, atom_node): -# Note: a f-string is kept as a single literal up to here. -# At this point only, we recursively call the AST compiler -# on all the '{expr}' parts. The 'expr' part is not parsed -# or even tokenized together with the rest of the source code! -from pypy.interpreter.pyparser import pyparse - -# complain if 'source' is only whitespace or an empty string -for c in source: -if c not in ' \t\n\r\v\f': -break -else: -self.error("f-string: empty expression not allowed", atom_node) - -if self.recursive_parser is None: -self.error("internal error: parser not available for parsing " - "the expressions inside the f-string", atom_node) -source = '(%s)' % source.encode('utf-8') - -info = pyparse.CompileInfo("", "eval", - consts.PyCF_SOURCE_IS_UTF8 | - consts.PyCF_IGNORE_COOKIE | - consts.PyCF_REFUSE_COMMENTS, - optimize=self.compile_info.optimize) -parse_tree = self.recursive_parser.parse_source(source, info) -return ast_from_node(self.space, parse_tree, info) - -def _f_string_expr(self, joined_pieces, u, start, atom_node, rec=0): -conversion = -1 # the conversion char. -1 if not specified. -format_spec = None -nested_depth = 0# nesting level for braces/parens/brackets in exprs -p = start -while p < len(u): -ch = u[p] -p += 1 -if ch in u'[{(': -nested_depth += 1 -elif nested_depth > 0 and ch in u']})': -nested_depth -= 1 -elif nested_depth == 0 and ch in u'!:}': -# special-case '!=' -if ch == u'!' and p < len(u) and u[p] == u'=': -continue -break # normal way out of this loop -else: -ch = u'\x00' -# -if nested_depth > 0: -self.error("f-string: mismatched '(', '{' or '['", atom_node) -end_expression = p - 1 -if ch == u'!': -if p + 1 < len(u): -conversion = ord(u[p]) -ch = u[p + 1] -p += 2 -if conversion not in (ord('s'), ord('r'), ord('a')): -self.error("f-string: invalid conversion character: " - "expected 's', 'r', or 'a'", atom_node) -if ch == u':': -if rec >= 2: -self.error("f-string: expressions nested too deeply", atom_node) -subpieces = [] -p = self._parse_f_string(subpieces, u, p, atom_node, rec + 1) -format_spec = self._f_string_to_ast_node(subpieces, atom_node) -ch = u[p] if p >= 0 else u'\x00' -p += 1 - -if ch != u'}': -self.error("f-string: exp
[pypy-commit] pypy py3.5-fstring-pep498: This version sticks to CPython more closely
Author: Armin Rigo Branch: py3.5-fstring-pep498 Changeset: r89722:d4206d15e05e Date: 2017-01-24 10:41 +0100 http://bitbucket.org/pypy/pypy/changeset/d4206d15e05e/ Log:This version sticks to CPython more closely diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py --- a/pypy/interpreter/astcompiler/consts.py +++ b/pypy/interpreter/astcompiler/consts.py @@ -33,7 +33,6 @@ PyCF_IGNORE_COOKIE = 0x0800 PyCF_ACCEPT_NULL_BYTES = 0x1000 # PyPy only, for compile() PyCF_FOUND_ENCODING = 0x2000 # PyPy only, for pytokenizer -PyCF_REFUSE_COMMENTS = 0x4000 # PyPy only, for f-strings # Masks and values used by FORMAT_VALUE opcode FVC_MASK = 0x3 diff --git a/pypy/interpreter/astcompiler/fstring.py b/pypy/interpreter/astcompiler/fstring.py --- a/pypy/interpreter/astcompiler/fstring.py +++ b/pypy/interpreter/astcompiler/fstring.py @@ -1,6 +1,8 @@ from pypy.interpreter.astcompiler import ast, consts from pypy.interpreter.pyparser import parsestring from pypy.interpreter import error +from pypy.interpreter import unicodehelper +from rpython.rlib.rstring import UnicodeBuilder def add_constant_string(astbuilder, joined_pieces, w_string, atom_node): @@ -46,96 +48,261 @@ info = pyparse.CompileInfo("", "eval", consts.PyCF_SOURCE_IS_UTF8 | - consts.PyCF_IGNORE_COOKIE | - consts.PyCF_REFUSE_COMMENTS, + consts.PyCF_IGNORE_COOKIE, optimize=astbuilder.compile_info.optimize) parse_tree = astbuilder.recursive_parser.parse_source(source, info) return ast_from_node(astbuilder.space, parse_tree, info) -def f_string_expr(astbuilder, joined_pieces, u, start, atom_node, rec=0): -conversion = -1 # the conversion char. -1 if not specified. + +def unexpected_end_of_string(astbuilder, atom_node): +astbuilder.error("f-string: expecting '}'", atom_node) + + +def fstring_find_expr(astbuilder, fstr, atom_node, rec): +# Parse the f-string at fstr.current_index. We know it starts an +# expression (so it must be at '{'). Returns the FormattedValue node, +# which includes the expression, conversion character, and +# format_spec expression. +conversion = -1 # the conversion char. -1 if not specified. format_spec = None -nested_depth = 0# nesting level for braces/parens/brackets in exprs -p = start -while p < len(u): -ch = u[p] -p += 1 -if ch in u'[{(': + +# 0 if we're not in a string, else the quote char we're trying to +# match (single or double quote). +quote_char = 0 + +# If we're inside a string, 1=normal, 3=triple-quoted. +string_type = 0 + +# Keep track of nesting level for braces/parens/brackets in +# expressions. +nested_depth = 0 + +# Can only nest one level deep. +if rec >= 2: +astbuilder.error("f-string: expressions nested too deeply", atom_node) + +# The first char must be a left brace, or we wouldn't have gotten +# here. Skip over it. +u = fstr.unparsed +i = fstr.current_index +assert u[i] == u'{' +i += 1 + +expr_start = i +while i < len(u): + +# Loop invariants. +assert nested_depth >= 0 +if quote_char: +assert string_type == 1 or string_type == 3 +else: +assert string_type == 0 + +ch = u[i] +# Nowhere inside an expression is a backslash allowed. +if ch == u'\\': +# Error: can't include a backslash character, inside +# parens or strings or not. +astbuilder.error("f-string expression part " + "cannot include a backslash", atom_node) + +if quote_char: +# We're inside a string. See if we're at the end. +# +if ord(ch) == quote_char: +# Does this match the string_type (single or triple +# quoted)? +if string_type == 3: +if i + 2 < len(u) and u[i + 1] == u[i + 2] == ch: +# We're at the end of a triple quoted string. +i += 3 +string_type = 0 +quote_char = 0 +continue +else: +# We're at the end of a normal string. +i += 1 +string_type = 0 +quote_char = 0 +continue +elif ch == u"'" or ch == u'"': +# Is this a triple quoted string? +if i + 2 < len(u) and u[i + 1] == u[i + 2] == ch: +string_type = 3 +i += 2 +else: +# Start of a normal string. +string_type = 1 +# Start looking for the end of the string. +quote_char = ord
[pypy-commit] pypy real-mode-translator-driver: More explicit arrangement of tasks
Author: William ML Leslie Branch: real-mode-translator-driver Changeset: r89723:b36e251c762f Date: 2017-01-24 21:19 +1100 http://bitbucket.org/pypy/pypy/changeset/b36e251c762f/ Log:More explicit arrangement of tasks diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -3,7 +3,6 @@ import shutil from rpython.translator.translator import TranslationContext -from rpython.translator.tool.taskengine import SimpleTaskEngine from rpython.translator.goal import query from rpython.translator.goal.timing import Timer from rpython.annotator.listdef import s_list_of_strings @@ -18,18 +17,7 @@ log = AnsiLogger("translation") - -def taskdef(deps, title, new_state=None, expected_states=[], -idemp=False, earlycheck=None): -def decorator(taskfunc): -taskfunc.task_deps = deps -taskfunc.task_title = title -taskfunc.task_newstate = None -taskfunc.task_expected_states = expected_states -taskfunc.task_idempotent = idemp -taskfunc.task_earlycheck = earlycheck -return taskfunc -return decorator +class Done(Exception): pass # TODO: # sanity-checks using states @@ -60,16 +48,13 @@ os._exit(0) -class TranslationDriver(SimpleTaskEngine): +class TranslationDriver(object): _backend_extra_options = {} -def __init__(self, setopts=None, default_goal=None, - disable=[], - exe_name=None, extmod_name=None, - config=None, overrides=None): +def __init__(self, setopts=None, default_goal=None, disable=(), + exe_name=None, config=None, overrides=None): from rpython.config import translationoption self.timer = Timer() -SimpleTaskEngine.__init__(self) self.log = log @@ -85,9 +70,8 @@ self.config.set(**setopts) self.exe_name = exe_name -self.extmod_name = extmod_name -self.done = {} +self.done = set() self.disable(disable) @@ -98,40 +82,51 @@ self.default_goal = default_goal self.extra_goals = [] -self.exposed = [] -# expose tasks -def expose_task(task, backend_goal=None): -if backend_goal is None: -backend_goal = task -def proc(): -return self.proceed(backend_goal) -self.exposed.append(task) -setattr(self, task, proc) +def annotate(self): +return self.proceed(['annotate']) -backend, ts = self.get_backend_and_type_system() -for task in self.tasks: -explicit_task = task -if task == 'annotate': -expose_task(task) -else: -task, postfix = task.split('_') -if task in ('rtype', 'backendopt', 'llinterpret', -'pyjitpl'): -if ts: -if ts == postfix: -expose_task(task, explicit_task) -else: -expose_task(explicit_task) -elif task in ('source', 'compile', 'run'): -if backend: -if backend == postfix: -expose_task(task, explicit_task) -elif ts: -if ts == 'lltype': -expose_task(explicit_task) -else: -expose_task(explicit_task) +def rtype(self): +return self.proceed(['rtype']) + +def backendopt(self): +return self.proceed(['backendopt']) + +def llinterpret(self): +return self.proceed(['llinterpret']) + +def pyjitpl(self): +return self.proceed(['pyjitpl']) + +def rtype_lltype(self): +return self.proceed(['rtype_lltype']) + +def backendopt_lltype(self): +return self.proceed(['backendopt_lltype']) + +def llinterpret_lltype(self): +return self.proceed(['llinterpret_lltype']) + +def pyjitpl_lltype(self): +return self.proceed(['pyjitpl_lltype']) + +def source(self): +return self.proceed(['source']) + +def compile(self): +return self.proceed(['compile']) + +def run(self): +return self.proceed(['run']) + +def source_c(self): +return self.proceed(['source_c']) + +def compile_c(self): +return self.proceed(['compile_c']) + +def run_c(self): +return self.proceed(['run_c']) def set_extra_goals(self, goals): self.extra_goals = goals @@ -148,31 +143,101 @@ backend = self.config.translation.backend return backend, type_system +def run_task(self, name, goals, *args, **kwargs): +if name in self.done or name in self._disabled: +return +task = getattr(self, 'task_%s' % name) + +self.fork_bef
[pypy-commit] pypy real-mode-translator-driver: Remove taskengine
Author: William ML Leslie Branch: real-mode-translator-driver Changeset: r89724:aa48dbd8e0e2 Date: 2017-01-24 21:30 +1100 http://bitbucket.org/pypy/pypy/changeset/aa48dbd8e0e2/ Log:Remove taskengine diff --git a/rpython/translator/tool/taskengine.py b/rpython/translator/tool/taskengine.py deleted file mode 100644 --- a/rpython/translator/tool/taskengine.py +++ /dev/null @@ -1,130 +0,0 @@ -class SimpleTaskEngine(object): -def __init__(self): -self._plan_cache = {} - -self.tasks = tasks = {} - -for name in dir(self): -if name.startswith('task_'): -task_name = name[len('task_'):] -task = getattr(self, name) -assert callable(task) -task_deps = getattr(task, 'task_deps', []) - -tasks[task_name] = task, task_deps - -def _plan(self, goals, skip=[]): -skip = [toskip for toskip in skip if toskip not in goals] - -key = (tuple(goals), tuple(skip)) -try: -return self._plan_cache[key] -except KeyError: -pass -constraints = [] - -def subgoals(task_name): -taskcallable, deps = self.tasks[task_name] -for dep in deps: -if dep.startswith('??'): # optional -dep = dep[2:] -if dep not in goals: -continue -if dep.startswith('?'): # suggested -dep = dep[1:] -if dep in skip: -continue -yield dep - -seen = {} - -def consider(subgoal): -if subgoal in seen: -return -else: -seen[subgoal] = True -constraints.append([subgoal]) -deps = subgoals(subgoal) -for dep in deps: -constraints.append([subgoal, dep]) -consider(dep) - -for goal in goals: -consider(goal) - -#sort - -plan = [] - -while True: -cands = dict.fromkeys([constr[0] for constr in constraints if constr]) -if not cands: -break - -for cand in cands: -for constr in constraints: -if cand in constr[1:]: -break -else: -break -else: -raise RuntimeError("circular dependecy") - -plan.append(cand) -for constr in constraints: -if constr and constr[0] == cand: -del constr[0] - -plan.reverse() - -self._plan_cache[key] = plan - -return plan - -def _depending_on(self, goal): -l = [] -for task_name, (task, task_deps) in self.tasks.iteritems(): -if goal in task_deps: -l.append(task_name) -return l - -def _depending_on_closure(self, goal): -d = {} - -def track(goal): -if goal in d: -return -d[goal] = True -for depending in self._depending_on(goal): -track(depending) -track(goal) -return d.keys() - -def _execute(self, goals, *args, **kwds): -task_skip = kwds.get('task_skip', []) -res = None -goals = self._plan(goals, skip=task_skip) -for goal in goals: -taskcallable, _ = self.tasks[goal] -self._event('planned', goal, taskcallable) -for goal in goals: -taskcallable, _ = self.tasks[goal] -self._event('pre', goal, taskcallable) -try: -res = self._do(goal, taskcallable, *args, **kwds) -except (SystemExit, KeyboardInterrupt): -raise -except: -self._error(goal) -raise -self._event('post', goal, taskcallable) -return res - -def _do(self, goal, func, *args, **kwds): -return func() - -def _event(self, kind, goal, func): -pass - -def _error(self, goal): -pass diff --git a/rpython/translator/tool/test/test_taskengine.py b/rpython/translator/tool/test/test_taskengine.py deleted file mode 100644 --- a/rpython/translator/tool/test/test_taskengine.py +++ /dev/null @@ -1,150 +0,0 @@ -from rpython.translator.tool.taskengine import SimpleTaskEngine - -def test_simple(): - -class ABC(SimpleTaskEngine): - -def task_A(self): -pass - -task_A.task_deps = ['B', '?C'] - -def task_B(self): -pass - -def task_C(self): -pass - -task_C.task_deps = ['B'] - -def task_D(self): -pass -task_D.task_deps = ['E'] - -def task_E(self): -pass -task_E.task_deps = ['F'] - -def task_F(self): -pass - -abc = ABC() - -assert abc._plan('B') == ['B
[pypy-commit] pypy real-mode-translator-driver: Quit early if there is nothing to do
Author: William ML Leslie Branch: real-mode-translator-driver Changeset: r89725:6429b253dfd2 Date: 2017-01-24 21:45 +1100 http://bitbucket.org/pypy/pypy/changeset/6429b253dfd2/ Log:Quit early if there is nothing to do diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -192,6 +192,9 @@ def _proceed_inner(self, goals): backend, ts = self.get_backend_and_type_system() goals = set(self.backend_select_goals(goals + self.extra_goals)) +if not goals: +self.log('Nothing to do.') +raise Done(None) if any(cgoal in goals for bakgoal in ['database', 'source', 'compile'] ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] extradoc extradoc: Leysin 2017
Author: Armin Rigo Branch: extradoc Changeset: r5764:7a0473301e83 Date: 2017-01-24 11:54 +0100 http://bitbucket.org/pypy/extradoc/changeset/7a0473301e83/ Log:Leysin 2017 diff --git a/sprintinfo/leysin-winter-2017/announcement.txt b/sprintinfo/leysin-winter-2017/announcement.txt new file mode 100644 --- /dev/null +++ b/sprintinfo/leysin-winter-2017/announcement.txt @@ -0,0 +1,74 @@ += + PyPy Leysin Winter Sprint (25/26th Feb. - 4th March 2016) += + +The next PyPy sprint will be in Leysin, Switzerland, for the twelveth time. +This is a fully public sprint: newcomers and topics other than those +proposed below are welcome. + +-- +Goals and topics of the sprint +-- + +The list of topics is very open. + +* The main topic is Python 3.5 support in PyPy, as most py3.5 + contributors should be present. It is also a good topic if you have + no or limited experience with PyPy contribution: we can easily find + something semi-independent that is not done in py3.5 so far, and + do pair-programming with you. + +* Any other topic is fine too: JIT compiler optimizations, CFFI, + the RevDB reverse debugger, improving to speed of your program on + PyPy, etc. + +* And as usual, the main side goal is to have fun in winter sports :-) + We can take a day off (for ski or anything else). + +--- +Exact times +--- + +Work days: starting 26th Feb (~noon), ending March 4th (~noon). + +I have pre-booked the week from Saturday Feb 25th to Saturday March 4th. +If it is possible for you to arrive Sunday before mid-afternoon, then +you should get a booking from Sunday only. The break day should be +around Wednesday. + +It is fine to stay a few more days on either side, or conversely to book +for a part of that time only. + +--- +Location & Accomodation +--- + +Leysin, Switzerland, "same place as before". Let me refresh your +memory: both the sprint venue and the lodging will be in a +pair of chalets built specifically for bed & breakfast: +http://www.ermina.ch/. The place has a good ADSL Internet connection +with wireless installed. You can also arrange your own lodging +elsewhere (as long as you are in Leysin, you cannot be more than a 15 +minutes walk away from the sprint venue). + +Please *confirm* that you are coming so that we can adjust the +reservations as appropriate. + +The options of rooms are a bit more limited than on previous years +because the place for bed-and-breakfast is shrinking; but we should +still have enough room for us. The price is around 60 CHF, breakfast +included, in shared rooms (3 or 4 people). If there are people that +would prefer a double or single room, please contact me and we'll see +what choices you have. There are also a choice of hotels in Leysin. + +Please register by Mercurial:: + + https://bitbucket.org/pypy/extradoc/ + https://bitbucket.org/pypy/extradoc/raw/extradoc/sprintinfo/leysin-winter-2017 + +or on the pypy-dev mailing list if you do not yet have check-in rights: + + http://mail.python.org/mailman/listinfo/pypy-dev + +You need a Swiss-to-(insert country here) power adapter. There will be +some Swiss-to-EU adapters around, and at least one EU-format power strip. diff --git a/sprintinfo/leysin-winter-2017/people.txt b/sprintinfo/leysin-winter-2017/people.txt new file mode 100644 --- /dev/null +++ b/sprintinfo/leysin-winter-2017/people.txt @@ -0,0 +1,25 @@ + +People coming to the Leysin sprint Winter 2016 +== + +People who have a ``?`` in their arrive/depart or accomodation +column are known to be coming but there are no details +available yet from them. + + == === +Name Arrive/Depart Accomodation + == === +Armin Rigo private + == === + +**NOTE:** lodging is by default in Ermina. There are two ~4 people +rooms as well as smaller rooms on demand. (Individual rooms should be +available if needed, but ask Armin Rigo.) + +Of course you're free to book a different hotel yourself if you prefer. + +The standard booking is for the nights from Saturday to Saturday, but it +is possible to extend that. If it is possible for you to arrive Sunday +not too late, then you should get a booking from Sunday only. We'll +work from Sunday noon-ish to the next Saturday (with a break day in the +middle of the week). ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] extradoc extradoc: typo
Author: Armin Rigo Branch: extradoc Changeset: r5765:fcf6157938b6 Date: 2017-01-24 11:56 +0100 http://bitbucket.org/pypy/extradoc/changeset/fcf6157938b6/ Log:typo diff --git a/sprintinfo/leysin-winter-2017/announcement.txt b/sprintinfo/leysin-winter-2017/announcement.txt --- a/sprintinfo/leysin-winter-2017/announcement.txt +++ b/sprintinfo/leysin-winter-2017/announcement.txt @@ -1,5 +1,5 @@ = - PyPy Leysin Winter Sprint (25/26th Feb. - 4th March 2016) + PyPy Leysin Winter Sprint (25/26th Feb. - 4th March 2017) = The next PyPy sprint will be in Leysin, Switzerland, for the twelveth time. diff --git a/sprintinfo/leysin-winter-2017/people.txt b/sprintinfo/leysin-winter-2017/people.txt --- a/sprintinfo/leysin-winter-2017/people.txt +++ b/sprintinfo/leysin-winter-2017/people.txt @@ -1,5 +1,5 @@ -People coming to the Leysin sprint Winter 2016 +People coming to the Leysin sprint Winter 2017 == People who have a ``?`` in their arrive/depart or accomodation ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] extradoc extradoc: update link
Author: Armin Rigo Branch: extradoc Changeset: r5766:37959844c889 Date: 2017-01-24 12:03 +0100 http://bitbucket.org/pypy/extradoc/changeset/37959844c889/ Log:update link diff --git a/sprintinfo/leysin-winter-2017/announcement.txt b/sprintinfo/leysin-winter-2017/announcement.txt --- a/sprintinfo/leysin-winter-2017/announcement.txt +++ b/sprintinfo/leysin-winter-2017/announcement.txt @@ -64,7 +64,7 @@ Please register by Mercurial:: https://bitbucket.org/pypy/extradoc/ - https://bitbucket.org/pypy/extradoc/raw/extradoc/sprintinfo/leysin-winter-2017 + https://bitbucket.org/pypy/extradoc/raw/extradoc/sprintinfo/leysin-winter-2017/ or on the pypy-dev mailing list if you do not yet have check-in rights: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5-fstring-pep498: test and fix + tweaks
Author: Armin Rigo Branch: py3.5-fstring-pep498 Changeset: r89726:086cef12dead Date: 2017-01-24 12:19 +0100 http://bitbucket.org/pypy/pypy/changeset/086cef12dead/ Log:test and fix + tweaks diff --git a/pypy/interpreter/astcompiler/fstring.py b/pypy/interpreter/astcompiler/fstring.py --- a/pypy/interpreter/astcompiler/fstring.py +++ b/pypy/interpreter/astcompiler/fstring.py @@ -50,8 +50,10 @@ consts.PyCF_SOURCE_IS_UTF8 | consts.PyCF_IGNORE_COOKIE, optimize=astbuilder.compile_info.optimize) -parse_tree = astbuilder.recursive_parser.parse_source(source, info) -return ast_from_node(astbuilder.space, parse_tree, info) +parser = astbuilder.recursive_parser +parse_tree = parser.parse_source(source, info) +return ast_from_node(astbuilder.space, parse_tree, info, + recursive_parser=parser) def unexpected_end_of_string(astbuilder, atom_node): @@ -257,7 +259,8 @@ fstr.current_index = i literal = builder.build() -if not fstr.raw_mode: +if not fstr.raw_mode and u'\\' in literal: +literal = literal.encode('utf-8') literal = unicodehelper.decode_unicode_escape(astbuilder.space, literal) return literal @@ -281,7 +284,10 @@ def parse_f_string(astbuilder, joined_pieces, fstr, atom_node, rec=0): -space = astbuilder.space +# In our case, parse_f_string() and fstring_find_literal_and_expr() +# could be merged into a single function with a clearer logic. It's +# done this way to follow CPython's source code more closely. + while True: literal, expr = fstring_find_literal_and_expr(astbuilder, fstr, atom_node, rec) diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -1184,6 +1184,8 @@ yield self.st, """z=f'{"}"}'""", 'z', '}' +yield self.st, """z=f'{f"{0}"*3}'""", 'z', '000' + def test_fstring_error(self): raises(SyntaxError, self.run, "f'{}'") raises(SyntaxError, self.run, "f'{ \t }'") ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy real-mode-translator-driver: Call the dependent function before running your task. Straightforward.
Author: William ML Leslie Branch: real-mode-translator-driver Changeset: r89728:8ffe9002f13b Date: 2017-01-24 22:50 +1100 http://bitbucket.org/pypy/pypy/changeset/8ffe9002f13b/ Log:Call the dependent function before running your task. Straightforward. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -17,8 +17,6 @@ log = AnsiLogger("translation") -class Done(Exception): pass - # TODO: # sanity-checks using states @@ -84,28 +82,57 @@ self.extra_goals = [] def annotate(self): -return self.proceed(['annotate']) +return self.run_task(self.task_annotate, 'annotate') def rtype_lltype(self): -return self.proceed(['rtype_lltype']) +self.annotate() +return self.run_task(self.task_rtype_lltype, 'rtype_lltype') + +def pyjitpl_lltype(self): +self.rtype_lltype() +return self.run_task(self.task_pyjitpl_lltype, 'pyjitpl_lltype') + +def jittest_lltype(self): +self.rtype_lltype() +return self.run_task(self.task_jittest_lltype, 'jittest_lltype') def backendopt_lltype(self): -return self.proceed(['backendopt_lltype']) +self.rtype_lltype() +if 'pyjitpl' in self.extra_goals: +self.pyjitpl_lltype() +if 'jittest' in self.extra_goals: +self.jittest_lltype() + +return self.run_task(self.task_backendopt_lltype, + 'backendopt_lltype') + +def stackcheckinsertion_lltype(self): +self.rtype_lltype() +if 'backendopt' in self.extra_goals: +self.backendopt_lltype() +return self.run_task(self.task_stackcheckinsertion_lltype, + 'stackcheckinsertion_lltype') def llinterpret_lltype(self): -return self.proceed(['llinterpret_lltype']) - -def pyjitpl_lltype(self): -return self.proceed(['pyjitpl_lltype']) +self.stackcheckinsertion_lltype() +return self.run_task(self.task_llinterpret_lltype, + 'llinterpret_lltype') def source_c(self): -return self.proceed(['source_c']) +if 'check_for_boehm' not in self.done: +self.possibly_check_for_boehm() +self.done.add('check_for_boehm') +self.stackcheckinsertion_lltype() +self.run_task(self.task_database_c, 'database_c') +return self.run_task(self.task_source_c, 'source_c') def compile_c(self): -return self.proceed(['compile_c']) +self.source_c() +return self.run_task(self.task_compile_c, 'compile_c') def run_c(self): -return self.proceed(['run_c']) +self.compile_c() +return self.run_task(self.task_run_c, 'run_c') def set_extra_goals(self, goals): self.extra_goals = goals @@ -122,7 +149,7 @@ backend = self.config.translation.backend return backend, type_system -def run_task(self, name, goals, *args, **kwargs): +def run_task(self, task, name, *args, **kwargs): if name in self.done or name in self._disabled: return task = getattr(self, 'task_%s' % name) @@ -157,47 +184,21 @@ self.log.info('usession directory: %s' % (udir,)) self.done.add(name) -goals.discard(name) -if not goals: -raise Done(res) return res def proceed(self, goals): -try: -self._proceed_inner(goals) -except Done as d: -return d.args[0] - -def _proceed_inner(self, goals): backend, ts = self.get_backend_and_type_system() goals = set(self.backend_select_goals(goals + self.extra_goals)) if not goals: self.log('Nothing to do.') -raise Done(None) +self.extra_goals += goals -if any(cgoal in goals - for bakgoal in ['database', 'source', 'compile'] - for cgoal in [bakgoal, bakgoal + '_c']): -if 'check_for_boehm' not in self.done: -self.possibly_check_for_boehm() -self.done.add('check_for_boehm') - -self.run_task('annotate', goals) -self.run_task('rtype_lltype', goals) -if 'pyjitpl_lltype' in goals or 'jittest_lltype' in goals: -self.run_task('pyjitpl_lltype', goals) -if 'jittest_lltype' in goals: -self.run_task('jittest_lltype', goals) -self.run_task('backendopt_lltype', goals) -self.run_task('stackcheckinsertion_lltype', goals) -if 'llinterpret_lltype' in goals: -self.run_task('llinterpret_lltype', goals) -self.run_task('backend_%s' % backend, goals, goals) - -def task_backend_c(self, goals): -self.run_task('database_c', goals) -self.run_task('source_c', goals) -self.run_task('compile_c', goals) +# run C goals fi
[pypy-commit] pypy real-mode-translator-driver: Remove unused methods
Author: William ML Leslie Branch: real-mode-translator-driver Changeset: r89727:7cff1328be02 Date: 2017-01-24 21:59 +1100 http://bitbucket.org/pypy/pypy/changeset/7cff1328be02/ Log:Remove unused methods diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -86,18 +86,6 @@ def annotate(self): return self.proceed(['annotate']) -def rtype(self): -return self.proceed(['rtype']) - -def backendopt(self): -return self.proceed(['backendopt']) - -def llinterpret(self): -return self.proceed(['llinterpret']) - -def pyjitpl(self): -return self.proceed(['pyjitpl']) - def rtype_lltype(self): return self.proceed(['rtype_lltype']) @@ -110,15 +98,6 @@ def pyjitpl_lltype(self): return self.proceed(['pyjitpl_lltype']) -def source(self): -return self.proceed(['source']) - -def compile(self): -return self.proceed(['compile']) - -def run(self): -return self.proceed(['run']) - def source_c(self): return self.proceed(['source_c']) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy real-mode-translator-driver: Move backend_select_goals up near get_backend_and_type_system to be less confusing
Author: William ML Leslie Branch: real-mode-translator-driver Changeset: r89729:fa9749741225 Date: 2017-01-24 22:56 +1100 http://bitbucket.org/pypy/pypy/changeset/fa9749741225/ Log:Move backend_select_goals up near get_backend_and_type_system to be less confusing diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -149,6 +149,27 @@ backend = self.config.translation.backend return backend, type_system +def backend_select_goals(self, goals): +backend, ts = self.get_backend_and_type_system() +result = [] +for goal in goals: +names = ['task_%s_%s' % (goal, backend), + 'task_%s_%s' % (goal, ts), + 'task_%s' % (goal,)] +if set(names).intersection(self.done): +continue +for name in names: +task = getattr(self, name, None) +if task is not None: +result.append(name[len('task_'):]) +break +else: +raise Exception("cannot infer complete goal from: %r" % goal) +return result + +def disable(self, to_disable): +self._disabled = to_disable + def run_task(self, task, name, *args, **kwargs): if name in self.done or name in self._disabled: return @@ -200,27 +221,6 @@ for goal in goals: getattr(self, goal)() -def backend_select_goals(self, goals): -backend, ts = self.get_backend_and_type_system() -result = [] -for goal in goals: -names = ['task_%s_%s' % (goal, backend), - 'task_%s_%s' % (goal, ts), - 'task_%s' % (goal,)] -if set(names).intersection(self.done): -continue -for name in names: -task = getattr(self, name, None) -if task is not None: -result.append(name[len('task_'):]) -break -else: -raise Exception("cannot infer complete goal from: %r" % goal) -return result - -def disable(self, to_disable): -self._disabled = to_disable - def setup(self, entry_point, inputtypes, policy=None, extra={}, empty_translator=None): standalone = inputtypes is None self.standalone = standalone ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Update to cffi/b0204d9d8b96
Author: Armin Rigo Branch: Changeset: r89730:c30204eb6247 Date: 2017-01-24 13:04 +0100 http://bitbucket.org/pypy/pypy/changeset/c30204eb6247/ Log:Update to cffi/b0204d9d8b96 diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.9.2 +Version: 1.10.0 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -1,11 +1,11 @@ __all__ = ['FFI', 'VerificationError', 'VerificationMissing', 'CDefError', 'FFIError'] -from .api import FFI, CDefError, FFIError -from .ffiplatform import VerificationError, VerificationMissing +from .api import FFI +from .error import CDefError, FFIError, VerificationError, VerificationMissing -__version__ = "1.9.2" -__version_info__ = (1, 9, 2) +__version__ = "1.10.0" +__version_info__ = (1, 10, 0) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -233,7 +233,7 @@ f = PySys_GetObject((char *)"stderr"); if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.9.2" + "\ncompiled with cffi version: 1.10.0" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -1,5 +1,7 @@ import sys, types from .lock import allocate_lock +from .error import CDefError +from . import model try: callable @@ -15,17 +17,6 @@ basestring = str -class FFIError(Exception): -pass - -class CDefError(Exception): -def __str__(self): -try: -line = 'line %d: ' % (self.args[1].coord.line,) -except (AttributeError, TypeError, IndexError): -line = '' -return '%s%s' % (line, self.args[0]) - class FFI(object): r''' @@ -49,18 +40,27 @@ """Create an FFI instance. The 'backend' argument is used to select a non-default backend, mostly for tests. """ -from . import cparser, model if backend is None: # You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ -assert backend.__version__ == __version__, \ - "version mismatch, %s != %s" % (backend.__version__, __version__) +if backend.__version__ != __version__: +# bad version! Try to be as explicit as possible. +if hasattr(backend, '__file__'): +# CPython +raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. When we import the top-level '_cffi_backend' extension module, we get version %s, located in %r. The two versions should be equal; check your installation." % ( +__version__, __file__, +backend.__version__, backend.__file__)) +else: +# PyPy +raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. This interpreter comes with a built-in '_cffi_backend' module, which is version %s. The two versions should be equal; check your installation." % ( +__version__, __file__, backend.__version__)) # (If you insist you can also try to pass the option # 'backend=backend_ctypes.CTypesBackend()', but don't # rely on it! It's probably not going to work well.) +from . import cparser self._backend = backend self._lock = allocate_lock() self._parser = cparser.Parser() @@ -212,7 +212,7 @@ def offsetof(self, cdecl, *fields_or_indexes): """Return the offset of the named field inside the given -structure or array, which must be given as a C type name. +structure or array, which must be given as a C type name. You can give several field names in case of nested structures. You can also give numeric values which correspond to array items, in case of an array type. @@ -300,7 +300,7 @@ return self._backend.string(cdata, maxlen) def unpack(self, cdata, length): -
[pypy-commit] pypy default: cffi issue300: return _Bool as Python booleans; related fixes
Author: Armin Rigo Branch: Changeset: r89731:b07132257e83 Date: 2017-01-24 13:32 +0100 http://bitbucket.org/pypy/pypy/changeset/b07132257e83/ Log:cffi issue300: return _Bool as Python booleans; related fixes diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -370,6 +370,19 @@ # bypass the method 'string' implemented in W_CTypePrimitive return W_CType.string(self, cdataobj, maxlen) +def convert_to_object(self, cdata): +space = self.space +value = ord(cdata[0]) +if value < 2: +return space.newbool(value != 0) +else: +raise oefmt(space.w_ValueError, +"got a _Bool of value %d, expected 0 or 1", +value) + +def unpack_list_of_int_items(self, ptr, length): +return None + class W_CTypePrimitiveFloat(W_CTypePrimitive): _attrs_ = [] diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -82,6 +82,8 @@ raise oefmt(space.w_IndexError, "initializer string is too long for '%s' (got %d " "characters)", self.name, n) +if isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool): +self._must_be_string_of_zero_or_one(s) copy_string_to_raw(llstr(s), cdata, 0, n) if n != self.length: cdata[n] = '\x00' @@ -101,9 +103,16 @@ else: raise self._convert_error("list or tuple", w_ob) +def _must_be_string_of_zero_or_one(self, s): +for c in s: +if ord(c) > 1: +raise oefmt(self.space.w_ValueError, +"an array of _Bool can only contain \\x00 or \\x01") + def string(self, cdataobj, maxlen): space = self.space -if isinstance(self.ctitem, ctypeprim.W_CTypePrimitive): +if (isinstance(self.ctitem, ctypeprim.W_CTypePrimitive) and + not isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool)): with cdataobj as ptr: if not ptr: raise oefmt(space.w_RuntimeError, @@ -283,6 +292,8 @@ if self.accept_str and space.isinstance_w(w_init, space.w_str): # special case to optimize strings passed to a "char *" argument value = w_init.str_w(space) +if isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool): +self._must_be_string_of_zero_or_one(value) keepalives[i] = value buf, buf_flag = rffi.get_nonmovingbuffer_final_null(value) rffi.cast(rffi.CCHARPP, cdata)[0] = buf diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -885,6 +885,15 @@ py.test.raises(OverflowError, f, 128, 0) py.test.raises(OverflowError, f, 0, 128) +def test_call_function_0_pretend_bool_result(): +BSignedChar = new_primitive_type("signed char") +BBool = new_primitive_type("_Bool") +BFunc0 = new_function_type((BSignedChar, BSignedChar), BBool, False) +f = cast(BFunc0, _testfunc(0)) +assert f(40, -39) is True +assert f(40, -40) is False +py.test.raises(ValueError, f, 40, 2) + def test_call_function_1(): BInt = new_primitive_type("int") BLong = new_primitive_type("long") @@ -1047,6 +1056,17 @@ res = f(b"foo") assert res == 1000 * ord(b'f') +def test_call_function_23_bool_array(): +# declaring the function as int(_Bool*) +BBool = new_primitive_type("_Bool") +BBoolP = new_pointer_type(BBool) +BInt = new_primitive_type("int") +BFunc23 = new_function_type((BBoolP,), BInt, False) +f = cast(BFunc23, _testfunc(23)) +res = f(b"\x01\x01") +assert res == 1000 +py.test.raises(ValueError, f, b"\x02\x02") + def test_cannot_pass_struct_with_array_of_length_0(): BInt = new_primitive_type("int") BArray0 = new_array_type(new_pointer_type(BInt), 0) @@ -2617,13 +2637,38 @@ py.test.raises(OverflowError, newp, BBoolP, 2) py.test.raises(OverflowError, newp, BBoolP, -1) BCharP = new_pointer_type(new_primitive_type("char")) -p = newp(BCharP, b'X') +p = newp(BCharP, b'\x01') q = cast(BBoolP, p) -assert q[0] == ord(b'X') +assert q[0] is True +p = newp(BCharP, b'\x00') +q = cast(BBoolP, p) +assert q[0] is False py.test.raises(TypeError, string, cast(BBool, False)) BDouble = new_primitive_type("double") assert int(cast(BBool, cast(BDouble, 0.1))) == 1 assert int(cast(BBool, cast(BDouble, 0.0))) == 0 +BBoolA = new_array_type(BBoo
[pypy-commit] cffi default: reintroduce a fast case for ffi.unpack(arrays of _Bool)
Author: Armin Rigo Branch: Changeset: r2872:19591d33fdb2 Date: 2017-01-24 13:56 +0100 http://bitbucket.org/cffi/cffi/changeset/19591d33fdb2/ Log:reintroduce a fast case for ffi.unpack(arrays of _Bool) diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -5944,12 +5944,12 @@ else if (itemsize == sizeof(short)) casenum = 1; else if (itemsize == sizeof(signed char)) casenum = 0; } -else if ((ctitem->ct_flags & (CT_PRIMITIVE_UNSIGNED | CT_IS_BOOL)) - == CT_PRIMITIVE_UNSIGNED) { +else if (ctitem->ct_flags & CT_PRIMITIVE_UNSIGNED) { /* Note: we never pick case 6 if sizeof(int) == sizeof(long), so that case 6 below can assume that the 'unsigned int' result would always fit in a 'signed long'. */ -if (itemsize == sizeof(unsigned long)) casenum = 7; +if (ctitem->ct_flags & CT_IS_BOOL) casenum = 11; +else if (itemsize == sizeof(unsigned long)) casenum = 7; else if (itemsize == sizeof(unsigned int)) casenum = 6; else if (itemsize == sizeof(unsigned short)) casenum = 5; else if (itemsize == sizeof(unsigned char)) casenum = 4; @@ -5982,6 +5982,13 @@ case 8: x = PyFloat_FromDouble(*(float *)src); break; case 9: x = PyFloat_FromDouble(*(double *)src); break; case 10: x = new_simple_cdata(*(char **)src, ctitem); break; +case 11: +switch (*(unsigned char *)src) { +case 0: x = Py_False; Py_INCREF(x); break; +case 1: x = Py_True; Py_INCREF(x); break; +default: x = convert_to_object(src, ctitem); /* error */ +} +break; } if (x == NULL) { Py_DECREF(result); ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: fix tests
Author: Ronan Lamy Branch: py3.5 Changeset: r89732:321e73239593 Date: 2017-01-24 14:02 + http://bitbucket.org/pypy/pypy/changeset/321e73239593/ Log:fix tests diff --git a/pypy/module/cpyext/test/test_memoryobject.py b/pypy/module/cpyext/test/test_memoryobject.py --- a/pypy/module/cpyext/test/test_memoryobject.py +++ b/pypy/module/cpyext/test/test_memoryobject.py @@ -13,8 +13,8 @@ w_hello = space.newbytes("hello") #assert api.PyObject_CheckBuffer(w_hello) w_view = from_ref(space, api.PyMemoryView_FromObject(w_hello)) -w_char = space.call_method(w_view, '__getitem__', space.wrap(0)) -assert space.eq_w(w_char, space.wrap('h')) +w_byte = space.call_method(w_view, '__getitem__', space.wrap(0)) +assert space.eq_w(w_byte, space.wrap(ord('h'))) w_bytes = space.call_method(w_view, "tobytes") assert space.unwrap(w_bytes) == "hello" @@ -72,7 +72,6 @@ class AppTestBufferProtocol(AppTestCpythonExtensionBase): def test_buffer_protocol_app(self): -import struct module = self.import_module(name='buffer_test') arr = module.PyMyArray(10) y = memoryview(arr) @@ -80,8 +79,7 @@ assert y.shape == (10,) assert len(y) == 10 s = y[3] -assert len(s) == struct.calcsize('i') -assert s == struct.pack('i', 3) +assert s == 3 def test_buffer_protocol_capi(self): foo = self.import_extension('foo', [ ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: Fix type creation in test
Author: Ronan Lamy Branch: py3.5 Changeset: r89733:0e5a44ac25a3 Date: 2017-01-24 14:11 + http://bitbucket.org/pypy/pypy/changeset/0e5a44ac25a3/ Log:Fix type creation in test diff --git a/pypy/module/cpyext/test/test_userslots.py b/pypy/module/cpyext/test/test_userslots.py --- a/pypy/module/cpyext/test/test_userslots.py +++ b/pypy/module/cpyext/test/test_userslots.py @@ -42,7 +42,7 @@ w_year = space.getattr(w_obj, space.newbytes('year')) assert space.int_w(w_year) == 1 -w_obj = generic_cpy_call(space, py_datetype.c_tp_new, py_datetype, +w_obj = generic_cpy_call(space, py_datetype.c_tp_new, py_datetype, arg, space.newdict({})) w_year = space.getattr(w_obj, space.newbytes('year')) assert space.int_w(w_year) == 1 @@ -137,25 +137,23 @@ return datetime_cls->tp_new(t, a, k); } -static void +static void _timestamp_dealloc(PyObject *op) { foocnt --; datetime_cls->tp_dealloc(op); } - + static PyTypeObject _Timestamp = { -PyObject_HEAD_INIT(NULL) -0,/* ob_size */ +PyVarObject_HEAD_INIT(NULL, 0) "foo._Timestamp", /* tp_name*/ 0, /* tp_basicsize*/ 0, /* tp_itemsize */ _timestamp_dealloc /* tp_dealloc */ }; static PyTypeObject Timestamp = { -PyObject_HEAD_INIT(NULL) -0,/* ob_size */ +PyVarObject_HEAD_INIT(NULL, 0) "foo.Timestamp", /* tp_name*/ 0, /* tp_basicsize*/ 0 /* tp_itemsize */ @@ -164,7 +162,7 @@ PyObject * mod1 = PyImport_ImportModule("datetime"); if (mod1 == NULL) INITERROR; PyObject * dt = PyUnicode_FromString("datetime"); -datetime_cls = (PyTypeObject*)PyObject_GetAttr(mod1, dt); +datetime_cls = (PyTypeObject*)PyObject_GetAttr(mod1, dt); if (datetime_cls == NULL) INITERROR; _Timestamp.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; _Timestamp.tp_base = datetime_cls; @@ -179,7 +177,7 @@ Timestamp.tp_dealloc = datetime_cls->tp_dealloc; if (PyType_Ready(&Timestamp) < 0) INITERROR; ''') -# _Timestamp has __new__, __del__ and +# _Timestamp has __new__, __del__ and # inherits from datetime.datetime # Timestamp has __new__, default __del__ (subtype_dealloc) and # inherits from _Timestamp ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fix type creation in test
Author: Ronan Lamy Branch: Changeset: r89734:4dbc89b22496 Date: 2017-01-24 14:11 + http://bitbucket.org/pypy/pypy/changeset/4dbc89b22496/ Log:Fix type creation in test (grafted from 0e5a44ac25a3501025d3198b7d6806672182aff0) diff --git a/pypy/module/cpyext/test/test_userslots.py b/pypy/module/cpyext/test/test_userslots.py --- a/pypy/module/cpyext/test/test_userslots.py +++ b/pypy/module/cpyext/test/test_userslots.py @@ -42,7 +42,7 @@ w_year = space.getattr(w_obj, space.newbytes('year')) assert space.int_w(w_year) == 1 -w_obj = generic_cpy_call(space, py_datetype.c_tp_new, py_datetype, +w_obj = generic_cpy_call(space, py_datetype.c_tp_new, py_datetype, arg, space.newdict({})) w_year = space.getattr(w_obj, space.newbytes('year')) assert space.int_w(w_year) == 1 @@ -137,25 +137,23 @@ return datetime_cls->tp_new(t, a, k); } -static void +static void _timestamp_dealloc(PyObject *op) { foocnt --; datetime_cls->tp_dealloc(op); } - + static PyTypeObject _Timestamp = { -PyObject_HEAD_INIT(NULL) -0,/* ob_size */ +PyVarObject_HEAD_INIT(NULL, 0) "foo._Timestamp", /* tp_name*/ 0, /* tp_basicsize*/ 0, /* tp_itemsize */ _timestamp_dealloc /* tp_dealloc */ }; static PyTypeObject Timestamp = { -PyObject_HEAD_INIT(NULL) -0,/* ob_size */ +PyVarObject_HEAD_INIT(NULL, 0) "foo.Timestamp", /* tp_name*/ 0, /* tp_basicsize*/ 0 /* tp_itemsize */ @@ -179,7 +177,7 @@ Timestamp.tp_dealloc = datetime_cls->tp_dealloc; if (PyType_Ready(&Timestamp) < 0) INITERROR; ''') -# _Timestamp has __new__, __del__ and +# _Timestamp has __new__, __del__ and # inherits from datetime.datetime # Timestamp has __new__, default __del__ (subtype_dealloc) and # inherits from _Timestamp ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5-fstring-pep498: test and fix
Author: Armin Rigo Branch: py3.5-fstring-pep498 Changeset: r89735:9069e5841365 Date: 2017-01-24 15:20 +0100 http://bitbucket.org/pypy/pypy/changeset/9069e5841365/ Log:test and fix diff --git a/pypy/interpreter/astcompiler/fstring.py b/pypy/interpreter/astcompiler/fstring.py --- a/pypy/interpreter/astcompiler/fstring.py +++ b/pypy/interpreter/astcompiler/fstring.py @@ -260,8 +260,12 @@ fstr.current_index = i literal = builder.build() if not fstr.raw_mode and u'\\' in literal: +# xxx messy +space = astbuilder.space literal = literal.encode('utf-8') -literal = unicodehelper.decode_unicode_escape(astbuilder.space, literal) +literal = parsestring.decode_unicode_utf8(space, literal, 0, + len(literal)) +literal = unicodehelper.decode_unicode_escape(space, literal) return literal @@ -328,22 +332,26 @@ space = astbuilder.space encoding = astbuilder.compile_info.encoding joined_pieces = [] -for i in range(atom_node.num_children()): -try: +try: +for i in range(atom_node.num_children()): w_next = parsestring.parsestr( space, encoding, atom_node.get_child(i).get_value()) -except error.OperationError as e: -if not (e.match(space, space.w_UnicodeError) or -e.match(space, space.w_ValueError)): -raise -# Unicode/ValueError in literal: turn into SyntaxError -raise astbuilder.error(e.errorstr(space), atom_node) -if not isinstance(w_next, parsestring.W_FString): -add_constant_string(astbuilder, joined_pieces, w_next, atom_node) -else: -parse_f_string(astbuilder, joined_pieces, w_next, atom_node) +if not isinstance(w_next, parsestring.W_FString): +add_constant_string(astbuilder, joined_pieces, w_next, +atom_node) +else: +parse_f_string(astbuilder, joined_pieces, w_next, atom_node) + +except error.OperationError as e: +if not (e.match(space, space.w_UnicodeError) or +e.match(space, space.w_ValueError)): +raise +# Unicode/ValueError in literal: turn into SyntaxError +raise astbuilder.error(e.errorstr(space), atom_node) + if len(joined_pieces) == 1: # <= the common path return joined_pieces[0] # ast.Str, Bytes or FormattedValue + # with more than one piece, it is a combination of Str and # FormattedValue pieces---if there is a Bytes, then we got # an invalid mixture of bytes and unicode literals diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -1192,6 +1192,7 @@ raises(SyntaxError, self.run, "f'{5#}'") raises(SyntaxError, self.run, "f'{5)#}'") raises(SyntaxError, self.run, "f'''{5)\n#}'''") +raises(SyntaxError, self.run, "f'\\x'") class AppTestCompiler: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: merge heads
Author: Armin Rigo Branch: Changeset: r89738:2a1d5f7642dc Date: 2017-01-24 15:41 +0100 http://bitbucket.org/pypy/pypy/changeset/2a1d5f7642dc/ Log:merge heads diff --git a/pypy/module/cpyext/test/test_userslots.py b/pypy/module/cpyext/test/test_userslots.py --- a/pypy/module/cpyext/test/test_userslots.py +++ b/pypy/module/cpyext/test/test_userslots.py @@ -42,7 +42,7 @@ w_year = space.getattr(w_obj, space.newbytes('year')) assert space.int_w(w_year) == 1 -w_obj = generic_cpy_call(space, py_datetype.c_tp_new, py_datetype, +w_obj = generic_cpy_call(space, py_datetype.c_tp_new, py_datetype, arg, space.newdict({})) w_year = space.getattr(w_obj, space.newbytes('year')) assert space.int_w(w_year) == 1 @@ -137,25 +137,23 @@ return datetime_cls->tp_new(t, a, k); } -static void +static void _timestamp_dealloc(PyObject *op) { foocnt --; datetime_cls->tp_dealloc(op); } - + static PyTypeObject _Timestamp = { -PyObject_HEAD_INIT(NULL) -0,/* ob_size */ +PyVarObject_HEAD_INIT(NULL, 0) "foo._Timestamp", /* tp_name*/ 0, /* tp_basicsize*/ 0, /* tp_itemsize */ _timestamp_dealloc /* tp_dealloc */ }; static PyTypeObject Timestamp = { -PyObject_HEAD_INIT(NULL) -0,/* ob_size */ +PyVarObject_HEAD_INIT(NULL, 0) "foo.Timestamp", /* tp_name*/ 0, /* tp_basicsize*/ 0 /* tp_itemsize */ @@ -179,7 +177,7 @@ Timestamp.tp_dealloc = datetime_cls->tp_dealloc; if (PyType_Ready(&Timestamp) < 0) INITERROR; ''') -# _Timestamp has __new__, __del__ and +# _Timestamp has __new__, __del__ and # inherits from datetime.datetime # Timestamp has __new__, default __del__ (subtype_dealloc) and # inherits from _Timestamp ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: test and fix
Author: Armin Rigo Branch: Changeset: r89736:ad54ed3f27d2 Date: 2017-01-24 15:31 +0100 http://bitbucket.org/pypy/pypy/changeset/ad54ed3f27d2/ Log:test and fix diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py --- a/pypy/interpreter/astcompiler/astbuilder.py +++ b/pypy/interpreter/astcompiler/astbuilder.py @@ -1104,8 +1104,9 @@ if not e.match(space, space.w_UnicodeError): raise # UnicodeError in literal: turn into SyntaxError -self.error(e.errorstr(space), atom_node) -sub_strings_w = [] # please annotator +e.normalize_exception(space) +errmsg = space.str_w(space.str(e.get_w_value(space))) +raise self.error('(unicode error) %s' % errmsg, atom_node) # This implements implicit string concatenation. if len(sub_strings_w) > 1: w_sub_strings = space.newlist(sub_strings_w) diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -1240,3 +1240,9 @@ if1, if2 = comps[0].ifs assert isinstance(if1, ast.Name) assert isinstance(if2, ast.Name) + +def test_decode_error_in_string_literal(self): +input = "u'\\x'" +exc = py.test.raises(SyntaxError, self.get_ast, input).value +assert exc.msg == ("(unicode error) 'unicodeescape' codec can't decode" + " bytes in position 0-1: truncated \\xXX escape") ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: OperationError.errorstr() gave results depending on whether the exception
Author: Armin Rigo Branch: Changeset: r89737:a6f3468a583e Date: 2017-01-24 15:40 +0100 http://bitbucket.org/pypy/pypy/changeset/a6f3468a583e/ Log:OperationError.errorstr() gave results depending on whether the exception was already normalized or not. Fix diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -71,6 +71,7 @@ def errorstr(self, space, use_repr=False): "The exception class and value, as a string." +self.normalize_exception(space) w_value = self.get_w_value(space) if space is None: # this part NOT_RPYTHON diff --git a/pypy/interpreter/test/test_error.py b/pypy/interpreter/test/test_error.py --- a/pypy/interpreter/test/test_error.py +++ b/pypy/interpreter/test/test_error.py @@ -81,7 +81,18 @@ def test_errorstr(space): operr = OperationError(space.w_ValueError, space.wrap("message")) assert operr.errorstr(space) == "ValueError: message" -assert operr.errorstr(space, use_repr=True) == "ValueError: 'message'" +assert operr.errorstr(space, use_repr=True) == ( +"ValueError: ValueError('message',)") +operr = OperationError(space.w_ValueError, space.w_None) +assert operr.errorstr(space) == "ValueError" +operr = OperationError(space.w_ValueError, +space.newtuple([space.wrap(6), space.wrap(7)])) +assert operr.errorstr(space) == "ValueError: (6, 7)" +operr = OperationError(space.w_UnicodeDecodeError, +space.wrap(('unicodeescape', r'\\x', 0, 2, r'truncated \\xXX escape'))) +assert operr.errorstr(space) == ( +"UnicodeDecodeError: 'unicodeescape' codec can't decode " +"bytes in position 0-1: truncated xXX escape") def test_wrap_oserror(): class FakeSpace: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: hg merge default
Author: Armin Rigo Branch: py3.5 Changeset: r89739:a0364a1c7f67 Date: 2017-01-24 15:46 +0100 http://bitbucket.org/pypy/pypy/changeset/a0364a1c7f67/ Log:hg merge default diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.9.2 +Version: 1.10.0 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -1,11 +1,11 @@ __all__ = ['FFI', 'VerificationError', 'VerificationMissing', 'CDefError', 'FFIError'] -from .api import FFI, CDefError, FFIError -from .ffiplatform import VerificationError, VerificationMissing +from .api import FFI +from .error import CDefError, FFIError, VerificationError, VerificationMissing -__version__ = "1.9.2" -__version_info__ = (1, 9, 2) +__version__ = "1.10.0" +__version_info__ = (1, 10, 0) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -233,7 +233,7 @@ f = PySys_GetObject((char *)"stderr"); if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.9.2" + "\ncompiled with cffi version: 1.10.0" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -1,5 +1,7 @@ import sys, types from .lock import allocate_lock +from .error import CDefError +from . import model try: callable @@ -15,17 +17,6 @@ basestring = str -class FFIError(Exception): -pass - -class CDefError(Exception): -def __str__(self): -try: -line = 'line %d: ' % (self.args[1].coord.line,) -except (AttributeError, TypeError, IndexError): -line = '' -return '%s%s' % (line, self.args[0]) - class FFI(object): r''' @@ -49,18 +40,27 @@ """Create an FFI instance. The 'backend' argument is used to select a non-default backend, mostly for tests. """ -from . import cparser, model if backend is None: # You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ -assert backend.__version__ == __version__, \ - "version mismatch, %s != %s" % (backend.__version__, __version__) +if backend.__version__ != __version__: +# bad version! Try to be as explicit as possible. +if hasattr(backend, '__file__'): +# CPython +raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. When we import the top-level '_cffi_backend' extension module, we get version %s, located in %r. The two versions should be equal; check your installation." % ( +__version__, __file__, +backend.__version__, backend.__file__)) +else: +# PyPy +raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. This interpreter comes with a built-in '_cffi_backend' module, which is version %s. The two versions should be equal; check your installation." % ( +__version__, __file__, backend.__version__)) # (If you insist you can also try to pass the option # 'backend=backend_ctypes.CTypesBackend()', but don't # rely on it! It's probably not going to work well.) +from . import cparser self._backend = backend self._lock = allocate_lock() self._parser = cparser.Parser() @@ -212,7 +212,7 @@ def offsetof(self, cdecl, *fields_or_indexes): """Return the offset of the named field inside the given -structure or array, which must be given as a C type name. +structure or array, which must be given as a C type name. You can give several field names in case of nested structures. You can also give numeric values which correspond to array items, in case of an array type. @@ -300,7 +300,7 @@ return self._backend.string(cdata, maxlen) def unpack(self, cdata, length): -"
[pypy-commit] pypy py3.5: hg merge default
Author: Armin Rigo Branch: py3.5 Changeset: r89741:40f6115fdf6d Date: 2017-01-24 15:49 +0100 http://bitbucket.org/pypy/pypy/changeset/40f6115fdf6d/ Log:hg merge default diff --git a/lib_pypy/cffi/error.py b/lib_pypy/cffi/error.py new file mode 100644 --- /dev/null +++ b/lib_pypy/cffi/error.py @@ -0,0 +1,20 @@ + +class FFIError(Exception): +pass + +class CDefError(Exception): +def __str__(self): +try: +line = 'line %d: ' % (self.args[1].coord.line,) +except (AttributeError, TypeError, IndexError): +line = '' +return '%s%s' % (line, self.args[0]) + +class VerificationError(Exception): +""" An error raised when verification fails +""" + +class VerificationMissing(Exception): +""" An error raised when incomplete structures are passed into +cdef, but no verification has been done +""" ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5-fstring-pep498: hg merge py3.5
Author: Armin Rigo Branch: py3.5-fstring-pep498 Changeset: r89742:3d484dcb6db5 Date: 2017-01-24 15:51 +0100 http://bitbucket.org/pypy/pypy/changeset/3d484dcb6db5/ Log:hg merge py3.5 diff too long, truncating to 2000 out of 3413 lines diff --git a/lib-python/3/test/test_asyncio/test_events.py b/lib-python/3/test/test_asyncio/test_events.py --- a/lib-python/3/test/test_asyncio/test_events.py +++ b/lib-python/3/test/test_asyncio/test_events.py @@ -825,9 +825,15 @@ server = self.loop.run_until_complete(f) self.assertEqual(len(server.sockets), 1) sock = server.sockets[0] -self.assertFalse( -sock.getsockopt( -socket.SOL_SOCKET, socket.SO_REUSEPORT)) +try: +self.assertFalse( +sock.getsockopt( +socket.SOL_SOCKET, socket.SO_REUSEPORT)) +except OSError: +raise unittest.SkipTest( +"Python's socket module was compiled using modern headers " +"thus defining SO_REUSEPORT but this process is running " +"under an older kernel that does not support SO_REUSEPORT.") server.close() test_utils.run_briefly(self.loop) diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.9.2 +Version: 1.10.0 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -1,11 +1,11 @@ __all__ = ['FFI', 'VerificationError', 'VerificationMissing', 'CDefError', 'FFIError'] -from .api import FFI, CDefError, FFIError -from .ffiplatform import VerificationError, VerificationMissing +from .api import FFI +from .error import CDefError, FFIError, VerificationError, VerificationMissing -__version__ = "1.9.2" -__version_info__ = (1, 9, 2) +__version__ = "1.10.0" +__version_info__ = (1, 10, 0) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -233,7 +233,7 @@ f = PySys_GetObject((char *)"stderr"); if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.9.2" + "\ncompiled with cffi version: 1.10.0" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -1,5 +1,7 @@ import sys, types from .lock import allocate_lock +from .error import CDefError +from . import model try: callable @@ -15,17 +17,6 @@ basestring = str -class FFIError(Exception): -pass - -class CDefError(Exception): -def __str__(self): -try: -line = 'line %d: ' % (self.args[1].coord.line,) -except (AttributeError, TypeError, IndexError): -line = '' -return '%s%s' % (line, self.args[0]) - class FFI(object): r''' @@ -49,18 +40,27 @@ """Create an FFI instance. The 'backend' argument is used to select a non-default backend, mostly for tests. """ -from . import cparser, model if backend is None: # You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ -assert backend.__version__ == __version__, \ - "version mismatch, %s != %s" % (backend.__version__, __version__) +if backend.__version__ != __version__: +# bad version! Try to be as explicit as possible. +if hasattr(backend, '__file__'): +# CPython +raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. When we import the top-level '_cffi_backend' extension module, we get version %s, located in %r. The two versions should be equal; check your installation." % ( +__version__, __file__, +backend.__version__, backend.__file__)) +else: +# PyPy +raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. This interpreter comes with a built-in '_cffi_backend' module, which is version %s. The two v
[pypy-commit] pypy default: forgot to check in this file
Author: Armin Rigo Branch: Changeset: r89740:e80e3f733c30 Date: 2017-01-24 15:49 +0100 http://bitbucket.org/pypy/pypy/changeset/e80e3f733c30/ Log:forgot to check in this file diff --git a/lib_pypy/cffi/error.py b/lib_pypy/cffi/error.py new file mode 100644 --- /dev/null +++ b/lib_pypy/cffi/error.py @@ -0,0 +1,20 @@ + +class FFIError(Exception): +pass + +class CDefError(Exception): +def __str__(self): +try: +line = 'line %d: ' % (self.args[1].coord.line,) +except (AttributeError, TypeError, IndexError): +line = '' +return '%s%s' % (line, self.args[0]) + +class VerificationError(Exception): +""" An error raised when verification fails +""" + +class VerificationMissing(Exception): +""" An error raised when incomplete structures are passed into +cdef, but no verification has been done +""" ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5-fstring-pep498: Add test file from CPython 3.6.0, unmodified so far
Author: Armin Rigo Branch: py3.5-fstring-pep498 Changeset: r89743:7d80e3347a86 Date: 2017-01-24 15:58 +0100 http://bitbucket.org/pypy/pypy/changeset/7d80e3347a86/ Log:Add test file from CPython 3.6.0, unmodified so far diff --git a/lib-python/3/test/test_fstring.py b/lib-python/3/test/test_fstring.py new file mode 100644 --- /dev/null +++ b/lib-python/3/test/test_fstring.py @@ -0,0 +1,762 @@ +# This test file is from CPython 3.6.0 + +import ast +import types +import decimal +import unittest + +a_global = 'global variable' + +# You could argue that I'm too strict in looking for specific error +# values with assertRaisesRegex, but without it it's way too easy to +# make a syntax error in the test strings. Especially with all of the +# triple quotes, raw strings, backslashes, etc. I think it's a +# worthwhile tradeoff. When I switched to this method, I found many +# examples where I wasn't testing what I thought I was. + +class TestCase(unittest.TestCase): +def assertAllRaise(self, exception_type, regex, error_strings): +for str in error_strings: +with self.subTest(str=str): +with self.assertRaisesRegex(exception_type, regex): +eval(str) + +def test__format__lookup(self): +# Make sure __format__ is looked up on the type, not the instance. +class X: +def __format__(self, spec): +return 'class' + +x = X() + +# Add a bound __format__ method to the 'y' instance, but not +# the 'x' instance. +y = X() +y.__format__ = types.MethodType(lambda self, spec: 'instance', y) + +self.assertEqual(f'{y}', format(y)) +self.assertEqual(f'{y}', 'class') +self.assertEqual(format(x), format(y)) + +# __format__ is not called this way, but still make sure it +# returns what we expect (so we can make sure we're bypassing +# it). +self.assertEqual(x.__format__(''), 'class') +self.assertEqual(y.__format__(''), 'instance') + +# This is how __format__ is actually called. +self.assertEqual(type(x).__format__(x, ''), 'class') +self.assertEqual(type(y).__format__(y, ''), 'class') + +def test_ast(self): +# Inspired by http://bugs.python.org/issue24975 +class X: +def __init__(self): +self.called = False +def __call__(self): +self.called = True +return 4 +x = X() +expr = """ +a = 10 +f'{a * x()}'""" +t = ast.parse(expr) +c = compile(t, '', 'exec') + +# Make sure x was not called. +self.assertFalse(x.called) + +# Actually run the code. +exec(c) + +# Make sure x was called. +self.assertTrue(x.called) + +def test_literal_eval(self): +# With no expressions, an f-string is okay. +self.assertEqual(ast.literal_eval("f'x'"), 'x') +self.assertEqual(ast.literal_eval("f'x' 'y'"), 'xy') + +# But this should raise an error. +with self.assertRaisesRegex(ValueError, 'malformed node or string'): +ast.literal_eval("f'x{3}'") + +# As should this, which uses a different ast node +with self.assertRaisesRegex(ValueError, 'malformed node or string'): +ast.literal_eval("f'{3}'") + +def test_ast_compile_time_concat(self): +x = [''] + +expr = """x[0] = 'foo' f'{3}'""" +t = ast.parse(expr) +c = compile(t, '', 'exec') +exec(c) +self.assertEqual(x[0], 'foo3') + +def test_compile_time_concat_errors(self): +self.assertAllRaise(SyntaxError, +'cannot mix bytes and nonbytes literals', +[r"""f'' b''""", + r"""b'' f''""", + ]) + +def test_literal(self): +self.assertEqual(f'', '') +self.assertEqual(f'a', 'a') +self.assertEqual(f' ', ' ') + +def test_unterminated_string(self): +self.assertAllRaise(SyntaxError, 'f-string: unterminated string', +[r"""f'{"x'""", + r"""f'{"x}'""", + r"""f'{("x'""", + r"""f'{("x}'""", + ]) + +def test_mismatched_parens(self): +self.assertAllRaise(SyntaxError, 'f-string: mismatched', +["f'{((}'", + ]) + +def test_double_braces(self): +self.assertEqual(f'{{', '{') +self.assertEqual(f'a{{', 'a{') +self.assertEqual(f'{{b', '{b') +self.assertEqual(f'a{{b', 'a{b') +self.assertEqual(f'}}', '}') +self.assertEqual(f'a}}', 'a}') +self.assertEqual(f'}}b', '}b') +self.assertEqual(f'a}}b', 'a}b') +self.assertEqual(f'{{}}', '{}') +self.assertEqual(f'a{{}}', 'a{}') +
[pypy-commit] pypy py3.5-fstring-pep498: translation fix
Author: Armin Rigo Branch: py3.5-fstring-pep498 Changeset: r89745:207d98a326e0 Date: 2017-01-24 17:09 +0100 http://bitbucket.org/pypy/pypy/changeset/207d98a326e0/ Log:translation fix diff --git a/pypy/interpreter/astcompiler/fstring.py b/pypy/interpreter/astcompiler/fstring.py --- a/pypy/interpreter/astcompiler/fstring.py +++ b/pypy/interpreter/astcompiler/fstring.py @@ -352,7 +352,7 @@ # Unicode/ValueError in literal: turn into SyntaxError e.normalize_exception(space) errmsg = space.str_w(space.str(e.get_w_value(space))) -raise self.error('(%s) %s' % (kind, errmsg), atom_node) +raise astbuilder.error('(%s) %s' % (kind, errmsg), atom_node) if len(joined_pieces) == 1: # <= the common path return joined_pieces[0] # ast.Str, Bytes or FormattedValue ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5-fstring-pep498: Can now translate a pypy with --no-objspace-fstrings. Might be useful
Author: Armin Rigo Branch: py3.5-fstring-pep498 Changeset: r89746:b8a7efb2f114 Date: 2017-01-24 17:10 +0100 http://bitbucket.org/pypy/pypy/changeset/b8a7efb2f114/ Log:Can now translate a pypy with --no-objspace-fstrings. Might be useful if you're absolutely convinced f-strings pose a danger or for some other reason don't want them in your PyPy 3.5. diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -196,6 +196,11 @@ default=False, requires=[("objspace.usemodules.cpyext", False)]), +BoolOption("fstrings", + "if you are really convinced that f-strings are a security " + "issue, you can disable them here", + default=True), + OptionDescription("std", "Standard Object Space Options", [ BoolOption("withtproxy", "support transparent proxies", default=True), diff --git a/pypy/interpreter/astcompiler/fstring.py b/pypy/interpreter/astcompiler/fstring.py --- a/pypy/interpreter/astcompiler/fstring.py +++ b/pypy/interpreter/astcompiler/fstring.py @@ -292,6 +292,16 @@ # could be merged into a single function with a clearer logic. It's # done this way to follow CPython's source code more closely. +space = astbuilder.space +if not space.config.objspace.fstrings: +raise oefmt(space.w_SystemError, +"f-strings have been disabled in this version of pypy " +"with the translation option --no-objspace-fstrings. " +"The PyPy team (and CPython) thinks f-strings don't " +"add any security risks, but we leave it to you to " +"convince whoever translated this pypy that it is " +"really the case") + while True: literal, expr = fstring_find_literal_and_expr(astbuilder, fstr, atom_node, rec) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5-fstring-pep498: regenerate this file
Author: Armin Rigo Branch: py3.5-fstring-pep498 Changeset: r89744:8bfc9e97b86b Date: 2017-01-24 17:09 +0100 http://bitbucket.org/pypy/pypy/changeset/8bfc9e97b86b/ Log:regenerate this file diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -2704,7 +2704,9 @@ def mutate_over(self, visitor): if self.values: -visitor._mutate_sequence(self.values) +for i in range(len(self.values)): +if self.values[i] is not None: +self.values[i] = self.values[i].mutate_over(visitor) return visitor.visit_JoinedStr(self) def to_object(self, space): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: Add #defines for the PyMem_Raw family of functions
Author: Ronan Lamy Branch: py3.5 Changeset: r89747:ecc2c1ad70a9 Date: 2017-01-24 16:29 + http://bitbucket.org/pypy/pypy/changeset/ecc2c1ad70a9/ Log:Add #defines for the PyMem_Raw family of functions diff --git a/pypy/module/cpyext/include/pymem.h b/pypy/module/cpyext/include/pymem.h --- a/pypy/module/cpyext/include/pymem.h +++ b/pypy/module/cpyext/include/pymem.h @@ -15,6 +15,10 @@ #define PyMem_Free PyMem_FREE #define PyMem_Realloc PyMem_REALLOC +#define PyMem_RawMalloc PyMem_Malloc +#define PyMem_RawFree PyMem_Free +#define PyMem_RawRealloc PyMem_Realloc + /* * Type-oriented memory interface * == ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: Add f-strings to PyPy 3.5. In CPython they are only there from 3.6, but
Author: Armin Rigo Branch: py3.5 Changeset: r89749:a19390150925 Date: 2017-01-24 17:31 +0100 http://bitbucket.org/pypy/pypy/changeset/a19390150925/ Log:Add f-strings to PyPy 3.5. In CPython they are only there from 3.6, but the idea is that if it is the only new feature that you really need to run your Python 3.x programs, then using PyPy 3.5 should work too. For people that, for some reason, think f-strings are a security issue and would like to disable them, translate with --no-objspace- fstrings. diff --git a/lib-python/3/opcode.py b/lib-python/3/opcode.py --- a/lib-python/3/opcode.py +++ b/lib-python/3/opcode.py @@ -214,6 +214,9 @@ def_op('BUILD_TUPLE_UNPACK', 152) def_op('BUILD_SET_UNPACK', 153) +def_op('FORMAT_VALUE', 155) # in CPython 3.6, but available in PyPy from 3.5 +def_op('BUILD_STRING', 157) # in CPython 3.6, but available in PyPy from 3.5 + # pypy modification, experimental bytecode def_op('LOOKUP_METHOD', 201) # Index in name list hasname.append(201) diff --git a/lib-python/3/test/test_fstring.py b/lib-python/3/test/test_fstring.py new file mode 100644 --- /dev/null +++ b/lib-python/3/test/test_fstring.py @@ -0,0 +1,762 @@ +# This test file is from CPython 3.6.0 + +import ast +import types +import decimal +import unittest + +a_global = 'global variable' + +# You could argue that I'm too strict in looking for specific error +# values with assertRaisesRegex, but without it it's way too easy to +# make a syntax error in the test strings. Especially with all of the +# triple quotes, raw strings, backslashes, etc. I think it's a +# worthwhile tradeoff. When I switched to this method, I found many +# examples where I wasn't testing what I thought I was. + +class TestCase(unittest.TestCase): +def assertAllRaise(self, exception_type, regex, error_strings): +for str in error_strings: +with self.subTest(str=str): +with self.assertRaisesRegex(exception_type, regex): +eval(str) + +def test__format__lookup(self): +# Make sure __format__ is looked up on the type, not the instance. +class X: +def __format__(self, spec): +return 'class' + +x = X() + +# Add a bound __format__ method to the 'y' instance, but not +# the 'x' instance. +y = X() +y.__format__ = types.MethodType(lambda self, spec: 'instance', y) + +self.assertEqual(f'{y}', format(y)) +self.assertEqual(f'{y}', 'class') +self.assertEqual(format(x), format(y)) + +# __format__ is not called this way, but still make sure it +# returns what we expect (so we can make sure we're bypassing +# it). +self.assertEqual(x.__format__(''), 'class') +self.assertEqual(y.__format__(''), 'instance') + +# This is how __format__ is actually called. +self.assertEqual(type(x).__format__(x, ''), 'class') +self.assertEqual(type(y).__format__(y, ''), 'class') + +def test_ast(self): +# Inspired by http://bugs.python.org/issue24975 +class X: +def __init__(self): +self.called = False +def __call__(self): +self.called = True +return 4 +x = X() +expr = """ +a = 10 +f'{a * x()}'""" +t = ast.parse(expr) +c = compile(t, '', 'exec') + +# Make sure x was not called. +self.assertFalse(x.called) + +# Actually run the code. +exec(c) + +# Make sure x was called. +self.assertTrue(x.called) + +def test_literal_eval(self): +# With no expressions, an f-string is okay. +self.assertEqual(ast.literal_eval("f'x'"), 'x') +self.assertEqual(ast.literal_eval("f'x' 'y'"), 'xy') + +# But this should raise an error. +with self.assertRaisesRegex(ValueError, 'malformed node or string'): +ast.literal_eval("f'x{3}'") + +# As should this, which uses a different ast node +with self.assertRaisesRegex(ValueError, 'malformed node or string'): +ast.literal_eval("f'{3}'") + +def test_ast_compile_time_concat(self): +x = [''] + +expr = """x[0] = 'foo' f'{3}'""" +t = ast.parse(expr) +c = compile(t, '', 'exec') +exec(c) +self.assertEqual(x[0], 'foo3') + +def test_compile_time_concat_errors(self): +self.assertAllRaise(SyntaxError, +'cannot mix bytes and nonbytes literals', +[r"""f'' b''""", + r"""b'' f''""", + ]) + +def test_literal(self): +self.assertEqual(f'', '') +self.assertEqual(f'a', 'a') +self.assertEqual(f' ', ' ') + +def test_unterminated_string(self): +self.assertAllRaise(SyntaxError, 'f-string: unterminated string', +
[pypy-commit] pypy py3.5: merge heads
Author: Armin Rigo Branch: py3.5 Changeset: r89750:08f726964553 Date: 2017-01-24 17:31 +0100 http://bitbucket.org/pypy/pypy/changeset/08f726964553/ Log:merge heads diff --git a/pypy/module/cpyext/include/pymem.h b/pypy/module/cpyext/include/pymem.h --- a/pypy/module/cpyext/include/pymem.h +++ b/pypy/module/cpyext/include/pymem.h @@ -15,6 +15,10 @@ #define PyMem_Free PyMem_FREE #define PyMem_Realloc PyMem_REALLOC +#define PyMem_RawMalloc PyMem_Malloc +#define PyMem_RawFree PyMem_Free +#define PyMem_RawRealloc PyMem_Realloc + /* * Type-oriented memory interface * == ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5-fstring-pep498: close branch, ready for merge
Author: Armin Rigo Branch: py3.5-fstring-pep498 Changeset: r89748:40322e3c6462 Date: 2017-01-24 17:29 +0100 http://bitbucket.org/pypy/pypy/changeset/40322e3c6462/ Log:close branch, ready for merge ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: Python.asdl gives attributes (lineno, col_offset) to the class 'arg',
Author: Armin Rigo Branch: py3.5 Changeset: r89751:fe93a6ca25bb Date: 2017-01-24 18:10 +0100 http://bitbucket.org/pypy/pypy/changeset/fe93a6ca25bb/ Log:Python.asdl gives attributes (lineno, col_offset) to the class 'arg', but because this ended up as a Product instead of a Sum the attributes were ignored. Fix diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -3879,9 +3879,11 @@ class arg(AST): -def __init__(self, arg, annotation): +def __init__(self, arg, annotation, lineno, col_offset): self.arg = arg self.annotation = annotation +self.lineno = lineno +self.col_offset = col_offset def mutate_over(self, visitor): if self.annotation: @@ -3897,19 +3899,27 @@ space.setattr(w_node, space.wrap('arg'), w_arg) w_annotation = self.annotation.to_object(space) if self.annotation is not None else space.w_None # expr space.setattr(w_node, space.wrap('annotation'), w_annotation) +w_lineno = space.wrap(self.lineno) # int +space.setattr(w_node, space.wrap('lineno'), w_lineno) +w_col_offset = space.wrap(self.col_offset) # int +space.setattr(w_node, space.wrap('col_offset'), w_col_offset) return w_node @staticmethod def from_object(space, w_node): w_arg = get_field(space, w_node, 'arg', False) w_annotation = get_field(space, w_node, 'annotation', True) +w_lineno = get_field(space, w_node, 'lineno', False) +w_col_offset = get_field(space, w_node, 'col_offset', False) _arg = space.identifier_w(w_arg) if _arg is None: raise_required_value(space, w_node, 'arg') _annotation = expr.from_object(space, w_annotation) -return arg(_arg, _annotation) - -State.ast_type('arg', 'AST', ['arg', 'annotation']) +_lineno = space.int_w(w_lineno) +_col_offset = space.int_w(w_col_offset) +return arg(_arg, _annotation, _lineno, _col_offset) + +State.ast_type('arg', 'AST', ['arg', 'annotation'], ['lineno', 'col_offset']) class keyword(AST): diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py --- a/pypy/interpreter/astcompiler/astbuilder.py +++ b/pypy/interpreter/astcompiler/astbuilder.py @@ -665,7 +665,8 @@ argname = name_node.get_value() argname = self.new_identifier(argname) self.check_forbidden_name(argname, name_node) -kwonly.append(ast.arg(argname, ann)) +kwonly.append(ast.arg(argname, ann, arg.get_lineno(), +arg.get_column())) i += 2 elif arg_type == tokens.DOUBLESTAR: return i @@ -678,7 +679,7 @@ ann = None if arg_node.num_children() == 3: ann = self.handle_expr(arg_node.get_child(2)) -return ast.arg(name, ann) +return ast.arg(name, ann, arg_node.get_lineno(), arg_node.get_column()) def handle_stmt(self, stmt): stmt_type = stmt.type diff --git a/pypy/interpreter/astcompiler/test/test_validate.py b/pypy/interpreter/astcompiler/test/test_validate.py --- a/pypy/interpreter/astcompiler/test/test_validate.py +++ b/pypy/interpreter/astcompiler/test/test_validate.py @@ -51,18 +51,18 @@ args = ast.arguments(args, vararg, kwonlyargs, kw_defaults, kwarg, defaults) return fac(args) -args = [ast.arg("x", ast.Name("x", ast.Store, 0, 0))] +args = [ast.arg("x", ast.Name("x", ast.Store, 0, 0), 0, 0)] check(arguments(args=args), "must have Load context") check(arguments(kwonlyargs=args), "must have Load context") check(arguments(defaults=[ast.Num(self.space.wrap(3), 0, 0)]), "more positional defaults than args") check(arguments(kw_defaults=[ast.Num(self.space.wrap(4), 0, 0)]), "length of kwonlyargs is not the same as kw_defaults") -args = [ast.arg("x", ast.Name("x", ast.Load, 0, 0))] +args = [ast.arg("x", ast.Name("x", ast.Load, 0, 0), 0, 0)] check(arguments(args=args, defaults=[ast.Name("x", ast.Store, 0, 0)]), "must have Load context") -args = [ast.arg("a", ast.Name("x", ast.Load, 0, 0)), -ast.arg("b", ast.Name("y", ast.Load, 0, 0))] +args = [ast.arg("a", ast.Name("x", ast.Load, 0, 0), 0, 0), +ast.arg("b", ast.Name("y", ast.Load, 0, 0), 0, 0)] check(arguments(kwonlyargs=args, kw_defaults=[None, ast.Name("x", ast.Store, 0, 0)]), "must have Load context") diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl
[pypy-commit] pypy py3.5: Attempt to fix lib-python's test_ast.py: change the recorded position
Author: Armin Rigo Branch: py3.5 Changeset: r89752:abf9387139e4 Date: 2017-01-24 18:23 +0100 http://bitbucket.org/pypy/pypy/changeset/abf9387139e4/ Log:Attempt to fix lib-python's test_ast.py: change the recorded position for ast.Set,Dict,SetComp,DictComp diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py --- a/pypy/interpreter/astcompiler/astbuilder.py +++ b/pypy/interpreter/astcompiler/astbuilder.py @@ -1249,10 +1249,10 @@ (n_maker_children > 1 and maker.get_child(1).type == tokens.COMMA)): # a set display -return self.handle_setdisplay(maker) +return self.handle_setdisplay(maker, atom_node) elif n_maker_children > 1 and maker.get_child(1).type == syms.comp_for: # a set comprehension -return self.handle_setcomp(maker) +return self.handle_setcomp(maker, atom_node) elif (n_maker_children > (3-is_dict) and maker.get_child(3-is_dict).type == syms.comp_for): # a dictionary comprehension @@ -1260,10 +1260,10 @@ raise self.error("dict unpacking cannot be used in " "dict comprehension", atom_node) -return self.handle_dictcomp(maker) +return self.handle_dictcomp(maker, atom_node) else: # a dictionary display -return self.handle_dictdisplay(maker) +return self.handle_dictdisplay(maker, atom_node) else: raise AssertionError("unknown atom") @@ -1361,22 +1361,22 @@ return ast.ListComp(elt, comps, listcomp_node.get_lineno(), listcomp_node.get_column()) -def handle_setcomp(self, set_maker): +def handle_setcomp(self, set_maker, atom_node): ch = set_maker.get_child(0) elt = self.handle_expr(ch) if isinstance(elt, ast.Starred): self.error("iterable unpacking cannot be used in comprehension", ch) comps = self.comprehension_helper(set_maker.get_child(1)) -return ast.SetComp(elt, comps, set_maker.get_lineno(), - set_maker.get_column()) +return ast.SetComp(elt, comps, atom_node.get_lineno(), + atom_node.get_column()) -def handle_dictcomp(self, dict_maker): +def handle_dictcomp(self, dict_maker, atom_node): i, key, value = self.handle_dictelement(dict_maker, 0) comps = self.comprehension_helper(dict_maker.get_child(i)) -return ast.DictComp(key, value, comps, dict_maker.get_lineno(), -dict_maker.get_column()) +return ast.DictComp(key, value, comps, atom_node.get_lineno(), + atom_node.get_column()) -def handle_dictdisplay(self, node): +def handle_dictdisplay(self, node, atom_node): keys = [] values = [] i = 0 @@ -1385,16 +1385,18 @@ keys.append(key) values.append(value) i += 1 -return ast.Dict(keys, values, node.get_lineno(), node.get_column()) +return ast.Dict(keys, values, atom_node.get_lineno(), + atom_node.get_column()) -def handle_setdisplay(self, node): +def handle_setdisplay(self, node, atom_node): elts = [] i = 0 while i < node.num_children(): expr = self.handle_expr(node.get_child(i)) elts.append(expr) i += 2 -return ast.Set(elts, node.get_lineno(), node.get_column()) +return ast.Set(elts, atom_node.get_lineno(), + atom_node.get_column()) def handle_exprlist(self, exprlist, context): exprs = [] ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: raise a regular SyntaxError
Author: Armin Rigo Branch: py3.5 Changeset: r89753:cee6cd3d91ce Date: 2017-01-24 18:27 +0100 http://bitbucket.org/pypy/pypy/changeset/cee6cd3d91ce/ Log:raise a regular SyntaxError diff --git a/pypy/interpreter/astcompiler/fstring.py b/pypy/interpreter/astcompiler/fstring.py --- a/pypy/interpreter/astcompiler/fstring.py +++ b/pypy/interpreter/astcompiler/fstring.py @@ -294,13 +294,13 @@ space = astbuilder.space if not space.config.objspace.fstrings: -raise oefmt(space.w_SystemError, -"f-strings have been disabled in this version of pypy " -"with the translation option --no-objspace-fstrings. " -"The PyPy team (and CPython) thinks f-strings don't " -"add any security risks, but we leave it to you to " -"convince whoever translated this pypy that it is " -"really the case") +raise astbuilder.error( +"f-strings have been disabled in this version of pypy " +"with the translation option '--no-objspace-fstrings'. " +"The PyPy team (and CPython) thinks f-strings don't " +"add any security risks, but we leave it to you to " +"convince whoever translated this pypy that it is " +"really the case", atom_node) while True: literal, expr = fstring_find_literal_and_expr(astbuilder, fstr, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] cffi default: Improve the error message for getattr/setattr
Author: Armin Rigo Branch: Changeset: r2873:8f9136ac88e6 Date: 2017-01-25 00:25 +0100 http://bitbucket.org/cffi/cffi/changeset/8f9136ac88e6/ Log:Improve the error message for getattr/setattr diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -455,6 +455,8 @@ static PyObject * get_field_name(CTypeDescrObject *ct, CFieldObject *cf); /* forward */ +/* returns 0 if the struct ctype is opaque, 1 if it is not, or -1 if + an exception occurs */ #define force_lazy_struct(ct) \ ((ct)->ct_stuff != NULL ? 1 : do_realize_lazy_struct(ct)) @@ -2452,11 +2454,26 @@ return _cdata_add_or_sub(v, w, -1); } +static void +_cdata_attr_errmsg(char *errmsg, CDataObject *cd, PyObject *attr) +{ +char *text; +if (!PyErr_ExceptionMatches(PyExc_AttributeError)) +return; +PyErr_Clear(); +text = PyText_AsUTF8(attr); +if (text == NULL) +return; +PyErr_Format(PyExc_AttributeError, errmsg, cd->c_type->ct_name, text); +} + static PyObject * cdata_getattro(CDataObject *cd, PyObject *attr) { CFieldObject *cf; CTypeDescrObject *ct = cd->c_type; +char *errmsg = "cdata '%s' has no attribute '%s'"; +PyObject *x; if (ct->ct_flags & CT_POINTER) ct = ct->ct_itemdescr; @@ -2488,14 +2505,19 @@ return new_simple_cdata(data, (CTypeDescrObject *)cf->cf_type->ct_stuff); } +errmsg = "cdata '%s' has no field '%s'"; break; case -1: return NULL; default: +errmsg = "cdata '%s' points to an opaque type: cannot read fields"; break; } } -return PyObject_GenericGetAttr((PyObject *)cd, attr); +x = PyObject_GenericGetAttr((PyObject *)cd, attr); +if (x == NULL) +_cdata_attr_errmsg(errmsg, cd, attr); +return x; } static int @@ -2503,6 +2525,8 @@ { CFieldObject *cf; CTypeDescrObject *ct = cd->c_type; +char *errmsg = "cdata '%s' has no attribute '%s'"; +int x; if (ct->ct_flags & CT_POINTER) ct = ct->ct_itemdescr; @@ -2522,14 +2546,19 @@ return -1; } } +errmsg = "cdata '%s' has no field '%s'"; break; case -1: return -1; default: +errmsg = "cdata '%s' points to an opaque type: cannot write fields"; break; } } -return PyObject_GenericSetAttr((PyObject *)cd, attr, value); +x = PyObject_GenericSetAttr((PyObject *)cd, attr, value); +if (x < 0) +_cdata_attr_errmsg(errmsg, cd, attr); +return x; } static PyObject * diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -748,8 +748,14 @@ BInt = new_primitive_type("int") BStruct = new_struct_type("struct foo") BStructPtr = new_pointer_type(BStruct) -p = cast(BStructPtr, 0) -py.test.raises(AttributeError, "p.a1")# opaque +p = cast(BStructPtr, 42) +e = py.test.raises(AttributeError, "p.a1")# opaque +assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " +"cannot read fields") +e = py.test.raises(AttributeError, "p.a1 = 10")# opaque +assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " +"cannot write fields") + complete_struct_or_union(BStruct, [('a1', BInt, -1), ('a2', BInt, -1)]) p = newp(BStructPtr, None) @@ -760,8 +766,24 @@ assert s.a2 == 123 py.test.raises(OverflowError, "s.a1 = sys.maxsize+1") assert s.a1 == 0 -py.test.raises(AttributeError, "p.foobar") -py.test.raises(AttributeError, "s.foobar") +e = py.test.raises(AttributeError, "p.foobar") +assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" +e = py.test.raises(AttributeError, "p.foobar = 42") +assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" +e = py.test.raises(AttributeError, "s.foobar") +assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" +e = py.test.raises(AttributeError, "s.foobar = 42") +assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" +j = cast(BInt, 42) +e = py.test.raises(AttributeError, "j.foobar") +assert str(e.value) == "cdata 'int' has no attribute 'foobar'" +e = py.test.raises(AttributeError, "j.foobar = 42") +assert str(e.value) == "cdata 'int' has no attribute 'foobar'" +j = cast(new_pointer_type(BInt), 42) +e = py.test.raises(AttributeError, "j.foobar") +assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" +e = py.test.raises(AttributeError, "j.foobar = 42") +assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" def test_union_instance(): BInt = new_primitive_type("int") __
[pypy-commit] cffi default: extra tests
Author: Armin Rigo Branch: Changeset: r2874:ece6f0f2da93 Date: 2017-01-25 00:44 +0100 http://bitbucket.org/cffi/cffi/changeset/ece6f0f2da93/ Log:extra tests diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -784,6 +784,11 @@ assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" e = py.test.raises(AttributeError, "j.foobar = 42") assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" +pp = newp(new_pointer_type(BStructPtr), p) +e = py.test.raises(AttributeError, "pp.a1") +assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" +e = py.test.raises(AttributeError, "pp.a1 = 42") +assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" def test_union_instance(): BInt = new_primitive_type("int") ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: update to cffi/ece6f0f2da93
Author: Armin Rigo Branch: Changeset: r89754:f6c083857478 Date: 2017-01-25 00:53 +0100 http://bitbucket.org/pypy/pypy/changeset/f6c083857478/ Log:update to cffi/ece6f0f2da93 diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -323,17 +323,28 @@ # return self._add_or_sub(w_other, -1) -def getcfield(self, w_attr): -return self.ctype.getcfield(self.space.str_w(w_attr)) +def getcfield(self, w_attr, mode): +space = self.space +attr = space.str_w(w_attr) +try: +cfield = self.ctype.getcfield(attr) +except KeyError: +raise oefmt(space.w_AttributeError, "cdata '%s' has no field '%s'", +self.ctype.name, attr) +if cfield is None: +raise oefmt(space.w_AttributeError, +"cdata '%s' points to an opaque type: cannot %s fields", +self.ctype.name, mode) +return cfield def getattr(self, w_attr): -cfield = self.getcfield(w_attr) +cfield = self.getcfield(w_attr, mode="read") with self as ptr: w_res = cfield.read(ptr, self) return w_res def setattr(self, w_attr, w_value): -cfield = self.getcfield(w_attr) +cfield = self.getcfield(w_attr, mode="write") with self as ptr: cfield.write(ptr, w_value) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -345,7 +345,10 @@ return result def getcfield(self, attr): -return self.ctitem.getcfield(attr) +from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion +if isinstance(self.ctitem, W_CTypeStructOrUnion): +return self.ctitem.getcfield(attr) +return W_CType.getcfield(self, attr) def typeoffsetof_field(self, fieldname, following): if following == 0: diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -161,18 +161,18 @@ return self._fields_dict[attr] def getcfield(self, attr): -ready = self._fields_dict is not None -if not ready and self.size >= 0: +# Returns a W_CField. Error cases: returns None if we are an +# opaque struct; or raises KeyError if the particular field +# 'attr' does not exist. The point of not directly building the +# error here is to get the exact ctype in the error message: it +# might be of the kind 'struct foo' or 'struct foo *'. +if self._fields_dict is None: +if self.size < 0: +return None self.force_lazy_struct() -ready = True -if ready: -self = jit.promote(self) -attr = jit.promote_string(attr) -try: -return self._getcfield_const(attr) -except KeyError: -pass -return W_CType.getcfield(self, attr) +self = jit.promote(self) +attr = jit.promote_string(attr) +return self._getcfield_const(attr)# <= KeyError here def cdata_dir(self): if self.size < 0: diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -737,8 +737,14 @@ BInt = new_primitive_type("int") BStruct = new_struct_type("struct foo") BStructPtr = new_pointer_type(BStruct) -p = cast(BStructPtr, 0) -py.test.raises(AttributeError, "p.a1")# opaque +p = cast(BStructPtr, 42) +e = py.test.raises(AttributeError, "p.a1")# opaque +assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " +"cannot read fields") +e = py.test.raises(AttributeError, "p.a1 = 10")# opaque +assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " +"cannot write fields") + complete_struct_or_union(BStruct, [('a1', BInt, -1), ('a2', BInt, -1)]) p = newp(BStructPtr, None) @@ -749,8 +755,29 @@ assert s.a2 == 123 py.test.raises(OverflowError, "s.a1 = sys.maxsize+1") assert s.a1 == 0 -py.test.raises(AttributeError, "p.foobar") -py.test.raises(AttributeError, "s.foobar") +e = py.test.raises(AttributeError, "p.foobar") +assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" +e = py.test.raises(AttributeError, "p.foobar = 42") +assert str(e.value) == "cdata 'struct foo *' has no field 'f
[pypy-commit] pypy py3.5: add test_fstring
Author: Philip Jenvey Branch: py3.5 Changeset: r89755:62d461b8e4a2 Date: 2017-01-24 20:40 -0800 http://bitbucket.org/pypy/pypy/changeset/62d461b8e4a2/ Log:add test_fstring diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -225,6 +225,7 @@ RegrTest('test_format.py', core=True), RegrTest('test_fractions.py'), RegrTest('test_frame.py'), +RegrTest('test_fstring.py'), RegrTest('test_ftplib.py'), RegrTest('test_funcattrs.py', core=True), RegrTest('test_functools.py'), ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit