Author: mattip <matti.pi...@gmail.com>
Branch: fold-arith-ops
Changeset: r77488:c754273874e0
Date: 2015-05-22 17:00 +0300
http://bitbucket.org/pypy/pypy/changeset/c754273874e0/

Log:    document branch

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.0.0
+Version: 1.0.2
 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
@@ -4,8 +4,8 @@
 from .api import FFI, CDefError, FFIError
 from .ffiplatform import VerificationError, VerificationMissing
 
-__version__ = "1.0.0"
-__version_info__ = (1, 0, 0)
+__version__ = "1.0.2"
+__version_info__ = (1, 0, 2)
 
 # 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/_cffi_include.h b/lib_pypy/cffi/_cffi_include.h
--- a/lib_pypy/cffi/_cffi_include.h
+++ b/lib_pypy/cffi/_cffi_include.h
@@ -1,3 +1,4 @@
+#define _CFFI_
 #include <Python.h>
 #ifdef __cplusplus
 extern "C" {
@@ -6,7 +7,8 @@
 #include "parse_c_type.h"
 
 /* this block of #ifs should be kept exactly identical between
-   c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py */
+   c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py
+   and cffi/_cffi_include.h */
 #if defined(_MSC_VER)
 # include <malloc.h>   /* for alloca() */
 # if _MSC_VER < 1600   /* MSVC < 2010 */
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
@@ -109,6 +109,11 @@
             if override:
                 for cache in self._function_caches:
                     cache.clear()
+            finishlist = self._parser._recomplete
+            if finishlist:
+                self._parser._recomplete = []
+                for tp in finishlist:
+                    tp.finish_backend_type(self, finishlist)
 
     def dlopen(self, name, flags=0):
         """Load and return a dynamic library identified by 'name'.
diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py
--- a/lib_pypy/cffi/cparser.py
+++ b/lib_pypy/cffi/cparser.py
@@ -101,6 +101,7 @@
         self._override = False
         self._packed = False
         self._int_constants = {}
+        self._recomplete = []
 
     def _parse(self, csource):
         csource, macros = _preprocess(csource)
@@ -555,6 +556,9 @@
                 raise NotImplementedError("%s: using both bitfields and '...;'"
                                           % (tp,))
         tp.packed = self._packed
+        if tp.completed:    # must be re-completed: it is not opaque any more
+            tp.completed = 0
+            self._recomplete.append(tp)
         return tp
 
     def _make_partial(self, tp, nested):
@@ -604,19 +608,21 @@
 
     def _build_enum_type(self, explicit_name, decls):
         if decls is not None:
-            enumerators1 = [enum.name for enum in decls.enumerators]
-            enumerators = [s for s in enumerators1
-                             if not _r_enum_dotdotdot.match(s)]
-            partial = len(enumerators) < len(enumerators1)
-            enumerators = tuple(enumerators)
+            partial = False
+            enumerators = []
             enumvalues = []
             nextenumvalue = 0
-            for enum in decls.enumerators[:len(enumerators)]:
+            for enum in decls.enumerators:
+                if _r_enum_dotdotdot.match(enum.name):
+                    partial = True
+                    continue
                 if enum.value is not None:
                     nextenumvalue = self._parse_constant(enum.value)
+                enumerators.append(enum.name)
                 enumvalues.append(nextenumvalue)
                 self._add_constants(enum.name, nextenumvalue)
                 nextenumvalue += 1
+            enumerators = tuple(enumerators)
             enumvalues = tuple(enumvalues)
             tp = model.EnumType(explicit_name, enumerators, enumvalues)
             tp.partial = partial
diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py
--- a/lib_pypy/cffi/model.py
+++ b/lib_pypy/cffi/model.py
@@ -293,7 +293,7 @@
 
 class StructOrUnion(StructOrUnionOrEnum):
     fixedlayout = None
-    completed = False
+    completed = 0
     partial = False
     packed = False
 
@@ -351,12 +351,13 @@
                                           "for '%s'" % (self.name,))
             return
         BType = ffi._cached_btypes[self]
-        if self.fldtypes is None:
-            return    # not completing it: it's an opaque struct
         #
         self.completed = 1
         #
-        if self.fixedlayout is None:
+        if self.fldtypes is None:
+            pass    # not completing it: it's an opaque struct
+            #
+        elif self.fixedlayout is None:
             fldtypes = [tp.get_cached_btype(ffi, finishlist)
                         for tp in self.fldtypes]
             lst = list(zip(self.fldnames, fldtypes, self.fldbitsize))
diff --git a/lib_pypy/cffi/parse_c_type.h b/lib_pypy/cffi/parse_c_type.h
--- a/lib_pypy/cffi/parse_c_type.h
+++ b/lib_pypy/cffi/parse_c_type.h
@@ -1,5 +1,5 @@
 
-/* See doc/parse_c_type.rst in the source of CFFI for more information */
+/* See doc/misc/parse_c_type.rst in the source of CFFI for more information */
 
 typedef void *_cffi_opcode_t;
 
diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py
--- a/lib_pypy/cffi/recompiler.py
+++ b/lib_pypy/cffi/recompiler.py
@@ -581,10 +581,11 @@
 
     def _generate_cpy_function_collecttype(self, tp, name):
         self._do_collect_type(tp.as_raw_function())
-        if tp.ellipsis:
+        if tp.ellipsis and not self.target_is_python:
             self._do_collect_type(tp)
 
     def _generate_cpy_function_decl(self, tp, name):
+        assert not self.target_is_python
         assert isinstance(tp, model.FunctionPtrType)
         if tp.ellipsis:
             # cannot support vararg functions better than this: check for its
@@ -702,7 +703,7 @@
         prnt()
 
     def _generate_cpy_function_ctx(self, tp, name):
-        if tp.ellipsis:
+        if tp.ellipsis and not self.target_is_python:
             self._generate_cpy_constant_ctx(tp, name)
             return
         type_index = self._typesdict[tp.as_raw_function()]
diff --git a/lib_pypy/cffi/setuptools_ext.py b/lib_pypy/cffi/setuptools_ext.py
--- a/lib_pypy/cffi/setuptools_ext.py
+++ b/lib_pypy/cffi/setuptools_ext.py
@@ -76,7 +76,7 @@
     from cffi import recompiler
 
     allsources = ['$PLACEHOLDER']
-    allsources.extend(kwds.get('sources', []))
+    allsources.extend(kwds.pop('sources', []))
     ext = Extension(name=module_name, sources=allsources, **kwds)
 
     def make_mod(tmpdir):
diff --git a/pypy/doc/sprint-reports.rst b/pypy/doc/sprint-reports.rst
--- a/pypy/doc/sprint-reports.rst
+++ b/pypy/doc/sprint-reports.rst
@@ -1,4 +1,4 @@
-Sprint reports from PyPy sprints 2003-2006
+Sprint reports from PyPy sprints 2003-2010
 ==========================================
 
 Here are links to sprint reports from various sprints in the PyPy project,
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-2.6.0.rst
copy from pypy/doc/whatsnew-head.rst
copy to pypy/doc/whatsnew-2.6.0.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-2.6.0.rst
@@ -117,4 +117,17 @@
 
 .. branch: cffi-1.0
 
+branch cffi-1.0
 PyPy now includes CFFI 1.0.
+
+.. branch: pypyw
+
+branch pypyw
+PyPy on windows provides a non-console pypyw.exe as well as pypy.exe.
+Similar to pythonw.exe, any use of stdout, stderr without redirection
+will crash.
+
+.. branch: fold-arith-ops
+
+branch fold-arith-ops
+remove multiple adds on add chains ("1 + 1 + 1 + ...")
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -1,120 +1,8 @@
 =======================
-What's new in PyPy 2.5+
+What's new in PyPy 2.6+
 =======================
 
-.. this is a revision shortly after release-2.5.1
-.. startrev: cb01edcb59414d9d93056e54ed060673d24e67c1
+.. this is a revision shortly after release-2.6.0
+.. startrev: 4c5c81da93e2e3c9df6be64d9bd79c958144de55
 
-issue2005:
-ignore errors on closing random file handles while importing a module (cpython 
compatibility)
 
-issue2013:
-added constants to _ssl for TLS 1.1 and 1.2
-
-issue2014:
-Add PyLong_FromUnicode to cpyext.
-
-issue2017: 
-On non-Linux-x86 platforms, reduced the memory impact of
-creating a lot of greenlets/tasklets.  Particularly useful on Win32 and
-on ARM, where you used to get a MemoryError after only 2500-5000
-greenlets (the 32-bit address space is exhausted).
-
-Update gdb_pypy for python3 (gdb comatability)
-
-Merged rstrategies into rpython which provides a library for Storage Strategies
-
-Support unicode strings in numpy.dtype creation i.e. np.dtype(u'int64')
-
-Various rpython cleanups for vmprof support
-
-issue2019:
-Fix isspace as called by rpython unicode.strip()
-
-issue2023:
-In the cpyext 'Concrete Object Layer' API,
-don't call methods on the object (which can be overriden),
-but directly on the concrete base type.
-
-issue2029:
-Hide the default_factory attribute in a dict
-
-issue2027:
-Better document pyinteractive and add --withmod-time
-
-.. branch: gc-incminimark-pinning-improve
-
-branch gc-incminimark-pinning-improve: 
-Object Pinning is now used in `bz2` and `rzlib` (therefore also affects
-Python's `zlib`). In case the data to compress/decompress is inside the nursery
-(incminimark) it no longer needs to create a non-moving copy of it. This saves
-one `malloc` and copying the data.  Additionally a new GC environment variable
-is introduced (`PYPY_GC_MAX_PINNED`) primarily for debugging purposes.
-
-.. branch: refactor-pycall
-
-branch refactor-pycall:
-Make `*`-unpacking in RPython function calls completely equivalent to passing
-the tuple's elements as arguments. In other words, `f(*(a, b))` now behaves 
-exactly like `f(a, b)`.
-
-.. branch: issue2018
-
-branch issue2018:
-Allow prebuilt rpython dict with function values
-
-.. branch: vmprof
-.. Merged but then backed out, hopefully it will return as vmprof2
-
-.. branch: object-dtype2
-
-branch object-dtype2:
-Extend numpy dtypes to allow using objects with associated garbage collection 
hook
-
-.. branch: vmprof2
-
-branch vmprof2:
-Add backend support for vmprof - a lightweight statistical profiler -
-to linux64, see client at https://vmprof.readthedocs.org
-
-.. branch: jit_hint_docs
-
-branch jit_hint_docs:
-Add more detail to @jit.elidable and @jit.promote in rpython/rlib/jit.py
-
-.. branch: remove-frame-debug-attrs
-
-branch remove_frame-debug-attrs:
-Remove the debug attributes from frames only used for tracing and replace
-them with a debug object that is created on-demand
-
-.. branch: can_cast
-
-branch can_cast:
-Implement np.can_cast, np.min_scalar_type and missing dtype comparison 
operations.
-
-.. branch: numpy-fixes
-
-branch numpy-fixes:
-Fix some error related to object dtype, non-contiguous arrays, inplement parts 
of 
-__array_interface__, __array_priority__, __array_wrap__
-
-.. branch: cells-local-stack
-
-branch cells-local-stack:
-Unify the PyFrame.cells and Pyframe.locals_stack_w lists, making frame objects
-1 or 3 words smaller.
-
-.. branch: pythonoptimize-env
-
-branch pythonoptimize-env
-Implement PYTHONOPTIMIZE environment variable, fixing issue #2044
-
-.. branch: numpy-flags
-
-branch numpy-flags
-Finish implementation of ndarray.flags, including str() and repr()
-
-.. branch: cffi-1.0
-
-PyPy now includes CFFI 1.0.
diff --git a/pypy/module/_cffi_backend/__init__.py 
b/pypy/module/_cffi_backend/__init__.py
--- a/pypy/module/_cffi_backend/__init__.py
+++ b/pypy/module/_cffi_backend/__init__.py
@@ -2,7 +2,7 @@
 from pypy.interpreter.mixedmodule import MixedModule
 from rpython.rlib import rdynload
 
-VERSION = "1.0.0"
+VERSION = "1.0.2"
 
 
 class Module(MixedModule):
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
@@ -3335,4 +3335,4 @@
 
 def test_version():
     # this test is here mostly for PyPy
-    assert __version__ == "1.0.0"
+    assert __version__ == "1.0.2"
diff --git a/pypy/module/cpyext/include/patchlevel.h 
b/pypy/module/cpyext/include/patchlevel.h
--- a/pypy/module/cpyext/include/patchlevel.h
+++ b/pypy/module/cpyext/include/patchlevel.h
@@ -29,7 +29,7 @@
 #define PY_VERSION             "2.7.9"
 
 /* PyPy version as a string */
-#define PYPY_VERSION "2.6.0-alpha0"
+#define PYPY_VERSION "2.7.0-alpha0"
 
 /* Subversion Revision number of this file (not of the repository).
  * Empty since Mercurial migration. */
diff --git a/pypy/module/cpyext/include/pyconfig.h 
b/pypy/module/cpyext/include/pyconfig.h
--- a/pypy/module/cpyext/include/pyconfig.h
+++ b/pypy/module/cpyext/include/pyconfig.h
@@ -28,7 +28,7 @@
 #endif
 
 #ifndef Py_BUILD_CORE /* not building the core - must be an ext */
-#    if defined(_MSC_VER)
+#    if defined(_MSC_VER) && !defined(_CFFI_)
      /* So MSVC users need not specify the .lib file in
       * their Makefile (other compilers are generally
       * taken care of by distutils.) */
diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py
--- a/pypy/module/sys/version.py
+++ b/pypy/module/sys/version.py
@@ -10,7 +10,7 @@
 #XXX # sync CPYTHON_VERSION with patchlevel.h, package.py
 CPYTHON_API_VERSION        = 1013   #XXX # sync with include/modsupport.h
 
-PYPY_VERSION               = (2, 6, 0, "alpha", 0)    #XXX # sync patchlevel.h
+PYPY_VERSION               = (2, 7, 0, "alpha", 0)    #XXX # sync patchlevel.h
 
 if platform.name == 'msvc':
     COMPILER_INFO = 'MSC v.%d 32 bit' % (platform.version * 10 + 600)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
@@ -1704,3 +1704,13 @@
         assert lib.DOT_HEX == 0x100
         assert lib.DOT_HEX2 == 0x10
         assert lib.DOT_UL == 1000
+
+    def test_opaque_struct_becomes_nonopaque(self):
+        # Issue #193: if we use a struct between the first cdef() where it is
+        # declared and another cdef() where its fields are defined, then the
+        # definition was ignored.
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("struct foo_s;")
+        py.test.raises(TypeError, ffi.new, "struct foo_s *")
+        ffi.cdef("struct foo_s { int x; };")
+        ffi.new("struct foo_s *")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py
@@ -765,6 +765,11 @@
     assert ffi.string(ffi.cast('enum ee2', -1239)) == 'EE4'
     assert ffi.string(ffi.cast('enum ee2', -1238)) == 'EE5'
 
+def test_nonfull_enum_bug3():
+    ffi = FFI()
+    ffi.cdef("enum ee2 { EE4=..., EE5=... };")
+    ffi.cdef("enum ee6 { EE7=10, EE8=..., EE9=... };")
+
 def test_get_set_errno():
     ffi = FFI()
     ffi.cdef("int foo(int);")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py
@@ -13,6 +13,7 @@
     #define BIGPOS 420000000000L
     #define BIGNEG -420000000000L
     int add42(int x) { return x + 42; }
+    int add43(int x, ...) { return x; }
     int globalvar42 = 1234;
     struct foo_s;
     typedef struct bar_s { int x; signed char a[]; } bar_t;
@@ -38,6 +39,7 @@
     #define BIGPOS 420000000000L
     #define BIGNEG -420000000000L
     int add42(int);
+    int add43(int, ...);
     int globalvar42;
     int no_such_function(int);
     int no_such_globalvar;
@@ -69,6 +71,13 @@
     assert lib.add42(-10) == 32
     assert type(lib.add42) is _cffi_backend.FFI.CData
 
+def test_function_with_varargs():
+    import _cffi_backend
+    from re_python_pysrc import ffi
+    lib = ffi.dlopen(extmod)
+    assert lib.add43(45, ffi.cast("int", -5)) == 45
+    assert type(lib.add43) is _cffi_backend.FFI.CData
+
 def test_dlclose():
     import _cffi_backend
     from re_python_pysrc import ffi
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
@@ -762,3 +762,18 @@
     py.test.raises(AttributeError, ffi.addressof, lib, 'unknown_var')
     py.test.raises(AttributeError, ffi.addressof, lib, "FOOBAR")
     assert ffi.addressof(lib, 'FetchRectBottom') == lib.FetchRectBottom
+
+def test_defines__CFFI_():
+    # Check that we define the macro _CFFI_ automatically.
+    # It should be done before including Python.h, so that PyPy's Python.h
+    # can check for it.
+    ffi = FFI()
+    ffi.cdef("""
+        #define CORRECT 1
+    """)
+    lib = verify(ffi, "test_defines__CFFI_", """
+    #ifdef _CFFI_
+    #    define CORRECT 1
+    #endif
+    """)
+    assert lib.CORRECT == 1
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -50,16 +50,23 @@
         os.system("chmod -R g-w %s" % dirname)
 
 
+cffi_build_scripts = {
+    "sqlite3": "_sqlite3_build.py",
+    "audioop": "_audioop_build.py",
+    "tk": "_tkinter/tklib_build.py",
+    "curses": "_curses_build.py" if sys.platform != "win32" else None,
+    "syslog": "_syslog_build.py" if sys.platform != "win32" else None,
+    "gdbm": "_gdbm_build.py"  if sys.platform != "win32" else None,
+    "pwdgrp": "_pwdgrp_build.py" if sys.platform != "win32" else None,
+    "xx": None,    # for testing: 'None' should be completely ignored
+    }
+
 def create_cffi_import_libraries(pypy_c, options, basedir):
     shutil.rmtree(str(basedir.join('lib_pypy', '__pycache__')),
                   ignore_errors=True)
-    modules = ['_sqlite3_build.py', '_audioop_build.py']
-    if not sys.platform == 'win32':
-        modules += ['_curses_build.py', '_syslog_build.py', '_gdbm_build.py',
-                    '_pwdgrp_build.py']
-    if not options.no_tk:
-        modules.append('_tkinter/tklib_build.py')
-    for module in modules:
+    for key, module in sorted(cffi_build_scripts.items()):
+        if module is None or getattr(options, 'no_' + key):
+            continue
         if module.endswith('.py'):
             args = [str(pypy_c), module]
             cwd = str(basedir.join('lib_pypy'))
@@ -70,9 +77,9 @@
         try:
             subprocess.check_call(args, cwd=cwd)
         except subprocess.CalledProcessError:
-            print >>sys.stderr, """Building {0} bindings failed.
+            print >>sys.stderr, """!!!!!!!!!!\nBuilding {0} bindings failed.
 You can either install development headers package or
-add --without-{0} option to skip packaging binary CFFI 
extension.""".format(module)
+add --without-{0} option to skip packaging this binary CFFI 
extension.""".format(key)
             raise MissingDependenciesError(module)
 
 def pypy_runs(pypy_c, quiet=False):
@@ -109,8 +116,7 @@
         try:
             create_cffi_import_libraries(pypy_c, options, basedir)
         except MissingDependenciesError:
-            # This is a non-fatal error
-            retval = -1
+            return 1, None
 
     if sys.platform == 'win32' and not rename_pypy_c.lower().endswith('.exe'):
         rename_pypy_c += '.exe'
@@ -142,6 +148,12 @@
     pypydir.ensure('include', dir=True)
 
     if sys.platform == 'win32':
+        src,tgt = binaries[0]
+        pypyw = src.new(purebasename=src.purebasename + 'w')
+        if pypyw.exists():
+            tgt = py.path.local(tgt)
+            binaries.append((pypyw, tgt.new(purebasename=tgt.purebasename + 
'w').basename))
+            print "Picking %s" % str(pypyw)
         # Can't rename a DLL: it is always called 'libpypy-c.dll'
         win_extras = ['libpypy-c.dll', 'sqlite3.dll']
         if not options.no_tk:
@@ -274,11 +286,18 @@
         pypy_exe = 'pypy'
     parser = argparse.ArgumentParser()
     args = list(args)
-    args[0] = str(args[0])
-    parser.add_argument('--without-tk', dest='no_tk', action='store_true',
-        help='build and package the cffi tkinter module')
+    if args:
+        args[0] = str(args[0])
+    else:
+        args.append('--help')
+    for key, module in sorted(cffi_build_scripts.items()):
+        if module is not None:
+            parser.add_argument('--without-' + key,
+                    dest='no_' + key,
+                    action='store_true',
+                    help='do not build and package the %r cffi module' % 
(key,))
     parser.add_argument('--without-cffi', dest='no_cffi', action='store_true',
-        help='do not pre-import any cffi modules')
+        help='skip building *all* the cffi modules listed above')
     parser.add_argument('--nostrip', dest='nostrip', action='store_true',
         help='do not strip the exe, making it ~10MB larger')
     parser.add_argument('--rename_pypy_c', dest='pypy_c', type=str, 
default=pypy_exe,
diff --git a/pypy/tool/release/test/test_package.py 
b/pypy/tool/release/test/test_package.py
--- a/pypy/tool/release/test/test_package.py
+++ b/pypy/tool/release/test/test_package.py
@@ -1,7 +1,7 @@
 
 import py
 from pypy.conftest import pypydir
-from pypy.tool.release import package, package
+from pypy.tool.release import package
 from pypy.module.sys.version import  CPYTHON_VERSION
 import tarfile, zipfile, sys
 
@@ -32,8 +32,9 @@
     else:
         fake_pypy_c = False
     try:
-        retval, builddir = package.package(py.path.local(pypydir).dirpath(), 
test,
-                                   rename_pypy_c)
+        retval, builddir = package.package(
+            '--without-cffi', str(py.path.local(pypydir).dirpath()),
+            test, rename_pypy_c)
         assert retval == 0
         prefix = builddir.join(test)
         cpyver = '%d.%d' % CPYTHON_VERSION[:2]
diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py
--- a/rpython/rlib/rdynload.py
+++ b/rpython/rlib/rdynload.py
@@ -152,9 +152,9 @@
     def dlclose(handle):
         res = rwin32.FreeLibrary(handle)
         if res:
-            return -1
+            return 0    # success
         else:
-            return 0
+            return -1   # error
 
     def dlsym(handle, name):
         res = rwin32.GetProcAddress(handle, name)
diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -293,7 +293,7 @@
         bk = self.translator.annotator.bookkeeper
         return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph())
 
-    def cmdexec(self, args='', env=None, err=False, expect_crash=False):
+    def cmdexec(self, args='', env=None, err=False, expect_crash=False, 
exe=None):
         assert self._compiled
         if sys.platform == 'win32':
             #Prevent opening a dialog box
@@ -314,9 +314,10 @@
             envrepr = ''
         else:
             envrepr = ' [env=%r]' % (env,)
-        log.cmdexec('%s %s%s' % (self.executable_name, args, envrepr))
-        res = self.translator.platform.execute(self.executable_name, args,
-                                               env=env)
+        if exe is None:
+            exe = self.executable_name
+        log.cmdexec('%s %s%s' % (exe, args, envrepr))
+        res = self.translator.platform.execute(exe, args, env=env)
         if sys.platform == 'win32':
             SetErrorMode(old_mode)
         if res.returncode != 0:
diff --git a/rpython/translator/c/test/test_standalone.py 
b/rpython/translator/c/test/test_standalone.py
--- a/rpython/translator/c/test/test_standalone.py
+++ b/rpython/translator/c/test/test_standalone.py
@@ -845,6 +845,13 @@
         #Do not set LD_LIBRARY_PATH, make sure $ORIGIN flag is working
         out, err = cbuilder.cmdexec("a b")
         assert out == "3"
+        if sys.platform == 'win32':
+            # Make sure we have a test_1w.exe
+            # Since stdout, stderr are piped, we will get output
+            exe = cbuilder.executable_name
+            wexe = exe.new(purebasename=exe.purebasename + 'w')
+            out, err = cbuilder.cmdexec("a b", exe = wexe)
+            assert out == "3"
 
     def test_gcc_options(self):
         # check that the env var CC is correctly interpreted, even if
diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py
--- a/rpython/translator/driver.py
+++ b/rpython/translator/driver.py
@@ -458,11 +458,14 @@
             shutil_copy(str(fname), str(dstname))
             self.log.info('Static data info written to %s' % dstname)
 
-    def compute_exe_name(self):
+    def compute_exe_name(self, suffix=''):
         newexename = self.exe_name % self.get_info()
         if '/' not in newexename and '\\' not in newexename:
             newexename = './' + newexename
-        return py.path.local(newexename)
+        newname = py.path.local(newexename)
+        if suffix:
+            newname = newname.new(purebasename = newname.purebasename + suffix)
+        return newname
 
     def create_exe(self):
         """ Copy the compiled executable into current directory, which is
@@ -478,6 +481,11 @@
                 shutil_copy(str(soname), str(newsoname))
                 self.log.info("copied: %s" % (newsoname,))
                 if sys.platform == 'win32':
+                    # Copy pypyw.exe
+                    newexename = mkexename(self.compute_exe_name(suffix='w'))
+                    exe = py.path.local(exename)
+                    exename = exe.new(purebasename=exe.purebasename + 'w')
+                    shutil_copy(str(exename), str(newexename))
                     # the import library is named python27.lib, according
                     # to the pragma in pyconfig.h
                     libname = str(newsoname.dirpath().join('python27.lib'))
diff --git a/rpython/translator/platform/windows.py 
b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -260,6 +260,8 @@
         if shared:
             so_name = exe_name.new(purebasename='lib' + exe_name.purebasename,
                                    ext=self.so_ext)
+            wtarget_name = exe_name.new(purebasename=exe_name.purebasename + 
'w',
+                                   ext=self.exe_ext)
             target_name = so_name.basename
         else:
             target_name = exe_name.basename
@@ -313,11 +315,13 @@
             ('MAKE', 'nmake.exe'),
             ('_WIN32', '1'),
             ]
+        if shared:
+            definitions.insert(0, ('WTARGET', wtarget_name.basename))
         if self.x64:
             definitions.append(('_WIN64', '1'))
 
         rules = [
-            ('all', '$(DEFAULT_TARGET)', []),
+            ('all', '$(DEFAULT_TARGET) $(WTARGET)', []),
             ('.asm.obj', '', '$(MASM) /nologo /Fo$@ /c $< $(INCLUDEDIRS)'),
             ]
 
@@ -411,14 +415,33 @@
                    'int main(int argc, char* argv[]) '
                    '{ return $(PYPY_MAIN_FUNCTION)(argc, argv); } > $@')
             deps = ['main.obj']
+            m.rule('wmain.c', '',
+                   ['echo #define WIN32_LEAN_AND_MEAN > $@',
+                   'echo #include "windows.h" >> $@',
+                   'echo int $(PYPY_MAIN_FUNCTION)(int, char*[]); >> $@',
+                   'echo int WINAPI WinMain( >> $@',
+                   'echo     HINSTANCE hInstance,      /* handle to current 
instance */ >> $@',
+                   'echo     HINSTANCE hPrevInstance,  /* handle to previous 
instance */ >> $@',
+                   'echo     LPSTR lpCmdLine,          /* pointer to command 
line */ >> $@',
+                   'echo     int nCmdShow              /* show state of window 
*/ >> $@',
+                   'echo ) >> $@',
+                   'echo    { return $(PYPY_MAIN_FUNCTION)(__argc, __argv); } 
>> $@'])
+            wdeps = ['wmain.obj']
             if icon:
                 deps.append('icon.res')
+                wdeps.append('icon.res')
             m.rule('$(DEFAULT_TARGET)', ['$(TARGET)'] + deps,
                    ['$(CC_LINK) /nologo /debug %s ' % (' '.join(deps),) + \
                     '$(SHARED_IMPORT_LIB) /out:$@ ' + \
                     '/MANIFEST /MANIFESTFILE:$*.manifest',
                     'mt.exe -nologo -manifest $*.manifest 
-outputresource:$@;1',
                     ])
+            m.rule('$(WTARGET)', ['$(TARGET)'] + wdeps,
+                   ['$(CC_LINK) /nologo /debug /SUBSYSTEM:WINDOWS %s ' % (' 
'.join(wdeps),) + \
+                    '$(SHARED_IMPORT_LIB) /out:$@ ' + \
+                    '/MANIFEST /MANIFESTFILE:$*.manifest',
+                    'mt.exe -nologo -manifest $*.manifest 
-outputresource:$@;1',
+                    ])
             m.rule('debugmode_$(DEFAULT_TARGET)', ['debugmode_$(TARGET)']+deps,
                    ['$(CC_LINK) /nologo /DEBUG %s ' % (' '.join(deps),) + \
                     'debugmode_$(SHARED_IMPORT_LIB) /out:$@',
diff --git a/rpython/translator/test/test_driver.py 
b/rpython/translator/test/test_driver.py
--- a/rpython/translator/test/test_driver.py
+++ b/rpython/translator/test/test_driver.py
@@ -53,17 +53,21 @@
 
     dst_name = udir.join('dst/pypy.exe')
     src_name = udir.join('src/dydy2.exe')
+    wsrc_name = udir.join('src/dydy2w.exe')
     dll_name = udir.join('src/pypy.dll')
     lib_name = udir.join('src/pypy.lib')
     pdb_name = udir.join('src/pypy.pdb')
     src_name.ensure()
     src_name.write('exe')
+    wsrc_name.ensure()
+    wsrc_name.write('wexe')
     dll_name.ensure()
     dll_name.write('dll')
     lib_name.ensure()
     lib_name.write('lib')
     pdb_name.ensure()
     pdb_name.write('pdb')
+    # Create the dst directory
     dst_name.ensure()
 
     class CBuilder(object):
@@ -76,6 +80,7 @@
     assert dst_name.read() == 'exe'
     assert dst_name.new(ext='dll').read() == 'dll'
     assert dst_name.new(purebasename='python27',ext='lib').read() == 'lib'
+    assert dst_name.new(purebasename=dst_name.purebasename + 'w').read() == 
'wexe'
 
 def test_shutil_copy():
     if os.name == 'nt':
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to