commit python3-pysendfile for openSUSE:Factory
Hello community, here is the log from the commit of package python3-pysendfile for openSUSE:Factory checked in at 2014-06-25 11:47:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python3-pysendfile (Old) and /work/SRC/openSUSE:Factory/.python3-pysendfile.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python3-pysendfile" Changes: -------- --- /work/SRC/openSUSE:Factory/python3-pysendfile/python3-pysendfile.changes 2013-06-21 19:01:58.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python3-pysendfile.new/python3-pysendfile.changes 2014-06-25 11:47:46.000000000 +0200 @@ -1,0 +2,16 @@ +Wed Jun 25 08:20:00 UTC 2014 - p.drouand@gmail.com + +- Update to version 2.0.1 + + #20: host tarball on PYPI + + #21: project migrated from google code to github + + #21: project migrated from SVN to GIT + + #22: pysendfile won't compile on python 3.4 + + #23: add a Makefile + + #24: use of travis continuous integration + + #25: use tox for multiple python versions testing +- Add HISTORY.rst in package documentation +- README has been renamed README.rst +- Fix Url home page and download Url +- Fix build on Factory + +------------------------------------------------------------------- Old: ---- pysendfile-2.0.0.tar.gz New: ---- pysendfile-2.0.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python3-pysendfile.spec ++++++ --- /var/tmp/diff_new_pack.Zkcwcs/_old 2014-06-25 11:47:47.000000000 +0200 +++ /var/tmp/diff_new_pack.Zkcwcs/_new 2014-06-25 11:47:47.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package python3-pysendfile # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,18 +17,17 @@ %define mod_name pysendfile Name: python3-pysendfile -Version: 2.0.0 +Version: 2.0.1 Release: 0 License: MIT Summary: A Python interface to sendfile(2) -Url: http://code.google.com/p/pysendfile/ +Url: https://github.com/giampaolo/pysendfile Group: Development/Languages/Python -Source: http://pysendfile.googlecode.com/files/%{mod_name}-%{version}.tar.gz +Source: https://pypi.python.org/packages/source/p/pysendfile/%{mod_name}-%{version}.tar.gz BuildRequires: python3 BuildRequires: python3-devel BuildRequires: python3-nose Requires: python3 -BuildRoot: %{_tmppath}/%{name}-%{version}-build %description A python interface to sendfile(2) system call. @@ -48,7 +47,7 @@ %files %defattr(-,root,root,-) -%doc LICENSE README +%doc HISTORY.rst LICENSE README.rst %{python3_sitearch}/* %changelog ++++++ pysendfile-2.0.0.tar.gz -> pysendfile-2.0.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/.travis.yml new/pysendfile-2.0.1/.travis.yml --- old/pysendfile-2.0.0/.travis.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/.travis.yml 2014-05-27 02:19:48.000000000 +0200 @@ -0,0 +1,21 @@ +language: python +python: + - 2.6 + - 2.7 + - 3.2 + - 3.3 + - 3.4 + - pypy +install: + - if [[ $TRAVIS_PYTHON_VERSION == '2.5' ]]; then pip install unittest2; fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install unittest2; fi +script: + - pip install flake8 + - python setup.py build + - python setup.py install + - python test/test_sendfile.py + - make flake8 +os: + - linux + - osx + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/HISTORY new/pysendfile-2.0.1/HISTORY --- old/pysendfile-2.0.0/HISTORY 2012-01-12 21:38:23.000000000 +0100 +++ new/pysendfile-2.0.1/HISTORY 1970-01-01 01:00:00.000000000 +0100 @@ -1,41 +0,0 @@ -Bug tracker at http://code.google.com/p/py-sendfile/issues/list - -Version 2.0.0 - 2012-01-12 -========================== - -(Giampaolo Rodolà took over maintenance) - -##: complete rewriting except AIX code -##: non blocking sockets support -##: threads support (release GIL) -#1: unit tests -#2: python 3 support -#3: FreeBSD implementation is broken -#4: python large file support -#5: header/trailer are now keyword arguments -#6: exposed SF_NODISKIO, SF_MNOWAIT and SF_SYNC constants on FreeBSD -#8: benchmark script -#10: Mac OSX support -#13: Sun OS support - - -Version 1.2.4 - 2009-03-06 -========================== - -(Stephan Peijnik took over maintenance) - -## Add AIX support. - - -Version 1.2.3 - 2008-04-09 -========================== - -## Use setuptools instead of distutils. - - -Version 1.2.2 - 2008-03-29 -========================== - -(Ben Woolley) - -## First release including support for Linux, FreeBSD and DragonflyBSD platforms. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/HISTORY.rst new/pysendfile-2.0.1/HISTORY.rst --- old/pysendfile-2.0.0/HISTORY.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/HISTORY.rst 2014-05-27 13:06:37.000000000 +0200 @@ -0,0 +1,49 @@ +Bug tracker at https://github.com/giampaolo/pysendfile/issues + +Version 2.0.1 - 2014-05-27 +========================== + +- #20: host tarball on PYPI +- #21: project migrated from google code to github +- #21: project migrated from SVN to GIT +- #22: pysendfile won't compile on python 3.4 +- #23: add a Makefile +- #24: use of travis continuous integration +- #25: use tox for multiple python versions testing + +Version 2.0.0 - 2012-01-12 +========================== + +(Giampaolo Rodolà took over maintenance) + +- ##: complete rewriting except AIX code +- ##: non blocking sockets support +- ##: threads support (release GIL) +- #1: unit tests +- #2: python 3 support +- #3: FreeBSD implementation is broken +- #4: python large file support +- #5: header/trailer are now keyword arguments +- #6: exposed SF_NODISKIO, SF_MNOWAIT and SF_SYNC constants on FreeBSD +- #8: benchmark script +- #10: Mac OSX support +- #13: Sun OS support + +Version 1.2.4 - 2009-03-06 +========================== + +(Stephan Peijnik took over maintenance) + +- ## Add AIX support. + +Version 1.2.3 - 2008-04-09 +========================== + +- ## Use setuptools instead of distutils. + +Version 1.2.2 - 2008-03-29 +========================== + +(Ben Woolley) + +- ## First release including support for Linux, FreeBSD and DragonflyBSD platforms. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/LICENSE new/pysendfile-2.0.1/LICENSE --- old/pysendfile-2.0.0/LICENSE 2012-01-12 19:18:35.000000000 +0100 +++ new/pysendfile-2.0.1/LICENSE 2014-05-27 02:26:49.000000000 +0200 @@ -8,7 +8,7 @@ Copyright (C) 2008-2009 Niklas Edmundsson <nikke@acc.umu.se> Rewritten from scratch and maintained by: - Copyright (C) 2009-2012 Giampaolo Rodola' <g.rodola@gmail.com> + Copyright (C) 2009-2014 Giampaolo Rodola' <g.rodola@gmail.com> Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/MANIFEST.in new/pysendfile-2.0.1/MANIFEST.in --- old/pysendfile-2.0.0/MANIFEST.in 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/MANIFEST.in 2014-05-27 02:26:49.000000000 +0200 @@ -0,0 +1,9 @@ +include .travis.yml +include HISTORY.rst +include LICENSE +include Makefile +include MANIFEST.in +include README.rst +include sendfilemodule.c +include setup.py +recursive-include test *.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/Makefile new/pysendfile-2.0.1/Makefile --- old/pysendfile-2.0.0/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/Makefile 2014-05-27 12:24:30.000000000 +0200 @@ -0,0 +1,60 @@ +# Shortcuts for various tasks (UNIX only). +# To use a specific Python version run: +# $ make install PYTHON=python3.3 + +# You can set these variables from the command line. +PYTHON = python +TSCRIPT = test/test_sendfile.py + +all: test + +clean: + rm -f `find . -type f -name \*.py[co]` + rm -f `find . -type f -name \*.so` + rm -f `find . -type f -nam1e .\*~` + rm -f `find . -type f -name \*.orig` + rm -f `find . -type f -name \*.bak` + rm -f `find . -type f -name \*.rej` + rm -rf `find . -type d -name __pycache__` + rm -rf *.egg-info + rm -rf *\$testfile* + rm -rf .tox + rm -rf build + rm -rf dist + +build: clean + $(PYTHON) setup.py build + +install: build + if test $(PYTHON) = python2.5; then \ + $(PYTHON) setup.py install; \ + else \ + $(PYTHON) setup.py install --user; \ + fi + +uninstall: + cd ..; $(PYTHON) -m pip uninstall -y -v pysendfile; \ + +test: install + $(PYTHON) $(TSCRIPT) + +# requires "pip install pep8" +pep8: + @git ls-files | grep \\.py$ | xargs pep8 + +# requires "pip install pyflakes" +pyflakes: + @export PYFLAKES_NODOCTEST=1 && \ + git ls-files | grep \\.py$ | xargs pyflakes + +# requires "pip install flake8" +flake8: + @git ls-files | grep \\.py$ | xargs flake8 + +# upload source tarball on https://pypi.python.org/pypi/pysendfile. +upload-src: clean + $(PYTHON) setup.py sdist upload + +# git-tag a new release +git-tag-release: + git tag -a release-`python -c "import setup; print(setup.VERSION)"` -m `git rev-list HEAD --count`:`git rev-parse --short HEAD` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/PKG-INFO new/pysendfile-2.0.1/PKG-INFO --- old/pysendfile-2.0.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/PKG-INFO 2014-05-27 13:07:23.000000000 +0200 @@ -0,0 +1,252 @@ +Metadata-Version: 1.1 +Name: pysendfile +Version: 2.0.1 +Summary: A Python interface to sendfile(2) +Home-page: https://github.com/giampaolo/pysendfile +Author: Giampaolo Rodola +Author-email: g.rodola@gmail.com +License: MIT +Description: .. image:: https://pypip.in/d/pysendfile/badge.png + :target: https://crate.io/packages/pysendfile/ + :alt: Download this month + + .. image:: https://pypip.in/v/pysendfile/badge.png + :target: https://pypi.python.org/pypi/pysendfile/ + :alt: Latest version + + .. image:: https://pypip.in/license/pysendfile/badge.png + :target: https://pypi.python.org/pypi/pysendfile/ + :alt: License + + .. image:: https://api.travis-ci.org/giampaolo/pysendfile.png?branch=master + :target: https://travis-ci.org/giampaolo/pysendfile + :alt: Travis + + =========== + Quick links + =========== + + - `Home page <https://github.com/giampaolo/pysendfile>`_ + - `Mailing list <http://groups.google.com/group/py-sendfile>`_ + - `Blog <http://grodola.blogspot.com/search/label/pysendfile>`_ + - `What's new <https://github.com/giampaolo/pysendfile/blob/master/HISTORY.rst>`_ + + ===== + About + ===== + + `sendfile(2) <http://linux.die.net/man/2/sendfile>`__ is a system call which + provides a "zero-copy" way of copying data from one file descriptor to another + (a socket). The phrase "zero-copy" refers to the fact that all of the copying + of data between the two descriptors is done entirely by the kernel, with no + copying of data into userspace buffers. This is particularly useful when + sending a file over a socket (e.g. FTP). + The normal way of sending a file over a socket involves reading data from the + file into a userspace buffer, then write that buffer to the socket via + `send() <http://docs.python.org/library/socket.html#socket.socket.send>`__ or + `sendall() <http://docs.python.org/library/socket.html#socket.socket.sendall>`__: + + .. code-block:: python + + # how a file is tipically sent + + import socket + + file = open("somefile", "rb") + sock = socket.socket() + sock.connect(("127.0.0.1", 8021)) + + while True: + chunk = file.read(65536) + if not chunk: + break # EOF + sock.sendall(chunk) + + This copying of the data twice (once into the userland buffer, and once out + from that userland buffer) imposes some performance and resource penalties. + `sendfile(2) <http://linux.die.net/man/2/sendfile>`__ syscall avoids these + penalties by avoiding any use of userland buffers; it also results in a single + system call (and thus only one context switch), rather than the series of + `read(2) <http://linux.die.net/man/2/read>`__ / + `write(2) <http://linux.die.net/man/2/write>`__ system calls (each system call + requiring a context switch) used internally for the data copying. + + .. code-block:: python + + import socket + from sendfile import sendfile + + file = open("somefile", "rb") + blocksize = os.path.getsize("somefile") + sock = socket.socket() + sock.connect(("127.0.0.1", 8021)) + offset = 0 + + while True: + sent = sendfile(sock.fileno(), file.fileno(), offset, blocksize) + if sent == 0: + break # EOF + offset += sent + + ================== + A simple benchmark + ================== + + This `benchmark script <https://github.com/giampaolo/pysendfile/blob/master/test/benchmark.py>`__ + implements the two examples above and compares plain socket.send() and + sendfile() performances in terms of CPU time spent and bytes transmitted per + second resulting in sendfile() being about **2.5x faster**. These are the + results I get on my Linux 2.6.38 box, AMD dual-core 1.6 GHz: + + *send()* + + +---------------+-----------------+ + | CPU time | 28.84 usec/pass | + +---------------+-----------------+ + | transfer rate | 359.38 MB/sec | + +---------------+-----------------+ + + *sendfile()* + + +---------------+-----------------+ + | CPU time | 11.28 usec/pass | + +---------------+-----------------+ + | transfer rate | 860.88 MB/sec | + +---------------+-----------------+ + + =========================== + When do you want to use it? + =========================== + + Basically any application sending files over the network can take advantage of + sendfile(2). HTTP and FTP servers are a typical example. + `proftpd <http://www.proftpd.org/>`__ and + `vsftpd <https://security.appspot.com/vsftpd.html>`__ are known to use it, so is + `pyftpdlib <http://code.google.com/p/pyftpdlib/>`__. + + ================= + API documentation + ================= + + sendfile module provides a single function: sendfile(). + + - ``sendfile.sendfile(out, in, offset, nbytes, header="", trailer="", flags=0)`` + + Copy *nbytes* bytes from file descriptor *in* (a regular file) to file + descriptor *out* (a socket) starting at *offset*. Return the number of + bytes just being sent. When the end of file is reached return 0. + On Linux, if *offset* is given as *None*, the bytes are read from the current + position of *in* and the position of *in* is updated. + *headers* and *trailers* are strings that are written before and after the + data from *in* is written. In cross platform applications their usage is + discouraged + (`send() <http://docs.python.org/library/socket.html#socket.socket.send>`__ or + `sendall() <http://docs.python.org/library/socket.html#socket.socket.sendall>`__ + can be used instead). On Solaris, _out_ may be the file descriptor of a + regular file or the file descriptor of a socket. On all other platforms, + *out* must be the file descriptor of an open socket. + *flags* argument is only supported on FreeBSD. + + - ``sendfile.SF_NODISKIO`` + - ``sendfile.SF_MNOWAIT`` + - ``sendfile.SF_SYNC`` + + Parameters for the _flags_ argument, if the implementation supports it. They + are available on FreeBSD platforms. See `FreeBSD's man sendfile(2) <http://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2>`__. + + ======================= + Differences with send() + ======================= + + - sendfile(2) works with regular (mmap-like) files only (e.g. you can't use it + with a `StringIO <http://docs.python.org/library/stringio.html>`__ object). + - Also, it must be clear that the file can only be sent "as is" (e.g. you + can't modify the content while transmitting). + There might be problems with non regular filesystems such as NFS, + SMBFS/Samba and CIFS. For this please refer to + `proftpd documentation <http://www.proftpd.org/docs/howto/Sendfile.html>`__. + - `OSError <http://docs.python.org/library/exceptions.html#exceptions.OSError>`__ + is raised instead of `socket.error <http://docs.python.org/library/socket.html#socket.error>`__. + The accompaining `error codes <http://docs.python.org/library/errno.html>`__ + have the same meaning though: EAGAIN, EWOULDBLOCK, EBUSY meaning you are + supposed to retry, ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED in case of + disconnection. Some examples: + `benchmark script <https://github.com/giampaolo/pysendfile/blob/release-2.0.1/test/benchmark.py#L182>`__, + `test suite <https://github.com/giampaolo/pysendfile/blob/release-2.0.1/test/test_sendfile.py#L202>`__, + `pyftpdlib wrapper <http://code.google.com/p/pyftpdlib/source/browse/tags/release-0.7.0/pyftpdlib/ftpserver.py#1035>`__. + + =================== + Supported platforms + =================== + + This module works with Python versions from **2.5** to **3.4**. The supported platforms are: + + - **Linux** + - **Mac OSX** + - **FreeBSD** + - **Dragon Fly BSD** + - **Sun OS** + - **AIX** (not properly tested) + + ======= + Support + ======= + + Feel free to mail me at *g.rodola [AT] gmail [DOT] com* or post on the the + mailing list: http://groups.google.com/group/py-sendfile. + + ====== + Status + ====== + + As of now the code includes a solid `test suite <https://github.com/giampaolo/pysendfile/blob/master/test/test_sendfile.py>`__ and its ready for production use. + It's been included in `pyftpdlib <http://code.google.com/p/pyftpdlib/>`__ + project and used in production environments for almost a year now without any + problem being reported so far. + + ======= + Authors + ======= + + pysendfile was originally written by *Ben Woolley* including Linux, FreeBSD and + DragonFly BSD support. Later on *Niklas Edmundsson* took over maintenance and + added AIX support. After a couple of years of project stagnation + `Giampaolo Rodola' <http://grodola.blogspot.com/p/about.html>`__ took over + maintenance and rewrote it from scratch adding support for: + + - Python 3 + - non-blocking sockets + - `large file <http://docs.python.org/library/posix.html#large-file-support>`__ support + - Mac OSX + - Sun OS + - FreeBSD flag argument + - multiple threads (release GIL) + - a simple benchmark suite + - unit tests + - documentation + +Keywords: sendfile,python,performance,ftp +Platform: UNIX +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Operating System :: POSIX :: Linux +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: POSIX :: BSD +Classifier: Operating System :: POSIX :: BSD :: FreeBSD +Classifier: Operating System :: POSIX :: SunOS/Solaris +Classifier: Operating System :: POSIX :: AIX +Classifier: Programming Language :: C +Classifier: Programming Language :: Python :: 2.5 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.0 +Classifier: Programming Language :: Python :: 3.1 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Topic :: System :: Networking +Classifier: Topic :: System :: Operating System +Classifier: Topic :: Internet :: File Transfer Protocol (FTP) +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: License :: OSI Approved :: MIT License diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/README new/pysendfile-2.0.1/README --- old/pysendfile-2.0.0/README 2012-01-12 21:37:07.000000000 +0100 +++ new/pysendfile-2.0.1/README 1970-01-01 01:00:00.000000000 +0100 @@ -1,62 +0,0 @@ -=========== -Quick links -=========== - -* Home page: http://code.google.com/p/pysendfile -* Download: http://code.google.com/p/pysendfile/downloads/list - -===== -About -===== - -A python interface to sendfile(2) system call. - -======= -Install -======= - -$ sudo setup.py install - -...or: - -$ easy_install pysendfile - -=================== -Supported platforms -=================== - -* Linux -* OSX -* FreeBSD -* Dragon Fly BSD -* SunOS -* AIX (non properly tested) - -Python versions from 2.5 to 3.3 by using a single code base. - -============= -Example usage -============= - -:: - - import socket - import errno - from sendfile import sendfile - - file = open("somefile", "rb") - sock = socket.socket() - sock.connect(("127.0.0.1", 8021)) - offset = 0 - - while 1: - try: - sent = sendfile(sock.fileno(), file.fileno(), offset, 4096) - except OSError, err: - if err.errno == (errno.EAGAIN, errno.EBUSY): # retry - continue - raise - else: - if sent == 0: - break # done - offset += sent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/README.rst new/pysendfile-2.0.1/README.rst --- old/pysendfile-2.0.0/README.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/README.rst 2014-05-27 12:48:00.000000000 +0200 @@ -0,0 +1,218 @@ +.. image:: https://pypip.in/d/pysendfile/badge.png + :target: https://crate.io/packages/pysendfile/ + :alt: Download this month + +.. image:: https://pypip.in/v/pysendfile/badge.png + :target: https://pypi.python.org/pypi/pysendfile/ + :alt: Latest version + +.. image:: https://pypip.in/license/pysendfile/badge.png + :target: https://pypi.python.org/pypi/pysendfile/ + :alt: License + +.. image:: https://api.travis-ci.org/giampaolo/pysendfile.png?branch=master + :target: https://travis-ci.org/giampaolo/pysendfile + :alt: Travis + +=========== +Quick links +=========== + +- `Home page <https://github.com/giampaolo/pysendfile>`_ +- `Mailing list <http://groups.google.com/group/py-sendfile>`_ +- `Blog <http://grodola.blogspot.com/search/label/pysendfile>`_ +- `What's new <https://github.com/giampaolo/pysendfile/blob/master/HISTORY.rst>`_ + +===== +About +===== + +`sendfile(2) <http://linux.die.net/man/2/sendfile>`__ is a system call which +provides a "zero-copy" way of copying data from one file descriptor to another +(a socket). The phrase "zero-copy" refers to the fact that all of the copying +of data between the two descriptors is done entirely by the kernel, with no +copying of data into userspace buffers. This is particularly useful when +sending a file over a socket (e.g. FTP). +The normal way of sending a file over a socket involves reading data from the +file into a userspace buffer, then write that buffer to the socket via +`send() <http://docs.python.org/library/socket.html#socket.socket.send>`__ or +`sendall() <http://docs.python.org/library/socket.html#socket.socket.sendall>`__: + +.. code-block:: python + + # how a file is tipically sent + + import socket + + file = open("somefile", "rb") + sock = socket.socket() + sock.connect(("127.0.0.1", 8021)) + + while True: + chunk = file.read(65536) + if not chunk: + break # EOF + sock.sendall(chunk) + +This copying of the data twice (once into the userland buffer, and once out +from that userland buffer) imposes some performance and resource penalties. +`sendfile(2) <http://linux.die.net/man/2/sendfile>`__ syscall avoids these +penalties by avoiding any use of userland buffers; it also results in a single +system call (and thus only one context switch), rather than the series of +`read(2) <http://linux.die.net/man/2/read>`__ / +`write(2) <http://linux.die.net/man/2/write>`__ system calls (each system call +requiring a context switch) used internally for the data copying. + +.. code-block:: python + + import socket + from sendfile import sendfile + + file = open("somefile", "rb") + blocksize = os.path.getsize("somefile") + sock = socket.socket() + sock.connect(("127.0.0.1", 8021)) + offset = 0 + + while True: + sent = sendfile(sock.fileno(), file.fileno(), offset, blocksize) + if sent == 0: + break # EOF + offset += sent + +================== +A simple benchmark +================== + +This `benchmark script <https://github.com/giampaolo/pysendfile/blob/master/test/benchmark.py>`__ +implements the two examples above and compares plain socket.send() and +sendfile() performances in terms of CPU time spent and bytes transmitted per +second resulting in sendfile() being about **2.5x faster**. These are the +results I get on my Linux 2.6.38 box, AMD dual-core 1.6 GHz: + +*send()* + ++---------------+-----------------+ +| CPU time | 28.84 usec/pass | ++---------------+-----------------+ +| transfer rate | 359.38 MB/sec | ++---------------+-----------------+ + +*sendfile()* + ++---------------+-----------------+ +| CPU time | 11.28 usec/pass | ++---------------+-----------------+ +| transfer rate | 860.88 MB/sec | ++---------------+-----------------+ + +=========================== +When do you want to use it? +=========================== + +Basically any application sending files over the network can take advantage of +sendfile(2). HTTP and FTP servers are a typical example. +`proftpd <http://www.proftpd.org/>`__ and +`vsftpd <https://security.appspot.com/vsftpd.html>`__ are known to use it, so is +`pyftpdlib <http://code.google.com/p/pyftpdlib/>`__. + +================= +API documentation +================= + +sendfile module provides a single function: sendfile(). + +- ``sendfile.sendfile(out, in, offset, nbytes, header="", trailer="", flags=0)`` + + Copy *nbytes* bytes from file descriptor *in* (a regular file) to file + descriptor *out* (a socket) starting at *offset*. Return the number of + bytes just being sent. When the end of file is reached return 0. + On Linux, if *offset* is given as *None*, the bytes are read from the current + position of *in* and the position of *in* is updated. + *headers* and *trailers* are strings that are written before and after the + data from *in* is written. In cross platform applications their usage is + discouraged + (`send() <http://docs.python.org/library/socket.html#socket.socket.send>`__ or + `sendall() <http://docs.python.org/library/socket.html#socket.socket.sendall>`__ + can be used instead). On Solaris, _out_ may be the file descriptor of a + regular file or the file descriptor of a socket. On all other platforms, + *out* must be the file descriptor of an open socket. + *flags* argument is only supported on FreeBSD. + +- ``sendfile.SF_NODISKIO`` +- ``sendfile.SF_MNOWAIT`` +- ``sendfile.SF_SYNC`` + + Parameters for the _flags_ argument, if the implementation supports it. They + are available on FreeBSD platforms. See `FreeBSD's man sendfile(2) <http://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2>`__. + +======================= +Differences with send() +======================= + +- sendfile(2) works with regular (mmap-like) files only (e.g. you can't use it + with a `StringIO <http://docs.python.org/library/stringio.html>`__ object). +- Also, it must be clear that the file can only be sent "as is" (e.g. you + can't modify the content while transmitting). + There might be problems with non regular filesystems such as NFS, + SMBFS/Samba and CIFS. For this please refer to + `proftpd documentation <http://www.proftpd.org/docs/howto/Sendfile.html>`__. +- `OSError <http://docs.python.org/library/exceptions.html#exceptions.OSError>`__ + is raised instead of `socket.error <http://docs.python.org/library/socket.html#socket.error>`__. + The accompaining `error codes <http://docs.python.org/library/errno.html>`__ + have the same meaning though: EAGAIN, EWOULDBLOCK, EBUSY meaning you are + supposed to retry, ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED in case of + disconnection. Some examples: + `benchmark script <https://github.com/giampaolo/pysendfile/blob/release-2.0.1/test/benchmark.py#L182>`__, + `test suite <https://github.com/giampaolo/pysendfile/blob/release-2.0.1/test/test_sendfile.py#L202>`__, + `pyftpdlib wrapper <http://code.google.com/p/pyftpdlib/source/browse/tags/release-0.7.0/pyftpdlib/ftpserver.py#1035>`__. + +=================== +Supported platforms +=================== + +This module works with Python versions from **2.5** to **3.4**. The supported platforms are: + +- **Linux** +- **Mac OSX** +- **FreeBSD** +- **Dragon Fly BSD** +- **Sun OS** +- **AIX** (not properly tested) + +======= +Support +======= + +Feel free to mail me at *g.rodola [AT] gmail [DOT] com* or post on the the +mailing list: http://groups.google.com/group/py-sendfile. + +====== +Status +====== + +As of now the code includes a solid `test suite <https://github.com/giampaolo/pysendfile/blob/master/test/test_sendfile.py>`__ and its ready for production use. +It's been included in `pyftpdlib <http://code.google.com/p/pyftpdlib/>`__ +project and used in production environments for almost a year now without any +problem being reported so far. + +======= +Authors +======= + +pysendfile was originally written by *Ben Woolley* including Linux, FreeBSD and +DragonFly BSD support. Later on *Niklas Edmundsson* took over maintenance and +added AIX support. After a couple of years of project stagnation +`Giampaolo Rodola' <http://grodola.blogspot.com/p/about.html>`__ took over +maintenance and rewrote it from scratch adding support for: + +- Python 3 +- non-blocking sockets +- `large file <http://docs.python.org/library/posix.html#large-file-support>`__ support +- Mac OSX +- Sun OS +- FreeBSD flag argument +- multiple threads (release GIL) +- a simple benchmark suite +- unit tests +- documentation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/pysendfile.egg-info/PKG-INFO new/pysendfile-2.0.1/pysendfile.egg-info/PKG-INFO --- old/pysendfile-2.0.0/pysendfile.egg-info/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/pysendfile.egg-info/PKG-INFO 2014-05-27 13:07:23.000000000 +0200 @@ -0,0 +1,252 @@ +Metadata-Version: 1.1 +Name: pysendfile +Version: 2.0.1 +Summary: A Python interface to sendfile(2) +Home-page: https://github.com/giampaolo/pysendfile +Author: Giampaolo Rodola +Author-email: g.rodola@gmail.com +License: MIT +Description: .. image:: https://pypip.in/d/pysendfile/badge.png + :target: https://crate.io/packages/pysendfile/ + :alt: Download this month + + .. image:: https://pypip.in/v/pysendfile/badge.png + :target: https://pypi.python.org/pypi/pysendfile/ + :alt: Latest version + + .. image:: https://pypip.in/license/pysendfile/badge.png + :target: https://pypi.python.org/pypi/pysendfile/ + :alt: License + + .. image:: https://api.travis-ci.org/giampaolo/pysendfile.png?branch=master + :target: https://travis-ci.org/giampaolo/pysendfile + :alt: Travis + + =========== + Quick links + =========== + + - `Home page <https://github.com/giampaolo/pysendfile>`_ + - `Mailing list <http://groups.google.com/group/py-sendfile>`_ + - `Blog <http://grodola.blogspot.com/search/label/pysendfile>`_ + - `What's new <https://github.com/giampaolo/pysendfile/blob/master/HISTORY.rst>`_ + + ===== + About + ===== + + `sendfile(2) <http://linux.die.net/man/2/sendfile>`__ is a system call which + provides a "zero-copy" way of copying data from one file descriptor to another + (a socket). The phrase "zero-copy" refers to the fact that all of the copying + of data between the two descriptors is done entirely by the kernel, with no + copying of data into userspace buffers. This is particularly useful when + sending a file over a socket (e.g. FTP). + The normal way of sending a file over a socket involves reading data from the + file into a userspace buffer, then write that buffer to the socket via + `send() <http://docs.python.org/library/socket.html#socket.socket.send>`__ or + `sendall() <http://docs.python.org/library/socket.html#socket.socket.sendall>`__: + + .. code-block:: python + + # how a file is tipically sent + + import socket + + file = open("somefile", "rb") + sock = socket.socket() + sock.connect(("127.0.0.1", 8021)) + + while True: + chunk = file.read(65536) + if not chunk: + break # EOF + sock.sendall(chunk) + + This copying of the data twice (once into the userland buffer, and once out + from that userland buffer) imposes some performance and resource penalties. + `sendfile(2) <http://linux.die.net/man/2/sendfile>`__ syscall avoids these + penalties by avoiding any use of userland buffers; it also results in a single + system call (and thus only one context switch), rather than the series of + `read(2) <http://linux.die.net/man/2/read>`__ / + `write(2) <http://linux.die.net/man/2/write>`__ system calls (each system call + requiring a context switch) used internally for the data copying. + + .. code-block:: python + + import socket + from sendfile import sendfile + + file = open("somefile", "rb") + blocksize = os.path.getsize("somefile") + sock = socket.socket() + sock.connect(("127.0.0.1", 8021)) + offset = 0 + + while True: + sent = sendfile(sock.fileno(), file.fileno(), offset, blocksize) + if sent == 0: + break # EOF + offset += sent + + ================== + A simple benchmark + ================== + + This `benchmark script <https://github.com/giampaolo/pysendfile/blob/master/test/benchmark.py>`__ + implements the two examples above and compares plain socket.send() and + sendfile() performances in terms of CPU time spent and bytes transmitted per + second resulting in sendfile() being about **2.5x faster**. These are the + results I get on my Linux 2.6.38 box, AMD dual-core 1.6 GHz: + + *send()* + + +---------------+-----------------+ + | CPU time | 28.84 usec/pass | + +---------------+-----------------+ + | transfer rate | 359.38 MB/sec | + +---------------+-----------------+ + + *sendfile()* + + +---------------+-----------------+ + | CPU time | 11.28 usec/pass | + +---------------+-----------------+ + | transfer rate | 860.88 MB/sec | + +---------------+-----------------+ + + =========================== + When do you want to use it? + =========================== + + Basically any application sending files over the network can take advantage of + sendfile(2). HTTP and FTP servers are a typical example. + `proftpd <http://www.proftpd.org/>`__ and + `vsftpd <https://security.appspot.com/vsftpd.html>`__ are known to use it, so is + `pyftpdlib <http://code.google.com/p/pyftpdlib/>`__. + + ================= + API documentation + ================= + + sendfile module provides a single function: sendfile(). + + - ``sendfile.sendfile(out, in, offset, nbytes, header="", trailer="", flags=0)`` + + Copy *nbytes* bytes from file descriptor *in* (a regular file) to file + descriptor *out* (a socket) starting at *offset*. Return the number of + bytes just being sent. When the end of file is reached return 0. + On Linux, if *offset* is given as *None*, the bytes are read from the current + position of *in* and the position of *in* is updated. + *headers* and *trailers* are strings that are written before and after the + data from *in* is written. In cross platform applications their usage is + discouraged + (`send() <http://docs.python.org/library/socket.html#socket.socket.send>`__ or + `sendall() <http://docs.python.org/library/socket.html#socket.socket.sendall>`__ + can be used instead). On Solaris, _out_ may be the file descriptor of a + regular file or the file descriptor of a socket. On all other platforms, + *out* must be the file descriptor of an open socket. + *flags* argument is only supported on FreeBSD. + + - ``sendfile.SF_NODISKIO`` + - ``sendfile.SF_MNOWAIT`` + - ``sendfile.SF_SYNC`` + + Parameters for the _flags_ argument, if the implementation supports it. They + are available on FreeBSD platforms. See `FreeBSD's man sendfile(2) <http://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2>`__. + + ======================= + Differences with send() + ======================= + + - sendfile(2) works with regular (mmap-like) files only (e.g. you can't use it + with a `StringIO <http://docs.python.org/library/stringio.html>`__ object). + - Also, it must be clear that the file can only be sent "as is" (e.g. you + can't modify the content while transmitting). + There might be problems with non regular filesystems such as NFS, + SMBFS/Samba and CIFS. For this please refer to + `proftpd documentation <http://www.proftpd.org/docs/howto/Sendfile.html>`__. + - `OSError <http://docs.python.org/library/exceptions.html#exceptions.OSError>`__ + is raised instead of `socket.error <http://docs.python.org/library/socket.html#socket.error>`__. + The accompaining `error codes <http://docs.python.org/library/errno.html>`__ + have the same meaning though: EAGAIN, EWOULDBLOCK, EBUSY meaning you are + supposed to retry, ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED in case of + disconnection. Some examples: + `benchmark script <https://github.com/giampaolo/pysendfile/blob/release-2.0.1/test/benchmark.py#L182>`__, + `test suite <https://github.com/giampaolo/pysendfile/blob/release-2.0.1/test/test_sendfile.py#L202>`__, + `pyftpdlib wrapper <http://code.google.com/p/pyftpdlib/source/browse/tags/release-0.7.0/pyftpdlib/ftpserver.py#1035>`__. + + =================== + Supported platforms + =================== + + This module works with Python versions from **2.5** to **3.4**. The supported platforms are: + + - **Linux** + - **Mac OSX** + - **FreeBSD** + - **Dragon Fly BSD** + - **Sun OS** + - **AIX** (not properly tested) + + ======= + Support + ======= + + Feel free to mail me at *g.rodola [AT] gmail [DOT] com* or post on the the + mailing list: http://groups.google.com/group/py-sendfile. + + ====== + Status + ====== + + As of now the code includes a solid `test suite <https://github.com/giampaolo/pysendfile/blob/master/test/test_sendfile.py>`__ and its ready for production use. + It's been included in `pyftpdlib <http://code.google.com/p/pyftpdlib/>`__ + project and used in production environments for almost a year now without any + problem being reported so far. + + ======= + Authors + ======= + + pysendfile was originally written by *Ben Woolley* including Linux, FreeBSD and + DragonFly BSD support. Later on *Niklas Edmundsson* took over maintenance and + added AIX support. After a couple of years of project stagnation + `Giampaolo Rodola' <http://grodola.blogspot.com/p/about.html>`__ took over + maintenance and rewrote it from scratch adding support for: + + - Python 3 + - non-blocking sockets + - `large file <http://docs.python.org/library/posix.html#large-file-support>`__ support + - Mac OSX + - Sun OS + - FreeBSD flag argument + - multiple threads (release GIL) + - a simple benchmark suite + - unit tests + - documentation + +Keywords: sendfile,python,performance,ftp +Platform: UNIX +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Operating System :: POSIX :: Linux +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: POSIX :: BSD +Classifier: Operating System :: POSIX :: BSD :: FreeBSD +Classifier: Operating System :: POSIX :: SunOS/Solaris +Classifier: Operating System :: POSIX :: AIX +Classifier: Programming Language :: C +Classifier: Programming Language :: Python :: 2.5 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.0 +Classifier: Programming Language :: Python :: 3.1 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Topic :: System :: Networking +Classifier: Topic :: System :: Operating System +Classifier: Topic :: Internet :: File Transfer Protocol (FTP) +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: License :: OSI Approved :: MIT License diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/pysendfile.egg-info/SOURCES.txt new/pysendfile-2.0.1/pysendfile.egg-info/SOURCES.txt --- old/pysendfile-2.0.0/pysendfile.egg-info/SOURCES.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/pysendfile.egg-info/SOURCES.txt 2014-05-27 13:07:23.000000000 +0200 @@ -0,0 +1,14 @@ +.travis.yml +HISTORY.rst +LICENSE +MANIFEST.in +Makefile +README.rst +sendfilemodule.c +setup.py +pysendfile.egg-info/PKG-INFO +pysendfile.egg-info/SOURCES.txt +pysendfile.egg-info/dependency_links.txt +pysendfile.egg-info/top_level.txt +test/benchmark.py +test/test_sendfile.py \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/pysendfile.egg-info/dependency_links.txt new/pysendfile-2.0.1/pysendfile.egg-info/dependency_links.txt --- old/pysendfile-2.0.0/pysendfile.egg-info/dependency_links.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/pysendfile.egg-info/dependency_links.txt 2014-05-27 13:07:23.000000000 +0200 @@ -0,0 +1 @@ + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/pysendfile.egg-info/top_level.txt new/pysendfile-2.0.1/pysendfile.egg-info/top_level.txt --- old/pysendfile-2.0.0/pysendfile.egg-info/top_level.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/pysendfile.egg-info/top_level.txt 2014-05-27 13:07:23.000000000 +0200 @@ -0,0 +1 @@ +sendfile diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/sendfilemodule.c new/pysendfile-2.0.1/sendfilemodule.c --- old/pysendfile-2.0.0/sendfilemodule.c 2012-01-12 20:11:35.000000000 +0100 +++ new/pysendfile-2.0.1/sendfilemodule.c 2014-05-27 02:26:49.000000000 +0200 @@ -1,8 +1,4 @@ /* - * $Id: sendfilemodule.c 101 2012-01-10 23:27:51Z g.rodola@gmail.com $ - */ - -/* * pysendfile * * A Python module interface to sendfile(2) @@ -14,7 +10,7 @@ * Copyright (C) 2008,2009 Niklas Edmundsson <nikke@acc.umu.se> * * Rewritten from scratch and maintained by Giampaolo Rodola' - * Copyright (C) 2009,2012 <g.rodola@gmail.com> + * Copyright (C) 2009,2014 <g.rodola@gmail.com> * * * The MIT License @@ -392,13 +388,6 @@ #endif if (module == NULL) INITERROR; - struct module_state *st = GETSTATE(module); - - st->error = PyErr_NewException("sendfile.Error", NULL, NULL); - if (st->error == NULL) { - Py_DECREF(module); - INITERROR; - } #if PY_MAJOR_VERSION >= 3 return module; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/setup.cfg new/pysendfile-2.0.1/setup.cfg --- old/pysendfile-2.0.0/setup.cfg 1970-01-01 01:00:00.000000000 +0100 +++ new/pysendfile-2.0.1/setup.cfg 2014-05-27 13:07:23.000000000 +0200 @@ -0,0 +1,5 @@ +[egg_info] +tag_build = +tag_date = 0 +tag_svn_revision = 0 + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/setup.py new/pysendfile-2.0.1/setup.py --- old/pysendfile-2.0.0/setup.py 2012-01-12 22:28:23.000000000 +0100 +++ new/pysendfile-2.0.1/setup.py 2014-05-27 02:37:19.000000000 +0200 @@ -1,10 +1,9 @@ #!/usr/bin/env python -# $Id: setup.py 113 2012-01-12 21:28:21Z g.rodola@gmail.com $ # ====================================================================== # This software is distributed under the MIT license reproduced below: # -# Copyright (C) 2009-2012 Giampaolo Rodola' <g.rodola@gmail.com> +# Copyright (C) 2009-2014 Giampaolo Rodola' <g.rodola@gmail.com> # # Permission to use, copy, modify, and distribute this software and # its documentation for any purpose and without fee is hereby @@ -30,6 +29,10 @@ except ImportError: from distutils.core import setup, Extension + +NAME = 'pysendfile' +VERSION = '2.0.1' + if sys.version_info < (2, 5): sys.exit('python version not supported (< 2.5)') @@ -38,24 +41,19 @@ else: libraries = [] -name = 'pysendfile' -version = '2.0.0' -download_url = "http://pysendfile.googlecode.com/files/" + name + "-" + \ - version + ".tar.gz" def main(): - setup(name=name, - url='http://code.google.com/p/pysendfile/', - version=version, + setup(name=NAME, + url='https://github.com/giampaolo/pysendfile', + version=VERSION, description='A Python interface to sendfile(2)', - long_description=open('README', 'r').read(), + long_description=open('README.rst', 'r').read(), author='Giampaolo Rodola', author_email='g.rodola@gmail.com', - download_url=download_url, platforms='UNIX', license='MIT', keywords=['sendfile', 'python', 'performance', 'ftp'], - classifiers = [ + classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Operating System :: POSIX :: Linux', @@ -65,7 +63,6 @@ 'Operating System :: POSIX :: SunOS/Solaris', 'Operating System :: POSIX :: AIX', 'Programming Language :: C', - 'Programming Language :: Python :: 2.4', 'Programming Language :: Python :: 2.5', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', @@ -73,15 +70,17 @@ 'Programming Language :: Python :: 3.0', 'Programming Language :: Python :: 3.1', 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', 'Topic :: System :: Networking', 'Topic :: System :: Operating System', 'Topic :: Internet :: File Transfer Protocol (FTP)', 'Topic :: Internet :: WWW/HTTP', 'License :: OSI Approved :: MIT License', ], - ext_modules = [Extension('sendfile', - sources=['sendfilemodule.c'], - libraries=libraries)], - ) + ext_modules=[Extension('sendfile', + sources=['sendfilemodule.c'], + libraries=libraries)]) -main() +if __name__ == '__main__': + main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/test/benchmark.py new/pysendfile-2.0.1/test/benchmark.py --- old/pysendfile-2.0.0/test/benchmark.py 2012-01-12 20:09:51.000000000 +0100 +++ new/pysendfile-2.0.1/test/benchmark.py 2014-05-27 02:27:16.000000000 +0200 @@ -1,10 +1,9 @@ #!/usr/bin/env python -# $Id: benchmark.py 109 2012-01-12 19:09:48Z g.rodola@gmail.com $ # ====================================================================== # This software is distributed under the MIT license reproduced below: # -# Copyright (C) 2009-2012 Giampaolo Rodola' <g.rodola@gmail.com> +# Copyright (C) 2009-2014 Giampaolo Rodola' <g.rodola@gmail.com> # # Permission to use, copy, modify, and distribute this software and # its documentation for any purpose and without fee is hereby @@ -43,34 +42,34 @@ """ from __future__ import with_statement -import socket -import os -import errno -import timeit -import time import atexit -import sys -import optparse -import threading +import contextlib +import errno import itertools +import optparse +import os import signal -import contextlib +import socket +import sys +import threading +import time +import timeit from multiprocessing import Process from sendfile import sendfile - - # overridable defaults HOST = "127.0.0.1" PORT = 8022 BIGFILE = "$testfile1" -BIGFILE_SIZE = 1024 * 1024 * 1024 # 1 GB +BIGFILE_SIZE = 1024 * 1024 * 1024 # 1 GB BUFFER_SIZE = 65536 + # python 3 compatibility layer def b(s): - return bytes(s, 'ascii') if sys.version_info >= (3,) else s + return bytes(s, 'ascii') if sys.version_info >= (3, ) else s + # python 2.5 compatibility try: @@ -79,6 +78,7 @@ def next(iterator): return iterator.next() + def print_(s, hilite=False): if hilite: bold = '1' @@ -86,6 +86,7 @@ sys.stdout.write(s + "\n") sys.stdout.flush() + def create_file(filename, size): with open(filename, 'wb') as f: bytes = 0 @@ -96,6 +97,7 @@ if bytes >= size: break + def safe_remove(file): try: os.remove(file) @@ -158,7 +160,8 @@ file = open(BIGFILE, 'rb') def on_exit(signum, fram): - file.close(); + file.close() + conn.close() sys.exit(0) signal.signal(signal.SIGTERM, on_exit) @@ -213,7 +216,7 @@ print_("starting benchmark...") # CPU time: use sendfile() - server = Process(target=start_server, kwargs={"use_sendfile":True}) + server = Process(target=start_server, kwargs={"use_sendfile": True}) server.start() time.sleep(0.1) t1 = timeit.Timer(setup="from __main__ import Client; client = Client()", @@ -222,7 +225,7 @@ server.join() # CPU time: use send() - server = Process(target=start_server, kwargs={"use_sendfile":False}) + server = Process(target=start_server, kwargs={"use_sendfile": False}) server.start() time.sleep(0.1) t2 = timeit.Timer(setup="from __main__ import Client; client = Client()", @@ -231,8 +234,8 @@ server.join() # MB/sec: use sendfile() - server = Process(target=start_server, kwargs={"use_sendfile":True, - "keep_sending":True}) + server = Process(target=start_server, kwargs={"use_sendfile": True, + "keep_sending": True}) server.start() time.sleep(0.1) client = Client() @@ -241,8 +244,8 @@ server.join() # MB/sec: use sendfile() - server = Process(target=start_server, kwargs={"use_sendfile":False, - "keep_sending":True}) + server = Process(target=start_server, kwargs={"use_sendfile": False, + "keep_sending": True}) server.start() time.sleep(0.1) client = Client() @@ -259,6 +262,7 @@ print_(" cpu: %7.2f usec/pass" % (1000000 * t1 / 100000)) print_(" rate: %7.2f MB/sec" % round(bytes1 / 1024.0 / 1024.0, 2)) + if __name__ == '__main__': s = Spinner() s.start() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pysendfile-2.0.0/test/test_sendfile.py new/pysendfile-2.0.1/test/test_sendfile.py --- old/pysendfile-2.0.0/test/test_sendfile.py 2012-01-12 20:09:51.000000000 +0100 +++ new/pysendfile-2.0.1/test/test_sendfile.py 2014-05-27 12:41:36.000000000 +0200 @@ -1,12 +1,9 @@ #!/usr/bin/env python -# -# $Id: test_sendfile.py 109 2012-01-12 19:09:48Z g.rodola@gmail.com $ -# # ====================================================================== # This software is distributed under the MIT license reproduced below: # -# Copyright (C) 2009-2012 Giampaolo Rodola' <g.rodola@gmail.com> +# Copyright (C) 2009-2014 Giampaolo Rodola' <g.rodola@gmail.com> # # Permission to use, copy, modify, and distribute this software and # its documentation for any purpose and without fee is hereby @@ -35,22 +32,23 @@ from __future__ import with_statement -import unittest +import asynchat +import asyncore +import atexit +import errno +import optparse import os -import sys import socket -import asyncore -import asynchat +import sys import threading -import errno import time -import atexit +import unittest import warnings -import optparse import sendfile -PY3 = sys.version_info >= (3,) +PY3 = sys.version_info >= (3, ) + def b(x): if PY3: @@ -72,12 +70,14 @@ except Exception: SUPPORT_HEADER_TRAILER = True + def safe_remove(file): try: os.remove(file) except OSError: pass + def has_large_file_support(): # taken from Python's Lib/test/test_largefile.py with open(TESTFN, 'wb', buffering=0) as f: @@ -150,7 +150,6 @@ self.handler_instance = None self._active = False self._active_lock = threading.Lock() - # --- public API @property @@ -174,7 +173,6 @@ while not getattr(self.handler_instance, "closed", True): time.sleep(0.001) self.stop() - # --- internals def run(self): @@ -201,7 +199,8 @@ raise -def sendfile_wrapper(sock, file, offset, nbytes=BUFFER_LEN, header="", trailer=""): +def sendfile_wrapper(sock, file, offset, nbytes=BUFFER_LEN, header="", + trailer=""): """A higher level wrapper representing how an application is supposed to use sendfile(). """ @@ -289,7 +288,8 @@ def test_header(self): total_sent = 0 header = b("x") * 512 - sent = sendfile.sendfile(self.sockno, self.fileno, 0, header=header) + sent = sendfile.sendfile(self.sockno, self.fileno, 0, + header=header) total_sent += sent offset = BUFFER_LEN while 1: @@ -358,7 +358,6 @@ err = sys.exc_info()[1] if err.errno not in (errno.EBUSY, errno.EAGAIN): raise - # --- corner cases def test_offset_overflow(self): @@ -485,13 +484,15 @@ sys.stdout.flush() def create_file(self): - if os.path.isfile(TESTFN3) and os.path.getsize(TESTFN3) >= BIGFILE_SIZE: + if (os.path.isfile(TESTFN3) and + os.path.getsize(TESTFN3) >= BIGFILE_SIZE): return f = open(TESTFN3, 'wb') chunk_len = 65536 chunk = b('x' * chunk_len) total = 0 - timer = RepeatedTimer(1, lambda: self.print_percent(total, BIGFILE_SIZE)) + timer = RepeatedTimer(1, lambda: self.print_percent(total, + BIGFILE_SIZE)) timer.start() try: while 1: @@ -538,6 +539,13 @@ self.assertEqual(file_size, data_len) +def cleanup(): + safe_remove(TESTFN) + safe_remove(TESTFN2) + +atexit.register(cleanup) + + def test_main(): parser = optparse.OptionParser() parser.add_option('-k', '--keepfile', action="store_true", default=False, @@ -546,22 +554,25 @@ if not options.keepfile: atexit.register(lambda: safe_remove(TESTFN3)) - def cleanup(): - safe_remove(TESTFN) - safe_remove(TESTFN2) - - atexit.register(cleanup) - test_suite = unittest.TestSuite() test_suite.addTest(unittest.makeSuite(TestSendfile)) if has_large_file_support(): test_suite.addTest(unittest.makeSuite(TestLargeFile)) else: - atexit.register(warnings.warn, "large files unsupported", RuntimeWarning) + atexit.register(warnings.warn, "large files unsupported", + RuntimeWarning) cleanup() with open(TESTFN, "wb") as f: f.write(DATA) - unittest.TextTestRunner(verbosity=2).run(test_suite) + result = unittest.TextTestRunner(verbosity=2).run(test_suite) + return result.wasSuccessful() + if __name__ == '__main__': - test_main() + try: + if not test_main(): + sys.exit(1) + except (KeyboardInterrupt, SystemExit): + # this will make the threaded server exit immediately + asyncore.socket_map.clear() + raise -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org
participants (1)
-
root@hilbert.suse.de