[pypy-commit] cffi default: Revert b84710ae130a again. Ensure we get a warning for every opaque
arigo
pypy.commits at gmail.com
Thu Oct 20 04:20:44 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r2795:94dc0b8274ee
Date: 2016-10-20 10:19 +0200
http://bitbucket.org/cffi/cffi/changeset/94dc0b8274ee/
Log: Revert b84710ae130a again. Ensure we get a warning for every opaque
enum, but then fall back to 'unsigned int'. See documentation for
motivation.
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -519,10 +519,18 @@
smallest_value = min(self.enumvalues)
largest_value = max(self.enumvalues)
else:
- raise api.CDefError("%r has no values explicitly defined: "
- "refusing to guess which integer type it is "
- "meant to be (unsigned/signed, int/long)"
- % self._get_c_name())
+ import warnings
+ try:
+ # XXX! The goal is to ensure that the warnings.warn()
+ # will not suppress the warning. We want to get it
+ # several times if we reach this point several times.
+ __warningregistry__.clear()
+ except NameError:
+ pass
+ warnings.warn("%r has no values explicitly defined; "
+ "guessing that it is equivalent to 'unsigned int'"
+ % self._get_c_name())
+ smallest_value = largest_value = 0
if smallest_value < 0: # needs a signed type
sign = 1
candidate1 = PrimitiveType("int")
diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst
--- a/doc/source/whatsnew.rst
+++ b/doc/source/whatsnew.rst
@@ -10,6 +10,13 @@
in typedefs: ``typedef int foo_t[...];``. It was already supported
for global variables or structure fields.
+* I turned in v1.8 a warning from ``cffi/model.py`` into an error:
+ ``'enum xxx' has no values explicitly defined: refusing to guess which
+ integer type it is meant to be (unsigned/signed, int/long)``. Now I'm
+ turning it back to a warning again; it seems that guessing that the
+ enum has size ``int`` is a 99%-safe bet. (But not 100%, so it stays
+ as a warning.)
+
v1.8.3
======
@@ -61,21 +68,6 @@
argument (in older versions, a copy would be made). This used to be
a CPython-only optimization.
-* Turned a warning from ``cffi/model.py`` into an error: ``'enum xxx'
- has no values explicitly defined: refusing to guess which integer type
- it is meant to be (unsigned/signed, int/long)``. The problem is that
- CFFI can't handle opaque enums. It can only handle enums as ``int``
- or ``long`` integer types. That seems to be enough in almost all
- cases, but strictly speaking, C code *can* handle opaque enums without
- knowing whether it is an ``int`` or a ``long``---i.e. without knowing
- its size. In this situation, in C you can pass pointers to such an
- enum around, and that's about it. CFFI can't do that so far. There
- is no fits-all solution, but try adding to the cdef: ``enum foo {
- FOO_MAX_VALUE=1 };``; and, if using API mode, add ``#define
- FOO_MAX_VALUE 1`` in the ``set_source()``. Replace ``1`` with
- ``9999999999`` in both places in the rare case where the enum needs to
- fit values larger than an int.
-
v1.7
====
diff --git a/testing/cffi0/backend_tests.py b/testing/cffi0/backend_tests.py
--- a/testing/cffi0/backend_tests.py
+++ b/testing/cffi0/backend_tests.py
@@ -1355,15 +1355,15 @@
assert ffi.getctype("e1*") == 'e1 *'
def test_opaque_enum(self):
+ import warnings
ffi = FFI(backend=self.Backend())
ffi.cdef("enum foo;")
- from cffi import __version_info__
- if __version_info__ < (1, 8):
- py.test.skip("re-enable me in version 1.8")
- e = py.test.raises(CDefError, ffi.cast, "enum foo", -1)
- assert str(e.value) == (
- "'enum foo' has no values explicitly defined: refusing to guess "
- "which integer type it is meant to be (unsigned/signed, int/long)")
+ with warnings.catch_warnings(record=True) as log:
+ n = ffi.cast("enum foo", -1)
+ assert int(n) == 0xffffffff
+ assert str(log[0].message) == (
+ "'enum foo' has no values explicitly defined; "
+ "guessing that it is equivalent to 'unsigned int'")
def test_new_ctype(self):
ffi = FFI(backend=self.Backend())
More information about the pypy-commit
mailing list