Method: PyCall::Import#pyfrom
- Defined in:
- lib/pycall/import.rb
#pyfrom(mod_name, import: nil) ⇒ Object
This function is implemented as a mimic of import_from function defined in Python/ceval.c.
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 |
# File 'lib/pycall/import.rb', line 23 def pyfrom(mod_name, import: nil) raise ArgumentError, "missing identifier(s) to be imported" unless import mod_name = mod_name.to_str if mod_name.respond_to? :to_str mod_name = mod_name.to_s if mod_name.is_a? Symbol import = Array(import) fromlist = import.map.with_index do |import_name, i| case import_name when assoc_array_matcher import_name[0] when Symbol, String import_name else raise ArgumentError, "wrong type of import name #{import_name.class} (expected String or Symbol)" end end from_list = PyCall.tuple(from_list) main_dict_ptr = PyCall.import_module('__main__').__dict__.__pyptr__ globals = main_dict_ptr # FIXME: this should mimic to `import_name` function defined in `Python/ceval.c`. locals = main_dict_ptr # FIXME: this should mimic to `import_name` function defined in `Python/ceval.c`. level = 0 # TODO: support prefixed dots (#25) mod = LibPython::Helpers.import_module(mod_name, globals, locals, fromlist, level) import.each do |import_name| case import_name when assoc_array_matcher name, asname = *import_name when Symbol, String name, asname = import_name, import_name end if PyCall::LibPython::Helpers.hasattr?(mod.__pyptr__, name) pyobj = PyCall::LibPython::Helpers.getattr(mod.__pyptr__, name) define_name(asname, pyobj) next end if mod.respond_to? :__name__ pkgname = mod.__name__ fullname = "#{pkgname}.#{name}" sys_modules = PyCall.import_module('sys').modules if sys_modules.has_key?(fullname) pyobj = module_dict[fullname] define_name(asname, pyobj) next end end raise ArgumentError, "cannot import name #{fullname}" unless pyobj end end |