[pypy-commit] pypy default: Invent a dummy thread id, if we ask for one during translation

2018-01-03 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r93614:05955e010535
Date: 2018-01-03 19:04 +0100
http://bitbucket.org/pypy/pypy/changeset/05955e010535/

Log:Invent a dummy thread id, if we ask for one during translation and
we're running a host with no threads

diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -106,14 +106,20 @@
 if we_are_translated():
 return tlfield_thread_ident.getraw()
 else:
-import thread
+try:
+import thread
+except ImportError:
+return 42
 return thread.get_ident()
 
 def get_or_make_ident():
 if we_are_translated():
 return tlfield_thread_ident.get_or_make_raw()
 else:
-import thread
+try:
+import thread
+except ImportError:
+return 42
 return thread.get_ident()
 
 @specialize.arg(0)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: First stab at parser.tuple2st()

2018-01-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: 
Changeset: r93615:28aa6e61df25
Date: 2017-12-28 22:49 +0100
http://bitbucket.org/pypy/pypy/changeset/28aa6e61df25/

Log:First stab at parser.tuple2st()

diff --git a/pypy/module/parser/__init__.py b/pypy/module/parser/__init__.py
--- a/pypy/module/parser/__init__.py
+++ b/pypy/module/parser/__init__.py
@@ -24,5 +24,7 @@
 'ASTType'  : 'pyparser.W_STType',
 'compilest': 'pyparser.compilest',
 'compileast'   : 'pyparser.compilest',
-'ParserError'  : 'space.new_exception_class("parser.ParserError")',
+'tuple2st' : 'pyparser.tuple2st',
+'sequence2st'  : 'pyparser.tuple2st',
+'ParserError'  : 'pyparser.get_error(space)',
 }
diff --git a/pypy/module/parser/pyparser.py b/pypy/module/parser/pyparser.py
--- a/pypy/module/parser/pyparser.py
+++ b/pypy/module/parser/pyparser.py
@@ -8,6 +8,14 @@
 from rpython.rlib.objectmodel import specialize
 
 
+class Cache:
+def __init__(self, space):
+self.error = space.new_exception_class("parser.ParserError")
+
+def get_error(space):
+return space.fromcache(Cache).error
+
+
 class W_STType(W_Root):
 def __init__(self, tree, mode):
 self.tree = tree
@@ -114,3 +122,59 @@
 @unwrap_spec(w_st=W_STType)
 def compilest(space, w_st, __args__):
 return space.call_args(space.getattr(w_st, space.newtext("compile")), 
__args__)
+
+
+def raise_parser_error(space, w_tuple, message):
+raise OperationError(get_error(space), space.newtuple(
+[w_tuple, space.newtext("Illegal component tuple.")]))
+
+
+def get_node_type(space, w_tuple):
+try:
+w_type = space.getitem(w_tuple, space.newint(0))
+return space.int_w(w_type)
+except OperationError:
+raise_parser_error(space, w_tuple, "Illegal component tuple.")
+
+class NodeState:
+def __init__(self):
+self.lineno = 0
+
+def build_node_tree(space, w_tuple):
+type = get_node_type(space, w_tuple)
+node_state = NodeState()
+if 0 <= type < 256:
+# The tuple is simple, but it doesn't start with a start symbol.
+# Raise an exception now and be done with it.
+raise_parser_error(space, w_tuple,
+   "Illegal syntax-tree; cannot start with terminal 
symbol.")
+node = pyparse.parser.Nonterminal(type, [])
+build_node_children(space, w_tuple, node, node_state)
+return node
+
+def build_node_children(space, w_tuple, node, node_state):
+for w_elem in space.unpackiterable(w_tuple)[1:]:
+type = get_node_type(space, w_elem)
+if type < 256:  # Terminal node
+length = space.len_w(w_elem)
+if length == 2:
+_, w_obj = space.unpackiterable(w_elem, 2)
+elif length == 3:
+_, w_obj, w_lineno = space.unpackiterable(w_elem, 3)
+else:
+raise_error(space, "terminal nodes must have 2 or 3 entries")
+strn = space.text_w(w_obj)
+child = pyparse.parser.Terminal(type, strn, node_state.lineno, 0)
+else:
+child = pyparse.parser.Nonterminal(type, [])
+node.append_child(child)
+if type >= 256:  # Nonterminal node
+build_node_children(space, w_elem, child, node_state)
+elif type == pyparse.pygram.tokens.NEWLINE:
+node_state.lineno += 1
+
+
+def tuple2st(space, w_sequence):
+# Convert the tree to the internal form before checking it
+tree = build_node_tree(space, w_sequence)
+return W_STType(tree, 'eval')
diff --git a/pypy/module/parser/test/test_parser.py 
b/pypy/module/parser/test/test_parser.py
--- a/pypy/module/parser/test/test_parser.py
+++ b/pypy/module/parser/test/test_parser.py
@@ -56,3 +56,18 @@
 
 def test_error(self):
 assert repr(self.m.ParserError) == ""
+
+def test_roundtrip(self):
+def roundtrip(f, s):
+st1 = f(s)
+t = st1.totuple()
+st2 = self.m.sequence2st(t)
+assert t == st2.totuple()
+
+def check_expr(s):
+roundtrip(self.m.expr, s)
+def check_suite(s):
+roundtrip(self.m.suite, s)
+
+check_expr("foo(1)")
+check_suite("def f(): yield 1")
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: parser.sequence2st: add validation of the passed tuple.

2018-01-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: 
Changeset: r93616:749063799a58
Date: 2018-01-02 00:53 +0100
http://bitbucket.org/pypy/pypy/changeset/749063799a58/

Log:parser.sequence2st: add validation of the passed tuple. Do it the
2016 way, by walking the grammar DFA, instead of a ton of custom
validation code.

diff --git a/pypy/module/parser/pyparser.py b/pypy/module/parser/pyparser.py
--- a/pypy/module/parser/pyparser.py
+++ b/pypy/module/parser/pyparser.py
@@ -124,9 +124,13 @@
 return space.call_args(space.getattr(w_st, space.newtext("compile")), 
__args__)
 
 
-def raise_parser_error(space, w_tuple, message):
+def parser_error(space, w_tuple, message):
 raise OperationError(get_error(space), space.newtuple(
-[w_tuple, space.newtext("Illegal component tuple.")]))
+[w_tuple, space.newtext(message)]))
+
+def parse_error(space, message):
+return OperationError(get_error(space),
+ space.newtext(message))
 
 
 def get_node_type(space, w_tuple):
@@ -134,7 +138,7 @@
 w_type = space.getitem(w_tuple, space.newint(0))
 return space.int_w(w_type)
 except OperationError:
-raise_parser_error(space, w_tuple, "Illegal component tuple.")
+raise parser_error(space, w_tuple, "Illegal component tuple.")
 
 class NodeState:
 def __init__(self):
@@ -146,7 +150,7 @@
 if 0 <= type < 256:
 # The tuple is simple, but it doesn't start with a start symbol.
 # Raise an exception now and be done with it.
-raise_parser_error(space, w_tuple,
+raise parser_error(space, w_tuple,
"Illegal syntax-tree; cannot start with terminal 
symbol.")
 node = pyparse.parser.Nonterminal(type, [])
 build_node_children(space, w_tuple, node, node_state)
@@ -162,7 +166,8 @@
 elif length == 3:
 _, w_obj, w_lineno = space.unpackiterable(w_elem, 3)
 else:
-raise_error(space, "terminal nodes must have 2 or 3 entries")
+raise parse_error(
+space, "terminal nodes must have 2 or 3 entries")
 strn = space.text_w(w_obj)
 child = pyparse.parser.Terminal(type, strn, node_state.lineno, 0)
 else:
@@ -174,7 +179,36 @@
 node_state.lineno += 1
 
 
+def validate_node(space, tree):
+assert tree.type >= 256
+type = tree.type - 256
+parser = pyparse.PythonParser(space)
+if type >= len(parser.grammar.dfas):
+raise parse_error(space, "Unrecognized node type %d." % type)
+dfa = parser.grammar.dfas[type]
+# Run the DFA for this nonterminal
+states, first = dfa
+arcs, is_accepting = states[0]
+for pos in range(tree.num_children()):
+ch = tree.get_child(pos)
+for i, next_state in arcs:
+label = parser.grammar.labels[i]
+if label == ch.type:
+# The child is acceptable; validate it recursively
+if ch.type >= 256:
+validate_node(space, ch)
+# Update the state, and move on to the next child.
+arcs, is_accepting = states[next_state]
+break
+else:
+raise parse_error(space, "Illegal node")
+if not is_accepting:
+raise parse_error(space, "Illegal number of children for %d node" %
+  tree.type)
+
+
 def tuple2st(space, w_sequence):
 # Convert the tree to the internal form before checking it
 tree = build_node_tree(space, w_sequence)
+validate_node(space, tree)
 return W_STType(tree, 'eval')
diff --git a/pypy/module/parser/test/test_parser.py 
b/pypy/module/parser/test/test_parser.py
--- a/pypy/module/parser/test/test_parser.py
+++ b/pypy/module/parser/test/test_parser.py
@@ -71,3 +71,19 @@
 
 check_expr("foo(1)")
 check_suite("def f(): yield 1")
+
+def test_bad_tree(self):
+import parser
+# from import a
+tree = \
+(257,
+ (267,
+  (268,
+   (269,
+(281,
+ (283, (1, 'from'), (1, 'import'),
+  (286, (284, (1, 'fred')),
+   (4, ''))),
+ (4, ''), (0, ''))
+raises(parser.ParserError,
+   parser.sequence2st, tree)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.6: Attempt to parse numbers with underscores

2018-01-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3.6
Changeset: r93620:c123301c02cc
Date: 2018-01-03 12:17 +0100
http://bitbucket.org/pypy/pypy/changeset/c123301c02cc/

Log:Attempt to parse numbers with underscores

diff --git a/pypy/interpreter/pyparser/dfa_generated.py 
b/pypy/interpreter/pyparser/dfa_generated.py
--- a/pypy/interpreter/pyparser/dfa_generated.py
+++ b/pypy/interpreter/pyparser/dfa_generated.py
@@ -7,10 +7,14 @@
 accepts = [True, True, True, True, True, True, True, True,
True, True, True, False, True, True, True, True,
True, False, False, False, True, False, False,
-   False, True, False, True, False, True, False,
False, True, False, False, True, False, False,
-   True, True, True, False, False, True, False,
-   False, False, True]
+   True, False, False, True, False, False, True,
+   False, False, True, False, True, False, True,
+   False, True, False, False, False, False, True,
+   True, False, False, False, False, True, False,
+   True, False, True, False, True, False, True, True,
+   False, True, False, True, False, False, True,
+   True, True, True, True]
 states = [
 # 0
 {'\t': 0, '\n': 15, '\x0c': 0,
@@ -110,21 +114,21 @@
  'v': 1, 'w': 1, 'x': 1, 'y': 1,
  'z': 1, '\x80': 1},
 # 5
-{'.': 26, '0': 24, '1': 25, '2': 25,
- '3': 25, '4': 25, '5': 25, '6': 25,
- '7': 25, '8': 25, '9': 25, 'B': 23,
- 'E': 27, 'J': 15, 'O': 22, 'X': 21,
- 'b': 23, 'e': 27, 'j': 15, 'o': 22,
- 'x': 21},
+{'.': 27, '0': 24, '1': 26, '2': 26,
+ '3': 26, '4': 26, '5': 26, '6': 26,
+ '7': 26, '8': 26, '9': 26, 'B': 23,
+ 'E': 28, 'J': 15, 'O': 22, 'X': 21,
+ '_': 25, 'b': 23, 'e': 28, 'j': 15,
+ 'o': 22, 'x': 21},
 # 6
-{'.': 26, '0': 6, '1': 6, '2': 6,
+{'.': 27, '0': 6, '1': 6, '2': 6,
  '3': 6, '4': 6, '5': 6, '6': 6,
- '7': 6, '8': 6, '9': 6, 'E': 27,
- 'J': 15, 'e': 27, 'j': 15},
+ '7': 6, '8': 6, '9': 6, 'E': 28,
+ 'J': 15, '_': 29, 'e': 28, 'j': 15},
 # 7
-{'.': 29, '0': 28, '1': 28, '2': 28,
- '3': 28, '4': 28, '5': 28, '6': 28,
- '7': 28, '8': 28, '9': 28},
+{'.': 31, '0': 30, '1': 30, '2': 30,
+ '3': 30, '4': 30, '5': 30, '6': 30,
+ '7': 30, '8': 30, '9': 30},
 # 8
 {'*': 14, '=': 15},
 # 9
@@ -144,107 +148,240 @@
 # 16
 {'\n': 15},
 # 17
-{automata.DEFAULT: 33, '\n': 30,
- '\r': 30, "'": 31, '\\': 32},
+{automata.DEFAULT: 35, '\n': 32,
+ '\r': 32, "'": 33, '\\': 34},
 # 18
-{automata.DEFAULT: 36, '\n': 30,
- '\r': 30, '"': 34, '\\': 35},
+{automata.DEFAULT: 38, '\n': 32,
+ '\r': 32, '"': 36, '\\': 37},
 # 19
 {'\n': 15, '\r': 16},
 # 20
-{automata.DEFAULT: 20, '\n': 30, '\r': 30},
+{automata.DEFAULT: 20, '\n': 32, '\r': 32},
 # 21
-{'0': 37, '1': 37, '2': 37, '3': 37,
- '4': 37, '5': 37, '6': 37, '7': 37,
- '8': 37, '9': 37, 'A': 37, 'B': 37,
- 'C': 37, 'D': 37, 'E': 37, 'F': 37,
- 'a': 37, 'b': 37, 'c': 37, 'd': 37,
- 'e': 37, 'f': 37},
+{'0': 39, '1': 39, '2': 39, '3': 39,
+ '4': 39, '5': 39, '6': 39, '7': 39,
+ '8': 39, '9': 39, 'A': 39, 'B': 39,
+ 'C': 39, 'D': 39, 'E': 39, 'F': 39,
+ '_': 40, 'a': 39, 'b': 39, 'c': 39,
+ 'd': 39, 'e': 39, 'f': 39},
 # 22
-{'0': 38, '1': 38, '2': 38, '3': 38,
- '4': 38, '5': 38, '6': 38, '7': 38},
+{'0': 41, '1': 41, '2': 41, '3': 41,
+ '4': 41, '5': 41, '6': 41, '7': 41,
+ '_': 42},
 # 23
-{'0': 39, '1': 39},
+{'0': 43, '1': 43, '_': 44},
 # 24
-{'.': 26, '0': 24, '1': 25, '2': 25,
- '3': 25, '4': 25, '5': 25, '6': 25,
- '7': 25, '8': 25, '9': 25, 'E': 27,
- 'J': 15, 'e': 27, 'j': 15},
+{'.': 27, '0': 24, '1': 26, '2': 26,
+ '3': 26, '4': 26, '5': 26, '6': 26,
+ '7': 26, '8': 26, '9': 26, 'E': 28,
+ 'J': 15, '_': 25, 'e': 28, 'j': 15},
 # 25
-{'.': 26, '0': 25, '1': 25, '2': 25,
- '3': 25, '4': 25, '5': 25, '6': 25,
- '7': 25, '8': 25, '9': 25, 'E': 27,
- 'J': 15, 'e': 27, 'j': 15},
+{'0': 45, '1': 46, '2': 46, '3': 46,
+ '4': 46, '5': 46, '6': 46, '7': 46,
+ '8': 46, '9': 46},
 # 26
-{'0': 26, '1': 26, '2': 26, '3': 26,
- '4': 26, '5': 26, '6': 26, '7': 26,
- '8': 26, '9': 26, 'E': 40, 'J': 15,
- 'e': 40, 'j': 15},
+{'.': 27, '0': 26, '1': 26, '2': 26,
+ '3': 26, '4': 26, '5': 26, '6': 26,
+ '7': 26, '8': 26, '9': 26, 'E': 28,
+ 'J': 15, '_': 47, 'e': 28, 'j': 15},
 # 27
-{'+': 41, '-': 41, '0': 42, '1': 42,
- '2': 42, '3': 42, '4': 42, '5': 42,
- '6': 42, '7': 42, '8': 42, '9': 42},
+{'0': 27, '1': 27, '2': 27, '3': 27,
+ '4': 27, '5': 27, '6': 27, '7': 27,
+ '8': 27, '9': 27, 'E': 48, 'J': 15,
+ 'e': 48, 'j': 15},
 # 28
-{'0': 28, '1': 28, '2': 28, '3': 28,
- '4': 28, '5': 28, '6': 28, '7': 28,
- '8': 28, '9

[pypy-commit] pypy py3.6: Allow undescores in int() literals.

2018-01-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3.6
Changeset: r93622:ff9805f6a687
Date: 2018-01-03 22:51 +0100
http://bitbucket.org/pypy/pypy/changeset/ff9805f6a687/

Log:Allow undescores in int() literals.

diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -810,7 +810,7 @@
 
 def _string_to_int_or_long(space, w_inttype, w_source, string, base=10):
 try:
-value = string_to_int(string, base)
+value = string_to_int(string, base, allow_underscores=True)
 except ParseStringError as e:
 raise wrap_parsestringerror(space, e, w_source)
 except ParseStringOverflowError as e:
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.6: Add sha3 (aka. Keccak) hashes to hashlib.

2018-01-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3.6
Changeset: r93618:88331f108204
Date: 2017-12-25 18:11 +0100
http://bitbucket.org/pypy/pypy/changeset/88331f108204/

Log:Add sha3 (aka. Keccak) hashes to hashlib.

diff too long, truncating to 2000 out of 5634 lines

diff --git a/lib-python/3/hashlib.py b/lib-python/3/hashlib.py
--- a/lib-python/3/hashlib.py
+++ b/lib-python/3/hashlib.py
@@ -57,10 +57,8 @@
 # always available algorithm is added.
 __always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
   'blake2b', 'blake2s',
-  # FIXME the following algorithms were added in
-  # cpython3.6 but are missing in pypy
-  # 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
-  # 'shake_128', 'shake_256'
+  'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
+  'shake_128', 'shake_256'
 )
 
 
diff --git a/lib_pypy/_sha3/__init__.py b/lib_pypy/_sha3/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_sha3/__init__.py
@@ -0,0 +1,107 @@
+from ._sha3_cffi import ffi as _ffi, lib as _lib
+import codecs
+
+SHA3_MAX_DIGESTSIZE = 64 # 64 Bytes (512 Bits) for 224 to 512
+SHA3_LANESIZE = (20 * 8) # ExtractLane needs max uint64_t[20] extra.
+
+class _sha3:
+_keccak_init = None  # Overridden in subclasses
+
+def __new__(cls, string=None):
+self = super().__new__(cls)
+self._hash_state = _ffi.new("Keccak_HashInstance*")
+
+cls._keccak_init(self._hash_state)
+
+if string:
+self.update(string)
+return self
+
+def update(self, string):
+buf = _ffi.from_buffer(string)
+res = _lib.Keccak_HashUpdate(self._hash_state, buf, len(buf) * 8)
+
+def digest(self):
+digest = _ffi.new("char[]",
+  SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE)
+state_copy = _ffi.new("Keccak_HashInstance*")
+_ffi.memmove(state_copy, self._hash_state,
+ _ffi.sizeof("Keccak_HashInstance"))
+if _lib.Keccak_HashFinal(state_copy, digest) != _lib.SUCCESS:
+raise RuntimeError("internal error in SHA3 Final()")
+return _ffi.unpack(digest, self._hash_state.fixedOutputLength // 8)
+
+def hexdigest(self):
+return codecs.encode(self.digest(), 'hex').decode()
+
+def copy(self):
+copy = super().__new__(type(self))
+copy._hash_state = _ffi.new("Keccak_HashInstance*")
+_ffi.memmove(copy._hash_state, self._hash_state,
+ _ffi.sizeof("Keccak_HashInstance"))
+return copy
+
+@property
+def digest_size(self):
+return self._hash_state.fixedOutputLength // 8
+
+@property
+def block_size(self):
+return self._hash_state.sponge.rate // 8
+
+@property
+def _capacity_bits(self):
+return 1600 - self._hash_state.sponge.rate
+
+@property
+def _rate_bits(self):
+return self._hash_state.sponge.rate
+
+@property
+def _suffix(self):
+return bytes([self._hash_state.delimitedSuffix])
+
+
+class _shake(_sha3):
+def digest(self, length):
+# ExtractLane needs at least SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE and
+# SHA_LANESIZE extra space.
+digest = _ffi.new("char[]", length + SHA3_LANESIZE)
+# Get the raw (binary) digest value
+state_copy = _ffi.new("Keccak_HashInstance*")
+_ffi.memmove(state_copy, self._hash_state,
+ _ffi.sizeof("Keccak_HashInstance"))
+if _lib.Keccak_HashFinal(state_copy, digest) != _lib.SUCCESS:
+raise RuntimeError("internal error in SHA3 Final()")
+if _lib.Keccak_HashSqueeze(state_copy, digest, length * 8) != 
_lib.SUCCESS:
+raise RuntimeError("internal error in SHA3 Squeeze()")
+return _ffi.unpack(digest, length)
+
+def hexdigest(self, length):
+return codecs.encode(self.digest(length), 'hex').decode()
+
+
+class sha3_224(_sha3):
+name = "sha3_224"
+_keccak_init = _lib.Keccak_HashInitialize_SHA3_224
+
+class sha3_256(_sha3):
+name = "sha3_256"
+_keccak_init = _lib.Keccak_HashInitialize_SHA3_256
+
+class sha3_384(_sha3):
+name = "sha3_384"
+_keccak_init = _lib.Keccak_HashInitialize_SHA3_384
+
+class sha3_512(_sha3):
+name = "sha3_512"
+_keccak_init = _lib.Keccak_HashInitialize_SHA3_512
+
+class shake_128(_shake):
+name = "shake_128"
+_keccak_init = _lib.Keccak_HashInitialize_SHAKE128
+
+class shake_256(_shake):
+name = "shake_256"
+_keccak_init = _lib.Keccak_HashInitialize_SHAKE256
+
diff --git a/lib_pypy/_sha3/_sha3_build.py b/lib_pypy/_sha3/_sha3_build.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_sha3/_sha3_build.py
@@ -0,0 +1,78 @@
+import os
+import sys
+
+from cffi import FFI
+
+
+ffi = FFI()
+ffi.cdef("""
+typedef struct {
+unsigned int rate;
+...;
+} KeccakWidth1600_SpongeInstance;
+
+typedef struct {
+ 

[pypy-commit] pypy py3.6: Add BLAKE2 (blake2b and blake2s) to hashlib.

2018-01-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3.6
Changeset: r93617:f6a0b040703c
Date: 2017-12-22 21:03 +0100
http://bitbucket.org/pypy/pypy/changeset/f6a0b040703c/

Log:Add BLAKE2 (blake2b and blake2s) to hashlib.

diff too long, truncating to 2000 out of 3659 lines

diff --git a/lib-python/3/hashlib.py b/lib-python/3/hashlib.py
--- a/lib-python/3/hashlib.py
+++ b/lib-python/3/hashlib.py
@@ -56,9 +56,9 @@
 # This tuple and __get_builtin_constructor() must be modified if a new
 # always available algorithm is added.
 __always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
+  'blake2b', 'blake2s',
   # FIXME the following algorithms were added in
   # cpython3.6 but are missing in pypy
-  # 'blake2b', 'blake2s',
   # 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
   # 'shake_128', 'shake_256'
 )
diff --git a/lib_pypy/_blake2/__init__.py b/lib_pypy/_blake2/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_blake2/__init__.py
@@ -0,0 +1,151 @@
+import codecs
+
+def make_blake_hash(class_name, cffi_mod):
+_ffi = cffi_mod.ffi
+_lib = cffi_mod.lib
+
+class _blake:
+SALT_SIZE = _lib.BLAKE_SALTBYTES
+PERSON_SIZE = _lib.BLAKE_PERSONALBYTES
+MAX_KEY_SIZE = _lib.BLAKE_KEYBYTES
+MAX_DIGEST_SIZE = _lib.BLAKE_OUTBYTES
+
+def __new__(cls, string=None, *, digest_size=MAX_DIGEST_SIZE,
+key=None, salt=None, person=None, fanout=1, depth=1,
+leaf_size=None, node_offset=None, node_depth=0,
+inner_size=0, last_node=False):
+self = super().__new__(cls)
+
+self._param = _ffi.new("blake_param*")
+self._state = _ffi.new("blake_state*")
+
+# Set digest size.
+if not 1 <= digest_size <= self.MAX_DIGEST_SIZE:
+raise ValueError(
+"digest_size must be between 1 and %s bytes" %
+self.MAX_DIGEST_SIZE)
+self._param.digest_length = digest_size
+
+# Set salt parameter.
+if salt is not None:
+if len(salt) > self.SALT_SIZE:
+raise ValueError(
+"maximum salt length is %d bytes" %
+self.SALT_SIZE)
+_ffi.memmove(self._param.salt, salt, len(salt))
+
+# Set personalization parameter.
+if person:
+if len(person) > _lib.BLAKE_PERSONALBYTES:
+raise ValueError("maximum person length is %d bytes" %
+ _lib.BLAKE_PERSONALBYTES)
+_ffi.memmove(self._param.personal, person, len(person))
+
+# Set tree parameters.
+if not 0 <= fanout <= 255:
+raise ValueError("fanout must be between 0 and 255")
+self._param.fanout = fanout
+
+if not 1 <= depth <= 255:
+raise ValueError("depth must be between 1 and 255")
+self._param.depth = depth
+
+if leaf_size is not None:
+if leaf_size > 0x:
+raise OverflowError("leaf_size is too large")
+# NB: Simple assignment here would be incorrect on big
+# endian platforms.
+_lib.store32(_ffi.addressof(self._param, 'leaf_length'),
+ leaf_size)
+
+if node_offset is not None:
+if class_name == 'blake2s':
+if node_offset > 0x:
+# maximum 2**48 - 1
+raise OverflowError("node_offset is too large")
+_lib.store48(_lib.addressof_node_offset(self._param),
+ node_offset)
+else:
+# NB: Simple assignment here would be incorrect on big
+# endian platforms.
+_lib.store64(_lib.addressof_node_offset(self._param),
+ node_offset)
+
+if not 0 <= node_depth <= 255:
+raise ValueError("node_depth must be between 0 and 255")
+self._param.node_depth = node_depth
+
+if not 0 <= inner_size <= _lib.BLAKE_OUTBYTES:
+raise ValueError("inner_size must be between 0 and is %d" %
+ _lib.BLAKE_OUTBYTES)
+self._param.inner_length = inner_size
+
+# Set key length.
+if key:
+if len(key) > _lib.BLAKE_KEYBYTES:
+raise ValueError("maximum key length is %d bytes" %
+ _lib.BLAKE_KEYBYTES)
+self._param.key_length = len(key)
+
+# Initialize hash state.
+if _lib.blake_init_param(self._state, self._param) < 0:
+raise Runti

[pypy-commit] pypy default: Add an option to allow underscores in integer literals. RPython part.

2018-01-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: 
Changeset: r93623:0d3c3f5e2bdb
Date: 2018-01-03 22:51 +0100
http://bitbucket.org/pypy/pypy/changeset/0d3c3f5e2bdb/

Log:Add an option to allow underscores in integer literals. RPython
part.

diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py
--- a/rpython/rlib/rarithmetic.py
+++ b/rpython/rlib/rarithmetic.py
@@ -845,7 +845,7 @@
 # String parsing support
 # ---
 
-def string_to_int(s, base=10):
+def string_to_int(s, base=10, allow_underscores=False):
 """Utility to converts a string to an integer.
 If base is 0, the proper base is guessed based on the leading
 characters of 's'.  Raises ParseStringError in case of error.
@@ -854,7 +854,8 @@
 from rpython.rlib.rstring import (
 NumberStringParser, ParseStringOverflowError, strip_spaces)
 s = literal = strip_spaces(s)
-p = NumberStringParser(s, literal, base, 'int')
+p = NumberStringParser(s, literal, base, 'int',
+   allow_underscores=allow_underscores)
 base = p.base
 result = 0
 while True:
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -272,7 +272,7 @@
 
 @staticmethod
 @jit.elidable
-def fromstr(s, base=0):
+def fromstr(s, base=0, allow_underscores=False):
 """As string_to_int(), but ignores an optional 'l' or 'L' suffix
 and returns an rbigint."""
 from rpython.rlib.rstring import NumberStringParser, \
@@ -281,7 +281,8 @@
 if (s.endswith('l') or s.endswith('L')) and base < 22:
 # in base 22 and above, 'L' is a valid digit!  try: long('L',22)
 s = s[:-1]
-parser = NumberStringParser(s, literal, base, 'long')
+parser = NumberStringParser(s, literal, base, 'long',
+allow_underscores=allow_underscores)
 return rbigint._from_numberstring_parser(parser)
 
 @staticmethod
diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py
--- a/rpython/rlib/rstring.py
+++ b/rpython/rlib/rstring.py
@@ -417,6 +417,9 @@
 def __init__(self, msg):
 self.msg = msg
 
+def __str__(self):
+return self.msg
+
 class InvalidBaseError(ParseStringError):
 """Signals an invalid base argument"""
 
@@ -431,7 +434,7 @@
 raise ParseStringError("invalid literal for %s() with base %d" %
(self.fname, self.original_base))
 
-def __init__(self, s, literal, base, fname):
+def __init__(self, s, literal, base, fname, allow_underscores=False):
 self.fname = fname
 sign = 1
 if s.startswith('-'):
@@ -441,6 +444,8 @@
 s = strip_spaces(s[1:])
 self.sign = sign
 self.original_base = base
+self.allow_underscores = allow_underscores
+self.last_is_underscore = False
 
 if base == 0:
 if s.startswith('0x') or s.startswith('0X'):
@@ -480,13 +485,22 @@
 digit = (digit - ord('A')) + 10
 elif 'a' <= c <= 'z':
 digit = (digit - ord('a')) + 10
+elif c == '_' and self.allow_underscores:
+if self.last_is_underscore:
+self.error()
+self.last_is_underscore = True
+self.i += 1
+return self.next_digit()
 else:
 self.error()
 if digit >= self.base:
 self.error()
 self.i += 1
+self.last_is_underscore = False
 return digit
 else:
+if self.last_is_underscore:
+self.error()
 return -1
 
 def prev_digit(self):
diff --git a/rpython/rlib/test/test_rarithmetic.py 
b/rpython/rlib/test/test_rarithmetic.py
--- a/rpython/rlib/test/test_rarithmetic.py
+++ b/rpython/rlib/test/test_rarithmetic.py
@@ -553,6 +553,51 @@
 py.test.raises(ParseStringError, string_to_int, '+'+s, base)
 py.test.raises(ParseStringError, string_to_int, '-'+s, base)
 
+def test_number_underscores(self):
+VALID_UNDERSCORE_LITERALS = [
+'0_0_0',
+'4_2',
+'1__',
+'0b1001_0100',
+'0x_',
+'0o5_7_7',
+'0b_0',
+'0x_f',
+'0o_5',
+]
+INVALID_UNDERSCORE_LITERALS = [
+# Trailing underscores:
+'0_',
+'42_',
+'1.4j_',
+'0x_',
+'0b1_',
+'0xf_',
+'0o5_',
+# Underscores in the base selector:
+'0_b0',
+'0_xf',
+'0_o5',
+# Old-style octal, still disallowed:
+'09_99',
+# Multiple consecutive underscores:
+'4___2',
+'0b1001__0100',
+'0x__',
+'0x___',
+  

[pypy-commit] pypy py3.6: Add an option to allow underscores in integer literals. RPython part.

2018-01-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3.6
Changeset: r93621:23240e4a895f
Date: 2018-01-03 22:51 +0100
http://bitbucket.org/pypy/pypy/changeset/23240e4a895f/

Log:Add an option to allow underscores in integer literals. RPython
part.

diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py
--- a/rpython/rlib/rarithmetic.py
+++ b/rpython/rlib/rarithmetic.py
@@ -845,7 +845,7 @@
 # String parsing support
 # ---
 
-def string_to_int(s, base=10):
+def string_to_int(s, base=10, allow_underscores=False):
 """Utility to converts a string to an integer.
 If base is 0, the proper base is guessed based on the leading
 characters of 's'.  Raises ParseStringError in case of error.
@@ -854,7 +854,8 @@
 from rpython.rlib.rstring import (
 NumberStringParser, ParseStringOverflowError, strip_spaces)
 s = literal = strip_spaces(s)
-p = NumberStringParser(s, literal, base, 'int')
+p = NumberStringParser(s, literal, base, 'int',
+   allow_underscores=allow_underscores)
 base = p.base
 result = 0
 while True:
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -272,7 +272,7 @@
 
 @staticmethod
 @jit.elidable
-def fromstr(s, base=0):
+def fromstr(s, base=0, allow_underscores=False):
 """As string_to_int(), but ignores an optional 'l' or 'L' suffix
 and returns an rbigint."""
 from rpython.rlib.rstring import NumberStringParser, \
@@ -281,7 +281,8 @@
 if (s.endswith('l') or s.endswith('L')) and base < 22:
 # in base 22 and above, 'L' is a valid digit!  try: long('L',22)
 s = s[:-1]
-parser = NumberStringParser(s, literal, base, 'long')
+parser = NumberStringParser(s, literal, base, 'long',
+allow_underscores=allow_underscores)
 return rbigint._from_numberstring_parser(parser)
 
 @staticmethod
diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py
--- a/rpython/rlib/rstring.py
+++ b/rpython/rlib/rstring.py
@@ -417,6 +417,9 @@
 def __init__(self, msg):
 self.msg = msg
 
+def __str__(self):
+return self.msg
+
 class InvalidBaseError(ParseStringError):
 """Signals an invalid base argument"""
 
@@ -431,7 +434,7 @@
 raise ParseStringError("invalid literal for %s() with base %d" %
(self.fname, self.original_base))
 
-def __init__(self, s, literal, base, fname):
+def __init__(self, s, literal, base, fname, allow_underscores=False):
 self.fname = fname
 sign = 1
 if s.startswith('-'):
@@ -441,6 +444,8 @@
 s = strip_spaces(s[1:])
 self.sign = sign
 self.original_base = base
+self.allow_underscores = allow_underscores
+self.last_is_underscore = False
 
 if base == 0:
 if s.startswith('0x') or s.startswith('0X'):
@@ -480,13 +485,22 @@
 digit = (digit - ord('A')) + 10
 elif 'a' <= c <= 'z':
 digit = (digit - ord('a')) + 10
+elif c == '_' and self.allow_underscores:
+if self.last_is_underscore:
+self.error()
+self.last_is_underscore = True
+self.i += 1
+return self.next_digit()
 else:
 self.error()
 if digit >= self.base:
 self.error()
 self.i += 1
+self.last_is_underscore = False
 return digit
 else:
+if self.last_is_underscore:
+self.error()
 return -1
 
 def prev_digit(self):
diff --git a/rpython/rlib/test/test_rarithmetic.py 
b/rpython/rlib/test/test_rarithmetic.py
--- a/rpython/rlib/test/test_rarithmetic.py
+++ b/rpython/rlib/test/test_rarithmetic.py
@@ -553,6 +553,51 @@
 py.test.raises(ParseStringError, string_to_int, '+'+s, base)
 py.test.raises(ParseStringError, string_to_int, '-'+s, base)
 
+def test_number_underscores(self):
+VALID_UNDERSCORE_LITERALS = [
+'0_0_0',
+'4_2',
+'1__',
+'0b1001_0100',
+'0x_',
+'0o5_7_7',
+'0b_0',
+'0x_f',
+'0o_5',
+]
+INVALID_UNDERSCORE_LITERALS = [
+# Trailing underscores:
+'0_',
+'42_',
+'1.4j_',
+'0x_',
+'0b1_',
+'0xf_',
+'0o5_',
+# Underscores in the base selector:
+'0_b0',
+'0_xf',
+'0_o5',
+# Old-style octal, still disallowed:
+'09_99',
+# Multiple consecutive underscores:
+'4___2',
+'0b1001__0100',
+'0x__',
+'0x___'

[pypy-commit] pypy py3.6: Add math.tau

2018-01-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3.6
Changeset: r93619:6190ca28a930
Date: 2017-12-25 19:08 +0100
http://bitbucket.org/pypy/pypy/changeset/6190ca28a930/

Log:Add math.tau

diff --git a/pypy/module/math/__init__.py b/pypy/module/math/__init__.py
--- a/pypy/module/math/__init__.py
+++ b/pypy/module/math/__init__.py
@@ -11,6 +11,7 @@
 interpleveldefs = {
'e'  : 'interp_math.get(space).w_e',
'pi' : 'interp_math.get(space).w_pi',
+   'tau': 'interp_math.get(space).w_tau',
'inf': 'interp_math.get(space).w_inf',
'nan': 'interp_math.get(space).w_nan',
'pow': 'interp_math.pow',
diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py
--- a/pypy/module/math/interp_math.py
+++ b/pypy/module/math/interp_math.py
@@ -10,6 +10,7 @@
 def __init__(self, space):
 self.w_e = space.newfloat(math.e)
 self.w_pi = space.newfloat(math.pi)
+self.w_tau = space.newfloat(math.pi * 2.0)
 self.w_inf = space.newfloat(rfloat.INFINITY)
 self.w_nan = space.newfloat(rfloat.NAN)
 def get(space):
diff --git a/pypy/module/math/test/test_math.py 
b/pypy/module/math/test/test_math.py
--- a/pypy/module/math/test/test_math.py
+++ b/pypy/module/math/test/test_math.py
@@ -380,3 +380,7 @@
 assert math.isinf(math.inf)
 assert math.inf > -math.inf
 assert math.isnan(math.nan)
+
+def test_pi_tau(self):
+import math
+assert math.tau == math.pi * 2.0
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit