Home Download Buy Blog Forum Support

unicode & sys.path

unicode & sys.path

Postby sublimator on Tue Jan 31, 2012 1:06 pm

Read this: http://www.sublimetext.com/blog/article ... ith-python
and then: viewtopic.php?f=6&t=4979&start=0#p22442

Image
Count von Count wrote:Of 3038 users only 31 have non ascii paths. All of them are importable (GetShortPathNameW on windows)
Last edited by sublimator on Thu Feb 02, 2012 9:28 am, edited 3 times in total.
It is better to remain silent and be thought a fool, than to speak out and remove all doubt
sublimator
 
Posts: 649
Joined: Thu Mar 20, 2008 5:41 am

Re: unicode & sys.path

Postby sublimator on Tue Jan 31, 2012 11:26 pm

Image

Image

Count von Count wrote:Out of 1500 users, 16 have non ascii characters in their packages path, of which all are on windows and all are sys.path able via GetShortPathName


Code: Select all
# `inspect.getfile`
def getfile(object):
    """Work out which source or compiled file an object was defined in."""
    if ismodule(object):
        if hasattr(object, '__file__'):
            return object.__file__
        raise TypeError('{!r} is a built-in module'.format(object))
    if isclass(object):
        object = sys.modules.get(object.__module__)
        if hasattr(object, '__file__'):
            return object.__file__
        raise TypeError('{!r} is a built-in class'.format(object))
    if ismethod(object):
        object = object.im_func
    if isfunction(object):
        object = object.func_code
    if istraceback(object):
        object = object.tb_frame
    if isframe(object):
        object = object.f_code
    if iscode(object):
        return object.co_filename
    raise TypeError('{!r} is not a module, class, method, '
                    'function, traceback, frame, or code object'.format(object))

Code: Select all
sys.excepthook(type, value, traceback)

    This function prints out a given traceback and exception to sys.stderr.

    When an exception is raised and uncaught, the interpreter calls sys.excepthook with three arguments, the exception class, exception instance, and a traceback object. In an interactive session this happens just before control is returned to the prompt; in a Python program this happens just before the program exits. The handling of such top-level exceptions can be customized by assigning another three-argument function to sys.excepthook.


Count von Count wrote:Just Saying
It is better to remain silent and be thought a fool, than to speak out and remove all doubt
sublimator
 
Posts: 649
Joined: Thu Mar 20, 2008 5:41 am

Re: unicode & sys.path

Postby sublimator on Tue Jan 31, 2012 11:38 pm

Image

Ernie wrote:Hey Bert. But what if there *IS* someone with unicode in their sys.path as a black cat walks under a ladder on friday the 13th?

Bert wrote: Windows - also available as a portable version

Ernie wrote:Wouldn't it be great if the whole `sublime.packages_path()` was on sys.path?

Bert wrote:So sublime packages could be fully fledged Python packages too if they want?
Last edited by sublimator on Wed Feb 01, 2012 12:04 am, edited 1 time in total.
It is better to remain silent and be thought a fool, than to speak out and remove all doubt
sublimator
 
Posts: 649
Joined: Thu Mar 20, 2008 5:41 am

Re: unicode & sys.path

Postby sublimator on Tue Jan 31, 2012 11:41 pm

Image

Cookie Monster wrote:So I can haz Web.cookies and Web2.cookies?

Count von Count wrote: Yes, let's give these boys an award
It is better to remain silent and be thought a fool, than to speak out and remove all doubt
sublimator
 
Posts: 649
Joined: Thu Mar 20, 2008 5:41 am

Re: unicode & sys.path

Postby skaet on Wed Feb 01, 2012 12:15 am

I don't.. I don't know what's going on here...
skaet
 
Posts: 93
Joined: Thu Sep 16, 2010 3:37 pm

Re: unicode & sys.path

Postby C0D312 on Wed Feb 01, 2012 12:34 am

skaet wrote:I don't.. I don't know what's going on here...


castles is having a moment...

@castles, you might want to start explaining what the hell you're doing/talking about...

Also, you might want to get your head checked out :P
C0D312
 
Posts: 1063
Joined: Sun Jul 10, 2011 3:23 am

Re: unicode & sys.path

Postby sublimator on Wed Feb 01, 2012 12:36 am

Image
It is better to remain silent and be thought a fool, than to speak out and remove all doubt
sublimator
 
Posts: 649
Joined: Thu Mar 20, 2008 5:41 am

Re: unicode & sys.path

Postby weslly on Wed Feb 01, 2012 12:56 am

Image

I'm so confused
weslly
 
Posts: 203
Joined: Sun Aug 28, 2011 3:57 am
Location: Brazil

Re: unicode & sys.path

Postby sublimator on Wed Feb 01, 2012 1:03 am

Image
It is better to remain silent and be thought a fool, than to speak out and remove all doubt
sublimator
 
Posts: 649
Joined: Thu Mar 20, 2008 5:41 am

Re: unicode & sys.path

Postby sublimator on Wed Feb 01, 2012 3:18 am

Image
J.C. Redish's law of useability performance states:

Something is only useful if it's readily useable


What the hell does that even mean?

People are lazy. Imagine you are working your arse off and in the middle of
something you think, Jeez, I wish I had a plugin, or could tweak an existing
plugin, to help me with this task.

Do you
  1. Reach for you handy command source teleportation plugin, make some tweaks
    to a plugin, smash out the work, quicker than it would have taken you
    otherwise and have an enhanced arsenal for the next time you face that
    situation?
  2. Just tough it out and do shit manually to `Get Shit Done` By the time
    you have navigated to the source (Which file was it in again? FFFF) you
    going to get distracted anyway right. Stop fucking around and nail it up
    and get the money.
How the hell does any of this relate to unicode in `sys.path` I imagine?
Everything is connected. A tiny detail can have big implications.

What *is* sys.path? It's basically an array of directories which Python will
search, in turn, for modules. It can take relative (to the working directory) or
absolute paths.

If you'd read the 'not all beer and sunshine' post you'll know that Sublime
employs some import chicanery to preemptively work around possible unicode
characters in sys.path which aren't supported on windows. Before loading each
plugin, sublime makes sure to change the directory to the folder containing the
plugin module.

What are the implications of this? Normally it's possible to take a Python
class/module and use introspection to determine the file it was declared in.
However, when you use relative paths on sys.path, namely '.' as Sublime does,
what's determined as a file for an object is a relative path.

If you been paying attention, you'll recall that Sublime changes directory
before loading each and every plugin. Therefore, the rug has been swept out from
underneath all the relative paths and they float without anchor.

Image

Let's try and make sense of the above:

"todays (psychotic) episode was brought to you by the letter f (__file___)"

You can see it's a QuickPanel containing a bunch of event handlers, commands
grouped by command/event type (window|application|text|on_.*)

Upon quickpanel selection it jumps to the source of PackageControls
`InstallPackageCommand`

How does it do that? You guessed it. It uses the introspection capabilities
exposed in the std lib `inspect` module.

Suddenly the following code makes sense:
Code: Select all
# `inspect.getfile`
def getfile(object):
    """Work out which source or compiled file an object was defined in."""
    if ismodule(object):
        if hasattr(object, '__file__'):
            return object.__file__
        raise TypeError('{!r} is a built-in module'.format(object))
    if isclass(object):
        object = sys.modules.get(object.__module__)
        if hasattr(object, '__file__'):
            return object.__file__
        raise TypeError('{!r} is a built-in class'.format(object))
    if ismethod(object):
        object = object.im_func
    if isfunction(object):
        object = object.func_code
    if istraceback(object):
        object = object.tb_frame
    if isframe(object):
        object = object.f_code
    if iscode(object):
        return object.co_filename
    raise TypeError('{!r} is not a module, class, method, '
                    'function, traceback, frame, or code object'.format(object))

Can you see the `object.__file__` mentioned above? When a module is imported,
rooted from a relative path on `sys.path`, at least on windows, you'll get a
relative path like say `.\Package Control.py`

That's not really enough information to navigate to the source of a plugin is
it?

For the navigation to work in the image above a quick patch was applied to
sublime_plugin.py to monkeypatch imported modules with the `__file__` attribute.

Ok, so if that's all you need to do, why not just do that then?

Recall J.C. Redish's, "Something is only useful if it's readily useable". Now
imagine you were working again, and you'd just successfully teleported to the
command to edit it and after some tinkering you got a half useful exception
message.

Code: Select all
Traceback (most recent call last):
  File ".\sublime_plugin.py", line 345, in run_
   
  File ".\sublimezen.py", line 118, in wrapper
  File ".\sublimezenplugin.py", line 208, in run
  File ".\zencoding\__init__.py", line 75, in run_action
  File ".\zencoding\actions\basic.py", line 96, in match_pair
ZeroDivisionError: integer division or modulo by zero

You thought that monkeypatch would have taken care of it yeah?
Code: Select all
>>> import sublimezenplugin
>>> sublimezenplugin.__file__
u'C:\\Users\\nick\\AppData\\Roaming\\Sublime Text 2\\Packages\\ZenCoding\\sublimezenplugin.py'

Hrmm, the __file__ is being set but something is amiss. Remember
`object.co_filename` from above? Wonder if he's the culprit?

Your coworker is getting ancy. Fuck.

Now if the paths on `sys.path` were absolute paths that traceback would contain
a lot more useful information. You could just copy paste the full paths to the
files. But, I mean, fuck that.

Newsflash, it's 2012, and Python has had `sys.excepthook` for ages
Code: Select all
sys.excepthook

excepthook(type, value, traceback)

This function prints out a given traceback and exception to sys.stderr.

When an exception is raised and uncaught, the interpreter calls sys.excepthook with three arguments, the exception class, exception instance, and a traceback object.

Now recall a relevant section in `inspect.getfile` and pay attention to `traceback`
Code: Select all
    if istraceback(object):
        object = object.tb_frame
    if isframe(object):
        object = object.f_code
    if iscode(object):
        return object.co_filename


So what if you had an sys.excepthook handler that opened an output panel (think
`Tools -> Build` ) and allowed you to navigate the traceback with f4/shift+f4
bindings? What if it automatically navigated to the `most recent call last`?

Image

Count von Count wrote:Out of 1500 users, 16 have non ascii characters in their packages path, of which all are on windows and all are sys.path able via GetShortPathName

So what the fuck is the Count trying to say? And where does he pull these
numbers from anyway? I'd guess he values numbers over intuition. Hes' called the
`Count` after all

Image

Ernie wrote:Hey Bert. But what if there *IS* someone with unicode in their sys.path as a black cat walks under a ladder on friday the 13th?

Bert wrote: Windows - also available as a portable version

Bert is saying in the remote case that someone actually IS on windows (roughly
half of sublime users are on OSX) and does have unicode in their sys.path and
DOES have short path names disabled they can always use the portable
installation.

He let it go without saying that if you can manage JSON for configuration then
you'll be likely be comfortable using a portable installation.

Ernie wrote:Wouldn't it be great if the whole `sublime.packages_path()` was on sys.path?

Bert wrote:So sublime packages could be fully fledged Python packages too if they want?

Now, that's something only tangentially related. If you look at @wbonds
community package index you'll see that there's currently at least 188
packages available.

Image

Captain obvious would probably say "It's only early days." How many packages
will there be at the end of the year?


Image
You could point out that namespacing was invented for a reason.
Code: Select all
>>> import this
The Zen of Python, by Tim Peters

...

Namespaces are one honking great idea -- let's do more of those!
It is better to remain silent and be thought a fool, than to speak out and remove all doubt
sublimator
 
Posts: 649
Joined: Thu Mar 20, 2008 5:41 am

Next

Return to Plugin Development

Who is online

Users browsing this forum: No registered users and 10 guests