将python代码编译为PyCodeObject并编组为pyc文件

时间:2017-12-25 09:17:20

标签: python compilation marshalling

我尝试将python代码编译为PyCodeObject并编组为pyc文件。 但是当我导入我的pyc文件时,它失败并且回溯是" ValueError:错误的编组数据(未知类型代码)" 这是我的代码

import mapView from './views/map.html';

routes.$inject = ['$stateProvider'];

function routes($stateProvider) {
    $stateProvider
        .state('map', {
            url: '/',
            templateUrl: mapView,
            controller: 'mapCtrl',
            controllerAs: 'vm',
            module: 'map'
        })
}

export default routes;

1 个答案:

答案 0 :(得分:0)

我认为引发ValueError是因为时间戳类型不匹配。您应该确保fmt中的L参数(struct.pack使用,标准大小为4个字节)与python可执行文件的长度相同。

由于时间戳的值不会影响最终结果,因此在这里使类型合适就足够了。如果您使用64位版本的CPython,请尝试使用Q而不是L来确保8个字节。

===更新开始===

抱歉,我在前面的描述中犯了一个严重的错误。

没有任何前缀的

L表示native,并且大小和字节顺序与机器的本机格式和字节顺序相同(在64位CPython中,它将是8个字节)。但是,写入pyc文件的时间戳在Python 2和3中始终为4个字节(小端)。

如果使用的是Python2,我们应该使用<L而不是L,它具有标准大小,4个字节。

如果使用的是Python3,除了timestamp之外,我们应该添加另外4个字节的字段source size,如下面的代码所示( importlib / _bootstrap_external.py,Python3.6.4

def _code_to_bytecode(code, mtime=0, source_size=0):
    """Compile a code object into bytecode for writing out to a byte-compiled
    file."""
    data = bytearray(MAGIC_NUMBER)
    data.extend(_w_long(mtime))
    data.extend(_w_long(source_size))
    data.extend(marshal.dumps(code))
    return data

最后,您可以参考pkgutil.read_code(),这与编写代码的顺序相反。

===更新结束===

顺便提一下,您的代码中存在一些缺陷:未使用co函数中的filenamedump参数