File: pythonfilepath.cpp

package info (click to toggle)
wsclean 3.6-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 16,296 kB
  • sloc: cpp: 129,246; python: 22,066; sh: 360; ansic: 230; makefile: 185
file content (85 lines) | stat: -rw-r--r-- 2,847 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "pythonfilepath.h"

#include <aocommon/logger.h>

#include <boost/filesystem.hpp>

#include <cstdlib>
#include <fstream>
#include <sstream>
#include <random>

namespace wsclean::system {

std::string FindPythonFilePath(const std::string& filename) {
  if (boost::filesystem::exists(filename)) return filename;
  aocommon::Logger::Debug << "Searching " << filename << "... ";
  aocommon::Logger::Debug.Flush();
  std::random_device rndDev;
  std::mt19937 gen(rndDev());
  std::stringstream filenameStr;
  filenameStr << "/tmp/ao-python-path-list" << gen() << ".tmp";
  boost::filesystem::path tempPath =
      filenameStr.str();  // boost::filesystem::unique_path();
  const std::string tempFilename = tempPath.string();  // optional
  std::string command =
      std::string(
          "echo \"from __future__ import print_function\nimport sys\nfor a in "
          "sys.path:\n  print(a)\"|python>") +
      tempFilename;
  int status = std::system(command.c_str());
  if (status != 0) {
    // retry with python3
    command = std::string(
                  "echo \"from __future__ import print_function\nimport "
                  "sys\nfor a in "
                  "sys.path:\n  print(a)\"|python3>") +
              tempFilename;
    status = std::system(command.c_str());
  }
  if (status != 0)
    throw std::runtime_error(
        "std::system() returned non-zero error code: might be out of memory, "
        "or "
        "python might not be working properly.\nCommand was:\n" +
        command);
  std::ifstream searchPathsFile(tempFilename.c_str());
  if (!searchPathsFile.good())
    throw std::runtime_error(("Error in findPythonFilePath: system call did "
                              "not create expected temporary file " +
                              tempFilename)
                                 .c_str());
  while (searchPathsFile.good()) {
    std::string prefixPath;
    std::getline(searchPathsFile, prefixPath);
    boost::filesystem::path searchPath(prefixPath);
    searchPath /= filename;

    bool pathExists = false;
    try {
      pathExists = boost::filesystem::exists(searchPath);
    } catch (...) {
    }
    if (pathExists) {
      const std::string result = searchPath.string();
      aocommon::Logger::Debug << result << '\n';
      searchPathsFile.close();
      boost::filesystem::remove(tempPath);
      return result;
    }
  }
  searchPathsFile.clear();
  searchPathsFile.seekg(0, std::ios::beg);
  std::string err(std::string("Could not find Python file ") + filename +
                  ". Paths searched:\n");
  while (searchPathsFile.good()) {
    std::string prefixPath;
    std::getline(searchPathsFile, prefixPath);
    err += prefixPath + '\n';
  }
  searchPathsFile.close();
  boost::filesystem::remove(tempPath);
  throw std::runtime_error(err);
}

}  // namespace wsclean::system