SlideShare una empresa de Scribd logo
1 de 48
Descargar para leer sin conexión
If you do not know what __path__ is,

    this talk is   NOT for you.
                   Sorry.
import this,
                  that, and the
                   other thing
                     Custom importers in Python


                                   Brett Cannon
                                  www.DrBrett.ca
                                 brett@python.org


Slides are sparse, so do listen to what I say.
Thanks ...


• Python Software Foundation
 • PyCon Financial Aid committee
• Nasuni
 • Jesse Noller
What the heck is an
             importer?



Relevant since Python 2.3
importer
       =
finder + loader
A finder finds
   modules.
A loader loads
   modules.
“Why do I want one?”



Customization/control, easier to work w/ than __import__
How are custom
             importers used by
                  import?


Simplified view; ignoring implicit importers
Meta path
 sys.meta_path
Start




                          for finder in sys.meta_path:        ...


      False


                     loader = finder.find_module(name, path)




                                    True


                       return loader.load_module(name)


What ‘path’ arg is
Path
sys.path or __path__, sys.path_hooks,
      & sys.path_importer_cache
...   Parent module
      has __path__
                             False       search = sys.path

                                                                  search


                      True           search = parent's __path__
Search




              for entry in search:          raise ImportError




        finder = sys.path_importer_cache               path
                     [entry]
                                          False
                                                      hook



                                          finder
False
                     True




        loader = finder.find_module(name)




                     True


        return loader.load_module(name)
path
                       hook




                    for hook in
                                               sys.path_importer_cache[entry] = dummy
                 sys.path_hooks:

 False


                finder = hook(entry)



                       True


      sys.path_importer_cache[entry] = finder                   finder




True/False = ImportError (not) raised
how do I write
   my own
  importer?
 Only masochists need apply.
Option 1:
 Painfully from
     scratch
Read PEP 302 for the gory details.
Option 2:
Use importlib
     Available since Python 3.1.
I have suffered so you don’t have to.
Option 3:
                         importers
               http://packages.python.org/importers/

           File path abstraction on top of importlib.
              Treating as purgatory for importlib
                           inclusion.




If a lesson here, then it is to use option 2 or 3 depending on your needs.
Rest of talk is about lessons that led to ‘importers’.
Using a
                   zipfile importer
                    as an example



Assuming use of importlib.
Talking from perspective of using an archive.
we need a hook
   For sys.path_hooks.
Refresher:
              Hooks look for a
              finder for a path


Path either from sys.path or __path__
Hooks can get
                funky paths
            E.g. /path/to/file/code.zip/some/pkg




Search backwards looking for a file; find a directory then you have gone too far.
Consider caching
         archive file objects



No need to keep 3 connection objects open for the same sqlite3 file
Pass your finder
            the “location”:
          1)the path/object &
          2) the package path


Import assumes you are looking in a part of a package.
Raise ImportError
if you got nuthin’
Have finder, will
 look for code
Don’t treat modules
        as code but as files



Just trust me. Too many people/code make this assumption already for stuff like __file__,
__path__, etc.
You did remember
               where in the
              package you are
             looking, RIGHT?!?


Needed because of __path__ manipulation by user code.
fullname.rpartition(‘.’)[-1]
Need to care
        about packages &
            modules
                      some/pkg/name/__init__.py
                                 and
                          some/pkg/name.py




Care about bytecode if you want.
Notice how many stat calls this takes?
Avoid caching
within a finder
 Blame sys.path_importer_cache
Tell the loader
  if package &
  path to code
Don’t Repeat Yourself ... within reason.
Nuthin’?
Give back None
Now it gets
  tricky
  Writing a loader.
Are you still
thinking in terms of
    file paths?
importlib.abc.PyLoader


           • source_path()
              • Might be changing...
           • is_package()
           • get_data()



Everything in terms of exactly what it takes to import source
importlib.abc.PyPycLoader

           • source_path()
           • is_package()
           • get_data()
           • source_mtime()
           • bytecode_path()
              • Might be changing...


This is what is needed to get source w/ bytecode right
Reasons to ignore .pyc

• Jython, IronPython couldn’t care less.
 • Safe to support, though.
• Another thing to code up.
 • Bytecode is just an optimization.
 • If you only ship .pyc for code
   protection, stop it.
What to do when
     using
importlib ABCs
Require anchor
            point for paths
                 somewhere/mod.py is too ambiguous




Too hazy as to where a relative path is anchored; archive? Package location?
Consider caching
            stat calls
                Only for stand-alone loaders!
            Also consider caching if package or not.




Consider whether storage is read-only, append-only, or read-write.
Don’t overdo
error checking
   EAFP is your friend.
Perk of importers is
  the abstraction
Lazy loader mix-in
    written in
     19 lines
class Module(types.ModuleType):
    pass

class Mixin:
    def load_module(self, name):
        if name in sys.modules:
             return super().load_module(name)
        # Create a lazy module that will type check.
        module = LazyModule(name)
        # Set the loader on the module as ModuleType will not.
        module.__loader__ = self
        # Insert the module into sys.modules.
        sys.modules[name] = module
        return module

class LazyModule(types.ModuleType):
    def __getattribute__(self, attr):
        # Remove this __getattribute__ method by re-assigning.
        self.__class__ = Module
        # Fetch the real loader.
        self.__loader__ = super(Mixin, self.__loader__)
        # Actually load the module.
        self.__loader__.load_module(self.__name__)
        # Return the requested attribute.
        return getattr(self, attr)
... or you could use
the importers package
 http://packages.python.org/importers/
Fin

Más contenido relacionado

La actualidad más candente

PyCon 2013 : Scripting to PyPi to GitHub and More
PyCon 2013 : Scripting to PyPi to GitHub and MorePyCon 2013 : Scripting to PyPi to GitHub and More
PyCon 2013 : Scripting to PyPi to GitHub and More
Matt Harrison
 

La actualidad más candente (19)

Python made easy
Python made easy Python made easy
Python made easy
 
python.ppt
python.pptpython.ppt
python.ppt
 
An introduction to Python for absolute beginners
An introduction to Python for absolute beginnersAn introduction to Python for absolute beginners
An introduction to Python for absolute beginners
 
Let’s Learn Python An introduction to Python
Let’s Learn Python An introduction to Python Let’s Learn Python An introduction to Python
Let’s Learn Python An introduction to Python
 
PyCon 2013 : Scripting to PyPi to GitHub and More
PyCon 2013 : Scripting to PyPi to GitHub and MorePyCon 2013 : Scripting to PyPi to GitHub and More
PyCon 2013 : Scripting to PyPi to GitHub and More
 
Why Python (for Statisticians)
Why Python (for Statisticians)Why Python (for Statisticians)
Why Python (for Statisticians)
 
Learn Python The Hard Way Presentation
Learn Python The Hard Way PresentationLearn Python The Hard Way Presentation
Learn Python The Hard Way Presentation
 
Cross platform php
Cross platform phpCross platform php
Cross platform php
 
Ruby from zero to hero
Ruby from zero to heroRuby from zero to hero
Ruby from zero to hero
 
Python basics
Python basicsPython basics
Python basics
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in Python
 
OpenGurukul : Language : Python
OpenGurukul : Language : PythonOpenGurukul : Language : Python
OpenGurukul : Language : Python
 
PHP7. Game Changer.
PHP7. Game Changer. PHP7. Game Changer.
PHP7. Game Changer.
 
Gcrc talk
Gcrc talkGcrc talk
Gcrc talk
 
Simple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETL
Simple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETLSimple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETL
Simple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETL
 
Introduction to Python Pandas for Data Analytics
Introduction to Python Pandas for Data AnalyticsIntroduction to Python Pandas for Data Analytics
Introduction to Python Pandas for Data Analytics
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
Python interview questions for experience
Python interview questions for experiencePython interview questions for experience
Python interview questions for experience
 
Fundamentals of Python Programming
Fundamentals of Python ProgrammingFundamentals of Python Programming
Fundamentals of Python Programming
 

Similar a ImpoImport this, that, and the other thing: custom importersrt not for_y

Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for Dummies
Elizabeth Smith
 

Similar a ImpoImport this, that, and the other thing: custom importersrt not for_y (20)

Python import mechanism
Python import mechanismPython import mechanism
Python import mechanism
 
EuroPython 2017 - Bonono - Simple ETL in python 3.5+
EuroPython 2017 - Bonono - Simple ETL in python 3.5+EuroPython 2017 - Bonono - Simple ETL in python 3.5+
EuroPython 2017 - Bonono - Simple ETL in python 3.5+
 
Pythonpresent
PythonpresentPythonpresent
Pythonpresent
 
Writing and using php streams and sockets
Writing and using php streams and socketsWriting and using php streams and sockets
Writing and using php streams and sockets
 
Packer Genetics: The selfish code
Packer Genetics: The selfish codePacker Genetics: The selfish code
Packer Genetics: The selfish code
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for Dummies
 
Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.
Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.
Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.
 
Django at Scale
Django at ScaleDjango at Scale
Django at Scale
 
Simple ETL in python 3.5+ with Bonobo, Romain Dorgueil
Simple ETL in python 3.5+ with Bonobo, Romain DorgueilSimple ETL in python 3.5+ with Bonobo, Romain Dorgueil
Simple ETL in python 3.5+ with Bonobo, Romain Dorgueil
 
Simple ETL in python 3.5+ with Bonobo - PyParis 2017
Simple ETL in python 3.5+ with Bonobo - PyParis 2017Simple ETL in python 3.5+ with Bonobo - PyParis 2017
Simple ETL in python 3.5+ with Bonobo - PyParis 2017
 
Python Imports
Python ImportsPython Imports
Python Imports
 
Porting to Python 3
Porting to Python 3Porting to Python 3
Porting to Python 3
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
 
Python 3.5: An agile, general-purpose development language.
Python 3.5: An agile, general-purpose development language.Python 3.5: An agile, general-purpose development language.
Python 3.5: An agile, general-purpose development language.
 
Code with style
Code with styleCode with style
Code with style
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony Barcelona
 
Code with Style - PyOhio
Code with Style - PyOhioCode with Style - PyOhio
Code with Style - PyOhio
 
How to Design a Great API (using flask) [ploneconf2017]
How to Design a Great API (using flask) [ploneconf2017]How to Design a Great API (using flask) [ploneconf2017]
How to Design a Great API (using flask) [ploneconf2017]
 

Más de Zoom Quiet

111218 zhtechparty-panda讲稿
111218 zhtechparty-panda讲稿111218 zhtechparty-panda讲稿
111218 zhtechparty-panda讲稿
Zoom Quiet
 
111218 zhtechparty-移动互联网产品需求分析
111218 zhtechparty-移动互联网产品需求分析111218 zhtechparty-移动互联网产品需求分析
111218 zhtechparty-移动互联网产品需求分析
Zoom Quiet
 
111218 zhtechparty-zd-浅谈symbian开发
111218 zhtechparty-zd-浅谈symbian开发111218 zhtechparty-zd-浅谈symbian开发
111218 zhtechparty-zd-浅谈symbian开发
Zoom Quiet
 

Más de Zoom Quiet (20)

42qu thrift1
42qu thrift142qu thrift1
42qu thrift1
 
产品信息收集系统Infoc的演变
产品信息收集系统Infoc的演变产品信息收集系统Infoc的演变
产品信息收集系统Infoc的演变
 
Go courseday3
Go courseday3Go courseday3
Go courseday3
 
Go courseday2
Go courseday2Go courseday2
Go courseday2
 
Go courseday1
Go courseday1Go courseday1
Go courseday1
 
01s0401 go,互联网时代的c语言 许式伟
01s0401 go,互联网时代的c语言   许式伟01s0401 go,互联网时代的c语言   许式伟
01s0401 go,互联网时代的c语言 许式伟
 
Zoz pwned-by-the-owner-表惹程序猿
Zoz pwned-by-the-owner-表惹程序猿Zoz pwned-by-the-owner-表惹程序猿
Zoz pwned-by-the-owner-表惹程序猿
 
金山云查询系统改进之路1
金山云查询系统改进之路1金山云查询系统改进之路1
金山云查询系统改进之路1
 
Zh120226techparty zd-story
Zh120226techparty zd-storyZh120226techparty zd-story
Zh120226techparty zd-story
 
Zh120226techparty velocity2011-review
Zh120226techparty velocity2011-reviewZh120226techparty velocity2011-review
Zh120226techparty velocity2011-review
 
Zh120226techparty jeff kit-ios-toolbox
Zh120226techparty jeff kit-ios-toolboxZh120226techparty jeff kit-ios-toolbox
Zh120226techparty jeff kit-ios-toolbox
 
Velocity2011分享
Velocity2011分享Velocity2011分享
Velocity2011分享
 
陈正 Introduction to-sae_python
陈正   Introduction to-sae_python陈正   Introduction to-sae_python
陈正 Introduction to-sae_python
 
111218 zhtechparty-panda讲稿
111218 zhtechparty-panda讲稿111218 zhtechparty-panda讲稿
111218 zhtechparty-panda讲稿
 
111218 zhtechparty-移动互联网产品需求分析
111218 zhtechparty-移动互联网产品需求分析111218 zhtechparty-移动互联网产品需求分析
111218 zhtechparty-移动互联网产品需求分析
 
111218 zhtechparty-zd-浅谈symbian开发
111218 zhtechparty-zd-浅谈symbian开发111218 zhtechparty-zd-浅谈symbian开发
111218 zhtechparty-zd-浅谈symbian开发
 
Import this, that, and the other thing: custom importers
Import this, that, and the other thing: custom importersImport this, that, and the other thing: custom importers
Import this, that, and the other thing: custom importers
 
金山卫士界面框架
金山卫士界面框架金山卫士界面框架
金山卫士界面框架
 
111030 gztechparty-小路-云时代的mysql
111030 gztechparty-小路-云时代的mysql111030 gztechparty-小路-云时代的mysql
111030 gztechparty-小路-云时代的mysql
 
111030 gztechparty-小路-sophia
111030 gztechparty-小路-sophia111030 gztechparty-小路-sophia
111030 gztechparty-小路-sophia
 

Último

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Último (20)

08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 

ImpoImport this, that, and the other thing: custom importersrt not for_y

  • 1. If you do not know what __path__ is, this talk is NOT for you. Sorry.
  • 2. import this, that, and the other thing Custom importers in Python Brett Cannon www.DrBrett.ca brett@python.org Slides are sparse, so do listen to what I say.
  • 3. Thanks ... • Python Software Foundation • PyCon Financial Aid committee • Nasuni • Jesse Noller
  • 4. What the heck is an importer? Relevant since Python 2.3
  • 5. importer = finder + loader
  • 6. A finder finds modules.
  • 7. A loader loads modules.
  • 8. “Why do I want one?” Customization/control, easier to work w/ than __import__
  • 9. How are custom importers used by import? Simplified view; ignoring implicit importers
  • 11. Start for finder in sys.meta_path: ... False loader = finder.find_module(name, path) True return loader.load_module(name) What ‘path’ arg is
  • 12. Path sys.path or __path__, sys.path_hooks, & sys.path_importer_cache
  • 13. ... Parent module has __path__ False search = sys.path search True search = parent's __path__
  • 14. Search for entry in search: raise ImportError finder = sys.path_importer_cache path [entry] False hook finder False True loader = finder.find_module(name) True return loader.load_module(name)
  • 15. path hook for hook in sys.path_importer_cache[entry] = dummy sys.path_hooks: False finder = hook(entry) True sys.path_importer_cache[entry] = finder finder True/False = ImportError (not) raised
  • 16. how do I write my own importer? Only masochists need apply.
  • 17. Option 1: Painfully from scratch Read PEP 302 for the gory details.
  • 18. Option 2: Use importlib Available since Python 3.1. I have suffered so you don’t have to.
  • 19. Option 3: importers http://packages.python.org/importers/ File path abstraction on top of importlib. Treating as purgatory for importlib inclusion. If a lesson here, then it is to use option 2 or 3 depending on your needs. Rest of talk is about lessons that led to ‘importers’.
  • 20. Using a zipfile importer as an example Assuming use of importlib. Talking from perspective of using an archive.
  • 21. we need a hook For sys.path_hooks.
  • 22. Refresher: Hooks look for a finder for a path Path either from sys.path or __path__
  • 23. Hooks can get funky paths E.g. /path/to/file/code.zip/some/pkg Search backwards looking for a file; find a directory then you have gone too far.
  • 24. Consider caching archive file objects No need to keep 3 connection objects open for the same sqlite3 file
  • 25. Pass your finder the “location”: 1)the path/object & 2) the package path Import assumes you are looking in a part of a package.
  • 26. Raise ImportError if you got nuthin’
  • 27. Have finder, will look for code
  • 28. Don’t treat modules as code but as files Just trust me. Too many people/code make this assumption already for stuff like __file__, __path__, etc.
  • 29. You did remember where in the package you are looking, RIGHT?!? Needed because of __path__ manipulation by user code.
  • 31. Need to care about packages & modules some/pkg/name/__init__.py and some/pkg/name.py Care about bytecode if you want. Notice how many stat calls this takes?
  • 32. Avoid caching within a finder Blame sys.path_importer_cache
  • 33. Tell the loader if package & path to code Don’t Repeat Yourself ... within reason.
  • 35. Now it gets tricky Writing a loader.
  • 36. Are you still thinking in terms of file paths?
  • 37. importlib.abc.PyLoader • source_path() • Might be changing... • is_package() • get_data() Everything in terms of exactly what it takes to import source
  • 38. importlib.abc.PyPycLoader • source_path() • is_package() • get_data() • source_mtime() • bytecode_path() • Might be changing... This is what is needed to get source w/ bytecode right
  • 39. Reasons to ignore .pyc • Jython, IronPython couldn’t care less. • Safe to support, though. • Another thing to code up. • Bytecode is just an optimization. • If you only ship .pyc for code protection, stop it.
  • 40. What to do when using importlib ABCs
  • 41. Require anchor point for paths somewhere/mod.py is too ambiguous Too hazy as to where a relative path is anchored; archive? Package location?
  • 42. Consider caching stat calls Only for stand-alone loaders! Also consider caching if package or not. Consider whether storage is read-only, append-only, or read-write.
  • 43. Don’t overdo error checking EAFP is your friend.
  • 44. Perk of importers is the abstraction
  • 45. Lazy loader mix-in written in 19 lines
  • 46. class Module(types.ModuleType): pass class Mixin: def load_module(self, name): if name in sys.modules: return super().load_module(name) # Create a lazy module that will type check. module = LazyModule(name) # Set the loader on the module as ModuleType will not. module.__loader__ = self # Insert the module into sys.modules. sys.modules[name] = module return module class LazyModule(types.ModuleType): def __getattribute__(self, attr): # Remove this __getattribute__ method by re-assigning. self.__class__ = Module # Fetch the real loader. self.__loader__ = super(Mixin, self.__loader__) # Actually load the module. self.__loader__.load_module(self.__name__) # Return the requested attribute. return getattr(self, attr)
  • 47. ... or you could use the importers package http://packages.python.org/importers/
  • 48. Fin