instaloader.py 文件源码

python
阅读 39 收藏 0 点赞 0 评论 0

项目:instaloader 作者: Thammus 项目源码 文件源码
def filterstr_to_filterfunc(filter_str: str, logged_in: bool) -> Callable[['Post'], bool]:
    """Takes an --only-if=... filter specification and makes a filter_func Callable out of it."""

    # The filter_str is parsed, then all names occurring in its AST are replaced by loads to post.<name>. A
    # function Post->bool is returned which evaluates the filter with the post as 'post' in its namespace.

    class TransformFilterAst(ast.NodeTransformer):
        def visit_Name(self, node: ast.Name):
            # pylint:disable=invalid-name,no-self-use
            if not isinstance(node.ctx, ast.Load):
                raise InvalidArgumentException("Invalid filter: Modifying variables ({}) not allowed.".format(node.id))
            if not hasattr(Post, node.id):
                raise InvalidArgumentException("Invalid filter: Name {} is not defined.".format(node.id))
            if node.id in Post.LOGIN_REQUIRING_PROPERTIES and not logged_in:
                raise InvalidArgumentException("Invalid filter: Name {} requires being logged in.".format(node.id))
            new_node = ast.Attribute(ast.copy_location(ast.Name('post', ast.Load()), node), node.id,
                                     ast.copy_location(ast.Load(), node))
            return ast.copy_location(new_node, node)

    input_filename = '<--only-if parameter>'
    compiled_filter = compile(TransformFilterAst().visit(ast.parse(filter_str, filename=input_filename, mode='eval')),
                              filename=input_filename, mode='eval')

    def filterfunc(post: 'Post') -> bool:
        # pylint:disable=eval-used
        return bool(eval(compiled_filter, {'post': post}))

    return filterfunc
评论列表
文章目录


问题


面经


文章

微信
公众号

扫码关注公众号