Beispiel #1
0
def get_dirname(module: ModuleOrStrTypes) -> str:
    '''
    Absolute dirname of the directory providing the passed module or package.

    If this module is a non-namespace package, this is the directory containing
    this package's top-level ``__init__`` submodule.

    Caveats
    ----------
    **This dirname is not guaranteed to be canonical.** Since this function
    does *not* resolve symbolic links in this dirname, one or more directory
    components of this dirname may be symbolic links. Consider calling the
    :func:`get_dirname_canonical` function instead if this is undesirable.

    Parameters
    ----------
    module : ModuleOrStrTypes
        Either:

        * The fully-qualified name of this module, in which case this function
          dynamically imports this module as a non-optional side effect.
        * A previously imported module object.

    Returns
    ----------
    str
        Absolute dirname of the directory providing this module or package.
    '''

    # Avoid circular import dependencies.
    from betse.util.path import pathnames

    # Return this dirname. Note that get_filename() returns the absolute
    # filename of the "__init__.py" file if this module is a package.
    return pathnames.get_dirname(get_filename(module))
Beispiel #2
0
def make_parent_unless_dir(*pathnames: str) -> None:
    '''
    Create the parent directories of all passed directories that do *not*
    already exist, silently ignoring those that *do* already exist.

    Parameters
    -----------
    pathnames : tuple[str]
        Tuple of the absolute or relative pathnames to create the parent
        directories of.

    See Also
    -----------
    :func:`make_unless_dir`
        Further details.
    '''

    # Avoid circular import dependencies.
    from betse.util.path.pathnames import get_dirname, canonicalize

    # Canonicalize each pathname *BEFORE* attempting to get its dirname.
    # Relative pathnames do *NOT* have sane dirnames (e.g., the dirname for a
    # relative pathname "metatron" is the empty string) and hence *MUST* be
    # converted to absolute pathnames first.
    for pathname in pathnames:
        make_unless_dir(get_dirname(canonicalize(pathname)))
Beispiel #3
0
def die_unless_parent_dir(pathname: str) -> None:
    '''
    Raise an exception unless the parent directory of the passed path exists.
    '''

    # Avoid circular import dependencies.
    from betse.util.path import pathnames

    # If the parent directory of this path does *NOT* exist, raise an
    # exception.
    die_unless_dir(pathnames.get_dirname(pathname))
Beispiel #4
0
def get_parent_dir_last(pathname: str) -> str:
    '''
    Absolute pathname of the most deeply nested existing parent directory of
    the path with the passed pathname.

    Since the passed pathname is required to be absolute *and* since the root
    directory (e.g., ``/`` on POSIX-compatible platforms) always exists, this
    function is guaranteed to return the pathname of an existing directory.

    Parameters
    -----------
    pathname : str
        Absolute pathname of the path to inspect.

    Returns
    -----------
    str
        Absolute pathname of the most deeply nested existing parent directory
        of this path.

    Examples
    -----------
    Given an existing directory ``/the/garden/of/earthly/`` and non-existing
    subdirectory ``/the/garden/of/earthly/delights/`` of that directory:

        >>> from betse.util.path import dirs
        >>> dirs.get_parent_dir_last('/the/garden/of/earthly/delights/')
        '/the/garden/of/earthly'
    '''

    # Avoid circular import dependencies.
    from betse.util.path import pathnames

    # If this pathname is relative rather than absolute, raise an exception.
    pathnames.die_if_relative(pathname)

    # Current directory component of this path to inspect the existence of.
    dirname_component = pathname

    # While this directory component is *NOT* an existing directory...
    while not is_dir(dirname_component):
        # Reduce this directory component to its parent directory.
        dirname_component = pathnames.get_dirname(dirname_component)

    # Return this existing directory component.
    return dirname_component
Beispiel #5
0
    def _set_conf_filename(self, conf_filename: str) -> None:
        '''
        Set the absolute path of the YAML-formatted file associated with this
        configuration.

        Design
        ----------
        To prevent external callers from unsafely setting this path, this
        setter is intentionally implemented as an manual setter rather than a
        more preferable :meth:`conf_filename` property setter.
        '''

        # Unique absolute filename of this file assigned *BEFORE* this file's
        # parent directory, ensuring the latter is non-empty.
        self._conf_filename = pathnames.canonicalize(conf_filename)

        # Basename of this file.
        self._conf_basename = pathnames.get_basename(self._conf_filename)

        # Unique absolute dirname of the parent directory of this file.
        self._conf_dirname = pathnames.get_dirname(self._conf_filename)
Beispiel #6
0
    def _run_pyinstaller_command(
        self,
        script_basename: str,
        script_type: str,
        entry_point,
    ) -> None:
        '''
        Run the currently configured PyInstaller command for the passed entry
        point's script wrapper.

        Attributes
        ----------
        script_basename : str
            Basename of the executable wrapper script running this entry point.
        script_type : str
            Type of the executable wrapper script running this entry point,
            guaranteed to be either:

            * If this script is console-specific, ``console`` .
            * Else, ``gui``.
        entry_point : EntryPoint
            Entry point, whose attributes specify the module to be imported and
            function to be run by this script.
        '''

        # Defer heavyweight imports.
        from betse.util.io import stderrs
        from betse.util.os.shell import shellstr
        from betse.util.path import files, pathnames

        # If this spec exists, instruct PyInstaller to reuse rather than
        # recreate this file, thus preserving edits to this file.
        if files.is_file(self._pyinstaller_spec_filename):
            print('Reusing spec file "{}".'.format(
                self._pyinstaller_spec_filename))

            # Append the relative path of this spec file.
            self._pyinstaller_args.append(
                shellstr.shell_quote(self._pyinstaller_spec_filename))

            # Freeze this script with this spec file.
            self._run_pyinstaller_imported()
        # Else, instruct PyInstaller to (re)create this spec file.
        else:
            # Absolute path of the directory containing this files.
            pyinstaller_spec_dirname = pathnames.get_dirname(
                self._pyinstaller_spec_filename)

            # Absolute path of the current script wrapper.
            script_filename = pathnames.join(self.install_dir, script_basename)
            files.die_unless_file(
                script_filename,
                'File "{}" not found. {}'.format(script_filename,
                                                 freeze.EXCEPTION_ADVICE))

            # Inform the user of this action *AFTER* the above validation.
            # Since specification files should typically be reused rather
            # than regenerated, do so as a non-fatal warning.
            stderrs.output_warning('Generating spec file "{}".'.format(
                self._pyinstaller_spec_filename))

            # Append all options specific to spec file generation.
            self._pyinstaller_args.extend([
                # If this is a console script, configure standard input and
                # output for console handling; else, do *NOT* and, if the
                # current operating system is OS X, generate an ".app"-suffixed
                # application bundle rather than a customary executable.
                '--console' if script_type == 'console' else '--windowed',

                # Non-default PyInstaller directories.
                '--additional-hooks-dir=' +
                shellstr.shell_quote(self._pyinstaller_hooks_dirname),
                '--specpath=' + shellstr.shell_quote(pyinstaller_spec_dirname),
            ])

            # Append all subclass-specific options.
            self._pyinstaller_args.extend(self._get_pyinstaller_options())

            # Append the absolute path of this script.
            self._pyinstaller_args.append(
                shellstr.shell_quote(script_filename))

            # Freeze this script and generate a spec file.
            self._run_pyinstaller_imported()

            # Absolute path of this file.
            script_spec_filename = pathnames.join(pyinstaller_spec_dirname,
                                                  script_basename + '.spec')

            # Rename this file to have the basename expected by the prior
            # conditional on the next invocation of this setuptools command.
            #
            # Note that "pyinstaller" accepts an option "--name" permitting
            # the basename of this file to be specified prior to generating
            # this file. Unfortunately, this option *ALSO* specifies the
            # basename of the generated executable. While the former is
            # reliably renamable, the former is *NOT* (e.g., due to code
            # signing). Hence, this file is manually renamed without passing
            # this option.
            files.move_file(script_spec_filename,
                            self._pyinstaller_spec_filename)
Beispiel #7
0
def get_package_worktree_dirname_or_none(
        package: ModuleType) -> StrOrNoneTypes:
    '''
    **Absolute canonical dirname** (i.e., absolute dirname after resolving
    symbolic links) of the **Git-based working tree** (i.e., top-level
    directory containing the canonical ``.git`` subdirectory) governing the
    passed top-level Python package if found *or* ``None`` otherwise.

    Caveats
    ----------
    **This directory typically does not exist.** This directory is only
    required during development by developers and hence should *not* be assumed
    to exist.

    For safety and efficiency, this function does *not* recursively search the
    filesystem up from the directory yielding this package for a ``.git``
    subdirectory; rather, this function only directly searches that directory
    itself for such a subdirectory. For that reason, this function typically
    returns ``None`` for *all* modules except top-level packages installed in a
    developer manner (e.g., by running ``sudo python3 setup.py develop``).

    Parameters
    ----------
    package : ModuleType
        Top-level Python package to be queried.

    Returns
    ----------
    StrOrNoneTypes
        Either:

        * The absolute canonical dirname of that package's Git working tree if
          that package was installed in a developer manner: e.g., by

          * ``python3 setup.py develop``.
          * ``python3 setup.py symlink``.

        * ``None`` if that package was installed in a non-developer manner:
          e.g., by

          * ``pip3 install``.
          * ``python3 setup.py develop``.
    '''

    # Avoid circular import dependencies.
    from betse.util.path import dirs, pathnames
    from betse.util.py.module import pymodule

    # Absolute canonical dirname of the directory providing this package,
    # canonicalized into a directory rather than symbolic link to increase the
    # likelihood of obtaining the actual parent directory of this package
    package_dirname = pymodule.get_dirname_canonical(package)

    # Absolute dirname of the parent directory of this directory.
    worktree_dirname = pathnames.get_dirname(package_dirname)

    # Absolute dirname of the ".git" subdirectory of this parent directory.
    git_subdirname = pathnames.join(worktree_dirname, '.git')

    # Return this parent directory's absolute dirname if this subdirectory
    # exists *OR* "None" otherwise.
    return worktree_dirname if dirs.is_dir(git_subdirname) else None
Beispiel #8
0
    def _init_logger_root_handler_file(self) -> None:
        '''
        Initialize the root logger handler appending log messages to the
        currently open logfile file handle.

        This method is designed to be called multiple times, permitting the
        filename associated with this handler to be modified at runtime.
        '''

        # Avoid circular import dependencies.
        from betse.util.io.log.logfilter import LogFilterThirdPartyDebug
        from betse.util.io.log.conf.logconfformat import LogFormatterWrap
        from betse.util.io.log.conf.logconfhandle import (
            LogHandlerFileRotateSafe)
        from betse.util.path import pathnames
        from betse.util.os.command import cmds
        from betse.util.type.numeric import ints

        # Absolute or relative path of the directory containing this file.
        file_dirname = pathnames.get_dirname(self._filename)

        # Minimum level of messages to be log to disk, defaulting to "INFO".
        file_level = LogLevel.INFO

        # If this handler has already been created...
        if self._logger_root_handler_file is not None:
            # Preserve the previously set minimum level of messages to log.
            file_level = self._logger_root_handler_file.level

            # If the root logger has also already been created, remove this
            # handler from this root logger.
            if self._logger_root is not None:
                self._logger_root.removeHandler(self._logger_root_handler_file)

        # If the dirname of the directory containing this file is non-empty,
        # create this directory if needed. Note this dirname is empty when this
        # filename is a pure basename (e.g., when the "--log-file=my.log"
        # option is passed).
        #
        # For safety, this directory is created with standard low-level Python
        # functionality rather than our custom higher-level
        # dirs.make_parent_unless_dir() function. The latter logs this
        # creation. Since the root logger is *NOT* fully configured yet,
        # calling that function here would induce subtle errors or exceptions.
        if file_dirname:
            os.makedirs(file_dirname, exist_ok=True)

        # Root logger file handler, preconfigured as documented above.
        self._logger_root_handler_file = LogHandlerFileRotateSafe(
            filename=self._filename,

            # Append rather than overwrite this file.
            mode='a',

            # Defer opening this file in a just-in-time manner (i.e., until the
            # first call to this handler's emit() method is called to write the
            # first log via this handler). Why? Because (in no particular
            # order):
            #
            # * If the end user requests that *NO* messages be logged to disk
            #   (e.g., by passing the "--log-level=none" option), this file
            #   should *NEVER* be opened and hence created. The simplest means
            #   of doing so is simply to indefinitely defer opening this file.
            # * Doing so slightly reduces the likelihood (but *NOT* eliminate
            #   the possibility) of race conditions between multiple BETSE
            #   processes attempting to concurrently rotate the same logfile.
            delay=True,

            # Encode this file's contents as UTF-8.
            encoding='utf-8',

            # Maximum filesize in bytes at which to rotate this file,
            # equivalent to 1MB.
            maxBytes=ints.MiB,

            # Maximum number of rotated logfiles to maintain.
            backupCount=8,
        )

        # Initialize this handler's level to the previously established level.
        self._logger_root_handler_file.setLevel(file_level)

        # Prevent third-party debug messages from being logged to disk.
        self._logger_root_handler_file.addFilter(LogFilterThirdPartyDebug())

        # Linux-style logfile format.
        #
        # Note that the "processName" attribute appears to *ALWAYS* expand to
        # "MainProcess", which is not terribly descriptive. Hence, the name of
        # the current process is manually embedded in this format.
        file_format = ('[{{asctime}}] '
                       '{} {{levelname}} '
                       '({{module}}.py:{{funcName}}():{{lineno}}) '
                       '<PID {{process}}>:\n'
                       '    {{message}}'.format(cmds.get_current_basename()))

        # Format this file according to this format.
        file_formatter = LogFormatterWrap(fmt=file_format, style='{')
        self._logger_root_handler_file.setFormatter(file_formatter)

        # Register this handler with the root logger.
        self._logger_root.addHandler(self._logger_root_handler_file)
Beispiel #9
0
    def setup(self, *args, **kwargs) -> None:
        '''
        Prepare to write animation frames.

        This method is implicitly called by the superclass :meth:`saving`
        method implicitly called by the :meth:`Anim.save` method. Note that,
        unfortunately, the design of both methods prohibits this method from
        accepting subclass-specific parameters.

        Parameters
        -----------
        outfile : str
            :meth:`str.format`-formatted template describing the filenames of
            the resulting frame images. This template is subject to the
            following :meth:`str.format` formatting:

            * The first ``{``- and ``}``-delimited substring (e.g., ``{:07d}``)
              will be replaced by the 0-based index of the current frame. If
              this substring does *not* exist, an exception is raised.

        See the superclass :meth:`setup` method for details on all other
        parameters.

        See Also
        -----------
        https://www.python.org/dev/peps/pep-3101
            For details on format specifiers.
        '''

        super().setup(*args, **kwargs)

        # Frame number of the next frame to be written.
        self._frame_number = 0

        # If this filename template is malformed, raise an exception.
        if not ('{' in self.outfile and '}' in self.outfile):
            raise BetseMatplotlibException(
                'Frame filename template "{}" contains no "{{"- and "}}"-'
                'delimited format specifier.'.format(self.outfile))

        # Output filetype. Override the superclass' awkward choice of "rgba" as
        # output filetype default.
        self.frame_format = pathnames.get_filetype_undotted_or_none(
            self.outfile)

        # List of all output filetypes supported by this class.
        #
        # Since this class serializes frames by calling the savefig() function
        # *AND* since that function supports all image filetypes supported by
        # the current backend, this syllogistically follows. (Q.E.D.)
        out_filetypes_supported = self.fig.canvas.get_supported_filetypes()

        # If this filetype is unsupported, raise an exception.
        if self.frame_format not in out_filetypes_supported:
            raise BetseMatplotlibException(
                'Frame filetype "{}" unsupported by the '
                'current Matplotlib backend (i.e., not in "{}").'.format(
                    self.frame_format, str(out_filetypes_supported)))

        # Parent directory of all output files.
        out_dirname = pathnames.get_dirname(self.outfile)

        # Create this directory if needed.
        dirs.make_parent_unless_dir(out_dirname)
Beispiel #10
0
def _is_blas_optimized_posix_symlink() -> BoolOrNoneTypes:
    '''
    ``True`` only if the current platform is POSIX-compliant and hence
    supports symbolic links *and* the first item of the ``libraries`` list of
    the global :data:`numpy.__config__.blas_opt_info` dictionary is a symbolic
    link masquerading as either the unoptimized reference BLAS implementation
    but in fact linking to an optimized BLAS implementation.

    This function returns ``None`` when unable to deterministically decide this
    boolean, in which case a subsequent heuristic will attempt to do so.
    '''

    # If the current platform is POSIX-incompatible and hence does *NOT*
    # support symbolic links, continue to the next heuristic.
    if not posix.is_posix():
        return None

    #FIXME: Generalize to macOS as well once the
    #libs.iter_linked_filenames() function supports macOS.

    # If the current platform is *NOT* Linux, continue to the next heuristic.
    #
    # The libs.iter_linked_filenames() function called below currently only
    # supports Linux.
    if not linux.is_linux():
        return None

    # First element of the list of uniquely identifying substrings of all BLAS
    # library basenames this version of Numpy is linked against.
    #
    # Note that this list is guaranteed to both exist and be non-empty due to
    # the previously called _is_blas_optimized_opt_info_basename() function.
    blas_basename_substr = numpy_config.blas_opt_info['libraries'][0]

    # If this element appears to be neither the reference BLAS or CBLAS
    # implementations (e.g., "blas", "cblas", "refblas", "refcblas"), continue
    # to the next heuristic.
    if not blas_basename_substr.endswith('blas'):
        return None

    # Arbitrary Numpy C extension.
    #
    # Unfortunately, the "numpy.__config__" API fails to specify the absolute
    # paths of the libraries it links against. Since there exists no reliable
    # means of reverse engineering these paths from this API, these paths must
    # be obtained by another means: specifically, by querying the standard
    # "numpy.core.multiarray" C extension installed under all supported Numpy
    # for the absolute paths of all external shared libraries to which this
    # extension links -- exactly one of which is guaranteed to be the absolute
    # path of what appears to be a reference BLAS or CBLAS implementation.
    numpy_lib = get_c_extension()

    # Absolute filename of this C extension.
    numpy_lib_filename = pymodule.get_filename(module=numpy_lib)

    # For the basename and absolute filename of each shared library linked to
    # by this Numpy shared library...
    for (numpy_linked_lib_basename, numpy_linked_lib_filename) in (
            dlls.iter_linked_filenames(numpy_lib_filename)):
        # Basename excluding all suffixing filetypes of this library.
        numpy_linked_lib_rootname = pathnames.get_pathname_sans_filetypes(
            numpy_linked_lib_basename)
        # logs.log_info('rootname: %s; basename: %s; filename: %s', numpy_linked_lib_rootname, numpy_linked_lib_basename, numpy_linked_lib_filename)

        # If this appears to be neither the BLAS nor CBLAS reference library,
        # continue to the next library.
        if not numpy_linked_lib_rootname.endswith('blas'):
            continue
        # Else, this is either the BLAS or CBLAS reference library.

        # Absolute filename of the target library to which this library links
        # if this library is a symbolic link *OR* of this library as is
        # otherwise (i.e., if this is a library rather than symbolic link).
        numpy_linked_lib_target_filename = pathnames.canonicalize(
            numpy_linked_lib_filename)
        # logs.log_info('target filename: %s', numpy_linked_lib_target_filename)

        # If either the basename or dirname of this path corresponds to that of
        # an optimized BLAS library, return True.
        if regexes.is_match(
                text=pathnames.get_basename(numpy_linked_lib_target_filename),
                regex=_OPTIMIZED_BLAS_LINKED_LIB_BASENAME_REGEX,
        ) or regexes.is_match(
                text=pathnames.get_dirname(numpy_linked_lib_target_filename),
                regex=_OPTIMIZED_BLAS_LINKED_LIB_DIRNAME_REGEX,
        ):
            return True

        # Else, Numpy links against an unoptimized BLAS implementation. Halt!
        break

    # Else, instruct our caller to continue to the next heuristic.
    return None
Beispiel #11
0
    def save(
        self,

        # Mandatory parameters.
        conf_filename: str,

        # Optional parameters.
        is_conf_file_overwritable: bool = False,
        conf_subdir_overwrite_policy: DirOverwritePolicy = (
            DirOverwritePolicy.SKIP_WITH_WARNING),
    ) -> None:
        '''
        Serialize (i.e., save, write) the low-level mapping or sequence
        internally persisted in this wrapper to the YAML-formatted file with
        the passed filename, copying *all* external resources internally
        referenced by this mapping or sequence into this file's directory.

        This method effectively implements the "Save As..." GUI metaphor.
        Specifically, this method (in order):

        #. Serializes this mapping or sequence to the file with this filename,
           optionally overwriting the existing contents of this file depending
           on the passed ``is_conf_file_overwritable`` parameter.
        #. Recursively copies all relative subdirectories internally referenced
           (and hence required) by this file from the directory of the current
           file associated with this wrapper into the directory of the passed
           file, optionally overwriting the existing contents of these
           subdirectories depending on the passed
           ``conf_subdir_overwrite_policy`` parameter.
        #. Associates this wrapper with this filename.

        Parameters
        ----------
        conf_filename : str
            Absolute or relative filename of the target file to be serialized.
        is_conf_file_overwritable : optional[bool]
            If this target file already exists *and* this boolean is:

            * ``True``, this target file is silently overwritten.
            * ``False``, an exception is raised.

            Defaults to ``False``.
        conf_subdir_overwrite_policy : DirOverwritePolicy
            **Subdirectory overwrite policy** (i.e., strategy for handling
            existing subdirectories to be overwritten by this save), where the
            subdirectories in question are all subdirectories of the directory
            of this target file. Defaults to
            :attr:`DirOverwritePolicy.SKIP_WITH_WARNING`, ignoring each target
            subdirectory that already exists with a non-fatal warning.

        Raises
        ----------
        BetseDirException
            If the passed ``conf_subdir_overwrite_policy`` parameter is
            :attr:`DirOverwritePolicy.HALT_WITH_EXCEPTION` *and* one or more
            subdirectories of the target directory already exist that are also
            subdirectories of the source directory.
        BetseFileException
            If the passed ``is_conf_file_overwritable`` parameter is ``False``
            *and* this target file already exists.
        '''

        # Log this save.
        logs.log_debug(
            'Saving YAML file: %s -> %s',
            self._conf_filename, conf_filename)

        # Serialize this mapping or sequence to this file.
        #
        # Note that the die_unless_loaded() method need *NOT* be called here,
        # as the "conf" property implicitly does so on our behalf.
        yamls.save(
            container=self.conf,
            filename=conf_filename,
            is_overwritable=is_conf_file_overwritable,
        )

        # Absolute dirnames of the directories containing the current file and
        # the passed file, canonicalized to permit comparison below.
        src_dirname = pathnames.canonicalize(self.conf_dirname)
        trg_dirname = pathnames.canonicalize(
            pathnames.get_dirname(conf_filename))

        # If these directories differ, recursively copy all relative
        # subdirectories internally referenced and hence required by this file.
        if src_dirname != trg_dirname:
            # For the basename of each such subdirectory...
            #
            # Note that the ideal solution of recursively copying this source
            # directory into the directory of this target file (e.g., via
            # "dirs.copy(src_dirname, pathnames.get_dirname(conf_filename))")
            # fails for the following subtle reasons:
            #
            # * This target directory may be already exist, which dirs.copy()
            #   prohibits even when the directory is empty.
            # * This target configuration file basename may differ from that of
            #   this source configuration file, necessitating a subsequent call
            #   to file.move().
            for conf_subdirname in self._iter_conf_subdir_basenames():
                # Absolute dirname of the source subdirectory.
                src_subdirname = pathnames.join(src_dirname, conf_subdirname)

                # Recursively copy from the old into the new subdirectory.
                dirs.copy_dir_into_dir(
                    src_dirname=src_subdirname,
                    trg_dirname=trg_dirname,
                    overwrite_policy=conf_subdir_overwrite_policy,

                    # Ignore all empty ".gitignore" files in all subdirectories
                    # of this source subdirectory. These files serve only as
                    # placeholders instructing Git to track otherwise empty
                    # subdirectories. Preserving such files only invites end
                    # user confusion.
                    ignore_basename_globs=('.gitignore',),
                )

        # Associate this object with this file *AFTER* successfully copying to
        # this file and all external paths required by this file.
        self._set_conf_filename(conf_filename)
Beispiel #12
0
def get_package_project_dirname_or_none(package: ModuleType) -> StrOrNoneTypes:
    '''
    **Absolute canonical dirname** (i.e., absolute dirname after resolving
    symbolic links) of the **root project directory** (i.e., top-level
    directory containing an installable ``pyproject.toml`` file or ``setup.py``
    script) governing the passed top-level Python package if found *or* raise
    an exception otherwise (i.e., if this directory is *not* found).

    Equivalently, this is the same as both:

    * The root directory archived by release tarballs for this application.
    * The Git-based working tree for this application (i.e., the top-level
      directory containing this application's ``.git`` subdirectory).

    Specifically, this function returns non-``None`` only if the parent
    directory of the passed package's directory contains either:

    * A ``pyproject.toml`` file, implying this package to be satisfy `PEP 518`_
      and hence be installable by at least poetry_.
    * A ``setup.py`` script, implying this package to be installable by either
      the standard :mod:`distutils` API or third-party :mod:`setuptools` API.

    :: _PEP 518:
       https://snarky.ca/clarifying-pep-518/
    :: _poetry:
       https://github.com/sdispater/poetry

    Caveats
    ----------
    **This directory typically does not exist.** This directory is only
    required during installation by non-developers *or* during development
    by developers. Once this application has been installed in a standard
    (i.e., non-editable) fashion by non-developers, this directory is no
    longer required and hence should *not* be assumed to exist.

    Parameters
    ----------
    package : ModuleType
        Top-level Python package to be queried.

    Returns
    ----------
    StrOrNoneTypes
        Either:

        * If the parent directory of the passed package's directory contains
          either a ``pyproject.toml`` or ``setup.py`` script, the absolute
          canonical dirname of that parent directory.
        * Else, ``None``.
    '''

    # Avoid circular import dependencies.
    from betse.util.path import files, pathnames
    from betse.util.py.module import pymodule

    # Absolute canonical dirname of the directory providing this package,
    # canonicalized into a directory rather than symbolic link to increase the
    # likelihood of obtaining the actual parent directory of this package.
    package_dirname = pymodule.get_dirname_canonical(package)

    # Absolute dirname of the parent directory of this directory.
    package_project_dirname = pathnames.get_dirname(package_dirname)

    # Absolute filenames of the "pyproject.toml" and "setup.py" files possibly
    # provided by this parent directory.
    pyproject_filename = pathnames.join(package_project_dirname,
                                        'pyproject.toml')
    setup_filename = pathnames.join(package_project_dirname, 'setup.py')

    # Return this parent directory's absolute dirname if either of these
    # requisite installation-time files exist *OR* "None" otherwise.
    return (package_project_dirname if
            (files.is_file(pyproject_filename)
             or files.is_file(setup_filename)) else None)