############################################
portalocker - Cross-platform locking library
############################################

.. image:: https://travis-ci.org/WoLpH/portalocker.svg?branch=master
    :alt: Linux Test Status
    :target: https://travis-ci.org/WoLpH/portalocker
    
.. image:: https://ci.appveyor.com/api/projects/status/mgqry98hgpy4prhh?svg=true
    :alt: Windows Tests Status
    :target: https://ci.appveyor.com/project/WoLpH/portalocker

.. image:: https://coveralls.io/repos/WoLpH/portalocker/badge.svg?branch=master
    :alt: Coverage Status
    :target: https://coveralls.io/r/WoLpH/portalocker?branch=master

Overview
--------

Portalocker is a library to provide an easy API to file locking.

An important detail to note is that on Linux and Unix systems the locks are
advisory by default. By specifying the `-o mand` option to the mount command it
is possible to enable mandatory file locking on Linux. This is generally not
recommended however. For more information about the subject:

 - https://en.wikipedia.org/wiki/File_locking
 - http://stackoverflow.com/questions/39292051/portalocker-does-not-seem-to-lock
 - https://stackoverflow.com/questions/12062466/mandatory-file-lock-on-linux

The module is currently maintained by Rick van Hattem <Wolph@wol.ph>.
The project resides at https://github.com/WoLpH/portalocker . Bugs and feature
requests can be submitted there. Patches are also very welcome.

Tips
----

On some networked filesystems it might be needed to force a `os.fsync()` before
closing the file so it's actually written before another client reads the file.
Effectively this comes down to:

::
    
   with portalocker.Lock('some_file', 'rb+', timeout=60) as fh:
       # do what you need to do
       ...
       
       # flush and sync to filesystem
       fh.flush()
       os.fsync(fh.fileno())

Links
-----

* Documentation
    - http://portalocker.readthedocs.org/en/latest/
* Source
    - https://github.com/WoLpH/portalocker
* Bug reports 
    - https://github.com/WoLpH/portalocker/issues
* Package homepage
    - https://pypi.python.org/pypi/portalocker
* My blog
    - http://w.wol.ph/

Examples
--------

To make sure your cache generation scripts don't race, use the `Lock` class:

>>> import portalocker
>>> with portalocker.Lock('somefile', timeout=1) as fh:
    print >>fh, 'writing some stuff to my cache...'

To customize the opening and locking a manual approach is also possible:

>>> import portalocker
>>> file = open('somefile', 'r+')
>>> portalocker.lock(file, portalocker.LOCK_EX)
>>> file.seek(12)
>>> file.write('foo')
>>> file.close()

Explicitly unlocking might not be needed in all cases:
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/issues/42#issuecomment-601108266

But can be done through:

>>> portalocker.unlock(file)

Do note that your data might still be in a buffer so it is possible that your
data is not available until you `flush()` or `close()`.

More examples can be found in the
`tests <http://portalocker.readthedocs.io/en/latest/_modules/tests/tests.html>`_.

Changelog
---------

See the `changelog <http://portalocker.readthedocs.io/en/latest/changelog.html>`_ page.

License
-------

See the `LICENSE <https://github.com/WoLpH/portalocker/blob/develop/LICENSE>`_ file.

