saved sys.path

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bengt dePaulis

    #1

    saved sys.path

    I have a local directory that I want to include in my sys.path

    How to save it permanently?

    Regards
    /Bengt


  • Alex Martelli

    #2
    Re: saved sys.path

    Bengt dePaulis <bdp003@hotmail .com> wrote:
    [color=blue]
    > I have a local directory that I want to include in my sys.path
    >
    > How to save it permanently?[/color]

    Add to the site-packages directory of your Python instalation a textfile
    named for example bengt.pth (name doesn't matter, extension does, and
    must be lowercase) with the line of text:

    /path/to/the/directory/you/mant


    Alex

    Comment

    • Eric S. Johansson

      #3
      Re: saved sys.path

      Alex Martelli wrote:[color=blue]
      > Bengt dePaulis <bdp003@hotmail .com> wrote:
      >
      >[color=green]
      >>I have a local directory that I want to include in my sys.path
      >>
      >>How to save it permanently?[/color]
      >
      >
      > Add to the site-packages directory of your Python instalation a textfile
      > named for example bengt.pth (name doesn't matter, extension does, and
      > must be lowercase) with the line of text:
      >
      > /path/to/the/directory/you/mant[/color]

      one of the things I've been bothered with using Python for larger
      applications is path manipulation. For example, how does one create the
      search path necessary to find your own modules if you do not wish
      pollute site-packages with your private code.

      the path file looks like this might be a good solution in preference to
      modifying sys.path in your code. Are there any scope or limitation
      rules for this path modifier? Can this modification be made specific to
      an application or is the new path visible to the entire world (which
      reintroduces the namespace pollution problem).

      ---eric

      Comment

      • Alex Martelli

        #4
        Re: saved sys.path

        Eric S. Johansson <esj@harvee.org > wrote:
        ...[color=blue]
        > one of the things I've been bothered with using Python for larger
        > applications is path manipulation. For example, how does one create the
        > search path necessary to find your own modules if you do not wish
        > pollute site-packages with your private code.
        >
        > the path file looks like this might be a good solution in preference to
        > modifying sys.path in your code. Are there any scope or limitation
        > rules for this path modifier? Can this modification be made specific to
        > an application or is the new path visible to the entire world (which
        > reintroduces the namespace pollution problem).[/color]

        The modifications to sys.path performed by .pth files are visible to all
        applications. A single application may (however it chooses to do so)
        find out or determine a path it wants only for its own imports, and
        prepend it to sys.path, during its startup (entry-point script). On
        Windows the popular choice is to stick stuff in the registry; on most
        Unix-like systems "run-command files" are usually preferred. The Mac
        (Mac OS X) has an extra possibility, since "an application" is a
        directory (with extension .app) and the Mac has its own conventions
        about what is where inside that directory. Python is not particularly
        different, from the point of view of "where does an app find its own
        configuration information", from most other languages.


        Alex

        Comment

        • Eric S. Johansson

          #5
          Re: saved sys.path

          Alex Martelli wrote:[color=blue]
          > The modifications to sys.path performed by .pth files are visible to all
          > applications. A single application may (however it chooses to do so)
          > find out or determine a path it wants only for its own imports, and[/color]
          ....historical record deleted[color=blue]
          > Python is not particularly
          > different, from the point of view of "where does an app find its own
          > configuration information", from most other languages.[/color]

          from historical perspective, I understand and appreciate your
          explanation. However, just because it's historically accurate, does it
          mean we should keep doing things the same old way?

          In natlink, Joel Gould's python extensions to NaturallySpeaki ng, he made
          each speech recognition grammar environment either globally accessible
          or command specific. He used the expedient technique of using the same
          name as the command for the Python file containing the grammar
          associated with that command. He also used another simple technique,
          prefacing a filename with an "_" to indicate a globally visible grammar
          and code. Turns out this was a frightfully useful technique as it
          allows for partitioning grammars. Unfortunately, because of path
          problems it's difficult to share modules between various grammars.

          It seems to me that a similar technique would serve for our purposes. A
          file, command_name.pa th, would contain all of the search as necessary
          for a command called by the same name. this technique would allow for a
          common platform independent method of finding application-specific
          modules and automatically generated paths for site-specific
          relocation/configuration.

          As I write this, it occurs to me that a provisional body of code to
          experiment with the technique would possibly serve the community well.
          I will generate something tomorrow for public scrutiny as I am up past
          my bedtime. Thank you for triggering the idea.

          Comment

          • Alex Martelli

            #6
            Re: saved sys.path

            Eric S. Johansson <esj@harvee.org > wrote:
            ...[color=blue]
            > file, command_name.pa th, would contain all of the search as necessary
            > for a command called by the same name. this technique would allow for a
            > common platform independent method of finding application-specific
            > modules and automatically generated paths for site-specific
            > relocation/configuration.
            >
            > As I write this, it occurs to me that a provisional body of code to
            > experiment with the technique would possibly serve the community well.
            > I will generate something tomorrow for public scrutiny as I am up past
            > my bedtime. Thank you for triggering the idea.[/color]

            You're welcome. Implementation should be easy, if you think that
            architecture is sound. Consider site.py, specifically the end of
            function addsitedir(site dir), which currently goes:

            names.sort()
            for name in names:
            if name[-4:] == os.extsep + "pth":
            addpackage(site dir, name)
            if reset:
            _dirs_in_sys_pa th = None

            It seems to me that all you need would be to make it:

            names.sort()
            for name in names:
            if name[-4:] == os.extsep + "pth" or name == specname:
            addpackage(site dir, name)
            if reset:
            _dirs_in_sys_pa th = None

            where specname is the application-specific path-filename you envisage.
            At module-global level, where now you have:

            prefixes = [sys.prefix]
            sitedir = None # make sure sitedir is initialized because of later 'del'

            your would add one further line going, for example:

            specname = '%s.appath' % os.path.basenam e(sys.argv[0])


            I would suggest .appath or something that stands out more than .path
            which looks too much like .pth -- just IMHO.

            Moreover, I think addpackage should take an optional flag:

            def addpackage(site dir, name, athead=False):

            and use it when it adds to the path: instead of

            if not dircase in _dirs_in_sys_pa th and os.path.exists( dir):
            sys.path.append (dir)

            it might go something like:

            if not dircase in _dirs_in_sys_pa th and os.path.exists( dir):
            if athead:
            sys.path.insert (0, dir)
            else:
            sys.path.append (dir)

            Then, the call to addpackage from functon addsite should become:

            if name[-4:] == os.extsep + "pth" or name == specname:
            addpackage(site dir, name, name == specname)

            All this is untested, but we're talking about a few lines worth of patch
            to site.py, nothing huge.


            As to whether the whole architecture is sound -- I pass. I'm not sure I
            see why it makes sense to have a foo.appath (or foo.path as you'd want
            it) that presumably gets autoedited during install to contain the
            relevant dirs, rather than just autoedit foo.py, the main script, whose
            purpose should, after all, be exactly to set up the environment
            (sys.path first and foremost) before importing and running the real
            stuff. The current bar.pth arrangement makes sense exactly because it's
            _not_ tied to apps, but to sites -- where has this site chosen to
            install some backage 'bar' which must be made available for import to
            all scripts running at this site. An application, as opposed to a
            package, gets to run its own code ("main script") and thus would seem
            not to need such arrangements.


            Alex

            Comment

            • Eric S. Johansson

              #7
              Re: saved sys.path

              Alex Martelli wrote:
              ....bunch of good stuff

              here's my working model. It's barely tested and I'll experiment with it
              in some code of the next couple of days.

              its usage is relatively simple. Stick this bit of code in
              site-packages. I call it application_pat h.py because it's easy to
              dictate. Then in a piece of code such as xyzzy.py, you start it was
              something like:

              #!/usr/bin/python

              import application_pat h
              application_pat h.set_path()
              import sys
              print sys.path

              and create xyzzy.pathlist in site-packages. Fill it with a list of
              directories that exist. If directories don't exist, they will not be
              added to the search path. And run the executable. The print statement
              will show you modified path. In this example, the default is to prepend
              paths because in my world, I want my changes to be found first just in
              case there is a naming conflict or I am overriding a system module.

              the first argument to set_path is the name. specifying the name is
              useful obviously because you may have multiple executables that use the
              same module set and this allows the application set to use a single path
              file. The second is at_head which if true (default) places the paths at
              the beginning of sys.path. If false, obviously they are appended to the
              end.

              as for the code style, it's mostly influenced by what is easy to do
              using speech recognition and Emacs. There have been a couple of
              projects to try and make programming by voice easier but they have run
              out of steam or run over by complexity. Maybe both.


              #!/usr/bin/python

              #application_pa th is a module an application can use to add
              #application-specific paths to an application's awareness

              import sys
              import os.path
              import re

              def set_path(name = None, at_head = True):
              """expand the site path from the file matching the given name or
              the executable name. Always append to the head of the search path
              unless at_head == False"""

              working_name = name
              if name == None:
              # strip off suffix and/or leading path
              working_name = sys.argv[0]

              # print "proto working name %s"% working_name
              dot_index = working_name.rf ind(".")
              if dot_index != -1:
              working_name = working_name[0:dot_index]
              working_name = os.path.basenam e(working_name)

              # convert name to path list
              path_list = get_paths(worki ng_name)

              if at_head:
              path_list.exten d(sys.path)
              sys.path=path_l ist

              else:
              sys.path.extend (path_list)

              print sys.path
              return working_name


              def get_paths (name):
              """based on a given name (which should be fully cleaned up to be
              just a name and not a path with extension) get a path file and """
              file_path = "".join([sys.prefix,
              "/lib/python",
              sys.version[:3],
              "/site-packages/",
              name,
              ".pathlist" ,
              ]
              )
              try:
              #print "file_path %s" % file_path
              handle = open(file_path, 'r')

              path_list = []
              for line in handle.readline s():
              line = line.strip()

              #ignore comments and blank lines
              ignore = re.search(r'^#| ^\s+$', line)
              if ignore : continue

              # does path exist?
              if os.path.isdir(l ine):

              # build a list of paths
              path_list.appen d(line.strip())

              handle.close()

              return path_list

              except IOError:
              #print "exception: file_path %s" % file_path
              return []


              if __name__ == '__main__':

              set_path()
              print
              print

              set_path("testi ng")

              print
              print

              set_path("testi ng", False)


              Comment

              • Eric S. Johansson

                #8
                Re: saved sys.path

                Peter Hansen wrote:[color=blue]
                > Most questions relating to this which haven't already been answered
                > by Alex can be answered by a perusal of the site.py source. It
                > makes good readin'...[/color]

                I'm sure it does and I will spend some bedtime reading (after I finish
                "lost in translation", an extremely good book that only shares the title
                with a movie. I also recommend tsil cafe.)
                [color=blue]
                > Note that between PYTHONPATH and .pth files, possibly the addition
                > of a little sitecustomize.p y file (see again site.py), and the
                > ability to modify sys.path in the __main__ module of the app as
                > Alex suggests, you can do pretty much anything you think is a good
                > thing to do.[/color]

                obviously, I need to grok site.py more. But as a basic philosophical
                basis, I really believe that configuration information should be
                externalized from the program as much as humanly possible. So things
                like modifying sys.path in __main__ is a source of maintenance problems
                further down the road. the way I've been able to encapsulate the
                changes in my demonstration code and separate configuration file treats
                for me an environment which is much more predictable and reliable.

                Another example is what I've done with configuration files in the camram
                project. I created a configuration file module which uses three files
                to build a single view of configuration data. At the base is the
                distribution default configuration elements. Overlaid on that is the
                site configuration file data and last overlaid is the user specific
                configuration file data. End result is that one I upgrade the system, I
                never ever need to touch the configuration file unless I'm modifying a
                new default.

                Another thing I did in order to keep myself from making lots of mistakes
                is that I prefaced every string in the configuration file with a type
                information and as a result when the configuration file variable is
                returned, is always returned in the right form. In addition to the
                normal string, integer, floats, I've also created paths so that file
                names will be automatically converted to the right form for that host.

                I guess this is a long-winded way of saying that I try to create
                environmental support to keep me from making mistakes in my code. I
                forget things, I use speech recognition and have to deal with
                recognition errors in addition to thinking about code or writing. It's
                a helluva lot of cognitive effort so if I can make my code and modules
                work for me and catch my mistakes automatically, then it's a win.

                but I will take your advice to heart. Thank you for giving it.

                ---eric

                Comment

                • Alex Martelli

                  #9
                  Re: saved sys.path

                  Eric S. Johansson <esj@harvee.org > wrote:
                  [color=blue]
                  > basis, I really believe that configuration information should be
                  > externalized from the program as much as humanly possible. So things[/color]

                  I agree. But putting it in a scriptfile instead of a datafile is just
                  as good, IMHO -- just like, say, config info for my bash shell sessions
                  goes into a file .bashrc which is a script rather than being just a
                  datafile. Most of what .bashrc does is setting environment variables,
                  but the extra flexibility of it being a script may still help.

                  Similarly, as I see things, config info for a big app (coded in Python,
                  or in whatever other language as long as it's got a Python accessible
                  interface) can be in a scriptfile instead of a datafile. The scriptfile
                  starts up, adjusts environment info (sys.path foremost, but maybe other
                  stuff too), imports the app's main module, launches 'main(sys.argv) '
                  therein. It _is_ externalized from the program, in my view -- it's a
                  configuration scriptfile. It just works better, with Python, to have
                  the configuration scriptfile call the app's main, rather than doing it
                  the other way round as you would in, say, C (where the app's main starts
                  and then calls a configuration scriptfile).

                  I do like what you've posted, don't get me wrong -- I'm just pointing
                  out that our different preferences on app configuration architectures do
                  not descend from differences on the "externaliz ed from the program"
                  philosophy!


                  Alex

                  Comment

                  • Eric S. Johansson

                    #10
                    Re: saved sys.path

                    Alex Martelli wrote:[color=blue]
                    > I agree. But putting it in a scriptfile instead of a datafile is just
                    > as good, IMHO -- just like, say, config info for my bash shell sessions
                    > goes into a file .bashrc which is a script rather than being just a
                    > datafile. Most of what .bashrc does is setting environment variables,
                    > but the extra flexibility of it being a script may still help.[/color]

                    agreed to a point. What makes me uncomfortable about configuration
                    files like .mumblerc files is what happens to them over time. That this
                    is not a python specific problem and it may just be a quirk of my
                    personality.

                    over time, the base knowledge underlying configuration files changes and
                    manual handling of those configuration files on every update should not
                    be a requirement. automatically updating files which are scripts as
                    well as configuration data is much more difficult than just
                    configuration files alone.

                    Another irritation is that if I set up configuration files to create a
                    particular environment on one machine, replicating the machine
                    independent portions of those configuration files and keeping everything
                    else up-to-date spread across a 10 or 15 other machines is quite a pain.
                    it really could be handled better. Not quite sure how yet but I'm
                    thinking about it. The solution is starting to smell like starter kit
                    and Web server containing machine specific and independent configuration
                    information.

                    [color=blue]
                    > Similarly, as I see things, config info for a big app (coded in Python,
                    > or in whatever other language as long as it's got a Python accessible
                    > interface) can be in a scriptfile instead of a datafile. The scriptfile
                    > starts up, adjusts environment info (sys.path foremost, but maybe other
                    > stuff too), imports the app's main module, launches 'main(sys.argv) '
                    > therein. It _is_ externalized from the program, in my view -- it's a
                    > configuration scriptfile. It just works better, with Python, to have
                    > the configuration scriptfile call the app's main, rather than doing it
                    > the other way round as you would in, say, C (where the app's main starts
                    > and then calls a configuration scriptfile).[/color]

                    so let me see if I understand. If a application has X commands, there
                    are X script files which set up the appropriate environments and call
                    the individual command mainline routines?

                    it would probably help me if you could point me at an example of which
                    you would consider a good version of this environment.
                    [color=blue]
                    > I do like what you've posted, don't get me wrong -- I'm just pointing
                    > out that our different preferences on app configuration architectures do
                    > not descend from differences on the "externaliz ed from the program"
                    > philosophy![/color]

                    thank you. It could probably be included into site.py without too much
                    trouble if there was any interest. I've been meaning to submit for
                    consideration a couple things including a version of smtpd.py that forks
                    off child processes and a file based queue system. But I fear this
                    conversation would start heading in the direction of the cpyan thread. :-)

                    ---eric

                    Comment

                    Working...