Skip to content

Commit

Permalink
Standalone: Better early frozen modules "__file__" values.
Browse files Browse the repository at this point in the history
* Do not set "__file__" if not set. Some modules, e.g. "sys" just don't
  have it, due to being built-in.

* For those that have it, adapt the bytecode contained path to one that
  points to inside the distribution folder. Otherwise it is pointing to
  the original installation.
  • Loading branch information
kayhayen committed Oct 22, 2017
1 parent 23b75e6 commit e5daa97
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 46 deletions.
5 changes: 0 additions & 5 deletions lib/hints.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ def _moduleRepr(module):
)

file_desc = "file " + _normalizePath(module_file).replace(".pyc", ".py")


if file_desc.endswith("not_present.py"):
raise AttributeError

except AttributeError:
file_desc = "built-in"

Expand Down
40 changes: 0 additions & 40 deletions nuitka/build/static_src/CompiledCodeHelpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -2530,46 +2530,6 @@ void _initBuiltinModule()

#include "HelpersCalling.c"

#if defined(_NUITKA_STANDALONE) || _NUITKA_FROZEN > 0

#ifdef _NUITKA_STANDALONE
extern PyObject *const_str_plain___file__;

// This is called for each module imported early on.
void setEarlyFrozenModulesFileAttribute( void )
{
Py_ssize_t ppos = 0;
PyObject *key, *value;

#if PYTHON_VERSION < 300
PyObject *file_value = MAKE_RELATIVE_PATH( PyString_FromString( "not_present.py" ) );
#else
PyObject *file_value = MAKE_RELATIVE_PATH( PyUnicode_FromString( "not_present.py" ) );
#endif

assert( file_value );

while( PyDict_Next( PyImport_GetModuleDict(), &ppos, &key, &value ) )
{
if ( key != NULL && value != NULL && PyModule_Check( value ) )
{
if ( !PyObject_HasAttr( value, const_str_plain___file__ ) )
{
PyObject_SetAttr( value, const_str_plain___file__, file_value );
}
}
}

Py_DECREF( file_value );

assert( !ERROR_OCCURRED() );
}
#endif


#endif


PyObject *MAKE_RELATIVE_PATH( PyObject *relative )
{
static PyObject *our_path_object = NULL;
Expand Down
66 changes: 65 additions & 1 deletion nuitka/build/static_src/MetaPathBasedLoader.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,36 @@ static void patchCodeObjectPaths( PyCodeObject *code_object, PyObject *module_pa
}
#endif

NUITKA_MAY_BE_UNUSED static PyObject *MAKE_RELATIVE_PATH_FROM_NAME( char const *name, bool is_package )
{
char buffer[ MAXPATHLEN+1 ];

copyModulenameAsPath( buffer, name );

if ( is_package )
{
char const sep_str[2] = { SEP, 0 };
strncat( buffer, sep_str, sizeof(buffer)-1 );
strncat( buffer, "__init__.py", sizeof(buffer)-1 );
}
else
{
strncat( buffer, ".py", sizeof(buffer)-1 );
}

#if PYTHON_VERSION < 300
PyObject *module_path_entry_base = PyString_FromString( buffer );
#else
PyObject *module_path_entry_base = PyUnicode_FromString( buffer );
#endif

PyObject *result = MAKE_RELATIVE_PATH( module_path_entry_base );

Py_DECREF( module_path_entry_base );

return result;
}

static PyObject *loadModuleFromCodeObject( PyCodeObject *code_object, char const *name, bool is_package )
{
assert( code_object != NULL );
Expand Down Expand Up @@ -159,7 +189,7 @@ static PyObject *loadModuleFromCodeObject( PyCodeObject *code_object, char const
module_path_entry = MAKE_RELATIVE_PATH( module_path_entry_base );
Py_DECREF( module_path_entry_base );

char sep_str[2] = { SEP, 0 };
char const sep_str[2] = { SEP, 0 };
strncat( buffer, sep_str, sizeof(buffer)-1 );
strncat( buffer, "__init__.py", sizeof(buffer)-1 );
}
Expand Down Expand Up @@ -1083,3 +1113,37 @@ void registerMetaPathBasedUnfreezer( struct Nuitka_MetaPathBasedLoaderEntry *_lo
);
assert( res == 0 );
}


#if defined(_NUITKA_STANDALONE) || _NUITKA_FROZEN > 0

extern PyObject *const_str_plain___file__;

// This is called for each module imported early on.
void setEarlyFrozenModulesFileAttribute( void )
{
Py_ssize_t ppos = 0;
PyObject *key, *value;

while( PyDict_Next( PyImport_GetModuleDict(), &ppos, &key, &value ) )
{
if ( key != NULL && value != NULL && PyModule_Check( value ) )
{
if ( PyObject_HasAttr( value, const_str_plain___file__ ) )
{
bool is_package = PyObject_HasAttr( value, const_str_plain___path__ ) == 1;

PyObject *file_value = MAKE_RELATIVE_PATH_FROM_NAME(
Nuitka_String_AsString( key ),
is_package
);
PyObject_SetAttr( value, const_str_plain___file__, file_value );
Py_DECREF( file_value );
}
}
}

assert( !ERROR_OCCURRED() );
}

#endif

0 comments on commit e5daa97

Please sign in to comment.