Python - NameError:使用 gevent 时未定义名称“PROTOCOL_SSLv3”

Posted

技术标签:

【中文标题】Python - NameError:使用 gevent 时未定义名称“PROTOCOL_SSLv3”【英文标题】:Python - NameError: name 'PROTOCOL_SSLv3' is not defined, when using gevent 【发布时间】:2016-11-30 20:16:24 【问题描述】:

所以我在 virtualenv(运行 raspbian 的树莓派)的一台机器上安装了一个 Flask 应用程序,一切正常,但是当我将它移植到另一个同样运行 raspbian 的树莓派上时,并准确地设置了一个新的 virtualenv相同的规格,运行应用程序会抛出这个:

Flask 应用是一个 socket-io 聊天应用,它使用 ajax 和其他东西。

Traceback (most recent call last):
File "application.py", line 10, in <module>
from flask.ext.socketio import SocketIO, emit
File "/home/host/chat-server/venv/local/lib/python2.7/site-packages/flask/exthook.py", line 62, in load_module
__import__(realname)
File "/home/host/chat-server/venv/local/lib/python2.7/site-packages/flask_socketio/__init__.py", line 2, in <module>
monkey.patch_all()
File "/home/host/chat-server/venv/local/lib/python2.7/site-packages/gevent/monkey.py", line 185, in patch_all
patch_socket(dns=dns, aggressive=aggressive)
File "/home/host/chat-server/venv/local/lib/python2.7/site-packages/gevent/monkey.py", line 124, in patch_socket
from gevent import socket
File "/home/host/chat-server/venv/local/lib/python2.7/site-packages/gevent/socket.py", line 659, in <module>
from gevent.ssl import sslwrap_simple as ssl, SSLError as sslerror, SSLSocket as SSLType
File "/home/host/chat-server/venv/local/lib/python2.7/site-packages/gevent/ssl.py", line 386, in <module>
def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None):
NameError: name 'PROTOCOL_SSLv3' is not defined
Exception KeyError: KeyError(3061183472L,) in <module 'threading' from '/usr/lib/python2.7/threading.pyc'> ignored

设置venv的过程如下,

virtualenv venv
source venv/bin/activate
pip install -r requirements.txt

requirements.txt 看起来像,

Flask==0.10.1
Flask-SocketIO==0.3.7
Jinja2==2.7.2
MarkupSafe==0.23
Werkzeug==0.9.4
gevent==1.0.1
gevent-socketio==0.3.6
gevent-websocket==0.9.3
greenlet==0.4.2
ipython==2.1.0
itsdangerous==0.24
pyreadline==2.0

当运行venv/bin/pip freeze 时,两台机器提供完全相同的包和版本。

顺便说一句,我的 application.py 如下,虽然我不认为这是问题的一部分,因为它在我的第一台机器上运行良好(是的,我知道它很草率,但这是一个实验)。

from flask.ext.socketio import SocketIO, emit
from flask import Flask, render_template, url_for, copy_current_request_context, request, session, redirect
from random import random
from time import sleep
import json, pickle, os, binascii, pickler

app = Flask(__name__)
app.config['SECRET_KEY'] = binascii.b2a_hex(os.urandom(16))
app.config['DEBUG'] = True
app.config['PICKLE_RESET'] = "KGxwMAou"
app.config['BAD_NAMES'] = ["wg4568"]
app.config['SECRET_PASSWORD'] = "thepassword"

#turn the flask app into a socketio app
socketio = SocketIO(app)

class Reciever():
    def __init__(self):
        self.messages = pickler.load("messages")

    def send(self, user, message):
        if len(message):
            self.messages.insert(0, (user, message))
            pickler.save(self.messages, "messages")
            socketio.emit('newmsg', 'content': message, 'user': user, namespace='/msg')
            return "Sent from " + user + " that reads, " + message
        else:
            return "Message was blank, not sent"

    def render(self):
#        if not session["VIEW"]:
#            return '<p id="alert"><strong>' + self.messages[0][0] + ': </strong>' + self.messages[0][1] + '</p>'
#        else:
    if 1:
            html = ""
            for msg in self.messages[:session["VIEW"]]:
                if msg[0] == "ALERT":
                    html += '<p id="alert"><strong>' + msg[0] + ': </strong>' + msg[1] + '</p>'
                else:
                    html += '<p><strong>' + msg[0] + ': </strong>' + msg[1] + '</p>'
            return html

rec = Reciever()

@app.before_request
def before_request():
    try: session["VIEW"]
    except KeyError: session["VIEW"] = 0
    try: session["USERNAME"]
    except KeyError: session["USERNAME"] = "AnonUser-" + binascii.b2a_hex(os.urandom(4))
#    if not request.url.split("/")[-1:][0] == "send":
#        rec.send("ALERT", session["USERNAME"] + " has joined the room")

@app.route('/user_newid')
def user_newid():
    session["USERNAME"] = "AnonUser-" + binascii.b2a_hex(os.urandom(4))
    return redirect("/")

@app.route('/user_setid', methods=["POST"])
def user_setname():
    username = request.form["username"]
    canbypass = False
    if username.split("-")[-1:][0] == app.config["SECRET_PASSWORD"]:
        canbypass = True
        username = username.split("-")[0]
    if not username in app.config['BAD_NAMES'] or canbypass:
        session["USERNAME"] = username
    return redirect("/")

@app.route('/send', methods=["POST"])
def send():
    user = request.form["user"]
    content = request.form["content"]
    return rec.send(user, content)

@app.route('/', methods=["GET", "POST"])
def index():
    if request.args.get("viewall"): session["VIEW"] += 10
    else: session["VIEW"] = 0
    print session["VIEW"]
    return render_template('index.html', old=rec.render(), username=session["USERNAME"])

@socketio.on('connect', namespace='/msg')
def test_connect():
    print('Client connected')

@socketio.on('disconnect', namespace='/msg')
def test_disconnect():
#    rec.send("ALERT", session["USERNAME"] + " has left the room",)
    print('Client disconnected')


if __name__ == '__main__':
    socketio.run(app, host="0.0.0.0")

有人知道这里发生了什么吗,我完全被难住了。

【问题讨论】:

和我一样的问题,我升级了gevevnt。 pip install -U gevent 【参考方案1】:

我通过替换 PROTOCOL_SSLv3 = PROTOCOL_SSLv23 解决了这个问题,感谢 mgogoulos 的回答,链接在这里:https://github.com/mistio/mist.io/issues/434

【讨论】:

以上是关于Python - NameError:使用 gevent 时未定义名称“PROTOCOL_SSLv3”的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Boost 获取 SyntaxError、NameError 等的 Python 错误信息

NameError:名称“reduce”未在 Python 中定义

NameError:未定义全局名称“PermissionError”(python 2.x)

Python - NameError:使用 gevent 时未定义名称“PROTOCOL_SSLv3”

NameError:使用 python-docx 时未定义名称“WD_COLOR_INDEX”

Python XML NameError:未定义全局名称“qn”