SlideShare a Scribd company logo
1 of 48
Download to read offline
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

More Related Content

What's hot

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
 

What's hot (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 to 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 to 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 - 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
 
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
 
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]
 

More from 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
 

More from 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
 

Recently uploaded

Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
UXDXConf
 

Recently uploaded (20)

FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 
The UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, OcadoThe UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, Ocado
 
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfHow Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024
 
Intro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераIntro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджера
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
PLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. StartupsPLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. Startups
 
THE BEST IPTV in GERMANY for 2024: IPTVreel
THE BEST IPTV in  GERMANY for 2024: IPTVreelTHE BEST IPTV in  GERMANY for 2024: IPTVreel
THE BEST IPTV in GERMANY for 2024: IPTVreel
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
 
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
 
Syngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdfSyngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdf
 

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