1# emacs: at the end of the file
2# ex: set sts=4 ts=4 sw=4 et:
3# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
4"""Stub file for a guaranteed safe import of duecredit constructs:  if duecredit
5is not available.
6
7To use it, place it into your project codebase to be imported, e.g. copy as
8
9    cp stub.py /path/tomodule/module/due.py
10
11Note that it might be better to avoid naming it duecredit.py to avoid shadowing
12installed duecredit.
13
14Then use in your code as
15
16    from .due import due, Doi, BibTeX
17
18See  https://github.com/duecredit/duecredit/blob/master/README.md for examples.
19
20Origin:     Originally a part of the duecredit
21Copyright:  2015-2016  DueCredit developers
22License:    BSD-2
23
24Modified for MDAnalysis to avoid calls to fork which raises cryptic
25warning under MPI(see PR #1794 for rationale)
26
27"""
28
29from __future__ import absolute_import
30__version__ = '0.0.5'
31
32
33class InactiveDueCreditCollector(object):
34    """Just a stub at the Collector which would not do anything"""
35    def _donothing(self, *args, **kwargs):
36        """Perform no good and no bad"""
37        pass
38
39    def dcite(self, *args, **kwargs):
40        """If I could cite I would"""
41        def nondecorating_decorator(func):
42            return func
43        return nondecorating_decorator
44
45    cite = load = add = _donothing
46
47    def __repr__(self):
48        return self.__class__.__name__ + '()'
49
50
51def _donothing_func(*args, **kwargs):
52    """Perform no good and no bad"""
53    pass
54
55
56try:
57    # Avoid call of fork inside duecredit; see
58    # https://github.com/MDAnalysis/mdanalysis/pull/1822#issuecomment-373009050
59    import sys
60    import os
61    if sys.version_info >= (3, 7):
62        import duecredit
63    else:
64        from mock import patch
65        if sys.version_info <= (2, ):
66            from contextlib import nested
67            with nested(patch('os.fork'), patch('os.popen')) \
68                 as (os_dot_fork, os_dot_popen):
69                import duecredit
70        else:
71            if not os.name == 'nt':
72                with patch('os.fork') as os_dot_fork, patch('os.popen') as os_dot_popen:
73                    import duecredit
74            else:
75                # Windows doesn't have os.fork
76                import duecredit
77
78    from duecredit import due, BibTeX, Doi, Url
79    if 'due' in locals() and not hasattr(due, 'cite'):
80        raise RuntimeError(
81            "Imported due lacks .cite. DueCredit is now disabled")
82except Exception as err:
83    if not isinstance(err, ImportError):
84        import logging
85        import warnings
86        errmsg = "Failed to import duecredit due to {}".format(str(err))
87        warnings.warn(errmsg)
88        logging.getLogger("duecredit").error(
89            "Failed to import duecredit due to {}".format(str(err)))
90    # else:
91    #   Do not issue any warnings if duecredit is not installed;
92    #   this is the user's choice (Issue #1872)
93
94    # Initiate due stub
95    due = InactiveDueCreditCollector()
96    BibTeX = Doi = Url = _donothing_func
97
98# Emacs mode definitions
99# Local Variables:
100# mode: python
101# py-indent-offset: 4
102# tab-width: 4
103# indent-tabs-mode: nil
104# End:
105