반응형

출처 : https://web.archive.org/web/20210404233204/https://ongspxm.gitlab.io/blog/2016/11/assertraises-testing-for-errors-in-unittest/

assertRaises - unittest에서 오류 테스트 하기

이 글에서, 저는 파이썬의 빌트인 unittest 모듈을 사용하였습니다.

갑자기 프레임워크에 대한 (잘못된 데이터가 입력되면 예외가 발생해야 하는) 새로운 요구가 생겼을 때 저는 제 프로젝트에서 몇 가지 테스트 작업을 하고 있었습니다.

저는 몇가지를 검색하였고 제가 필요한 것 - TestCase.assertRaises 같은 함수를 찾았습니다.

다른 모든 assert 함수가 unittest에서 사용되는 것과 동일한 형식으로 시도했습니다. 그래서 저는 다음과 같이 작성하였습니다.

import unittest

def func():
    raise Exception('lets see if this works')

class ExampleTest(unittest.TestCase):
    def test_error(self):
        self.assertRaises(func(), Exception)

if __name__=='__main__':
    unittest.main()

논리적으로 보입니다. 그렇지 않습니까? 글쎄요. 나는 그것을 실행하려고 시도했고 테스트는 오류로 판명되었습니다.

예, 오류가 있다는 것을 알고 있습니다. 그것이 제가 테스트하고 있는 것입니다. 그렇지요? 왜 이런 일이 일어나고 있는지에 대해 혼란스러워서 파이썬 문서와 stackOverflow를 찾아 답을 찾았습니다.

lambda 해결책

다음은 제가 검색하여 찾은 가장 일반적인 해결책입니다.

import unittest

def func():
    raise Exception('lets see if this works')

class ExampleTest(unittest.TestCase):
    def test_error(self):
        self.assertRaises(Exception, lambda:func())

if __name__=='__main__':
    unittest.main()

제가 좋아하는 해결책

하지만 lambda는 그 자체로 전부 새로운 괴물입니다. 함수에 대한 wrapper로 사용하기 위해 올바른 도구는 아닌 듯 합니다.

다음은 assertRaise를 사용하는 매우 더 적절한 파이썬스러운 방법입니다.

import unittest

def func():
    raise Exception('lets see if this works')

class ExampleTest(unittest.TestCase):
    def test_error(self):
        with self.assertRaises(Exception): func()

if __name__=='__main__':
    unittest.main()

왜 작동하지 않았을까요?

분명히 assertRaises가 작동하려면 예외를 잡기 위해 함수 호출이 일종의 wrapper 내에 포함되어야 합니다.

첫 번째 예제처럼 실행하면, 그 함수는 스스로 실행될 것이며 그 예외는 잡히지 않고 test case는 대신에 오류가 발생하게 됩니다.

lambda 메소드를 사용하면, lambda 함수는 함수가 실행될 wrapper로 작동하기 때문에 그 예외는 잡히게 되며 비교가 발생합니다.

"with 구문"도 똑같습니다. "with 구문"으로 함수 호출을 wrapping하면, 그 예외는 구문에서 "assertRaises"로 전달될 것입니다. "assertRaises" 함수는 이제 실행될 예외와 비교할 수 있으며 그래서 유용한 결과를 얻습니다.

성공적인 테스트 실행

더 기술적인 세부사항에 관심 있으시면, unittest 소스 코드를 살펴보세요 (소스 코드는 언제든지 가능하며, 파이썬이 짱인 이유입니다.)

다른 문제가 있으시면 저에게 세부사항에 대한 이메일이나 댓글 남겨주세요.

반응형
반응형

출처 : https://stackoverflow.com/questions/43267157/python-attributeerror-module-object-has-no-attribute-ssl-st-init

파이썬 AttributeError: 'module' 객체는 'SSL_ST_INIT' 속성이 없습니다

저의 파이썬 스크립트는 다음 오류가 발생했습니다.

Traceback (most recent call last):
  File "./inspect_sheet.py", line 21, in <module>
    main()
  File "./inspect_sheet.py", line 12, in main
    workbook_name=workbook_name,
  File "./google_sheets.py", line 56, in __init__
    self.login()
  File "./google_sheets.py", line 46, in login
    self.client = gspread.authorize(credentials)
  File "/usr/local/lib/python2.7/site-packages/gspread/client.py", line 335, in authorize
    client.login()
  File "/usr/local/lib/python2.7/site-packages/gspread/client.py", line 98, in login
    self.auth.refresh(http)
  File "/usr/local/lib/python2.7/site-packages/oauth2client/client.py", line 598, in refresh
    self._refresh(http.request)
  File "/usr/local/lib/python2.7/site-packages/oauth2client/client.py", line 769, in _refresh
    self._do_refresh_request(http_request)
  File "/usr/local/lib/python2.7/site-packages/oauth2client/client.py", line 795, in _do_refresh_request
    body = self._generate_refresh_request_body()
  File "/usr/local/lib/python2.7/site-packages/oauth2client/client.py", line 1425, in _generate_refresh_request_body
    assertion = self._generate_assertion()
  File "/usr/local/lib/python2.7/site-packages/oauth2client/client.py", line 1554, in _generate_assertion
    private_key, self.private_key_password), payload)
  File "/usr/local/lib/python2.7/site-packages/oauth2client/crypt.py", line 162, in from_string
    from OpenSSL import crypto
  File "/usr/local/lib/python2.7/site-packages/OpenSSL/__init__.py", line 8, in <module>
    from OpenSSL import rand, crypto, SSL
  File "/usr/local/lib/python2.7/site-packages/OpenSSL/SSL.py", line 118, in <module>
    SSL_ST_INIT = _lib.SSL_ST_INIT
AttributeError: 'module' object has no attribute 'SSL_ST_INIT'

20개의 답변 중 1개의 답변만 추려냄

저는 pip로 pyopenssl 업그레이드 하는 것이 pip와 관련된 명령어 중에서는 작동하는 것이 없었습니다. easy_installpyopenssl을 업그레이드 함으로써, 위의 문제는 해결될 수 있습니다.

sudo python -m easy_install --upgrade pyOpenSSL

credit @delimiter (Answer)

반응형
반응형

출처 : https://stackoverflow.com/questions/24720442/selecting-second-child-in-beautiful-soup-with-soup-select

soup.select로 beautiful soup에서 두번째 child 선택하기

다음 태그가 있습니다.

<h2 id='names'>Names</h2>
<p>John</p>
<p>Peter</p>

이제 h2 태그가 이미 있으면 Peter를 얻기 위한 이제 가장 쉬운 방법은 무엇입니까? 다음을 시도하였습니다.

soup.select("#names > p:nth-child(1)")

여기에 nth-child에서 NotImplementedError: 오류가 발생하였습니다.

NotImplementedError: Only the following pseudo-classes are implemented: nth-of-type.

그래서 나는 여기서 무슨 일이 일어나고 있는지 잘 모르겠습니다. 두 번째 방법은 모든 'p' 태그 자식들을 얻어 직접 [1]을 선택하는 것이지만 조금 무식한 try/except 구문으로 Peter를 얻기 위해 전부 시도하는 것을 요구하여 out of range 인덱스 오류의 위험이 있습니다.

soup.select() 함수로 nth-child를 선택하는 방법이 있습니까?

편집:: 트릭같지만 nth-of-type로 nth-child를 대체합니다. 수정한 내용은:

soup.select("#names > p:nth-of-type(1)")

nth-child를 받아들이지 않는 이유가 확실하지 않지만 nth-child와 nth-of-type는 같은 결과를 리턴하는 거 같습니다.

2개의 답변 중 1개의 답변만 추려냄

다른 사람이 더 쉽게 찾을 수 있도록 수정 사항을 답변으로 추가 :

nth-of-type 대신에 nth-child를 사용합니다.

soup.select("#names > p:nth-of-type(1)")
반응형
반응형

출처 : https://stackoverflow.com/questions/54101923/1006-connection-closed-abnormally-error-with-python-3-7-websockets

python 3.7 websockets에서 비정상적으로 1006 접속 종료 오류

저는 python websockets에서 이러한 github 이슈와 같은 문제가 있습니다.
https://github.com/aaugustin/websockets/issues/367

제안된 해결책은 저는 작동하지 않습니다. 제가 본 오류는

websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1006 (connection closed abnormally [internal]), no reason

이는 제 코드입니다.

async def get_order_book(symbol):
    with open('test.csv', 'a+') as csvfile:
        csvw = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
        DT = Data(data=data, last_OB_id=ob_id, last_TR_id=tr_id, sz=10, csvw=csvw)

        while True:
            if not websocket.open:
                print('Reconnecting')
                websocket = await websockets.connect(ws_url)
            else:
                resp = await websocket.recv()
                update = ujson.loads(resp)
                DT.update_data(update)

async def get_order_books():
    r = requests.get(url='https://api.binance.com/api/v1/ticker/24hr')
    await asyncio.gather(*[get_order_book(data['symbol']) for data in r.json()])

if __name__ == '__main__':
    asyncio.run(get_order_books())

내가 테스트 한 방법은 인터넷 연결을 종료하는 것이지만 10초 후에도 여전히 1006 오류가 반환됩니다.

Python 3.7 및 Websockets 7.0을 실행하고 있습니다.

당신의 생각이 무엇인지 알려주십시오. 감사합니다!

5개의 답변 중 1개의 답변만 추려냄

저도 같은 문제에 직면했습니다. 잠시 동안 파고들자 다시 연결하라는 여러 버전의 답변을 찾았지만 합리적인 방법이라고 생각하지 않았으므로 더 파고 들었습니다.

DEBUG 레벨 로깅을 활성화하면 파이썬 웹소켓이 기본적으로 핑 패킷을 보내고 응답을 받지 못하면 연결 시간이 초과된다는 것을 알았습니다. 이것이 표준과 일치하는지 확실하지 않지만 적어도 파이썬 스크립트 시간이 초과되는 서버에는 적어도 자바 스크립트의 웹 소켓은 완전히 좋았습니다.

수정은 간단합니다. connect (연결)하기 위한 다른 kw 인수를 추가합니다.

websockets.connect(uri, ping_interval=None)

같은 인자는 서버쪽 함수 serve로 작동해야 합니다.

https://websockets.readthedocs.io/en/stable/api.html에서 정보를 더 얻을 수 있습니다.

반응형
반응형

출처 : https://pythontic.com/modules/socket/udp-client-server-example

UDP - 파이썬에서 클라이언트 서버 예제 프로그램

UDP 개요

UDP는 User Datagram Protocol의 약어입니다. UDP는 TCP/IP 슈트의 인터넷 프로토콜을 사용합니다. UDP를 사용한 통신에서 클라이언트 프로그램은 메시지 패킷을 대상 서버로 전송하며 대상 서버도 UDP에서 실행됩니다.

UDP의 속성

  • UDP는 메시지 패킷 전달을 보장하지 않습니다. 네트워크에서 일부 문제가 발생하면 패킷이 손실되면 영원히 손실될 수 있습니다.
  • 확실한 메시지 전달을 보장할 수 없으므로 UDP는 신뢰할 수 없는 프로토콜로 간주됩니다.
  • UDP를 구현하는 기본 메커니즘에는 연결 기반 통신이 필요하지 않습니다. UDP 서버 또는 UDP 클라이언트 간에 데이터 스트리밍이 없습니다.
  • UDP 클라이언트는 "n"개의 별개의 패킷을 UDP 서버로 보낼 수 있으며 UDP 서버의 응답으로 "n"개의 별개의 패킷을 수신할 수도 있습니다.
  • UDP는 비 연결 프로토콜이므로 UDP와 관련된 오버 헤드는 TCP와 같은 연결 기반 프로토콜에 비해 적습니다.

예시: 파이썬을 사용한 UDP 서버

import socket

localIP     = "127.0.0.1"
localPort   = 20001
bufferSize  = 1024

msgFromServer       = "Hello UDP Client"
bytesToSend         = str.encode(msgFromServer)

# 데이터그램 소켓을 생성
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)

# 주소와 IP로 Bind
UDPServerSocket.bind((localIP, localPort))

print("UDP server up and listening")

# 들어오는 데이터그램 Listen
while(True):
    bytesAddressPair = UDPServerSocket.recvfrom(bufferSize)
    message = bytesAddressPair[0]
    address = bytesAddressPair[1]

    clientMsg = "Message from Client:{}".format(message)
    clientIP  = "Client IP Address:{}".format(address)

    print(clientMsg)
    print(clientIP)

    # Sending a reply to client
    UDPServerSocket.sendto(bytesToSend, address)

출력:

UDP server up and listening
Message from Client:b"Hello UDP Server"
Client IP Address:("127.0.0.1", 51696)

예시: 파이썬을 사용한 UDP 클라이언트

import socket

msgFromClient       = "Hello UDP Server"
bytesToSend         = str.encode(msgFromClient)
serverAddressPort   = ("127.0.0.1", 20001)
bufferSize          = 1024

# 클라이언트 쪽에서 UDP 소켓 생성
UDPClientSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)

# 생성된 UDP 소켓을 사용하여 서버로 전송
UDPClientSocket.sendto(bytesToSend, serverAddressPort)

msgFromServer = UDPClientSocket.recvfrom(bufferSize)

msg = "Message from Server {}".format(msgFromServer[0])
print(msg)

출력:

Message from Server b"Hello UDP Client"

관련글

반응형
반응형

출처 : https://stackoverflow.com/questions/12791997/how-do-you-do-a-simple-chmod-x-from-within-python

python에서 간단하게 "chmod +x"을 어떻게 합니까?

저는 실행할 수 있는 python 스크립트 파일을 만들고 싶습니다.

import os
import stat
os.chmod('somefile', stat.S_IEXEC)

os.chmod는 unix가 chmod를 하는 방법으로 권한을 '추가'하지는 않는듯이 보입니다. 마지막 행을 주석 처리한 상태에서 그 파일의 파일모드는 -rw-r--r-- 이며, 주석 처리를 하지 않으면, 파일 모드는 ---x------ 입니다.. 모드의 나머지를 그대로 유지하면서 어떻게 u+x 플래그를 추가할 수 있습니까?

7개의 답변 중 1개의 답변만 추려냄

현재 권한을 얻기 위해 os.stat() 사용하시고, 비트를 결합하기 위해 | 사용하여 갱신된 권한을 설정하기 위해 os.chmod()를 사용하시면 됩니다.

예시:

import os
import stat

st = os.stat('somefile')
os.chmod('somefile', st.st_mode | stat.S_IEXEC)
반응형
반응형

출처 : https://stackoverflow.com/questions/5537876/get-utc-offset-from-time-zone-name-in-python

Python에서 시간대(timezone) 이름으로 UTC 시차(offset) 구하기

Python에서 시간대(timezone) 이름으로 UTC 시차(offset)을 어떻게 구합니까?

예시: 저는 Asia/Jerusalem을 통해 +0200을 얻고 싶습니다.


미국동부시간으로 한국 시간 구하기 예시

import datetime
import pytz

est = datetime.datetime.now(pytz.timezone('America/New_York'))
diff_min = (est.utcoffset().seconds - 86400) // 60 - 540
# ...중략...
# 02:38:00 28.02.20
svr_time = datetime.datetime.strptime(svr_str, "%H:%M:%S %d.%m.%y") - datetime.timedelta(minutes=diff_min)

3개의 답변 중 2개의 답변만 추려냄

pytz 프로젝트와 utcoffset 메소드 사용을 시도하신 적 있으신가요?

예시

>>> import datetime
>>> import pytz
>>> pacific_now = datetime.datetime.now(pytz.timezone('US/Pacific'))
>>> pacific_now.utcoffset().total_seconds()/60/60
-7.0

DST(일광절약시간, 서머타임) 때문에 결과는 그 해의 시간에 따라 다릅니다.

import datetime, pytz

datetime.datetime.now(pytz.timezone('Asia/Jerusalem')).strftime('%z')

# returns '+0300' ('now' 지금은 DST(일광절약시간, 서머타임)이기 때문입니다)

pytz.timezone('Asia/Jerusalem').localize(datetime.datetime(2011,1,1)).strftime('%z')

# returns '+0200' (1월에는 DST(일광절약시간, 서머타임)이 아니기 때문입니다)
반응형
반응형

출처 :https://stackoverflow.com/questions/12523044/how-can-i-tail-a-log-file-in-python

Python에서 로그 파일 tail 하는 방법?

저는 blocking이나 locking 없이 Python에서 tail -F 또는 뭔가 비슷한 방법으로 출력을 하고 싶습니다. 저는 여기에서 이를 할 수 있는 오래된 코드를 찾았지만 같은 것을 할 수 있는 라이브러리나 더 좋은 방법이 있을거라 생각합니다.

저는 더 많은 데이터를 원할때마다 호출할 수 있는 tail.getNewData()처럼 뭔가 있으면 합니다.

12개의 답변 중 1개의 답변만 추려냄

Non Blocking

리눅스에 있다면 (윈도우가 파일에서 select 호출을 지원하지 않기 때문에) select 모듈과 함께 서브 프로세스 모듈을 사용할 수 있습니다.

import time 
import subprocess 
import select 

f = subprocess.Popen(['tail','-F',filename],\ 
        stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
p = select.poll() 
p.register(f.stdout) 
while True: 
    if p.poll(1): 
        print f.stdout.readline() 
    time.sleep(1)

이는 새로운 데이터를 위한 출력 pipe를 poll하고 가능할 때 print 합니다. 일반적으로 time.sleep(1)print f.stdout.readline() 은 유용한 코드로 대체될 수 있습니다.

Blocking

추가적은 select 모듈 호출 없이 subprocess 모듈을 사용할 수 있습니다.

import subprocess
f = subprocess.Popen(['tail','-F',filename],\
        stdout=subprocess.PIPE,stderr=subprocess.PIPE)
while True:
    line = f.stdout.readline()
    print line

이는 추가될 때 새로운 line이 출력될 것이지만, tail program이 f.kill에 의해 닫힐 때까지 blocking 될 것입니다.

반응형
반응형

출처 : https://stackoverflow.com/questions/5574702/how-to-print-to-stderr-in-python

Python에서 표준에러로 출력하는 방법?

표준 출력으로 쓰는 몇가지 방법이 있습니다.

# Note: 첫번째 문장은 Python 3에서 실행되지 않습니다.
print >> sys.stderr, "spam"

sys.stderr.write("spam\n")

os.write(2, b"spam\n")

from __future__ import print_function
print("spam", file=sys.stderr)

그것은 파이썬의 선 #13†과 모순되는 것처럼 보입니다. 그래서 여기의 차이점은 무엇이며 어떤 방법을 사용하던 장단점이 있습니까? 어떤 방법을 사용해야 합니까?

† 문제를 해결할 하나의 - 바람직하고 유일한 - 명백한 방법이 있을 것이다.

15개의 답변 중 1개의 답변만 추려냄

저는 짧고 유연하고 이식하기 좋고 읽기 좋은 유일한 방법을 찾았습니다.

from __future__ import print_function
import sys

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

함수 eprint는 표준 print 함수와 같은 방법으로 사용될 수 있습니다.

>>> print("Test")
Test
>>> eprint("Test")
Test
>>> eprint("foo", "bar", "baz", sep="---")
foo---bar---baz
반응형
반응형

출처 : https://stackoverflow.com/questions/29523954/distinguishing-between-two-quickfix-initiator-sessions

2개의 QuickFix initiator 세션을 구분하기

저는 broker로 접속하기 위한 Python binding으로 QuickFix를 사용하고 있고 config 파일에서 2 개의 initiator 세션이 있습니다. 하나는 가격을 위한 것이고 다른 것은 주문 세션을 위한 것입니다.

제 질문은 그들 중 하나만 온라인일 때 뭔가를 하고 싶습니다.

initiator = fix.SocketInitiator(application, storeFactory, settings, logFactory)
if initiator.isLoggedOn():
    function()

가격이나 주문 세션이나 로그인 된 둘 다에 관련하여 function이 호출될 것입니다. 저는 특정 initiator가 로그인되어 있을 때 알아낼 수 있을까요?


1개의 답변 중 1개의 답변

언급하신대로, 메소드 bool Initiator::isLoggedOn()는 어떤 세션이든 현재 로그인 되었는지 당신에게 알려줍니다.

특별한 세션을 확인하기 위해 bool Initiator::isConnected( const SessionID& sessionID )를 사용하세요.

SocketInitiatorInitiator로 부터 이들 둘 다를 상속합니다.

반응형

+ Recent posts