a  ze@sdZddlZddlZddlmZGdddZGdddZGd d d eZejeej d \Z Z Gd d d eZ eje ej d \Z ZGdddZGdddeejZGdddeejZedkredS)aPEP 366 ("Main module explicit relative imports") specifies the semantics for the __package__ attribute on modules. This attribute is used, when available, to detect which package a module belongs to (instead of using the typical __path__/__name__ test). N)utilc@sXeZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ dS)Using__package__a Use of __package__ supersedes the use of __name__/__path__ to calculate what package a module belongs to. The basic algorithm is [__package__]:: def resolve_name(name, package, level): level -= 1 base = package.rsplit('.', level)[0] return '{0}.{1}'.format(base, name) But since there is no guarantee that __package__ has been set (or not been set to None [None]), there has to be a way to calculate the attribute's value [__name__]:: def calc_package(caller_name, has___path__): if has__path__: return caller_name else: return caller_name.rsplit('.', 1)[0] Then the normal algorithm for relative name imports can proceed as if __package__ had been set. c Cs||dd\}tj|gd.|d|jd|dgdd}Wdn1sP0YWdn1sn0Y|S)N pkg.__init__pkg.fake meta_pathattrr)globalsfromlistlevel) mock_modulesr import_state __import__)selfglobals_Zimportermoduler`/opt/bitninja-python-dojo/embedded/lib/python3.9/test/test_importlib/import_/test___package__.py import_module%s BzUsing__package__.import_modulecCs |ddi}||jddS)N __package__rpkg)r assertEqual__name__rrrrrtest_using___package__.sz'Using__package__.test_using___package__cCsTt*td|dgd}Wdn1s80Y||jddS)Nignorerr__path__rwarningscatch_warnings simplefilterrrrrrrrtest_using___name__3s   &z$Using__package__.test_using___name__cCs>|t |dgdWdn1s00YdS)Nrr) assertWarns ImportWarningrrrrrtest_warn_when_using___name__;s z.Using__package__.test_warn_when_using___name__cCsVt,td|dgdd}Wdn1s:0Y||jddS)Nrr)rrrrr rrrrtest_None_as___package__?s   &z)Using__package__.test_None_as___package__cCs$|dtdi}||jddS)N__spec__rr)rFakeSpecrrrrrrtest_spec_fallbackGsz#Using__package__.test_spec_fallbackcCsB|t$|dtddWdn1s40YdS)Nrz pkg.fakefake)rr*)r%r&rr+r'rrr(test_warn_when_package_and_spec_disagreeLs z9Using__package__.test_warn_when_package_and_spec_disagreecCsJddi}|t$|d|idgdWdn1s<0YdS)Nrz r relimport) assertRaisesModuleNotFoundErrorrrr rrrtest_bad__package__Rs z$Using__package__.test_bad__package__cCsJddi}|t$|d|idgdWdn1s<0YdS)Nr*r r.r/)r0 TypeErrorrr2rrrtest_bunk__package__Ws z%Using__package__.test_bunk__package__N) r __module__ __qualname____doc__rrr$r(r)r,r-r3r6rrrrr s rc@seZdZddZdS)r+cCs ||_dS)N)parent)rr:rrr__init__^szFakeSpec.__init__N)rr7r8r;rrrrr+]sr+c@seZdZejZdS)Using__package__PEP302Nrr7r8rrrrrrr<bsr<)rc@seZdZejZdS)Using__package__PEP451Nrr7r8rZ mock_specrrrrrr>ksr>c@s2eZdZdZejdZddZddZddZd S) Setting__package__atBecause __package__ is a new feature, it is not always set by a loader. Import will set it as needed to help with the transition to relying on __package__. For a top-level module, __package__ is set to None [top-level]. For a package __name__ is used for __package__ [package]. For submodules the value is __name__.rsplit('.', 1)[0] [submodule]. ZSourcec Cs||d^}tj|gd0|d`|d}||jdWdn1sP0YWdn1sn0YdS)NZ top_levelrr rrrrrrrmockrrrrtest_top_levels   z!Setting__package__.test_top_levelc Cs||d^}tj|gd0|d`|d}||jdWdn1sP0YWdn1sn0YdS)NrrrrArBrrr test_packages   zSetting__package__.test_packagec Cs|ddh}tj|gd:|d`|d}t|d}||jdWdn1s\0YWdn1sz0YdS)Nrzpkg.modrmodr)rrrrrgetattrr)rrCrrrrrtest_submodules   z!Setting__package__.test_submoduleN) rr7r8r9rrrDrErHrrrrr@ts  r@c@seZdZejZdS)Setting__package__PEP302Nr=rrrrrIsrIc@seZdZejZdS)Setting__package__PEP451Nr?rrrrrJsrJ__main__)r9Zunittestr!r rrr+r<Z test_bothrZFrozen_UsingPackagePEP302ZSource_UsingPackagePEP302r>ZFrozen_UsingPackagePEP451ZSource_UsingPackagePEP451r@ZTestCaserIrJrmainrrrrs$ Q'