Commits

Armin Rigo  committed 5f31908

Fix the logic: it was possible to reach the following bug (for which
I don't know how to write a small test):

- in cffi: python setup.py install

- in demo/bsdopendirtype: python setup.py install

- rm -r demo/__pycache__ demo/build

- in demo/bsdopendirtype: python setup.py install

Then it would crash because it would not regenerate the C source
but call the compiler anyway.

  • Participants
  • Parent commits aa00674

Comments (0)

Files changed (1)

File cffi/verifier.py

 
 
 class Verifier(object):
-    _status = '?'
 
     def __init__(self, ffi, preamble, force_generic_engine=False, **kwds):
         self.ffi = ffi
         suffix = _get_so_suffix()
         self.sourcefilename = os.path.join(_TMPDIR, modulename + '.c')
         self.modulefilename = os.path.join(_TMPDIR, modulename + suffix)
-        self._status = 'init'
+        self._has_source = False
+        self._has_module = False
 
     def write_source(self, file=None):
         """Write the C source code.  It is produced in 'self.sourcefilename',
         which can be tweaked beforehand."""
-        if self._status == 'init':
-            self._write_source(file)
-        else:
+        if self._has_source and file is None:
             raise ffiplatform.VerificationError("source code already written")
+        self._write_source(file)
 
     def compile_module(self):
         """Write the C source code (if not done already) and compile it.
         This produces a dynamic link library in 'self.modulefilename'."""
-        if self._status == 'init':
+        if self._has_module:
+            raise ffiplatform.VerificationError("module already compiled")
+        if not self._has_source:
             self._write_source()
-        if self._status == 'source':
-            self._compile_module()
-        else:
-            raise ffiplatform.VerificationError("module already compiled")
+        self._compile_module()
 
     def load_library(self):
         """Get a C module from this Verifier instance.
         operations to the C module.  If necessary, the C code is written
         and compiled first.
         """
-        if self._status == 'init':       # source code not written yet
+        if not self._has_module:
             self._locate_module()
-        if self._status == 'init':
-            self._write_source()
-        if self._status == 'source':
-            self._compile_module()
-        assert self._status == 'module'
+            if not self._has_module:
+                self.compile_module()
         return self._load_library()
 
     def get_module_name(self):
         return basename.split('.', 1)[0]
 
     def get_extension(self):
-        if self._status == 'init':
+        if not self._has_source:
             self._write_source()
         sourcename = self.sourcefilename
         modname = self.get_module_name()
                 f.close()
             self.modulefilename = filename
         self._vengine.collect_types()
-        self._status = 'module'
+        self._has_module = True
 
     def _write_source(self, file=None):
         must_close = (file is None)
             del self._vengine._f
             if must_close:
                 file.close()
-        self._status = 'source'
+        if file is None:
+            self._has_source = True
 
     def _compile_module(self):
         # compile this C source
         if not same:
             _ensure_dir(self.modulefilename)
             shutil.move(outputfilename, self.modulefilename)
-        self._status = 'module'
+        self._has_module = True
 
     def _load_library(self):
+        assert self._has_module
         return self._vengine.load_library()
 
 # ____________________________________________________________