gitlab.com/thomasboni/go-enry/v2@v2.8.3-0.20220418031202-30b0d7a3de98/python/enry.py (about)

     1  """
     2  Python library calling enry Go implementation trough cFFI (API, out-of-line) and Cgo.
     3  """
     4  
     5  from _c_enry import ffi, lib
     6  
     7  ## cgo -> ffi helpers
     8  def py_bytes_to_go(py_bytes: bytes):
     9      c_bytes = ffi.new("char[]", len(py_bytes))
    10      go_slice = ffi.new("GoSlice *", [c_bytes, len(py_bytes), len(py_bytes)])
    11      return (go_slice[0], c_bytes)
    12  
    13  def py_str_to_go(py_str: str):
    14      str_bytes = py_str.encode()
    15      c_str = ffi.new("char[]", str_bytes)
    16      go_str = ffi.new("_GoString_ *", [c_str, len(str_bytes)])
    17      return (go_str[0], c_str)
    18  
    19  def go_str_to_py(go_str: str):
    20      str_len = go_str.n
    21      if str_len > 0:
    22          return ffi.unpack(go_str.p, go_str.n).decode()
    23      return ""
    24  
    25  def go_bool_to_py(go_bool: bool):
    26      return go_bool == 1
    27  
    28  
    29  ## API, TODO(bzz): add docstrings
    30  def language(filename: str, content: bytes) -> str:
    31      fName, c_str = py_str_to_go(filename)
    32      fContent, c_bytes = py_bytes_to_go(content)
    33      guess = lib.GetLanguage(fName, fContent)
    34      lang = go_str_to_py(guess)
    35      return lang
    36  
    37  def language_by_extension(filename: str) -> str:
    38      fName, c_str = py_str_to_go(filename)
    39      guess = lib.GetLanguageByExtension(fName)
    40      lang = go_str_to_py(guess.r0)
    41      return lang
    42  
    43  def language_by_filename(filename: str) -> str:
    44      fName, c_str = py_str_to_go(filename)
    45      guess = lib.GetLanguageByFilename(fName)
    46      lang = go_str_to_py(guess.r0)
    47      return lang
    48  
    49  def is_vendor(filename: str) -> bool:
    50      fName, c_str = py_str_to_go(filename)
    51      guess = lib.IsVendor(fName)
    52      return go_bool_to_py(guess)
    53  
    54  def is_generated(filename: str, content: bytes) -> bool:
    55      fname, c_str = py_str_to_go(filename)
    56      fcontent, c_bytes = py_bytes_to_go(content)
    57      guess = lib.IsGenerated(fname, fcontent)
    58      return go_bool_to_py(guess)
    59  
    60  
    61  ## Tests
    62  from collections import namedtuple
    63  
    64  def main():
    65      TestFile = namedtuple("TestFile", "name, content, lang")
    66      files = [
    67          TestFile("Parse.hs", b"", "Haskell"), TestFile("some.cpp", b"", "C++"), 
    68          TestFile("orand.go", b"", "Go"), TestFile("type.h", b"", "C"), 
    69          TestFile(".bashrc", b"", "Shell"), TestFile(".gitignore", b"", "Ignore List")
    70      ]
    71  
    72      print("\nstrategy: extension")
    73      for f in files:
    74          lang = language_by_extension(f.name)
    75          print("\tfile: {:10s} language: '{}'".format(f.name, lang))
    76  
    77      print("\nstrategy: filename")
    78      for f in files:
    79          lang = language_by_filename(f.name)
    80          print("\tfile: {:10s} language: '{}'".format(f.name, lang))
    81  
    82      print("\ncheck: is vendor?")
    83      for f in files:
    84          vendor = is_vendor(f.name)
    85          print("\tfile: {:10s} vendor: '{}'".format(f.name, vendor))
    86  
    87      print("\nstrategy: all")
    88      for f in files:
    89          lang = language(f.name, f.content)
    90          print("\tfile: {:10s} language: '{}'".format(f.name, lang))
    91          assert lang == f.lang, "Expected '{}' but got '{}'".format(f.lang, lang)
    92  
    93  if __name__ == "__main__":
    94      main()