diff --git a/pyc_code.cpp b/pyc_code.cpp index 2b57107be..ba63eed48 100644 --- a/pyc_code.cpp +++ b/pyc_code.cpp @@ -64,6 +64,13 @@ void PycCode::load(PycData* stream, PycModule* mod) else m_flags = 0; + if (mod->verCompare(3, 8) < 0) { + // Remap flags to new values introduced in 3.8 + if (m_flags & 0xF0000000) + throw std::runtime_error("Cannot remap unexpected flags"); + m_flags = (m_flags & 0xFFFF) | ((m_flags & 0xFFF0000) << 4); + } + m_code = LoadObject(stream, mod).cast(); m_consts = LoadObject(stream, mod).cast(); m_names = LoadObject(stream, mod).cast(); diff --git a/pyc_code.h b/pyc_code.h index 4d6e47cd0..e6b2ce9bc 100644 --- a/pyc_code.h +++ b/pyc_code.h @@ -12,23 +12,29 @@ class PycCode : public PycObject { public: typedef std::vector> globals_t; enum CodeFlags { - CO_OPTIMIZED = 0x1, - CO_NEWLOCALS = 0x2, - CO_VARARGS = 0x4, - CO_VARKEYWORDS = 0x8, - CO_NESTED = 0x10, - CO_GENERATOR = 0x20, - CO_NOFREE = 0x40, - CO_COROUTINE = 0x80, - CO_ITERABLE_COROUTINE = 0x100, - CO_GENERATOR_ALLOWED = 0x1000, - CO_FUTURE_DIVISION = 0x2000, - CO_FUTURE_ABSOLUTE_IMPORT = 0x4000, - CO_FUTURE_WITH_STATEMENT = 0x8000, - CO_FUTURE_PRINT_FUNCTION = 0x10000, - CO_FUTURE_UNICODE_LITERALS = 0x20000, - CO_FUTURE_BARRY_AS_BDFL = 0x40000, - CO_FUTURE_GENERATOR_STOP = 0x80000, + CO_OPTIMIZED = 0x1, // 1.3 -> + CO_NEWLOCALS = 0x2, // 1.3 -> + CO_VARARGS = 0x4, // 1.3 -> + CO_VARKEYWORDS = 0x8, // 1.3 -> + CO_NESTED = 0x10, // 2.1 -> + CO_GENERATOR = 0x20, // 2.2 -> + CO_NOFREE = 0x40, // 2.3 -> + CO_COROUTINE = 0x80, // 3.5 -> + CO_ITERABLE_COROUTINE = 0x100, // 3.5 -> + CO_ASYNC_GENERATOR = 0x200, // 3.6 -> + CO_GENERATOR_ALLOWED = 0x1000, // 2.3 only + + // The FUTURE flags are shifted left 4 bits starting from Python 3.8 + // Older versions are automatically mapped to the new values in load() + CO_FUTURE_DIVISION = 0x20000, // 2.3 - 2.7, 3.1 -> + CO_FUTURE_ABSOLUTE_IMPORT = 0x40000, // 2.5 - 2.7, 3.1 -> + CO_FUTURE_WITH_STATEMENT = 0x80000, // 2.5 - 2.7, 3.1 -> + CO_FUTURE_PRINT_FUNCTION = 0x100000, // 2.6 - 2.7, 3.1 -> + CO_FUTURE_UNICODE_LITERALS = 0x200000, // 2.6 - 2.7, 3.1 -> + CO_FUTURE_BARRY_AS_BDFL = 0x400000, // 3.1 -> + CO_FUTURE_GENERATOR_STOP = 0x800000, // 3.5 -> + CO_FUTURE_ANNOTATIONS = 0x1000000, // 3.7 -> + CO_NO_MONITORING_EVENTS = 0x2000000, // 3.13 -> }; PycCode(int type = TYPE_CODE)