东东东 陈煜东的博客

月份存档: 七月 2016

Disqus已被认证

社交化评论系统Disqus在国外非常的流行,前几个月,我也是从duoshuo转到了Disqus,感觉评论的风格还算简洁,个人感觉也挺喜欢的。

用了一段时间,Disqus用HTTP无法访问了。为此专门研究了一下,原来HTTPS还可以访问,特意加将全站转向了HTTPS。没想到用了几个月,这两天发现评论框出不来了。

找了站长工具超级PING,发现基本一片红色呀。

大陆的访问disqus情况

大陆的访问disqus情况

各个地域的域名DNS解析

各个地域的disqus域名解析

各个地域的disqus域名解析

域名解析出来,已经到了『阿塞拜疆』,一个中东国家。

要想继续使用Disqus,那么只能靠有个海外的服务器进行反向代理了。目前没有购买海外服务器,改天看看有没有能搞一个海外服务器做反向代理。

本来想再用回duoshuo的,但是微博的头像竟然没有HTTPS的连接,想想还是先算了吧。真好搞,网上有很多『多说完美HTTPS』教程,看着搞代理,修改源码,都不太稳定。

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: Disqus已被认证 – https://www.chenyudong.com/archives/disqus-connect-timeout.html

分类: 网站建设

Graphviz安装失败的一个尝试

Graphviz来对sphinx进行画图,不过发现一直无法编译出来。

PS:Graphviz的官网在大陆访问非常的慢。

首先参考http://graphviz.org/Download_linux_rhel.php,增加一个repo源,

然后执行yum install 'graphviz*'安装graphviz的软件。

在安装的过程中出现了

Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Hashtbl) = 718cd6ce8bc18371ce22483e362f78b4
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Hashtbl) = 024edc3512403b725052aec8e41ed971
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Array) = 4d5efba91ec70acd7b184fd4b277708c
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Array) = 8a6bb22925744456eb66180ea42e3344
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(List) = bd7c662c09e850306a62c12fed5ef5ce
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(List) = d757117653d9319fefb7ddc78a998f41
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(runtime) = 4.00.1
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(runtime) = 4.01.1
ocaml(runtime) = 4.01.0
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Gc) = 23b8d067f883f7a218c4945a42625a31
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Gc) = 292a1cd61d8e068943589882415bdf7d
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Obj) = ad977b422bbde52cd6cd3b9d04d71db1
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Obj) = b0adfa4175f86e4394859886c1a374bb
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Int32) = 265928798c0b8a63fa48cf9ac202f0ce
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Int32) = ad06f04cfca6d404d1de76c3dc67324a
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Callback) = 6fd6d47b2f6a171a493621bc5edbfb32
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Callback) = 198fb4bcde892143b0866b03cfae8085
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(List) = bd7c662c09e850306a62c12fed5ef5ce
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(List) = d757117653d9319fefb7ddc78a998f41
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Callback) = 6fd6d47b2f6a171a493621bc5edbfb32
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Callback) = 198fb4bcde892143b0866b03cfae8085
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Pervasives) = 4836c254f0eacad92fbf67abc525fdda
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Pervasives) = 36b5bc8227dc9914c6d9fd9bdcfadb45
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Hashtbl) = 718cd6ce8bc18371ce22483e362f78b4
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Hashtbl) = 024edc3512403b725052aec8e41ed971
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Pervasives) = 4836c254f0eacad92fbf67abc525fdda
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Pervasives) = 36b5bc8227dc9914c6d9fd9bdcfadb45
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Array) = 4d5efba91ec70acd7b184fd4b277708c
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Array) = 8a6bb22925744456eb66180ea42e3344
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(runtime) = 4.00.1
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(runtime) = 4.01.1
ocaml(runtime) = 4.01.0
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Int32) = 265928798c0b8a63fa48cf9ac202f0ce
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Int32) = ad06f04cfca6d404d1de76c3dc67324a
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Gc) = 23b8d067f883f7a218c4945a42625a31
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Gc) = 292a1cd61d8e068943589882415bdf7d
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Int64) = 0d5ecd8dffcffac43aec2ebe427d3bde
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Int64) = 3945db6e8df0d5a79bcbc949ee550d52
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Obj) = ad977b422bbde52cd6cd3b9d04d71db1
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Obj) = b0adfa4175f86e4394859886c1a374bb
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Int64) = 0d5ecd8dffcffac43aec2ebe427d3bde
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Int64) = 3945db6e8df0d5a79bcbc949ee550d52
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest

看这个论坛说,修改之后,再次安装,果然可以装上。

Just edit the snapshot section so that “enabled=1”, and correspondingly disable the stable section.

[graphviz-snapshot]
name=Graphviz - RHEL $releasever - $basearch
baseurl=http://www.graphviz.org/pub/graphviz/development/redhat/el$releasever/$basearch/os/
enabled=1
gpgcheck=0
skip_if_unavailable=1

[graphviz-snapshot-source]
name=Graphviz - RHEL $releasever - Source
baseurl=http://www.graphviz.org/pub/graphviz/development/SRPMS/
enabled=1
gpgcheck=0
skip_if_unavailable=1

最后安装的dot程序

dot - graphviz version 2.39.20160710.1729 (20160710.1729)
libdir = "/usr/lib64/graphviz"
Activated plugin library: libgvplugin_dot_layout.so.6
Using layout: dot:dot_layout
Activated plugin library: libgvplugin_core.so.6
Using render: dot:core
Using device: dot:dot:core
The plugin configuration file:
        /usr/lib64/graphviz/config6
                was successfully loaded.
    render      :  cairo dot dot_json fig gd json json0 map mp pic pov ps svg tk vml vrml xdot xdot_json
    layout      :  circo dot fdp neato nop nop1 nop2 osage patchwork sfdp twopi
    textlayout  :  textlayout
    device      :  bmp canon cmap cmapx cmapx_np dot dot_json eps fig gd gd2 gif gtk gv ico imap imap_np ismap jpe jpeg jpg json json0 mp pdf pic plain plain-ext png pov ps ps2 svg svgz tif tiff tk vml vmlz vrml wbmp x11 xdot xdot1.2 xdot1.4 xdot_json xlib
    loadimage   :  (lib) bmp eps gd gd2 gif ico jpe jpeg jpg pdf png ps svg xbm

PS:如果有些程序没有安装好,那么没办法生成pdf的格式。

如下面的错误信息,硬是没有pdf的格式。原来是插件没有安装全。

Graphviz produced errors. Verify it has support for filetype=pdf, or use filetype=dot.
Original error: Format: "pdf" not recognized. Use one of: canon cmap cmapx cmapx_np dot eps fig gd gd2 gif gv imap imap_np ismap jpe jpeg jpg plain plain-ext png ps ps2 svg svgz tk vml vmlz vrml wbmp xdot

不过还残留一个没有解决的问题

[stderr]
Warning: flat edge between adjacent nodes one of which has a record shape - replace records with HTML-like labels
  Edge A -> B
Error: lost A B edge

我把两个node放在同一个level,然后做了箭头,报错了,得再研究研究。

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: Graphviz安装失败的一个尝试 – https://www.chenyudong.com/archives/graphviz-install-fail.html

分类: Python, 软件

Python重新抛出异常的姿势

异常对于一个语言来说非常重要,异常的栈信息对于开发者特别重要,因为可以根据异常栈来找到第一次抛出异常的地方。但是懂得正确的抛出异常的人不是很多。

首先,以下是最糟糕的

def revert_stuff():
    pass

def some_code():
    raise Exception('oops, some error occur')

try:
    some_code()
except:
    revert_stuff()
    raise Exception("some_code failed!")
Traceback (most recent call last):
  File "1.py", line 11, in <module>
    raise Exception("some_code failed!")
Exception: some_code failed!

为什么说是最糟糕呢?因为关于some_code()的失败信息全部都丢失了。不过这些异常堆栈,可能是我们期望的信息,也可能不是。

以下代码是稍微改进过,但还是不是非常好:

def revert_stuff():
    pass

def some_code():
    raise Exception('oops, some error occur')

try:
    some_code()
except:
    import traceback
    traceback.print_exc()
    revert_stuff()
    raise Exception("some_code failed!")
Traceback (most recent call last):
  File "2.py", line 8, in <module>
    some_code()
  File "2.py", line 5, in some_code
    raise Exception('oops, some error occur')
Exception: oops, some error occur
Traceback (most recent call last):
  File "2.py", line 13, in <module>
    raise Exception("some_code failed!")
Exception: some_code failed!

使用traceback.print_exc() 把原始的异常堆栈(traceback)打印了出来。从某些角度来看这是最好的方法了,因为可以异常的错误信息找出来。但是如果不想恢复着新异常信息,那么应该这么做:

def revert_stuff():
    pass

def some_code():
    raise Exception('oops, some error occur')

try:
    some_code()
except:
    revert_stuff()
    raise
Traceback (most recent call last):
  File "3.py", line 8, in <module>
    some_code()
  File "3.py", line 5, in some_code
    raise Exception('oops, some error occur')
Exception: oops, some error occur

使用不用带任何参数raise可以重新抛出最后的异常。有时人们直接留空从来不用except:语句,但是这个特殊的形式(except: + raise)也是可以的。

有另外一种raise抛出异常的方式,知道的人比较少,但是也很容易上手。类似无参数的raise一样,这种方法也可以保留异常堆栈:

def some_code():
    raise Exception('oops, some error occur')

def maybe_raise(exc_info):
    raise exc_info[0], exc_info[1], exc_info[2]

try:
    some_code()
except:
    import sys
    exc_info = sys.exc_info()
    maybe_raise(exc_info)
Traceback (most recent call last):
  File "4.py", line 12, in <module>
    maybe_raise(exc_info)
  File "4.py", line 8, in <module>
    some_code()
  File "4.py", line 2, in some_code
    raise Exception('oops, some error occur')
Exception: oops, some error occur

如果你需要在异常发生的代码的其他地方处理异常是个不错的选择。但通常它不是很方便,因为这样比较晦涩难懂。

还有一类经常修改异常堆栈的情况是:想加一些额外的信息到异常堆栈中。

for lineno, line in enumerate(file):
    try:
        process_line(line)
    except Exception, exc:
        raise Exception("Error in line %s: %s" % (lineno, exc))

这里保留了异常信息,但却丢失了异常堆栈。有一个方法可以保留异常堆栈。下面的方法不仅可以保留异常,也可以改变异常的信息。

except Exception, exc:
    args = exc.args
    if not args:
        arg0 = ''
    else:
        arg0 = args[0]
    arg0 += ' at line %s' % lineno
    exc.args = arg0 + args[1:]
    raise

有些小尴尬。从技术上讲(虽然它不建议使用),你可以抛出任何的异常。如果使用except Exception:那么就不能捕获一些例如string异常或者其他异常。想要这么用取决于是否关心这些场景。不过异常也可能没有.args属性,或者异常的字符串信息不能从这些参数中获取,又或者有其他的方法展示(例如KeyError信息有些不同 ) 。因此这不是万能的。想要增强版,可以这么做:

except:
    exc_class, exc, tb = sys.exc_info()

exc_class是一个字符串类型,不过可能有人会raise "not found"。所以这种风格被废弃了。如果坚持想去把周围的东西搞的一团糟,可以这么用:

new_exc = Exception("Error in line %s: %s"
                    % (lineno, exc or exc_class))
raise new_exc.__class__, new_exc, tb

这样改变了异常类周围使得它变的混乱了,但至少保留完好异常堆栈。在异常堆栈中raise ValueError(...)或者在错误信息raise Exception可能看上去有些奇怪。

小结:Python2中的较佳方法

以下是在Python2中一个较佳重新抛出异常的方法。

try:
    code()
except:
    exc_info = sys.exc_info()
    try:
        revert_stuff()
    except:
        # If this happens, it clobbers exc_info, which is why we had
        # to save it above
        import traceback
        print >> sys.stderr, "Error in revert_stuff():"
        traceback.print_exc()
        raise exc_info[0], exc_info[1], exc_info[2]

在with语句中抛出异常

如果想在某些场景下保留异常,有些场景下又想不捕获异常,那么可以怎么做

class ignore_or_reraise_exception(object):
    def __init__(self, reraise=True):
        self.reraise = reraise

    def __enter__(self):
        self.type_, self.value, self.tb, = sys.exc_info()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is not None:
            if self.reraise:
                log.error('Original exception being dropped: %s' % self.value)
        if self.reraise:
            return True   #  reraise exception
        return False    # ignore exception

....
except Exception:
   with ignore_or_reraise_exception(reraise=False) as ctxt:
       if statements to determine whether to raise a new exception:
           # Not raising a new exception, so reraise
           ctxt.reraise = True

通过这个方法,可以自由的选择是忽略异常,还是想继续抛出异常。当需要抛出异常的时候,指定属性ctxt.reraise = True即可。

另外可以在ignore_or_reraise_exception中的处理异常,可以把异常都收集起来到一个全局变量,最后程序退出的时候,把所有的异常都打印出来。

总结:兼容Python2、Python3的重新抛出异常方法

在Python2中,重新抛出异常是用raise exc_info[0], exc_info[1], exc_info[2]这样的三个参数。但在Python3中却不一样了。

这个时候只能使用兼容Python2、Python3的类库six了。

使用方法

def some_code():
    raise Exception('oops, some error occur')

class SwaggerValidationError(Exception):
    pass

try:
    some_code()
except Exception as e:
    import six, sys
    six.reraise(
                SwaggerValidationError,
                SwaggerValidationError(str(e)),
                sys.exc_info()[2])

Traceback (most recent call last):
  File "5.py", line 14, in <module>
    sys.exc_info()[2])
  File "5.py", line 8, in <module>
    some_code()
  File "5.py", line 2, in some_code
    raise Exception('oops, some error occur')
__main__.SwaggerValidationError: oops, some error occur

参考文章:http://www.ianbicking.org/blog/2007/09/re-raising-exceptions.html

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: Python重新抛出异常的姿势 – https://www.chenyudong.com/archives/python-reraise-exception.html

分类: Python

Copyright © 2017 东东东 陈煜东的博客 粤ICP备13059639号-1

SITEMAP回到顶部 ↑